def __str__(self): res = self.ret + " " + str_bold(self.name()) res += "(" res += ', '.join( [a[0] + " " + str_special(a[1]) for a in self.def_args]) res += ")" return res
def print_functions_list(func_list): """ func_list - list of pairs (str, int) = (funcName, funcAddress) """ space = 28 print(str_bold("\n\tFunction" + " " * (space - 8) + "Address")) print("\t------------------------------------") for (funcName, funcAddr) in sorted(func_list, key=lambda x: x[0]): space2 = space - len(funcName) if (space2 < 0): space2 = 2 print("\t" + str_special(funcName) + " " * space2 + hex(funcAddr)) print("")
def deliver_shellcode(args): global OUTPUT, OUTPUT_CONSOLE, OUTPUT_PYTHON if (not args): print_help() return OUTPUT = OUTPUT_CONSOLE offset = 0 i = 0 seenOutput = False seenBadBytes = False seenKeepRegs = False seenShortest = False seenLmax = False seenOffset = False seenRw = False bad_bytes = [] keep_regs = [] lmax = get_default_lmax() * 6 # 6 is an arbitrary value here lower_valid_write_addr = 0 higher_valid_write_addr = 0 verbose = False # Parsing arguments # First argument must be the target OS if (len(args) == 0): error("Missing arguments") return system = Systems.str_to_target_system(args[0]) if (system is None): error("Unsupported system '" + args[0] + "'") print( str_bold("\tSupported systems") + ": " + ', '.join( [str_special(s) for s in Systems.available_systems_str()])) return # Then parse the options args = args[1:] while i < len(args): arg = args[i] if (args[i] in [OPTION_BAD_BYTES, OPTION_BAD_BYTES_SHORT]): if (seenBadBytes): error("'" + arg + "' option should be used only once.") return if (i + 1 >= len(args)): error("Missing bad bytes after option '" + arg + "'") return seenBadBytes = True (success, bad_bytes) = parse_bad_bytes(args[i + 1]) if (not success): error(bad_bytes) return i = i + 1 elif (args[i] in [OPTION_KEEP_REGS, OPTION_KEEP_REGS_SHORT]): if (seenKeepRegs): error("'" + arg + "' option should be used only once.") return if (i + 1 >= len(args)): error("Missing registers after option '" + arg + "'") return seenKeepRegs = True (success, keep_regs) = parse_keep_regs(args[i + 1]) if (not success): error(keep_regs) return i = i + 1 elif (args[i] == OPTION_OFFSET or args[i] == OPTION_OFFSET_SHORT): if (seenOffset): error("'" + arg + "' option should be used only once.") return if (i + 1 >= len(args)): error("Missing output format after option '" + arg + "'") return (success, offset) = parse_offset(args[i + 1]) if (not success): error(offset) return i = i + 1 seenOffset = True elif (args[i] in [OPTION_RW_MEMORY, OPTION_RW_MEMORY_SHORT]): if (seenRw): error("'" + arg + "' option should be used only once.") return if (i + 1 >= len(args)): error("Missing address range after option '" + arg + "'") return seenRw = True (success, addr_range) = parse_range(args[i + 1]) if (not success): error(addr_range) return (lower_valid_write_addr, higher_valid_write_addr) = addr_range i = i + 1 elif (args[i] in [OPTION_SHORTEST, OPTION_SHORTEST_SHORT]): if (seenShortest): error("'" + arg + "' option should be used only once.") return seenShortest = True elif (args[i] == OPTION_LMAX or args[i] == OPTION_LMAX_SHORT): if (seenLmax): error("'" + arg + "' option should be used only once.") return if (i + 1 >= len(args)): error("Missing length after option '" + arg + "'") return (success, lmax) = parse_lmax(args[i + 1]) if (not success): error(lmax) return i = i + 1 seenLmax = True elif (args[i] in [OPTION_OUTPUT, OPTION_OUTPUT_SHORT]): if (seenOutput): error("'" + arg + "' option should be used only once.") return if (i + 1 >= len(args)): error("Missing output format after option '" + arg + "'") return if (args[i + 1] in [OUTPUT_CONSOLE, OUTPUT_PYTHON]): OUTPUT = args[i + 1] seenOutput = True i = i + 1 else: error("'" + args[i + 1] + "' output format is not supported") return elif (args[i] in [OPTION_VERBOSE, OPTION_VERBOSE_SHORT]): verbose = True elif (args[i] in [OPTION_HELP, OPTION_HELP_SHORT]): print_help() return else: error("Error. Unknown option '{}'".format(args[i])) return i += 1 # Check if the user loaded some binaries if (not loaded_binary()): error("You should load a binary before building ROPChains") return # Check for valid writable memory to copy strings if (lower_valid_write_addr == 0): (lower_valid_write_addr, higher_valid_write_addr) = get_readwrite_memory() # Select shellcode (shellcode, description) = select_shellcode(curr_arch_type()) if (shellcode is None): return # Set offset set_gadgets_offset(offset) set_binary_offset(offset) # Set verbose set_io_verbose(verbose) # Build the ropchain print('') info("Building exploit: Alloc-Copy-Execute strategy \n\n") params = SearchParametersBinding( keep_regs, bad_bytes, lmax, seenShortest, lower_valid_write_addr=lower_valid_write_addr, higher_valid_write_addr=higher_valid_write_addr) res = deliver_shellcode_build(shellcode, params, system) # Print result if (res is None): error("No matching ROPChain found") elif (isinstance(res, str)): error(res) else: print('') if (OUTPUT == OUTPUT_CONSOLE): print(res.to_str_console(curr_arch_octets(), bad_bytes)) elif (OUTPUT == OUTPUT_PYTHON): print(res.to_str_python(curr_arch_octets(), bad_bytes)) # Reset offset set_gadgets_offset(0) set_binary_offset(0) # Reset verbose set_io_verbose(False)
OPTION_SHORTEST_SHORT = '-s' OPTION_LMAX = '--max-length' OPTION_LMAX_SHORT = '-m' OPTION_HELP = "--help" OPTION_HELP_SHORT = "-h" OPTION_RW_MEMORY = '--rw-memory' OPTION_RW_MEMORY_SHORT = '-rw' OPTION_VERBOSE = "--verbose" OPTION_VERBOSE_SHORT = "-v" CMD_DSHELL_HELP = banner([str_bold("'(A)lloc (C)opy (E)xecute' command"),\ str_special("(Deliver a shellcode & Execute it)")]) CMD_DSHELL_HELP += "\n\n\t"+str_bold("Description:")+\ "\n\t\tThis method first creates an executable memory area,"+\ "\n\t\tthen copies a shellcode into this area, and finally"+\ "\n\t\tjumps to execute the shellcode" CMD_DSHELL_HELP += "\n\n\t"+str_bold("Usage:")+\ "\n\t\tace <sys> [OPTIONS]" CMD_DSHELL_HELP += "\n\n\t" + str_bold("Options") + ":" CMD_DSHELL_HELP += "\n\n\t\t" + str_special( OPTION_BAD_BYTES_SHORT ) + "," + str_special( OPTION_BAD_BYTES ) + " <bytes>\t Bad bytes for payload.\n\t\t\t\t\t Expected format is a list of bytes \n\t\t\t\t\t separated by comas (e.g '-b 0A,0B,2F')" CMD_DSHELL_HELP += "\n\n\t\t" + str_special( OPTION_KEEP_REGS_SHORT ) + "," + str_special(
def syscall(args): global OUTPUT, OUTPUT_CONSOLE, OUTPUT_PYTHON if (not args): print_help() return OUTPUT = OUTPUT_CONSOLE funcName = None offset = 0 i = 0 seenOutput = False seenFunction = False seenBadBytes = False seenKeepRegs = False seenShortest = False seenLmax = False seenOffset = False seenRw = False bad_bytes = [] keep_regs = [] lmax = get_default_lmax() additionnal_lmax = 0 lower_valid_write_addr = 0 higher_valid_write_addr = 0 # Parsing arguments while i < len(args): arg = args[i] if (args[i] in [OPTION_LIST, OPTION_LIST_SHORT]): list_syscalls(args[1:]) return if (args[i] in [OPTION_BAD_BYTES, OPTION_BAD_BYTES_SHORT]): if (seenBadBytes): error("'" + arg + "' option should be used only once.") return if (i + 1 >= len(args)): error("Missing bad bytes after option '" + arg + "'") return seenBadBytes = True (success, bad_bytes) = parse_bad_bytes(args[i + 1]) if (not success): error(bad_bytes) return i = i + 1 elif (args[i] in [OPTION_KEEP_REGS, OPTION_KEEP_REGS_SHORT]): if (seenKeepRegs): error("'" + arg + "' option should be used only once.") return if (i + 1 >= len(args)): error("Missing registers after option '" + arg + "'") return seenKeepRegs = True (success, keep_regs) = parse_keep_regs(args[i + 1]) if (not success): error(keep_regs) return i = i + 1 elif (args[i] == OPTION_OFFSET or args[i] == OPTION_OFFSET_SHORT): if (seenOffset): error("'" + arg + "' option should be used only once.") return if (i + 1 >= len(args)): error("Missing output format after option '" + arg + "'") return (success, offset) = parse_offset(args[i + 1]) if (not success): error(offset) return i = i + 1 seenOffset = True elif (args[i] in [OPTION_RW_MEMORY, OPTION_RW_MEMORY_SHORT]): if (seenRw): error("'" + arg + "' option should be used only once.") return if (i + 1 >= len(args)): error("Missing address range after option '" + arg + "'") return seenRw = True (success, addr_range) = parse_range(args[i + 1]) if (not success): error(addr_range) return (lower_valid_write_addr, higher_valid_write_addr) = addr_range i = i + 1 elif (args[i] in [OPTION_SHORTEST, OPTION_SHORTEST_SHORT]): if (seenShortest): error("'" + arg + "' option should be used only once.") return seenShortest = True elif (args[i] == OPTION_LMAX or args[i] == OPTION_LMAX_SHORT): if (seenLmax): error("'" + arg + "' option should be used only once.") return if (i + 1 >= len(args)): error("Missing length after option '" + arg + "'") return (success, lmax) = parse_lmax(args[i + 1]) if (not success): error(lmax) return i = i + 1 seenLmax = True elif (args[i] in [OPTION_FUNCTION, OPTION_FUNCTION_SHORT]): if (not loaded_binary()): error("You should load a binary before building ROPChains") return elif (seenFunction): error("Option '{}' should be used only once".format(args[i])) return # Get system if (i + 1 >= len(args)): error("Missing argument after option '" + arg + "'") return system = Systems.str_to_target_system(args[i + 1]) if (system is None): error("Unsupported system '" + args[i + 1] + "'") print( str_bold("\tSupported systems") + ": " + ', '.join([ str_special(s) for s in Systems.available_systems_str() ])) return i += 1 # Get function userInput = '' while (i + 1 < len(args) and args[i + 1][0] != "-"): userInput += args[i + 1] i += 1 (funcName, funcArgs) = parse_function(userInput) if (not funcName): error(funcArgs) return seenFunction = True # Get additionnal lmax if string arguments for funcArg in funcArgs: if (isinstance(funcArg, str)): additionnal_lmax += len(funcArg) * curr_arch_octets( ) * 6 # 6 arbitrary max gadgets to copy one byte :/ elif (args[i] in [OPTION_OUTPUT, OPTION_OUTPUT_SHORT]): if (seenOutput): error("'" + arg + "' option should be used only once.") return if (i + 1 >= len(args)): error("Missing output format after option '" + arg + "'") return if (args[i + 1] in [OUTPUT_CONSOLE, OUTPUT_PYTHON]): OUTPUT = args[i + 1] seenOutput = True i = i + 1 else: error("'" + args[i + 1] + "' output format is not supported") return elif (args[i] in [OPTION_HELP, OPTION_HELP_SHORT]): print_help() return else: error("Error. Unknown option '{}'".format(args[i])) return i += 1 # Do the search if (not funcName): error("Missing function to call") return else: # Set offset set_gadgets_offset(offset) set_binary_offset(offset) # Check for valid writable memory to copy strings (!DO IT AFTER SETTING OFFSET) if (lower_valid_write_addr == 0): (lower_valid_write_addr, higher_valid_write_addr) = get_readwrite_memory() # If no max len specified, adjust it for string arguments if (not seenLmax): lmax += additionnal_lmax # Make syscall params = SearchParametersBinding( keep_regs, bad_bytes, lmax, seenShortest, lower_valid_write_addr=lower_valid_write_addr, higher_valid_write_addr=higher_valid_write_addr) res = build_syscall(funcName, funcArgs, params, system) # Print result if (res is None): error("No matching ROPChain found") elif (isinstance(res, str)): error(res) else: print('') if (OUTPUT == OUTPUT_CONSOLE): print(res.to_str_console(curr_arch_octets(), bad_bytes)) elif (OUTPUT == OUTPUT_PYTHON): print( res.to_str_python(curr_arch_octets(), bad_bytes, True, False)) # Reset offset set_gadgets_offset(0) set_binary_offset(0)
OPTION_OFFSET_SHORT = "-off" OPTION_SHORTEST = '--shortest' OPTION_SHORTEST_SHORT = '-s' OPTION_LMAX = '--max-length' OPTION_LMAX_SHORT = '-m' OPTION_HELP = "--help" OPTION_HELP_SHORT = "-h" OPTION_RW_MEMORY = '--rw-memory' OPTION_RW_MEMORY_SHORT = '-rw' CMD_SYSCALL_HELP = banner([str_bold("'syscall' command"),\ str_special("(Call system functions with ROPChains)")]) CMD_SYSCALL_HELP += "\n\n\t"+str_bold("Usage:")+\ "\n\t\tsyscall [OPTIONS]" CMD_SYSCALL_HELP += "\n\n\t" + str_bold("Options") + ":" CMD_SYSCALL_HELP += "\n\t\t"+str_special(OPTION_FUNCTION_SHORT)+","+\ str_special(OPTION_FUNCTION)+" <sys> <func>\t Call a system function" CMD_SYSCALL_HELP += "\n\n\t\t" + str_special( OPTION_BAD_BYTES_SHORT ) + "," + str_special( OPTION_BAD_BYTES ) + " <bytes>\t Bad bytes for payload.\n\t\t\t\t\t Expected format is a list of bytes \n\t\t\t\t\t separated by comas (e.g '-b 0A,0B,2F')" CMD_SYSCALL_HELP += "\n\n\t\t" + str_special( OPTION_KEEP_REGS_SHORT ) + "," + str_special( OPTION_KEEP_REGS ) + " <regs>\t Registers that shouldn't be modified.\n\t\t\t\t\t Expected format is a list of registers \n\t\t\t\t\t separated by comas (e.g '-k edi,eax')"
from ropgenerator.exploit.Shellcode import shellcode from ropgenerator.exploit.DeliverShellcode import deliver_shellcode import sys # Definitions of commands CMD_HELP = "help" CMD_SHELLCODE = "shellcode" CMD_SYSCALL = "syscall" CMD_FUNCTION = "function" CMD_DSHELL = "ace" CMD_MAIN = "main" CMD_EXIT = "exit" helpStr = banner([str_bold('Exploit-Mode Commands'), str_special('(For more info about a command type <cmd -h>)')]) helpStr += '\n\t' + str_bold(CMD_SYSCALL) + ': \tperform a syscall' helpStr += '\n\t' + str_bold(CMD_FUNCTION) + ':\tcall a regular function' helpStr += '\n\t' + str_bold(CMD_DSHELL) + ':\t\tdeliver & execute any shellcode' helpStr += '\n\t' + str_bold(CMD_SHELLCODE) + ': \tmanage shellcodes' helpStr += '\n\n\t' + str_bold(CMD_HELP) + ': \t\tshow this help' helpStr += '\n\t' + str_bold(CMD_MAIN) + ': \t\treturn to the main menu' helpStr += '\n\t' + str_bold(CMD_EXIT) + ': \t\texit ROPGenerator' promptSession = PromptSession(ANSI(u"("+ str_exploit(u'exploit') +u")> ")) def exploit_mode(): """ Returns -------