Exemplo n.º 1
0
def load(args):

    if (len(args) > 0):
        filename = args[0]
        msg = string_bold(
            "Extracting gadgets from file") + " '" + filename + "'"
        if (len(args) > 1):
            msg += " (Ignoring extra arguments '"
            msg += ', '.join(args[1:])
            msg += "')"
        info_colored(msg + '\n')
    else:
        print(
            string_bold("\n\tMissing argument.\n\tType 'load help' for help"))

    # Cleaning the data structures
    Gadget.reinit()
    Database.reinit()
    Analysis.reinit()
    SearchHelper.reinit()

    if (generate_opcodes.generate(filename)):
        BinaryScanner.set_binary(filename)
        Database.generated_gadgets_to_DB()
        Database.simplifyGadgets()
        Database.gadgetLookUp.fill()
Exemplo n.º 2
0
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]))))
Exemplo n.º 3
0
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("")
Exemplo n.º 4
0
def print_config():
    global ARCH
    global PATH_ROPGADGET
    global LIMIT

    print(string_bold("\n\tROPGenerator's current configuration:\n"))
    print(string_bold("\tropgadget:\t") + PATH_ROPGADGET)
    print(string_bold("\tlimit:\t\t") + str(LIMIT))
    print("")
Exemplo n.º 5
0
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')
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
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()
Exemplo n.º 8
0
def update_config(args):
    """
    Update config with user supplied args
    """
    if (len(args) == 1 and args[0] == 'show'):
        print_config()
        return

    info_colored(string_bold("Updating configuration\n"))
    for arg in args:
        arg_list = arg.split('=')
        left = arg_list[0]
        if (len(arg_list) < 2):
            notify("Error. Missing right part in argument " + arg)
            return
        else:
            right = arg_list[1]
            if (left == "arch"):
                set_arch(right)
            elif (left == "ropgadget"):
                set_ropgadget(right)
            elif (left == "limit"):
                set_limit(right)
            else:
                notify("Ignored unknown parameter '" + left + "'")
Exemplo n.º 9
0
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))))
Exemplo n.º 10
0
def generate(filename):
    """
    Returns true if success, false otherwise 
    """
    global opcodes_file

    if (not os.path.isfile(filename)):
        print(
            string_bold(
                "\n\tError. Could not find file '{}'".format(filename)))
        return False

    binType = check_binaryType(filename)
    if (not binType):
        error_colored("Could not determine architecture for binary: " +
                      filename + "\n")
        return False
    else:
        Config.set_arch(binType, quiet=True)

    ropgadget = Config.PATH_ROPGADGET
    notify("Executing ROPgadget as: " + ropgadget)
    try:
        p = subprocess.Popen(
            [ropgadget, "--binary", filename, "--dump", "--all"],
            stdout=subprocess.PIPE)
    except Exception as e:
        error_colored("Could not execute ' " + ropgadget + " --binary " +
                      filename + " --dump '")
        print("\tError message is: " + str(e))
        print(
            "\n\t(Maybe check/update your config with the 'config' command, or make sure you have the last ROPgadget version installed)"
        )
        return False

    f = open(opcodes_file, "w")

    # Write gadgets
    first = True
    count = 0
    for l in p.stdout.readlines():
        if ("0x" in l):
            arr = l.split(' ')
            addr = arr[0]
            gadget = arr[-1]
            it = iter(gadget)
            gadget = ''.join(a + b for a, b in zip(it, it))
            f.write(addr + '#')
            f.write(gadget + '\n')
            count += 1
    f.close()

    notify("Finished : %d gadgets generated" % (count))

    return (count > 0)
Exemplo n.º 11
0
def set_context(args):
    for arg in args:
        try:
            (left,right)=arg.split('=')
            if( not left or not right ):
                print(string_bold("\n\tError. Invalid parameter {}".format(arg)))
                return 
        except:
            print(string_bold("\n\tError. Invalid parameter {}".format(arg)))
            return
        if( left in [ASLR, NX] ):
            if( right not in ['yes', 'no']):
                print(string_bold("\n\tError. Invalid {} value: {}".format(left, right)))
                return 
            values[left]= s2b(right)
        elif( left == BAD_BYTES ):
            print(string_bold("\n\tError. Bad bytes not supported yet for context. Comming soon ;) ".format(left, right)))
            return
        else:
            print(string_bold("\n\tError. Unknown parameter: {}".format(left)))
            return 
Exemplo n.º 12
0
def payload(args):
    # Parsing arguments
    if( args[0] == 'current' ):
        show_selected()
    elif( args[0] == 'list' ):
        list_payloads(args[1:])
    elif( args[0] == 'add' ):
        add_payload()
    elif( args[0] == 'select'):
        select_payload()
    elif( args[0] == 'remove' ):
        remove_payload()
    else:
        print(string_bold("\n\tError. Unknown sub-command '{}'".format(args[0])))
    return 
Exemplo n.º 13
0
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)
Exemplo n.º 14
0
def build_REG_write_to_memory():
    global record_REG_write_to_memory
    global built_REG_write_to_memory

    if (built_REG_write_to_memory):
        return

    # Initialization for printing charging bar
    chargingBarSize = Analysis.ssaRegCount
    chargingBarStr = " " * chargingBarSize
    info_colored(
        string_bold("Performing additionnal analysis") +
        ": writing registers on stack\n")
    sys.stdout.write("\tProgression [")
    sys.stdout.write(chargingBarStr)
    sys.stdout.write("]\r\tProgression [")
    sys.stdout.flush()

    # Initializing the dictionnaries
    for reg in range(0, Analysis.ssaRegCount):
        record_REG_write_to_memory[reg] = dict()
        for reg2 in range(0, Analysis.ssaRegCount):
            record_REG_write_to_memory[reg][reg2] = dict()

    # Filling the dictionnaries :

    db = Database.gadgetLookUp[GadgetType.REGtoMEM]
    for reg in range(0, Analysis.ssaRegCount):
        # Printing the charging bar
        sys.stdout.write("|")
        sys.stdout.flush()

        for i in range(0, len(db.addr_list)):
            addr = db.addr_list[i]
            # We want to store only addresses of type REG +-/* CST
            (isInc, inc) = addr.isRegIncrement(addr)
            if (isInc):
                add_REG_write_to_memory(reg, reg_list[0], offset, [
                    g for g in db.written_values[i]
                    if Database.gadgetDB[g].hasNormalRet()
                    and Database.gadgetDB[g].isValidSpInc()
                ])

    sys.stdout.write("\r" + " " * 70 + "\r")
    built_REG_write_to_memory = True
Exemplo n.º 15
0
def simplifyGadgets():
    """
    Apply some simplifications on the gadget dependencies
    """
    chargingBarSize = 30
    chargingBarStr = " " * chargingBarSize
    i = 0
    info_colored(string_bold("Processing gadgets\n"))
    for gadget in gadgetDB:
        charging_bar(len(gadgetDB) - 1, i, 30)
        gadget.getDependencies().simplifyConditions()
        i = i + 1

    # Second pass analysis once all gadgets are collected
    for gadget in gadgetDB:
        gadget.calculateSpInc()
        gadget.calculateRet()
        gadget.calculatePreConstraint()
Exemplo n.º 16
0
def run_payload():
    """
    Builds an exploit that aims at executing a payload 
    """
    # get the shellcode
    (payload, payload_info) = selected(Analysis.ArchInfo.currentArch)
    if (not payload):
        print(
            string_bold("\n\tError, no payload selected :/" +
                        "\n\tCheck the 'payload select' command "))
        return

    # Check context
    Context.check_context()

    # Build exploit
    exploit = build_mprotect_datareuse(payload)
    return exploit
Exemplo n.º 17
0
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]]))
Exemplo n.º 18
0
    def fill(self):
        def filter_cond(condition):
            if (condition.isTrue()):
                return None
            else:
                return condition

        # Initialize the data structures !
        self.types[GadgetType.CSTtoMEM] = cstToMemLookUp()
        self.types[GadgetType.REGEXPRtoMEM] = exprToMemLookUp()
        self.types[GadgetType.MEMEXPRtoMEM] = exprToMemLookUp()
        for reg_num in Analysis.revertRegNamesTable.keys():
            self.types[GadgetType.CSTtoREG][reg_num] = cstLookUp()
            self.types[GadgetType.REGEXPRtoREG][reg_num] = exprLookUp(reg_num)
            self.types[GadgetType.MEMEXPRtoREG][reg_num] = exprLookUp(reg_num)

        # Initialize the printed charging bar
        chargingBarSize = 30
        chargingBarStr = " " * chargingBarSize
        info_colored(string_bold("Sorting gadgets semantics\n"))
        # Update the gadgetLookUp table
        for i in range(0, len(gadgetDB)):
            charging_bar(len(gadgetDB) - 1, i, 30)
            gadget = gadgetDB[i]
            # Check for special gadgets (int 0x80 and syscall
            if (gadget.sort == GadgetSort.INT80):
                self.list_int80.append(i)
                continue
            elif (gadget.sort == GadgetSort.SYSCALL):
                self.list_syscall.append(i)
                continue
            # For XXXtoREG
            for reg, deps in gadget.getDependencies().regDep.iteritems():
                for dep in deps:
                    # For REGEXPRtoREG
                    if (isinstance(dep[0], Expr.SSAExpr)):
                        self.types[GadgetType.REGEXPRtoREG][
                            reg.num].add_gadget(dep[0].reg.num,
                                                0,
                                                i,
                                                condition=filter_cond(dep[1]))
                    elif (isinstance(dep[0], Expr.Op)):
                        (isInc, num, inc) = dep[0].isRegIncrement(-1)
                        if (isInc):
                            self.types[GadgetType.REGEXPRtoREG][
                                reg.num].add_gadget(num,
                                                    inc,
                                                    i,
                                                    condition=filter_cond(
                                                        dep[1]))
                    # For CSTtoREG
                    elif (isinstance(dep[0], Expr.ConstExpr)):
                        self.types[GadgetType.CSTtoREG][reg.num].add_gadget(
                            dep[0].value, i, condition=filter_cond(dep[1]))
                    # For MEMEXPRtoREG
                    elif (isinstance(dep[0], Expr.MEMExpr)):
                        if (isinstance(dep[0].addr, Expr.SSAExpr)):
                            self.types[GadgetType.MEMEXPRtoREG][
                                reg.num].add_gadget(dep[0].addr.reg.num,
                                                    0,
                                                    i,
                                                    condition=filter_cond(
                                                        dep[1]))
                        elif (isinstance(dep[0].addr, Expr.Op)):
                            (isInc, num, inc) = dep[0].addr.isRegIncrement(-1)
                            if (isInc):
                                self.types[GadgetType.MEMEXPRtoREG][
                                    reg.num].add_gadget(num,
                                                        inc,
                                                        i,
                                                        condition=filter_cond(
                                                            dep[1]))
                    # If we found a true dependency, no need to check others
                    #if( dep[1].isTrue()):
                    #    break

            # For XXXtoMEM
            for addr, deps in gadget.getDependencies().memDep.iteritems():
                addr_reg = None
                addr_cst = None
                # Check if the address is of type REG + CST
                if (isinstance(addr, Expr.SSAExpr)):
                    addr_reg = addr.reg.num
                    addr_cst = 0
                elif (isinstance(addr, Expr.Op)):
                    (isInc, addr_reg, addr_cst) = addr.isRegIncrement(-1)
                    if (not isInc):
                        continue
                else:
                    continue

                # Going through dependencies
                for dep in deps:
                    # Check for integrity of the database
                    if (not isinstance(dep[0], Expr.Expr)):
                        raise Exception(
                            "Invalid dependency in fillGadgetLookUp(): " +
                            str(dep[0]))

                    # For REGEXPRtoMEM
                    if (isinstance(dep[0], Expr.SSAExpr)):

                        self.types[GadgetType.REGEXPRtoMEM].add_gadget(addr_reg, \
                            addr_cst, dep[0].reg.num, 0, i,condition=filter_cond(dep[1]))
                    elif (isinstance(dep[0], Expr.Op)):
                        (isInc, num, inc) = dep[0].isRegIncrement(-1)
                        if (isInc):
                            self.types[GadgetType.REGEXPRtoMEM].add_gadget(addr_reg,\
                             addr_cst, num, inc, i,condition=filter_cond(dep[1]))

                    # For CSTtoMEM
                    elif (isinstance(dep[0], Expr.ConstExpr)):
                        self.types[GadgetType.CSTtoMEM].add_gadget(addr_reg, \
                        addr_cst, dep[0].value, i,condition=filter_cond(dep[1]))
                    # For MEMEXPRtoMEM
                    elif (isinstance(dep[0], Expr.MEMExpr)):
                        if (isinstance(dep[0].addr, Expr.SSAExpr)):
                            self.types[GadgetType.MEMEXPRtoMEM].add_gadget(addr_reg,\
                             addr_cst, dep[0].addr.reg.num, 0, i,condition=filter_cond(dep[1]))
                        elif (isinstance(dep[0].addr, Expr.Op)):
                            (isInc, num, inc) = dep[0].addr.isRegIncrement(-1)
                            if (isInc):
                                self.types[GadgetType.MEMEXPRtoMEM].add_gadget(addr_reg,\
                                 addr_cst, num, inc, i,condition=filter_cond(dep[1]))
                    # If we found a true dependency, no need to check others
                    #if( dep[1].isTrue()):
                    #    break

        # Clean the charging bar
        sys.stdout.write("\r" + " " * 70 + "\r")
