Exemple #1
0
def init_impossible_REGtoREG(env):
    global INIT_LMAX, INIT_MAXDEPTH
    global baseAssertion
    # DEBUG
    #try:
    startTime = datetime.now()
    i = 0
    impossible_count = 0
    for reg1 in sorted(Arch.registers()):
        reg_name = Arch.r2n(reg1)
        if (len(reg_name) < 6):
            reg_name += " " * (6 - len(reg_name))
        elif (len(reg_name) >= 6):
            reg_name = reg_name[:5] + "."
        for reg2 in Arch.registers():
            i += 1
            charging_bar(len(Arch.registers() * len(Arch.registers())), i, 30)
            if (reg2 == reg1 or reg2 == Arch.ipNum()):
                continue
            _search(QueryType.REGtoREG, reg1, (reg2, 0), env, n=1)
            if (env.checkImpossible_REGtoREG(reg1, reg2, 0)):
                impossible_count += 1
    cTime = datetime.now() - startTime
    # Get how many impossible path we found
    impossible_rate = int(100 * (float(impossible_count) / float(
        (len(Arch.registers()) - 1) * len(Arch.registers()))))
    notify('Optimization rate : {}%'.format(impossible_rate))
    notify("Computation time : " + str(cTime))
Exemple #2
0
def init_impossible_REGtoREG(env):
    global INIT_LMAX, INIT_MAXDEPTH
    global baseAssertion

    try:
        startTime = datetime.now()
        i = 0
        impossible_count = 0
        for reg1 in sorted(Arch.registers()):
            reg_name = Arch.r2n(reg1)
            if (len(reg_name) < 6):
                reg_name += " " * (6 - len(reg_name))
            elif (len(reg_name) >= 6):
                reg_name = reg_name[:5] + "."
            for reg2 in Arch.registers():
                i += 1
                charging_bar(len(Arch.registers() * len(Arch.registers())), i,
                             30)
                if (reg2 == reg1 or reg2 == Arch.ipNum()):
                    continue
                _search(QueryType.REGtoREG, reg1, (reg2, 0), env, n=1)
                if (env.checkImpossible_REGtoREG(reg1, reg2, 0)):
                    impossible_count += 1
        cTime = datetime.now() - startTime
        # Get how many impossible path we found
        impossible_rate = int(100 * (float(impossible_count) / float(
            (len(Arch.registers()) - 1) * len(Arch.registers()))))
        notify('Optimization rate : {}%'.format(impossible_rate))
        notify("Computation time : " + str(cTime))
    except:
        print("\n")
        fatal("Exception caught, stopping Semantic Engine init process...\n")
        fatal("Search time might get very long !\n")
        env = SearchEnvironment(INIT_LMAX, Constraint(), baseAssertion,
                                INIT_MAXDEPTH)
Exemple #3
0
def getGadgets(filename):
    """
    Returns a list of gadgets extracted from a file 
    Precondition: the file exists 
    
    Returns
    -------
    list of pairs (addr, asm) if succesful
    None if failure 
    """    
   
    ropgadget = "ROPgadget"
    notify("Executing ROPgadget as: " + ropgadget )
    try:
        p = subprocess.Popen([ropgadget,"--binary",filename,"--dump", "--all"],stdout=subprocess.PIPE)
    except Exception as e:
        error("Could not execute '" +ropgadget+ " --binary " + filename + " --dump --all'")
        print("\tError message is: " + str(e))
        print("\n\t(Maybe check/update your config with the 'config' command,\n\t or make sure you have the last ROPgadget version installed)")
        return None

    # Get the gadget list 
    # Pairs (address, raw_asm)
    first = True
    count = 0
    res = []
    for l in p.stdout.readlines():
        if("0x" in l):
            arr = l.split(' ')
            addr = arr[0]
            raw = b16decode(arr[-1].upper().strip())
            res.append((int(addr,16), raw))
            count += 1 
    notify("Finished : %d gadgets generated" % (count))
    return res
Exemple #4
0
def getPlatformInfo(filename):
    """
    Checks the binary type of the file
    Precondition: the file exists ! 
    
    Effects: set the Arch.currentBinType variable
    Return : the architecture 
    """
    INTEL_strings = ["x86", "x86-64", "X86", "X86-64", "Intel", "80386"]
    ELF32_strings = ["ELF 32-bit"]
    ELF64_strings = ["ELF 64-bit"]
    PE32_strings = ["PE32 "]
    PE64_strings = ["PE32+"]

    output = from_file(os.path.realpath(filename))
    if ([sub for sub in INTEL_strings if sub in output]):
        if ([sub for sub in ELF32_strings if sub in output]):
            notify("ELF 32-bits detected")
            Arch.currentBinType = Arch.BinaryType.X86_ELF
            return Arch.ArchX86
        elif ([sub for sub in ELF64_strings if sub in output]):
            notify("ELF 64-bits detected")
            Arch.currentBinType = Arch.BinaryType.X64_ELF
            return Arch.ArchX64
        elif ([sub for sub in PE32_strings if sub in output]):
            notify("PE 32-bits detected")
            Arch.currentBinType = Arch.BinaryType.X86_PE
            return Arch.ArchX86
        elif ([sub for sub in PE64_strings if sub in output]):
            notify("PE 64-bits detected")
            Arch.currentBinType = Arch.BinaryType.X64_PE
            return Arch.ArchX64
        else:
            notify("Unknown binary type")
            Arch.currentBinType = Arch.BinaryType.UNKNOWN
            return None
    else:
        return None
Exemple #5
0
def remove(arch):
    if (not shellcodes[arch]):
        error("No shellcodes to remove for architecture " + arch)
        return

    list_shellcodes(arch)
    print("")

    choice = ''
    ok = False
    sys.stdout.write('\t' + string_ropg('> ') +
                     'Select a shellcode to remove:\n')
    while (not ok):
        choice_input = prompt(u"        > ")
        try:
            choice = int(choice_input)
            ok = remove_shellcode(arch, choice)
            if (not ok):
                print(string_special("\tError. Invalid choice"))
        except:
            ok = False

    print("")
    notify('Shellcode removed')
Exemple #6
0
def build_dshell(shellcode, constraint, assertion, address, limit, lmax):
    """
    Returns a PwnChain() instance or None
    """
    # Build exploit
    #################

    res = PwnChain()

    #Find address for the payload
    if (not address):
        # Get the .bss address
        # TODO
        notify("Getting delivery address for shellcode")
        address = getSectionAddress('.bss')
        addr_str = ".bss"
        if (not address):
            verbose("Couldn't find .bss address")
            return []
    else:
        addr_str = hex(address)

    if (not limit):
        limit = address + Arch.minPageSize()

    # Deliver shellcode
    notify("Building chain to copy shellcode in memory")
    verbose("{}/{} bytes available".format(lmax * Arch.octets(),
                                           lmax * Arch.octets()))
    (shellcode_address, STRtoMEM_chain) = STRtoMEM(shellcode,
                                                   address,
                                                   constraint,
                                                   assertion,
                                                   limit=limit,
                                                   lmax=lmax,
                                                   addr_str=addr_str,
                                                   hex_info=True,
                                                   optimizeLen=True)
    address = shellcode_address
    addr_str = hex(address)
    if (not STRtoMEM_chain):
        verbose("Could not copy shellcode into memory")
        return None

    # Building mprotect
    notify("Building mprotect() chain")
    # Getting page to make executable
    # Arg of mprotect MUST be a valid multiple of page size
    over_page_size = address % Arch.minPageSize()
    page_address = address - over_page_size
    length = len(shellcode) + 1 + over_page_size
    flag = 7
    lmax2 = lmax - len(STRtoMEM_chain)
    verbose("{}/{} bytes available".format(lmax2 * Arch.octets(),
                                           lmax * Arch.octets()))
    if (lmax2 <= 0):
        return None
    if (Arch.currentArch == Arch.ArchX86):
        mprotect_chain = build_mprotect32(page_address,
                                          length,
                                          flag,
                                          constraint.add(Chainable(ret=True)),
                                          assertion,
                                          clmax=lmax2 - 2,
                                          optimizeLen=True)
    elif (Arch.currentArch == Arch.ArchX64):
        mprotect_chain = build_mprotect64(page_address,
                                          length,
                                          flag,
                                          constraint.add(Chainable(ret=True)),
                                          assertion,
                                          clmax=lmax2 - 2,
                                          optimizeLen=True)
    else:
        mprotect_chain = None
        verbose("mprotect call not supported for architecture {}".format(
            Arch.currentArch.name))
        return None
    if (not mprotect_chain):
        return None
    verbose("Done")

    # Jump to shellcode
    notify("Searching chain to jump to shellcode")
    verbose("{}/{} bytes available".format(
        (lmax2 - len(mprotect_chain)) * Arch.octets(), lmax * Arch.octets()))
    jmp_shellcode_chains = search(QueryType.CSTtoREG,
                                  Arch.ipNum(),
                                  address,
                                  constraint,
                                  assertion,
                                  clmax=lmax - len(STRtoMEM_chain) -
                                  len(mprotect_chain),
                                  optimizeLen=True)
    if (not jmp_shellcode_chains):
        verbose("Couldn't find a jump to the shellcode")
        return None
    verbose("Done")
    notify("Done")

    # Build PwnChain res and return
    res.add(mprotect_chain,
            "Call mprotect({},{},{})".format(hex(page_address), length, flag))
    res.add(STRtoMEM_chain, "Copy shellcode to {}".format(addr_str))
    res.add(jmp_shellcode_chains[0],
            "Jump to shellcode (address {})".format(addr_str))
    return res
Exemple #7
0
def build(pair_list):
    """
    Takes a list of pairs (addr, raw_asm) corresponding to 
    gagets (their address and their intructions as a byte string)
    Fills the 'gadgets' and 'db' global structures ;) 
    """
    def sigint_handler(signal, frame):
        global sigint
        sigint = True

    def timeout_handler(signum, frame):
        global sigalarm
        sigalarm = True
        signal.alarm(0)
        raise TimeOutException('Timeout')

    global gadgets, db, sigint
    gadgets = []
    raw_to_gadget = dict()
    sigint = False
    original_sigint_handler = signal.getsignal(signal.SIGINT)
    signal.signal(signal.SIGINT, sigint_handler)
    signal.signal(signal.SIGALRM, timeout_handler)

    info(string_bold("Creating gadget database\n"))
    startTime = datetime.now()
    success = i = 0
    # Create the gadgets list
    for (addr, raw) in pair_list:
        charging_bar(len(pair_list) - 1, i, 30)
        if (sigint):
            break
        if (raw in raw_to_gadget):
            gadgets[raw_to_gadget[raw]].addrList.append(addr)
            success += 1
        else:
            try:
                signal.alarm(1)
                gadget = Gadget([addr], raw)
                signal.alarm(0)
                success += 1
                gadgets.append(gadget)
                raw_to_gadget[raw] = len(gadgets) - 1
            except (GadgetException, TimeOutException) as e:
                signal.alarm(0)
                if (isinstance(e, GadgetException)):
                    log("Gadget ({}) :  ".format('\\x'+'\\x'\
                    .join("{:02x}".format(ord(c)) for c in raw)) + str(e))
        i += 1
    # Find syscalls
    # TODO

    # Getting time
    cTime = datetime.now() - startTime
    signal.signal(signal.SIGINT, original_sigint_handler)

    if (sigint):
        print("\n")
        fatal(
            "SIGINT ended the analysis prematurely, gadget database might be incomplete\n"
        )
        sigint = False
    notify("Gadgets analyzed : " + str(len(pair_list)))
    notify("Successfully translated : " + str(success))
    notify("Computation time : " + str(cTime))

    # Create the database
    db = Database(gadgets)