def add_payload(): print(string_bold('\n\t----------------------\n\tAdding a new payload\n\t----------------------\n')) arch_input = '' while( not arch_input in Analysis.supportedArchs ): sys.stdout.write('\t'+ROPGENERATOR_COLOR_ANSI+'> '+END_COLOR_ANSI+'Enter the target architecture ({}):\n\t'.format\ (','.join([string_special(s) for s in Analysis.supportedArchs]))) arch_input = prompt(u"") shellcode = '' ok = False while( not ok ): sys.stdout.write('\t'+ROPGENERATOR_COLOR_ANSI+'> '+END_COLOR_ANSI+'Enter your payload as a string in hex format:\n\t') shellcode_input = prompt(u"") try: shellcode = shellcode_input.replace('\\x','').decode('hex') ok = True except: ok = False if( not ok ): print(string_special("\tError. Your payload input is in wrong format or invalid")) sys.stdout.write('\t'+ROPGENERATOR_COLOR_ANSI+'> '+END_COLOR_ANSI+'Enter short payload description:\n\t') info = prompt(u"") info = filter( lambda x: x in set(string.printable), info) add_shellcode(arch_input, shellcode, info)
def select_payload(): if( Database.gadgetDB ): arch_input = Analysis.ArchInfo.currentArch print("") notify('Detected architecture from loaded binary: ' + string_special(arch_input)) else: print(string_bold('\n\tOops! You should load a binary before selecting a payload')) return show_shellcodes(arch_input) print("") choice = '' ok = False while( not ok ): sys.stdout.write('\t'+ROPGENERATOR_COLOR_ANSI+'> '+END_COLOR_ANSI+'Select a payload number:\n\t') choice_input = prompt(u"") try: choice = int(choice_input) ok = select_shellcode(arch_input, choice) except: ok = False if( not ok ): print(string_special("\tError. Invalid payload number\n")) show_selected()
def show_shellcodes(arch): global native_shellcodes global custom_shellcodes global selected_shellcode if (arch not in Analysis.supportedArchs): print( string_bold( "\n\tError. Architecture {} is not supported".format(arch))) return print(string_bold('\n\t------------------------------------')) print(string_bold("\tAvailable payloads for arch " + string_special(arch))) if (selected_shellcode[arch] == 0): print("\t(Currently selected: None)") else: print("\t(Currently selected: {})".format( string_payload(str(selected_shellcode[arch])))) print(string_bold('\t------------------------------------')) if ((not native_shellcodes[arch]) and (not custom_shellcodes[arch])): print("\n\tNo payloads available for architecture " + arch) i = 0 for shellcode in custom_shellcodes[arch] + native_shellcodes[arch]: i = i + 1 if (i == selected_shellcode[arch]): number = "(" + ROPGENERATOR_COLOR_ANSI + "*" + END_COLOR_ANSI + ")" else: number = "({})".format(string_bold(str(i))) print("\n\t{} {}\n\t{} - {} bytes".format(number, shellcode[1], \ string_special(short_shellcode(shellcode[0])), str(len(shellcode[0]))))
def remove_shellcode(arch, number): global custom_shellcodes global native_shellcodes if( number > len(custom_shellcodes[arch])): print(string_special("\tYou can not remove ROPGenerator's embedded payloads\n")) return False elif( number < 1 ): print(string_special("\tInvalid payload number\n")) return False del custom_shellcodes[arch][number-1] if( selected_shellcode[arch] > 0 ): selected_shellcode[arch] = selected_shellcode[arch] - 1 return True
def remove_payload(): print(string_bold('\n\t--------------------\n\tRemoving a payload\n\t--------------------\n')) arch_input = '' while( not arch_input in Analysis.supportedArchs ): sys.stdout.write('\t'+ROPGENERATOR_COLOR_ANSI+'> '+END_COLOR_ANSI+'Enter the payload architecture ({}):\n\t'.format\ (','.join([string_special(s) for s in Analysis.supportedArchs]))) arch_input = prompt(u"") show_shellcodes(arch_input) print("") choice = '' ok = False while( not ok ): sys.stdout.write('\t'+ROPGENERATOR_COLOR_ANSI+'> '+END_COLOR_ANSI+'Select a payload to remove:\n\t') choice_input = prompt(u"") try: choice = int(choice_input) ok = remove_shellcode(arch_input, choice) except: ok = False print("") notify('Payload removed')
def show_context(): print(string_bold("\n\tROPGenerator's current context:\n")) print(string_bold("\t{}:\t\t".format(ASLR)) + b2s(values[ASLR])) print(string_bold("\t{}:\t\t".format(NX)) + b2s(values[NX])) print(string_bold("\t{}:\t\t".format(BAD_BYTES)) + \ ','.join([string_special(b) for b in values[BAD_BYTES]])) print("")
def show_selected(): if( not Database.gadgetDB ): print(string_bold("\n\tOops! You should load a binary before selecting a payload")) return else: arch = Analysis.ArchInfo.currentArch if( selected_shellcode[arch] == 0 ): print(string_bold("\n\tNo payload selected for architecture ") + string_special(arch)) return print(string_bold('\n\t-------------------------------')) print(string_bold("\tSelected payload - arch " + string_special(arch))) print(string_bold('\t-------------------------------')) (shellcode, info) = selected(arch) print("\n\t{}\n\n{} - {} bytes".format( info, \ string_special(pack_shellcode(shellcode)), str(len(shellcode))))
def pretty_print_registers(): if (not gadgetDB): print( "You should generate gadgets before looking at the registers. Type 'load help' for help" ) else: print(string_bold("\n\tRegisters present in the gadget database:")) print( string_special("\t(Architeture is '" + Analysis.ArchInfo.currentArch + "')\n")) for reg in Analysis.regNamesTable.keys(): if (reg == Analysis.ArchInfo.ip): print('\t' + reg + string_special(" (instruction pointer)")) elif (reg == Analysis.ArchInfo.sp): print('\t' + reg + string_special(" (stack pointer)")) else: print('\t' + reg)
# ROPGenerator - Config.py module # Stores the configuration for the tool import ropgenerator.Analysis as Analysis from ropgenerator.Colors import notify, string_special, string_bold, info_colored, error_colored, BOLD_COLOR_ANSI, END_COLOR_ANSI import os # Help for the config command CMD_CONFIG_HELP = string_bold("\n\t------------------------------") CMD_CONFIG_HELP += string_bold("\n\tROPGenerator 'config' command\n\t") CMD_CONFIG_HELP += string_special("(Configure ROPGenerator)") CMD_CONFIG_HELP += string_bold("\n\t------------------------------") CMD_CONFIG_HELP += "\n\n\t" + string_bold( "Usage" ) + ":\tconfig show\n\t\tconfig <parameter>=<value> [<parameter>=<value> ...]" CMD_CONFIG_HELP += "\n\n\t" + string_bold( "Parameters" ) + ":\n\t\t" + string_special( "ropgadget" ) + ':\tcommand to run ROPgadget tool (typically\n\t\t\t\t"ROPgadget" or "/path/to/ROPgadget.py")\n\t\t' + string_special( "limit") + ':\t\tnumber of matching gadgets to find for a query' CMD_CONFIG_HELP += "\n\n\t" + string_bold( "Examples" ) + ":\n\t\tconfig ropgadget=ROPgadget\n\t\tconfig ropgadget=/usr/ROPgadget.py limit=4" # ROPGENERATOR CONIGURATION DEFAULT DEFAULT_ARCH = "X86-64" DEFAULT_PATH_ROPGADGET = "ROPgadget" DEFAULT_LIMIT = 3 ARCH = DEFAULT_ARCH PATH_ROPGADGET = DEFAULT_PATH_ROPGADGET
def print_exploit(exploit, output, outstream, colors=True): """ Exploit format is a list of pairs (ropchain, description) """ if (not colors): disable_colors() if (output == OUTPUT_CONSOLE): print( string_bold("\n\tBuilt exploit - {} bytes\n".format( (Analysis.ArchInfo.bits / 8) * sum([len(chain) for (chain, info) in exploit])))) for (chain, info) in exploit: info_string = string_bold( "\t" + '-' * len(info) + '\n') + string_exploit( '\t' + info + '\n') + string_bold("\t" + '-' * len(info) + '\n') outstream.write(info_string) for gadget_num in chain: if (SearchHelper.is_padding(gadget_num)): padding_str = string_special( '0x' + format(SearchHelper.get_padding_unit(gadget_num), '0' + str(Analysis.ArchInfo.bits / 4) + 'x')) if (gadget_num == SearchHelper.DEFAULT_PADDING_UNIT_INDEX): padding_str += " (Padding)" elif (gadget_num in SearchHelper.num_to_str): padding_str += " (" + SearchHelper.num_to_str[ gadget_num] + ")" elif (SearchHelper.get_padding_unit(gadget_num) in SearchHelper.addr_to_gadgetStr): padding_str += " (" + SearchHelper.addr_to_gadgetStr[ SearchHelper.get_padding_unit(gadget_num)] + ")" else: padding_str += " (Custom Padding)" outstream.write("\t" + padding_str + "\n") else: outstream.write( "\t" + string_special(Database.gadgetDB[gadget_num].addrStr) + " (" + string_bold(Database.gadgetDB[gadget_num].asmStr) + ")\n") elif (output == OUTPUT_PYTHON): # Getting endianness to pack values if (Analysis.ArchInfo.bits == 32): endianness_str = '<I' else: endianness_str = '<Q' pack_str = "p += pack(" + endianness_str + "," # Printing outstream.write( string_bold("\n\tBuilt exploit - {} bytes\n".format( (Analysis.ArchInfo.bits / 8) * sum([len(chain) for (chain, info) in exploit]))) + '\n') outstream.write(string_bold("\t#" + '-------------\n')) outstream.write(string_exploit('\t# Padding here\n')) outstream.write(string_bold("\t#" + '-------------\n')) outstream.write("\tp = ''\n") for (chain, info) in exploit: outstream.write(string_bold("\t# " + '-' * len(info)) + '\n') outstream.write(string_exploit('\t# ' + info) + '\n') outstream.write(string_bold("\t# " + '-' * len(info)) + '\n') for gadget_num in chain: if (SearchHelper.is_padding(gadget_num)): padding_str = pack_str padding_str += string_special('0x' + format( SearchHelper.get_padding_unit(gadget_num), '0' + str(Analysis.ArchInfo.bits / 4) + 'x')) + ")" if (gadget_num == SearchHelper.DEFAULT_PADDING_UNIT_INDEX): padding_str += " # Padding" elif (gadget_num in SearchHelper.num_to_str): padding_str += " # " + SearchHelper.num_to_str[ gadget_num] elif (SearchHelper.get_padding_unit(gadget_num) in SearchHelper.addr_to_gadgetStr): padding_str += " # " + SearchHelper.addr_to_gadgetStr[ SearchHelper.get_padding_unit(gadget_num)] else: padding_str += " # Custom Padding" outstream.write("\t" + padding_str + "\n") else: outstream.write( "\t" + pack_str + string_special(Database.gadgetDB[gadget_num].addrStr) + ") # " + string_bold(Database.gadgetDB[gadget_num].asmStr) + '\n') elif (output == OUTPUT_RAW): print("\tRaw output not supported yet :'( ") enable_colors()
OPTION_OUTPUT = '--output-format' OPTION_OUTFILE = '--output-file' # Short options OPTION_VERBOSE_SHORT = '-v' OPTION_OUTPUT_SHORT = '-f' OPTION_OUTFILE_SHORT = '-o' # Options for output OUTPUT_CONSOLE = 'console' OUTPUT_PYTHON = 'python' OUTPUT_RAW = 'raw' # Help CMD_EXPLOIT_HELP = string_bold("\n\t-------------------------------") CMD_EXPLOIT_HELP += string_bold("\n\tROPGenerator 'exploit' command\n\t") CMD_EXPLOIT_HELP += string_special("(Build exploits automatically)") CMD_EXPLOIT_HELP += string_bold("\n\t-------------------------------") CMD_EXPLOIT_HELP += "\n\n\t" + string_bold( "Usage") + ":\texploit [OPTIONS] <" + string_ropg("subcommand") + ">" CMD_EXPLOIT_HELP += "\n\n\t"+string_bold("Sub-commands")+":"+\ "\n\t\t"+string_ropg("run-payload")+"\t("+string_special('build an exploit that runs the selected payload')+")" CMD_EXPLOIT_HELP += "\n\n\t" + string_bold("Options") + ":" CMD_EXPLOIT_HELP += "\n\t\t" + string_special( OPTION_VERBOSE_SHORT) + "," + string_special(OPTION_VERBOSE) CMD_EXPLOIT_HELP += "\n\t\t" + string_special( OPTION_OUTPUT_SHORT) + "," + string_special( OPTION_OUTPUT) + " <" + '|'.join( [string_special(g) for g in [OUTPUT_CONSOLE, OUTPUT_PYTHON]]) + ">" CMD_EXPLOIT_HELP += "\n\t\t" + string_special( OPTION_OUTFILE_SHORT) + "," + string_special( OPTION_OUTFILE) + " <filename>"
# ROPGenerator - PAYLOAD module # Building PAYLOADs from ropgenerator.Colors import BOLD_COLOR_ANSI, END_COLOR_ANSI, string_bold, info_colored, string_special, ROPGENERATOR_COLOR_ANSI, notify from ropgenerator.payload.Shellcode import remove_shellcode, show_shellcodes, save_shellcodes, add_shellcode, select_shellcode, show_selected from prompt_toolkit import prompt import ropgenerator.Analysis as Analysis import sys import string import ropgenerator.Database as Database CMD_PAYLOAD_HELP = string_bold("\n\t------------------------------------") CMD_PAYLOAD_HELP += string_bold("\n\tROPGenerator 'payload' command\n\t") CMD_PAYLOAD_HELP += string_special("(Manage payloads for your exploit)") CMD_PAYLOAD_HELP += string_bold("\n\t------------------------------------") CMD_PAYLOAD_HELP += "\n\n\t"+string_bold("Usage")+\ ":\tpayload current \t(" + string_special('show currently selected payload') + ")" +\ "\n\t\tpayload list [<arch>]\t(" + string_special('list available payloads') + ")" +\ "\n\t\tpayload select \t\t(" + string_special('select a payload for your exploit') + ")" +\ "\n\t\tpayload add\t\t("+ string_special('add a payload to your exploit') + ")"+\ "\n\t\tpayload remove\t\t("+string_special('remove a previously added payload') + ")" CMD_PAYLOAD_HELP += "\n\n\t"+string_bold("Supported architectures")+": "+','.join([string_special(arch) for arch in Analysis.supportedArchs]) def print_help(): print(CMD_PAYLOAD_HELP) def payload(args): # Parsing arguments if( args[0] == 'current' ): show_selected() elif( args[0] == 'list' ): list_payloads(args[1:])
def check_context(): info_colored(string_bold('Checking exploit context\n')) notify('NX stack: ' + b2s(values[NX])) notify('ASLR: ' + b2s(values[NX])) notify('Forbidden bytes in exploit: ' +\ ','.join([string_special(b) for b in values[BAD_BYTES]]))
# Context parameters ASLR='ASLR' NX='NX' BAD_BYTES='BAD-BYTES' # Default values values = dict() values[ASLR]=True values[NX]=True values[BAD_BYTES]=[] # Help for the context command CMD_CONTEXT_HELP = string_bold("\n\t-----------------------------------") CMD_CONTEXT_HELP += string_bold("\n\tROPGenerator 'context' command\n\t") CMD_CONTEXT_HELP += string_special("(Set a security context for your exploit)") CMD_CONTEXT_HELP += string_bold("\n\t-----------------------------------") CMD_CONTEXT_HELP += "\n\n\t"+string_bold("Usage")+":\tcontext show\n\t\tcontext <parameter>=<value> [<parameter>=<value> ...]" CMD_CONTEXT_HELP += "\n\n\t"+string_bold("Parameters")+\ ":\n\t\t"+string_bold('Name'+"\t\tValues")+\ "\n\t\t"+string_special(ASLR)+":\t\t'yes'/'no'"+\ "\n\t\t"+string_special(NX)+":\t\t'yes'/'no'"+\ "\n\t\t"+string_special(BAD_BYTES)+':\tlist of bad bytes' CMD_CONTEXT_HELP += "\n\n\t"+string_bold("Examples")+":\n\t\tcontext ASLR=yes\n\t\tcontext ASLR=no NX=yes" def print_help(): print(CMD_CONTEXT_HELP) def b2s(value):
def main(time_mesure=False): if (time_mesure): pr = cProfile.Profile() pr.enable() style = Style.from_dict({ 'prompt': '#00FF00', }) message = [ (u'class:prompt', u'>>> '), ] #try: # Launching ROPGenerator write_colored(ASCII_art) Config.load_config() Logs.init() session = PromptSession() quit = False while (not quit): try: user_input = session.prompt(message, style=style) args = user_input.split() argslen = len(args) if (argslen > 0): command = args[0] else: command = None if (command == None): pass elif (command == CMD_HELP): print( string_bold( "\n\t-----------------------------------------------------------\n\tROPGenerator commands" )) print( string_special( "\t(For more information about a command type '<command> help')" )) print( string_bold( "\t-----------------------------------------------------------\n" )) print('\t' + string_bold(CMD_LOAD) + ': \t\tload usable gadgets from a binary file') print('\t' + string_bold(CMD_FIND) + ': \t\tsemantic search for gadgets/ropchains') print('\t' + string_bold(CMD_PAYLOAD) + ': \tmanage payloads to use in your exploit') print('\t' + string_bold(CMD_EXPLOIT) + ':\tbuild an exploit') print( '\t' + string_bold(CMD_REGISTERS) + ': \tprint available registers for the current architecture' ) print('\t' + string_bold(CMD_CONFIG) + ': \tconfigure ROPGenerator') print('\t' + string_bold(CMD_HELP) + ': \t\tprint available commands') print('\t' + string_bold(CMD_EXIT) + ': \t\texit ROPGenerator') elif (command == CMD_FIND): if (argslen > 1): if (args[1] == CMD_HELP): SearchEngine.print_help() else: SearchEngine.set_user_input(user_input[len(CMD_FIND):]) SearchEngine.find_gadgets(args[1:]) else: SearchEngine.print_help() #print("Missing arguments. Type 'find help' for help") elif (command == CMD_EXPLOIT): if (argslen > 1): if (args[1] == CMD_HELP): Exploit.print_help() else: Exploit.exploit(args[1:]) else: Exploit.print_help() elif (command == CMD_PAYLOAD): if (argslen > 1): if (args[1] == CMD_HELP): Payload.print_help() else: Payload.payload(args[1:]) else: Payload.print_help() #print("Missing arguments. Type 'payload help' for help") elif (command == CMD_LOAD): if (argslen > 1): if (args[1] == CMD_HELP): Load.print_help() else: Load.load(args[1:]) else: Load.print_help() #print("Missing arguments. Type 'load help' for help") elif (command == CMD_REGISTERS): pretty_print_registers() elif (command == CMD_CONFIG): if (argslen > 1): if (args[1] == CMD_HELP): Config.print_help() else: Config.update_config(args[1:]) else: Config.print_help() #print("Missing arguments. Type 'config help' for help") elif (command == CMD_CONTEXT): if (argslen > 1): if (args[1] == CMD_HELP): Context.print_help() else: Context.context(args[1:]) else: Context.print_help() elif (command == CMD_EXIT): quit = True Config.save_config() Payload.save_payloads() else: print(string_bold("\n\tUnknown command '" + command+\ "'. Type 'help' for available commands")) # New line if (command != None): print("") except KeyboardInterrupt: pass info_colored(string_bold("Closing ROPGenerator...\n")) #except KeyboardInterrupt: # pass #except Exception as e: # print("") # error_colored("ROPGenerator failed unexpectedly\n") # print(e) if (time_mesure): pr.disable() s = pstats.Stats(pr).sort_stats('tottime') s.print_stats(0.02) exit(0)
# RPGEnerator - Load.py module # Read a binary and load the gadgets contained in the file import ropgenerator.Database as Database import ropgenerator.Analysis as Analysis import ropgenerator.generate_opcodes as generate_opcodes import ropgenerator.SearchHelper as SearchHelper import ropgenerator.Gadget as Gadget import ropgenerator.BinaryScanner as BinaryScanner from ropgenerator.Colors import string_bold, info_colored, BOLD_COLOR_ANSI, END_COLOR_ANSI, string_special # Help for the load command CMD_LOAD_HELP = string_bold("\n\t---------------------------------") CMD_LOAD_HELP += string_bold("\n\tROPGenerator 'load' command\n\t") CMD_LOAD_HELP += string_special("(Load gadgets from a binary file)") CMD_LOAD_HELP += string_bold("\n\t---------------------------------") CMD_LOAD_HELP += "\n\n\t" + string_bold( "Usage") + ":\tload [OPTIONS] <filename>" CMD_LOAD_HELP += "\n\n\t" + string_bold( "Options") + ": No options available for the moment" CMD_LOAD_HELP += "\n\n\t" + string_bold( "Examples" ) + ":\n\t\tload /bin/ls\t\t(load gadgets from /bin/ls program)\n\t\tload ../test/vuln_prog\t(load gadgets from own binary)" def print_help(): print(CMD_LOAD_HELP) def load(args):