예제 #1
0
class RPG:
    def __init__(self, binary, depth=20):
        self.__opt = PseudoOpt(binary, depth)
        self.__binary = Binary(self.__opt)
        self.__rpg_core = Gadgets(self.__binary, self.__opt, 0)
        self.__gadget_list = []

        self.__serach_gadget()

    @property
    def gadget_list(self):
        return self.__gadget_list


    def __serach_gadget(self):
        exec_sections = self.__binary.getExecSections()

        for sct in exec_sections:
            self.__gadget_list += self.__rpg_core.addROPGadgets(sct)
            self.__gadget_list += self.__rpg_core.addSYSGadgets(sct)
            self.__gadget_list += self.__rpg_core.addJOPGadgets(sct)

        self.__gadget_list = self.__rpg_core.passClean(self.__gadget_list, False)

        self.__gadget_list = alphaSortgadgets(self.__gadget_list)


    def dump_gadget(self):
        print(self.__gadget_list[0])
        for gadget in self.__gadget_list:
            print(f"{gadget['vaddr']:x}: {gadget['gadget']}")
예제 #2
0
파일: core.py 프로젝트: jbrower95/crop
class Core(cmd.Cmd):
    def __init__(self, options):
        cmd.Cmd.__init__(self)
        self.__options = options
        self.__binary = None
        self.__gadgets = []
        self.__offset = 0
        self.prompt = '(ROPgadget)> '

    def __checksBeforeManipulations(self):
        if self.__binary == None or self.__binary.getBinary(
        ) == None or self.__binary.getArch(
        ) == None or self.__binary.getArchMode() == None:
            return False
        return True

    def __getAllgadgets(self):

        if self.__checksBeforeManipulations() == False:
            return False

        G = Gadgets(self.__binary, self.__options, self.__offset)
        execSections = self.__binary.getExecSections()

        # Find ROP/JOP/SYS gadgets
        self.__gadgets = []
        for section in execSections:
            if not self.__options.norop:
                self.__gadgets += G.addROPGadgets(section)
            if not self.__options.nojop:
                self.__gadgets += G.addJOPGadgets(section)
            if not self.__options.nosys:
                self.__gadgets += G.addSYSGadgets(section)

        # Pass clean single instruction and unknown instructions
        self.__gadgets = G.passClean(self.__gadgets, self.__options.multibr)

        # Delete duplicate gadgets
        if not self.__options.all:
            self.__gadgets = rgutils.deleteDuplicateGadgets(self.__gadgets)

        # Applicate some Options
        self.__gadgets = Options(self.__options, self.__binary,
                                 self.__gadgets).getGadgets()

        # Sorted alphabetically
        self.__gadgets = rgutils.alphaSortgadgets(self.__gadgets)

        return True

    def getGadgetsQuiet(self):
        self.__binary = Binary(self.__options)
        self.__getAllgadgets()
        return self.__gadgets

    def __lookingForGadgets(self):

        if self.__checksBeforeManipulations() == False:
            return False

        arch = self.__binary.getArchMode()
        print(
            "Gadgets information\n============================================================"
        )
        for gadget in self.__gadgets:
            vaddr = gadget["vaddr"]
            insts = gadget["gadget"]
            bytes = gadget["bytes"]
            bytesStr = " // " + bytes.encode(
                'hex') if self.__options.dump else ""

            print(("0x%08x" % (vaddr) if arch == CS_MODE_32 else "0x%016x" %
                   (vaddr)) + " : %s" % (insts) + bytesStr)

        print("\nUnique gadgets found: %d" % (len(self.__gadgets)))
        return True

    def __lookingForAString(self, string):

        if self.__checksBeforeManipulations() == False:
            return False

        dataSections = self.__binary.getDataSections()
        arch = self.__binary.getArchMode()
        print(
            "Strings information\n============================================================"
        )
        for section in dataSections:
            allRef = [
                m.start() for m in re.finditer(string, section["opcodes"])
            ]
            for ref in allRef:
                vaddr = self.__offset + section["vaddr"] + ref
                string = section["opcodes"][ref:ref + len(string)]
                rangeS = int(self.__options.range.split('-')[0], 16)
                rangeE = int(self.__options.range.split('-')[1], 16)
                if (rangeS == 0 and rangeE == 0) or (vaddr >= rangeS
                                                     and vaddr <= rangeE):
                    print(("0x%08x" %
                           (vaddr) if arch == CS_MODE_32 else "0x%016x" %
                           (vaddr)) + " : %s" % (string))
        return True

    def __lookingForOpcodes(self, opcodes):

        if self.__checksBeforeManipulations() == False:
            return False

        execSections = self.__binary.getExecSections()
        arch = self.__binary.getArchMode()
        print(
            "Opcodes information\n============================================================"
        )
        for section in execSections:
            allRef = [
                m.start()
                for m in re.finditer(opcodes.decode("hex"), section["opcodes"])
            ]
            for ref in allRef:
                vaddr = self.__offset + section["vaddr"] + ref
                rangeS = int(self.__options.range.split('-')[0], 16)
                rangeE = int(self.__options.range.split('-')[1], 16)
                if (rangeS == 0 and rangeE == 0) or (vaddr >= rangeS
                                                     and vaddr <= rangeE):
                    print(("0x%08x" %
                           (vaddr) if arch == CS_MODE_32 else "0x%016x" %
                           (vaddr)) + " : %s" % (opcodes))
        return True

    def __lookingForMemStr(self, memstr):

        if self.__checksBeforeManipulations() == False:
            return False

        sections = self.__binary.getExecSections()
        sections += self.__binary.getDataSections()
        arch = self.__binary.getArchMode()
        print(
            "Memory bytes information\n======================================================="
        )
        chars = list(memstr)
        for char in chars:
            try:
                for section in sections:
                    allRef = [
                        m.start()
                        for m in re.finditer(char, section["opcodes"])
                    ]
                    for ref in allRef:
                        vaddr = self.__offset + section["vaddr"] + ref
                        rangeS = int(self.__options.range.split('-')[0], 16)
                        rangeE = int(self.__options.range.split('-')[1], 16)
                        if (rangeS == 0
                                and rangeE == 0) or (vaddr >= rangeS
                                                     and vaddr <= rangeE):
                            print(
                                ("0x%08x" %
                                 (vaddr) if arch == CS_MODE_32 else "0x%016x" %
                                 (vaddr)) + " : '%c'" % (char))
                            raise
            except:
                pass
        return True

    def analyze(self):

        try:
            self.__offset = int(self.__options.offset,
                                16) if self.__options.offset else 0
        except ValueError:
            print("[Error] The offset must be in hexadecimal")
            return False

        if self.__options.console:
            if self.__options.binary:
                self.__binary = Binary(self.__options)
                if self.__checksBeforeManipulations() == False:
                    return False
            self.cmdloop()
            return True

        self.__binary = Binary(self.__options)
        if self.__checksBeforeManipulations() == False:
            return False

        if self.__options.string:
            return self.__lookingForAString(self.__options.string)
        elif self.__options.opcode:
            return self.__lookingForOpcodes(self.__options.opcode)
        elif self.__options.memstr:
            return self.__lookingForMemStr(self.__options.memstr)
        else:
            self.__getAllgadgets()
            self.__lookingForGadgets()
            if self.__options.ropchain:
                ROPMaker(self.__binary, self.__gadgets, self.__offset)
            return True

    def gadgets(self):
        return self.__gadgets

    # Console methods  ============================================

    def do_binary(self, s, silent=False):
        # Do not split the filename with spaces since it might contain
        # whitespaces
        if len(s) == 0:
            if not silent:
                return self.help_binary()
            return False

        binary = s

        self.__options.binary = binary
        self.__binary = Binary(self.__options)
        if self.__checksBeforeManipulations() == False:
            return False

        if not silent:
            print("[+] Binary loaded")

    def help_binary(self):
        print("Syntax: binary <file> -- Load a binary")
        return False

    def do_EOF(self, s, silent=False):
        return self.do_quit(s, silent)

    def do_quit(self, s, silent=False):
        return True

    def help_quit(self):
        print("Syntax: quit -- Terminates the application")
        return False

    def do_load(self, s, silent=False):

        if self.__binary == None:
            if not silent:
                print("[-] No binary loaded.")
            return False

        if not silent:
            print("[+] Loading gadgets, please wait...")
        self.__getAllgadgets()

        if not silent:
            print("[+] Gadgets loaded !")

    def help_load(self):
        print("Syntax: load -- Load all gadgets")
        return False

    def do_display(self, s, silent=False):
        self.__lookingForGadgets()

    def help_display(self):
        print("Syntax: display -- Display all gadgets loaded")
        return False

    def do_depth(self, s, silent=False):
        try:
            depth = int(s.split()[0])
        except:
            if not silent:
                return self.help_depth()
            return False
        if depth <= 0:
            if not silent:
                print("[-] The depth value must be > 0")
            return False
        self.__options.depth = int(depth)

        if not silent:
            print("[+] Depth updated. You have to reload gadgets")

    def help_depth(self):
        print("Syntax: depth <value> -- Set the depth search engine")
        return False

    def do_badbytes(self, s, silent=False):
        try:
            bb = s.split()[0]
        except:
            if not silent:
                return self.help_badbytes()
            else:
                return False
        self.__options.badbytes = bb

        if not silent:
            print("[+] Bad bytes updated. You have to reload gadgets")

    def help_badbytes(self):
        print("Syntax: badbytes <badbyte1|badbyte2...> -- ")
        return False

    def __withK(self, listK, gadget):
        if len(listK) == 0:
            return True
        for a in listK:
            if a not in gadget:
                return False
        return True

    def __withoutK(self, listK, gadget):
        for a in listK:
            if a in gadget:
                return False
        return True

    def do_search(self, s, silent=False):
        args = s.split()
        if not len(args):
            return self.help_search()
        withK, withoutK = [], []
        for a in args:
            if a[0:1] == "!":
                withoutK += [a[1:]]
            else:
                withK += [a]
        if self.__checksBeforeManipulations() == False:
            if not silent:
                print("[-] You have to load a binary")
            return False
        arch = self.__binary.getArchMode()
        for gadget in self.__gadgets:
            vaddr = gadget["vaddr"]
            insts = gadget["gadget"]
            if self.__withK(withK, insts) and self.__withoutK(withoutK, insts):
                # What to do if silent = True?
                print(("0x%08x" %
                       (vaddr) if arch == CS_MODE_32 else "0x%016x" %
                       (vaddr)) + " : %s" % (insts))

    def help_search(self):
        print(
            "Syntax: search <keyword1 keyword2 keyword3...> -- Filter with or without keywords"
        )
        print("keyword  = with")
        print("!keyword = witout")
        return False

    def count(self):
        return len(self.__gadgets)

    def do_count(self, s, silent=False):
        if not silent:
            print("[+] %d loaded gadgets." % self.count())

    def help_count(self):
        print("Shows the number of loaded gadgets.")
        return False

    def do_filter(self, s, silent=False):
        try:
            self.__options.filter = s.split()[0]
        except:
            if not silent:
                return self.help_filter()
            return False

        if not silent:
            print("[+] Filter setted. You have to reload gadgets")

    def help_filter(self):
        print(
            "Syntax: filter <filter1|filter2|...> - Suppress specific instructions"
        )
        return False

    def do_only(self, s, silent=False):
        try:
            if s.lower() == "none":
                self.__options.only = None
            else:
                self.__options.only = s.split()[0]
        except:
            if not silent:
                return self.help_only()
            return False

        if not silent:
            print("[+] Only setted. You have to reload gadgets")

    def help_only(self):
        print(
            "Syntax: only <only1|only2|...> - Only show specific instructions")
        return False

    def do_range(self, s, silent=False):
        try:
            rangeS = int(s.split('-')[0], 16)
            rangeE = int(s.split('-')[1], 16)
            self.__options.range = s.split()[0]
        except:
            if not silent:
                return self.help_range()
            return False

        if rangeS > rangeE:
            if not silent:
                print("[-] The start value must be greater than the end value")
            return False

        if not silent:
            print("[+] Range setted. You have to reload gadgets")

    def help_range(self):
        print(
            "Syntax: range <start-and> - Search between two addresses (0x...-0x...)"
        )
        return False

    def do_settings(self, s, silent=False):
        print("All:         %s" % (self.__options.all))
        print("Badbytes:    %s" % (self.__options.badbytes))
        print("Binary:      %s" % (self.__options.binary))
        print("Depth:       %s" % (self.__options.depth))
        print("Filter:      %s" % (self.__options.filter))
        print("Memstr:      %s" % (self.__options.memstr))
        print("MultiBr:     %s" % (self.__options.multibr))
        print("NoJOP:       %s" % (self.__options.nojop))
        print("NoROP:       %s" % (self.__options.norop))
        print("NoSYS:       %s" % (self.__options.nosys))
        print("Offset:      %s" % (self.__options.offset))
        print("Only:        %s" % (self.__options.only))
        print("Opcode:      %s" % (self.__options.opcode))
        print("ROPchain:    %s" % (self.__options.ropchain))
        print("Range:       %s" % (self.__options.range))
        print("RawArch:     %s" % (self.__options.rawArch))
        print("RawMode:     %s" % (self.__options.rawMode))
        print("Re:          %s" % (self.__options.re))
        print("String:      %s" % (self.__options.string))
        print("Thumb:       %s" % (self.__options.thumb))

    def help_settings(self):
        print("Display setting's environment")
        return False

    def do_nojop(self, s, silent=False):
        try:
            arg = s.split()[0]
        except:
            return self.help_nojop()

        if arg == "enable":
            self.__options.nojop = True
            if not silent:
                print("[+] NoJOP enable. You have to reload gadgets")

        elif arg == "disable":
            self.__options.nojop = False
            if not silent:
                print("[+] NoJOP disable. You have to reload gadgets")

        else:
            if not silent:
                return self.help_nojop()
            return False

    def help_nojop(self):
        print("Syntax: nojop <enable|disable> - Disable JOP search engin")
        return False

    def do_norop(self, s, silent=False):
        try:
            arg = s.split()[0]
        except:
            return self.help_norop()

        if arg == "enable":
            self.__options.norop = True
            if not silent:
                print("[+] NoROP enable. You have to reload gadgets")

        elif arg == "disable":
            self.__options.norop = False
            if not silent:
                print("[+] NoROP disable. You have to reload gadgets")

        else:
            if not silent:
                return self.help_norop()
            return False

    def help_norop(self):
        print("Syntax: norop <enable|disable> - Disable ROP search engin")
        return False

    def do_nosys(self, s, silent=False):
        try:
            arg = s.split()[0]
        except:
            return self.help_nosys()

        if arg == "enable":
            self.__options.nosys = True
            if not silent:
                print("[+] NoSYS enable. You have to reload gadgets")

        elif arg == "disable":
            self.__options.nosys = False
            if not silent:
                print("[+] NoSYS disable. You have to reload gadgets")

        else:
            if not silent:
                return self.help_nosys()

            return False

    def help_nosys(self):
        print("Syntax: nosys <enable|disable> - Disable SYS search engin")
        return False

    def do_thumb(self, s, silent=False):
        try:
            arg = s.split()[0]
        except:
            return self.help_thumb()

        if arg == "enable":
            self.__options.thumb = True
            if not silent:
                print("[+] Thumb enable. You have to reload gadgets")

        elif arg == "disable":
            self.__options.thumb = False
            if not silent:
                print("[+] Thumb disable. You have to reload gadgets")

        else:
            if not silent:
                return self.help_thumb()
            return False

    def help_thumb(self):
        print(
            "Syntax: thumb <enable|disable> - Use the thumb mode for the search engine (ARM only)"
        )
        return False

    def do_all(self, s, silent=False):
        if s == "enable":
            self.__options.all = True
            if not silent:
                print(
                    "[+] Showing all gadgets enabled. You have to reload gadgets"
                )

        elif s == "disable":
            self.__options.all = False
            if not silent:
                print(
                    "[+] Showing all gadgets disabled. You have to reload gadgets"
                )

        else:
            if not silent:
                return self.help_all()

            return False

    def help_multibr(self):
        print(
            "Syntax: multibr <enable|disable> - Enable/Disable multiple branch gadgets"
        )
        return False

    def do_multibr(self, s, silent=False):
        if s == "enable":
            self.__options.multibr = True
            if not silent:
                print(
                    "[+] Multiple branch gadgets enabled. You have to reload gadgets"
                )

        elif s == "disable":
            self.__options.multibr = False
            if not silent:
                print(
                    "[+] Multiple branch gadgets disabled. You have to reload gadgets"
                )

        else:
            if not silent:
                return self.help_all()

            return False

    def help_all(self):
        print(
            "Syntax: all <enable|disable - Show all gadgets (disable removing duplicate gadgets)"
        )
        return False

    def help_re(self):
        print("Syntax: re <pattern1 | pattern2 |...> - Regular expression")
        return False

    def do_re(self, s, silent=False):
        if s.lower() == 'none':
            self.__options.re = None
        elif s == "":
            self.help_re()
            silent = True
        else:
            self.__options.re = s

        if not silent:
            print("[+] Re setted. You have to reload gadgets")
예제 #3
0
        nucleus_out,
    }

    # ----- ROPgadget -----
    rg_offset = 0
    config = [
        '--binary',
        os.path.join(pe_dir, f),
        '--all',
        '--nojop',
        '--nosys',
    ]
    rg_args = Args(config).getArgs()
    rg_bin = Binary(rg_args)
    G = Gadgets(rg_bin, rg_args, rg_offset)
    exec_sections = rg_bin.getExecSections()
    rg_gadgets = []
    for section in exec_sections:
        rg_gadgets += G.addROPGadgets(section)
    rg_gadgets = G.passClean(rg_gadgets, rg_args.multibr)
    rg_gadgets = Options(rg_args, rg_bin, rg_gadgets).getGadgets()
    # ---------------------

    if not ropper_parsing_error:
        rs.setArchitectureFor(name=f, arch='x86')
        rs.loadGadgetsFor(name=f)
        rp_gadgets = rs.getFileFor(f).gadgets
        rp_gadgets.sort(key=attrgetter('address'))
        print 'Found {} gadgets!'.format(len(rp_gadgets))
        rs.setImageBaseFor(name=f, imagebase=0x0)
    else: