示例#1
0
def list_syscalls(args):
    local_available_archs = [ArchType.ARCH_X86, ArchType.ARCH_X64]

    # Parse args
    systems = []
    archs = []
    for arg in args:
        if (arg in Systems.available_systems_str()):
            systems.append(Systems.str_to_target_system(arg))
        elif (is_supported_arch_str(arg)):
            archs.append(str_to_arch_type(arg))
        else:
            error("Unknown system/arch: '{}'".format(arg))
            return
    if ((not systems)):
        systems = Systems.available_systems()
    if (not archs):
        archs = available_archs_type()

    # Remove duplicates
    systems = list(set(systems))
    archs = list(set(archs))
    # Print
    for system in systems:
        for arch in archs:
            if (system == Systems.TargetSystem.Linux
                    and arch == ArchType.ARCH_X86):
                available = LinuxX86.available_syscalls()
                print(str_bold("\n\n\tSupported Linux X86 syscalls"))
                print_syscalls_list(available)
            elif (system == Systems.TargetSystem.Linux
                  and arch == ArchType.ARCH_X64):
                available = LinuxX64.available_syscalls()
                print(str_bold("\n\n\tSupported Linux X64 syscalls"))
                print_syscalls_list(available)
示例#2
0
def exploit_mode():
    """
    Returns
    -------
    True if ROPGenerator must continue
    False if ROPGenerator must be closed 
    """
    
    finish = False
    while( not finish ):
        try:
            # Get command 
            user_input = promptSession.prompt()
            args = user_input.split()
            argslen = len(args)
            if( argslen > 0 ):
                command = args[0]
            else:
                command = None
                continue
                
            # Execute command 
            if( command == CMD_SHELLCODE ):
                shellcode(args[1:])
            elif( command == CMD_SYSCALL ):
                syscall(args[1:])
            elif( command == CMD_FUNCTION ):
                function(args[1:])
            elif( command == CMD_EXIT ):
                return False
            elif( command == CMD_HELP ):
                print(helpStr)
            elif( command == CMD_MAIN ):
                finish = True
            elif( command == CMD_DSHELL ):
                deliver_shellcode(args[1:])
            else:
                error("Unknown command '{}'".format(command))
            if( command != None ):
                print('')
        except KeyboardInterrupt:
            pass
    return True
示例#3
0
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)
示例#4
0
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)