Exemplo n.º 19
0
# 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
Exemplo n.º 20
0
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()
Exemplo n.º 21
0
def build_mprotect_datareuse(payload):
    """
    Build a ROPchain that does :
        - mprotect RWX to a static memory area
        - copy payload to this memory area
        - jmp to payload 
    """
    info_colored(string_bold('Building mprotect + datareuse exploit\n'))

    # Get the initial constraint
    constraint = Constraint().add(ConstraintType.BAD_BYTES,
                                  Context.bad_bytes())

    # Then get address of the bss
    notify('Getting .bss address')
    bss_addr = BinaryScanner.bss_address()
    if (not bss_addr):
        info("Could not find static .bss section to copy payload to")
        return []
    else:
        info("Found .bss at address: " + hex(bss_addr))

    # Then get the mprotect chain
    notify('Building mprotect ropchain to make .bss RWX')
    if (Analysis.ArchInfo.currentArch == "X86-64"):
        mprotect_chain = mprotect_X64(bss_addr, len(payload) + 1, 7)
    elif (Analysis.ArchInfo.currentArch == "X86"):
        mprotect_chain = mprotect_X86(bss_addr, len(payload) + 1, 7)
    else:
        info("mprotect chain for arch '{}' not supported yet".format(
            Analysis.ArchInfo.currentArch))
        return []
    if (not mprotect_chain):
        info("Could not build mprotect chain")
        return []
    mprotect_info = "Create RWX memory : calling mprotect({},{},{})".format(
        hex(bss_addr),
        len(payload) + 1, 7)

    # Then write shellcode in memory
    notify('Building data-reuse chain to copy payload into .bss')
    datareuse = search.str_to_mem(bss_addr,
                                  '.bss',
                                  payload,
                                  constraint.add(ConstraintType.CHAINABLE_RET,
                                                 []),
                                  hex_info=True)
    if (not datareuse):
        info("Could not build datareuse chain")
        return []
    datareuse_info = "Copy payload into custom RWX memory"

    notify('Building a chain to jump to .bss and execute payload')
    # Then jump to the payload
    ip_num = Analysis.regNamesTable[Analysis.ArchInfo.ip]
    jmp_payload = search.jmp_addr(bss_addr, constraint)
    if (not jmp_payload):
        info("Could not build jmp_payload chain")
        return []
    jmp_payload_info = "Jump to payload"
    # Concatenate to full exploit
    return [[mprotect_chain, mprotect_info], [datareuse, datareuse_info],
            [jmp_payload, jmp_payload_info]]
