コード例 #1
0
ファイル: crash.py プロジェクト: Holmeswww/rex
    def point_to_flag(self):
        '''
        Create a testcase which points an arbitrary-read crash at the flag page.
        '''
        if not self.one_of(
            [Vulnerability.ARBITRARY_READ, Vulnerability.ARBITRARY_TRANSMIT]):
            raise CannotExploit(
                "only arbitrary-reads can be exploited this way")

        violating_actions = []

        if self.one_of([Vulnerability.ARBITRARY_READ]):
            if self.violating_action:
                violating_actions.append(
                    (self.state, self.violating_action.addr))

        zp = self.state.get_plugin('zen_plugin')
        if zp is not None:
            for st, addr in zp.controlled_transmits:
                st.preconstrainer.remove_preconstraints()
                violating_actions.append((st, addr))

        for st, va in violating_actions:
            try:
                cp = self._get_state_pointing_to_flag(st, va)
                self._reconstrain_flag_data(cp)
                yield ChallRespInfo.atoi_dumps(cp)
            except CannotExploit:
                l.warning("crash couldn't be pointed at flag skipping")
                pass

        # look for contiguous flag bytes of length 4 or longer and try to leak only one
        max_tries = 20
        num_tries = 0
        for start, length in self.flag_mem.items():
            if length < 4:
                continue
            data = self.state.memory.load(start, length)
            four_flag_offset = self._four_flag_bytes_offset(data)
            if four_flag_offset is not None:
                leak_addr = start + four_flag_offset
                l.debug("found flag at addr %#x", leak_addr)
                for st, va in violating_actions:
                    if num_tries > max_tries:
                        l.warning("passed the maximum number of tries")
                        break
                    num_tries += 1
                    try:
                        cp = self._get_state_pointing_to_addr(
                            st, va, leak_addr)
                        self._reconstrain_flag_data(cp)
                        l.debug("pointed successfully")
                        yield ChallRespInfo.atoi_dumps(cp)
                        # okay we got one we are done
                        return
                    except CannotExploit:
                        l.warning("crash couldn't be pointed at flag skipping")
                        pass
コード例 #2
0
    def _generate_formula(self, extra_vars_to_solve=None):
        """
        This function is used to generate the equations which are inserted inside C exploits
        """

        if extra_vars_to_solve is None:
            extra_vars_to_solve = []

        st = self.crash.state.copy()

        self._prepare_chall_resp(st)

        # get variables representing stdin
        stdin = st.posix.get_file(0)
        length = st.se.eval(stdin.pos)

        ft = st.se._solver._merged_solver_for(lst=[self._mem] +
                                              extra_vars_to_solve)
        # filter out constants
        the_vars = set()
        split = ft.split()
        for solver in split:
            if len(solver.variables) > 1:
                the_vars.update(solver.variables)
        ft = st.se._solver._merged_solver_for(names=the_vars)

        self._payload_len = length
        self._raw_payload = ChallRespInfo.atoi_dumps(st)

        self._create_solvers(ft, extra_vars_to_solve)
コード例 #3
0
ファイル: crash.py プロジェクト: Holmeswww/rex
    def _explore_arbitrary_read(self, path_file=None):
        # crash type was an arbitrary-read, let's point the violating address at a
        # symbolic memory region

        largest_regions = sorted(self.symbolic_mem.items(),
                                 key=operator.itemgetter(1),
                                 reverse=True)

        min_read = self.state.se.min(self.violating_action.addr)
        max_read = self.state.se.max(self.violating_action.addr)

        largest_regions = map(operator.itemgetter(0), largest_regions)
        # filter addresses which fit between the min and max possible address
        largest_regions = filter(lambda x: (min_read <= x) and (x <= max_read),
                                 largest_regions)

        # populate the rest of the list with addresses from the binary
        min_addr = self.project.loader.main_object.min_addr
        max_addr = self.project.loader.main_object.max_addr
        pages = range(min_addr, max_addr, 0x1000)
        pages = filter(lambda x: (min_read <= x) and (x <= max_read), pages)

        read_addr = None
        constraint = None
        for addr in largest_regions + pages:
            read_addr = addr
            constraint = self.violating_action.addr == addr

            if self.state.se.satisfiable(extra_constraints=(constraint, )):
                break

            constraint = None

        if constraint is None:
            raise CannotExploit(
                "unable to find suitable read address, cannot explore")

        self.state.add_constraints(constraint)

        l.debug("constraining input to read from address %#x", read_addr)

        l.info(
            "starting a new crash exploration phase based off the crash at address 0x%x",
            self.violating_action.ins_addr)

        new_input = ChallRespInfo.atoi_dumps(self.state)
        if path_file is not None:
            l.info("dumping new crash evading input into file '%s'", path_file)
            with open(path_file, 'w') as f:
                f.write(new_input)

        # create a new crash object starting here
        use_rop = False if self.rop is None else True
        self.__init__(self.binary,
                      new_input,
                      explore_steps=self.explore_steps + 1,
                      constrained_addrs=self.constrained_addrs +
                      [self.violating_action],
                      use_rop=use_rop,
                      angrop_object=self.rop)
コード例 #4
0
ファイル: crash.py プロジェクト: zeph1912/rex
    def _explore_arbitrary_write(self, path_file=None):
        # crash type was an arbitrary-write, this routine doesn't care about taking advantage
        # of the write it just wants to try to find a more valuable crash by pointing the write
        # at some writable memory

        # find a writable data segment

        elf_objects = self.project.loader.all_elf_objects

        assert len(elf_objects
                   ) > 0, "target binary is not ELF or CGC, unsupported by rex"

        min_write = self.state.solver.min(self.violating_action.addr)
        max_write = self.state.solver.max(self.violating_action.addr)

        segs = []
        for eobj in elf_objects:
            segs.extend(filter(lambda s: s.is_writable, eobj.segments))

        segs = [
            s for s in segs if s.min_addr <= min_write <= s.max_addr
            or min_write <= s.min_addr <= max_write
        ]

        write_addr = None
        constraint = None
        for seg in segs:
            for page in range(seg.min_addr, seg.max_addr, 0x1000):
                write_addr = page
                constraint = self.violating_action.addr == page

                if self.state.solver.satisfiable(
                        extra_constraints=(constraint, )):
                    break

                constraint = None

        if constraint is None:
            raise CannotExploit("Cannot point write at any writeable segments")

        self.state.add_constraints(constraint)
        l.debug("constraining input to write to address %#x", write_addr)

        l.info(
            "starting a new crash exploration phase based off the crash at address %#x",
            self.violating_action.ins_addr)
        new_input = ChallRespInfo.atoi_dumps(self.state)
        if path_file is not None:
            l.info("dumping new crash evading input into file '%s'", path_file)
            with open(path_file, 'w') as f:
                f.write(new_input)

        use_rop = False if self.rop is None else True
        self.__init__(self.binary,
                      new_input,
                      explore_steps=self.explore_steps + 1,
                      constrained_addrs=self.constrained_addrs +
                      [self.violating_action],
                      use_rop=use_rop,
                      angrop_object=self.rop)
コード例 #5
0
ファイル: cgc_exploit.py プロジェクト: zeph1912/rex
    def _generate_formula(self, extra_vars_to_solve=None):
        """
        This function is used to generate the equations which are inserted inside C exploits
        """

        if extra_vars_to_solve is None:
            extra_vars_to_solve = []

        st = self.crash.state.copy()

        self._prepare_chall_resp(st)

        # get variables representing stdin
        length = st.solver.eval(st.posix.fd[0].read_pos)

        ft = st.solver._solver._merged_solver_for(lst=[self._mem] +
                                                  extra_vars_to_solve)
        # filter out constants
        the_vars = set()
        split = ft.split()
        for solver in split:
            if len(solver.variables) > 1:
                the_vars.update(solver.variables)
        ft = st.solver._solver._merged_solver_for(names=the_vars)

        # try to use original crash_input instead of random ones if some input is still symbolic at this stage
        size = st.solver.eval(st.posix.stdin.size)

        # there is a weird crash type called FakeCrash which is totally dummy
        # have no idea why we still keep it
        if hasattr(
                self.crash,
                'use_crash_input') and self.crash.use_crash_input and hasattr(
                    self.crash, 'crash'):
            for i in range(size):
                byte_value = st.posix.stdin.load(i, 1)
                if not st.solver.symbolic(byte_value):
                    continue
                constraint = (byte_value == self.crash.crash[i])
                if not st.solver.satisfiable(extra_constraints=[constraint]):
                    continue
                st.solver.add(constraint)

        self._payload_len = length
        self._raw_payload = ChallRespInfo.atoi_dumps(st)

        self._create_solvers(ft, extra_vars_to_solve)