Exemplo n.º 22
0
def exploit(args):
    # Parse args
    i = 0
    verbose = False
    output = OUTPUT_CONSOLE
    outfile = sys.stdout
    seenOutput = False
    seenOutfile = False
    colors = True
    while (i < len(args) and args[i][0] == '-'):
        if (args[i] == OPTION_VERBOSE or args[i] == OPTION_VERBOSE_SHORT):
            verbose = True
        elif (args[i] == OPTION_OUTPUT or args[i] == OPTION_OUTPUT_SHORT):
            if (seenOutput):
                print(
                    string_bold("\n\tError. '" + OPTION_OUTPUT +
                                "' option should be used only once."))
                return
            if (i + 1 >= len(args)):
                print(
                    string_bold(
                        "\n\tError. Missing output format after option '" +
                        args[i] + "'"))
                return
            if (args[i + 1] in [OUTPUT_CONSOLE, OUTPUT_PYTHON]):
                output = args[i + 1]
                seenOutput = True
                i = i + 1
            else:
                print(
                    string_bold("\n\tError. '" + args[i + 1] +
                                "' output format is not supported"))
                return
        elif (args[i] == OPTION_OUTFILE or args[i] == OPTION_OUTFILE_SHORT):
            if (seenOutfile):
                print(
                    string_bold("\n\tError. '" + OPTION_OUTFILE +
                                "' option should be used only once."))
                return
            if (i + 1 >= len(args)):
                print(
                    string_bold(
                        "\n\tError. Missing output format after option '" +
                        args[i] + "'"))
                return
            try:
                outfile = open(args[i + 1], "w")
                seenOutfile = True
                colors = False  # No ANSI colors when writing in file
                i = i + 1
            except:
                print(
                    string_bold("\n\tError. Could not open file '{}'".format(
                        args[i + 1])))
                return
        else:
            print(string_bold("\n\tUnknown option '{}'".format(args[i])))
            return
        i = i + 1
    # Process options
    verbose_mode(verbose)

    if (i == len(args)):
        print(
            string_bold(
                "\n\tMissing sub-command\n\tType 'exploit help' for help".
                format(args[0])))
        return

    # BuIld exploit
    if (args[i] == 'run-payload'):
        exploit_chain = run_payload()
        if (exploit_chain):
            print_exploit(exploit_chain, output, outfile, colors)
        else:
            print(string_bold("\n\tFailed to build exploit"))
    else:
        print(string_bold("\n\tSub-command '{}' not supported".format(
            args[0])))

    # Restore normal state
    verbose_mode(False)
    # Close output stream
    if (seenOutfile):
        outfile.close()
Exemplo n.º 23
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):
Exemplo n.º 24
0
# Options
OPTION_VERBOSE = '--verbose'
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(
Exemplo n.º 25
0
import ropgenerator.Context as Context
import ropgenerator.exploit.Exploit as Exploit
import ropgenerator.Logs as Logs

from prompt_toolkit import PromptSession
from prompt_toolkit.history import InMemoryHistory
from prompt_toolkit.completion import WordCompleter
from prompt_toolkit.styles import Style

import sys
import cProfile, pstats

ASCII_art = string_bold("""
   ___  ____  ___  _____                     __          
  / _ \/ __ \/ _ \/ ______ ___ ___ _______ _/ /____  ________
 / , _/ /_/ / ___/ (_ / -_/ _ / -_/ __/ _ `/ __/ _ \/ ______/
/_/|_|\____/_/   \___/\__/_//_\__/_/  \_,_/\__/\___/_/ v0.5 
    
 
""")

# Definitions of commands
CMD_HELP = "help"
CMD_LOAD = "load"
CMD_REGISTERS = "registers"
CMD_FIND = "find"
CMD_PAYLOAD = "payload"
CMD_CONTEXT = "context"
CMD_CONFIG = "config"
CMD_EXPLOIT = "exploit"
CMD_EXIT = "exit"
Exemplo n.º 26
0
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)
Exemplo n.º 27
0
# Manage the context for exploit development
from ropgenerator.Colors import string_special, string_bold, notify, info_colored

# 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)
Exemplo n.º 28
0
# 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:])
Exemplo n.º 29
0
def generated_gadgets_to_DB():
    """
    Generates the list of the available gadgets for ROP 
    Usage : must be called after the gadgets opcodes have been stored into the opcodes_gadget array in Generated_opcodes.py file.
    Result : 
        No value returned. But the gadgets are stored in the gadgets[] array in Database module.
    """
    global sigint
    global current_gadget
    global old_stdout
    global old_stderr

    def sigint_handler(signal, frame):
        global sigint
        sigint = True

    # Read all gadgets that have been generated !
    f = open(opcodes_file, "r")
    asmGadgets = []
    for line in f:
        (addr, instr) = line[:-1].split('#')
        addr = int(addr, 16)
        instr = instr.decode("hex")
        asmGadgets.append((addr, instr))
    f.close()
    # Sort the gadgets according to their instructions
    asmGadgets.sort(key=lambda x: x[1])
    # Analyze them
    junk_file = open("/dev/null", "w")
    i = 0
    success = 0
    warnings = 0
    info_colored(
        string_bold("Working under architecture: ") +
        Analysis.ArchInfo.currentArch + '\n')
    info_colored(string_bold("Creating gadget database\n"))
    warnings_file = ROPGENERATOR_DIRECTORY + "warnings-logs"
    f = open(warnings_file, "w")
    original_sigint_handler = signal.getsignal(signal.SIGINT)
    signal.signal(signal.SIGINT, sigint_handler)
    startTime = datetime.now()
    for g in asmGadgets:
        if (sigint):
            break
        asm = g[1]
        addr = g[0]
        try:
            charging_bar(len(asmGadgets) - 1, i, 30)
            #print("Gadget : " + '\\x'.join(["%02x" % ord(c) for c in asm]) + "\n")
            sys.stdout = sys.stderr = junk_file
            signal.alarm(1)
            gadget = Gadget(i, addr, asm)
            signal.alarm(0)
            sys.stdout = old_stdout
            sys.stderr = old_stderr
            success += 1
            gadgetDB.append(gadget)

        except Exception as e:
            signal.alarm(0)
            sys.stdout = old_stdout
            sys.stderr = old_stderr
            if (not isinstance(e, GadgetException)):
                warnings = warnings + 1
                f.write("Unexpected error in : " +
                        '\\x'.join(["%02x" % ord(c) for c in asm]) +
                        "\nException type: " + str(type(e)) +
                        "\nException message: " + str(e) + '\n\n')

        i = i + 1

    # Trick to find syscalls
    for addr in find_syscalls():
        gadget = Gadget(i, addr, '\x0f\x05')
        gadgetDB.append(gadget)
        i = i + 1

    # Restoring the state
    f.close()
    junk_file.close()
    signal.signal(signal.SIGINT, original_sigint_handler)
    # This variable should be written before calculating spInc or simplifying conditions !!!
    Expr.nb_regs = Analysis.ssaRegCount - 1

    # Getting time
    cTime = datetime.now() - startTime
    # Printing summary information
    if (sigint):
        print("\n")
        error_colored(
            "SIGINT ended the analysis prematurely, gadget database might be incomplete\n"
        )
        sigint = False
    notify("Gadgets analyzed : " + str(i))
    notify("Successfully translated : " + str(success))
    notify("Computation time : " + str(cTime))
    if (warnings > 0):
        pass