def test_cache_stall():
    '''
    Test cache restoration stall
    '''

    # test a valid palindrome
    t = tracer.Tracer(
        os.path.join(bin_location, "tests/cgc/CROMU_00071"),
        "0c0c492a53acacacacacacacacacacacacac000100800a0b690e0aef6503697d660a0059e20afc0a0a332f7d66660a0059e20afc0a0a332f7fffffff16fb1616162516161616161616166a7dffffff7b0e0a0a6603697d660a0059e21c"
        .decode('hex'))
    rex.trace_additions.ZenPlugin.prep_tracer(t)
    crash_path, crash_state = t.run()

    nose.tools.assert_not_equal(crash_path, None)
    nose.tools.assert_not_equal(crash_state, None)

    # load it again
    t = tracer.Tracer(
        os.path.join(bin_location, "tests/cgc/CROMU_00071"),
        "0c0c492a53acacacacacacacacacacacacac000100800a0b690e0aef6503697d660a0059e20afc0a0a332f7d66660a0059e20afc0a0a332f7fffffff16fb1616162516161616161616166a7dffffff7b0e0a0a6603697d660a0059e21c"
        .decode('hex'))
    rex.trace_additions.ZenPlugin.prep_tracer(t)
    crash_path, crash_state = t.run()

    nose.tools.assert_not_equal(crash_path, None)
    nose.tools.assert_not_equal(crash_state, None)
Beispiel #2
0
def test_cgc_se1_palindrome_raw():
    # Test CGC Scored Event 1's palindrome challenge with raw input
    #import ipdb; ipdb.set_trace()

    # test a valid palindrome
    t = tracer.Tracer(os.path.join(bin_location, "tests/cgc/sc1_0b32aa01_01"), b"racecar\n")
    result_state, crash_state = t.run()

    # make sure the heap base is correct and hasn't been altered from the default
    nose.tools.assert_equal(result_state.cgc.allocation_base, 0xb8000000)

    # make sure there is no crash state
    nose.tools.assert_equal(crash_state, None)

    # make sure angr modeled the correct output
    stdout_dump = result_state.posix.dumps(1)
    nose.tools.assert_true(stdout_dump.startswith(b"\nWelcome to Palindrome Finder\n\n"
                                                  b"\tPlease enter a possible palindrome: "
                                                  b"\t\tYes, that's a palindrome!\n\n"
                                                  b"\tPlease enter a possible palindrome: "))
    # make sure there were no 'Nope's from non-palindromes
    nose.tools.assert_false(b"Nope" in stdout_dump)

    # now test crashing input
    t = tracer.Tracer(os.path.join(bin_location, "tests/cgc/sc1_0b32aa01_01"), b"B" * 129)
    result_state, crash_state = t.run()

    nose.tools.assert_not_equal(result_state, None)
    nose.tools.assert_not_equal(crash_state, None)
Beispiel #3
0
def trace():
    import tracer

    b = "/tmp/KPRCA_00025"
    pov = "/home/fish/cgc/benign_traffic/KPRCA_00025/for-testing__GEN_00001.xml"

    tracer = tracer.Tracer(b, pov_file=pov)
Beispiel #4
0
def main():
    parser = argparse.ArgumentParser(description='Python tracer CLI',
                                     usage=argparse.SUPPRESS)
    parser.usage = 'tracer [options]\ninput pipe: {"source?": "string", "input"?: "string", "steps?": "number"}'
    parser.add_argument('--pretty',
                        default=False,
                        action='store_true',
                        help='Pretty print output')
    parser.add_argument('--test',
                        default=False,
                        action='store_true',
                        help='Run the test source, ignoring the provided')
    arguments = parser.parse_args()

    trace = json.loads(input())

    trace['source'] = \
        trace['source'] if not arguments.test and trace.get('source') is not None else \
        pathlib.Path('./res/main.py').read_text(encoding='utf8') if arguments.test else \
        ''
    trace['input'] = trace['input'] if trace.get('input') is not None else ''
    trace['steps'] = trace['steps'] if trace.get(
        'steps') is not None else 2**31 - 1

    t = tracer.Tracer(trace)
    result = t.run()

    print(json.dumps(result,
                     check_circular=False,
                     indent=4 if arguments.pretty else None,
                     separators=None if arguments.pretty else (',', ':')),
          end='')
Beispiel #5
0
def test_allocation_base_continuity():
    correct_out = b'prepare for a challenge\nb7fff000\nb7ffe000\nb7ffd000\nb7ffc000\nb7ffb000\nb7ffa000\nb7ff9000\nb7ff8000\nb7ff7000\nb7ff6000\nb7ff5000\nb7ff4000\nb7ff3000\nb7ff2000\nb7ff1000\nb7ff0000\nb7fef000\nb7fee000\nb7fed000\nb7fec000\ndeallocating b7ffa000\na: b7ffb000\nb: b7fff000\nc: b7ff5000\nd: b7feb000\ne: b7fe8000\ne: b7fa8000\na: b7ffe000\nb: b7ffd000\nc: b7ff7000\nd: b7ff6000\ne: b7ff3000\ne: b7f68000\nallocate: 3\na: b7fef000\n'

    t = tracer.Tracer(os.path.join(bin_location, "tests/i386/cgc_allocations"), b"")
    state, _ = t.run()

    nose.tools.assert_equal(state.posix.dumps(1), correct_out)
Beispiel #6
0
    def __init__(self, configfile=None):
        '''
            Initialization method of Choronzon. Reads the configuration,
            instantiates objects of the vital classes, builds and
            analyzes the first generation of chromosomes by reading
            the initial population provided to the fuzzer.
        '''
        # configuration is a singleton
        self.configuration = configuration.Configuration(configfile)
        self.campaign = campaign.Campaign(self.configuration['CampaignName'])

        seedpath = self.campaign.copy_directory(
            self.configuration['InitialPopulation'], name='seedfiles')

        self.tracer = tracer.Tracer()
        self.strategy = strategy.FuzzingStrategy()
        self.population = world.Population(self.tracer.cache)
        self.evaluator = evaluator.Evaluator(self.tracer.cache)

        try:
            self.sharedpath = self.campaign.create_shared_directory(
                self.configuration['ChromosomeShared'])
        except:
            self.sharedpath = None

        # Initialize factory for building chromosome
        # and the proxy for computing the fitness.
        chromosomes = chromosome.Factory.build(seedpath)
        for chromo in chromosomes:
            self.population.add_chromosome(chromo)

        self.analyze()
Beispiel #7
0
    def _run(self, job):
        """Create a cache"""
        assert not job.cs.is_multi_cbn, "CacheWorker scheduled on multicb, this should NOT happen"

        LOG.debug("Invoking cache worker on challenge %s", self._cs.name)

        if job.atoi_flag:
            # fix the cache manager
            self.tracer_cache = CRSTracerCacheManager(atoi_flag=True)
            tracer.tracer.GlobalCacheManager = self.tracer_cache
            self.tracer_cache.cs = self._cs

        # Run until the first receive
        tr = tracer.Tracer(self._cbn.path, str(""))

        # Enable the ZenPlugin
        ZenPlugin.prep_tracer(tr)

        # Hook up atoi stuff if needed
        if job.atoi_flag:
            atoi_infos = worker.workers.AtoiManager.get_atoi_info(
                self._cs.symbols)
            ChallRespInfo.prep_tracer(tr, atoi_infos)
            LOG.info("Hooked up %d atoi infos", len(atoi_infos))

        tr.run()
Beispiel #8
0
def test_recursion():
    blob = "00aadd114000000000000000200000001d0000000005000000aadd2a1100001d0000000001e8030000aadd21118611b3b3b3b3b3e3b1b1b1adb1b1b1b1b1b1118611981d8611".decode(
        'hex')
    t = tracer.Tracer(
        os.path.join(os.path.dirname(__file__),
                     "../../binaries/tests/cgc/NRFIN_00075"), blob)
    t.run()
Beispiel #9
0
def test_symbolic_sized_receives():
    binary_path = os.path.join(bin_location, "tests/cgc/CROMU_00070")
    t = tracer.Tracer(binary_path, b"hello")

    # will except if failed
    result_state, crash_state = t.run()

    nose.tools.assert_true(result_state is not None)
    nose.tools.assert_equal(crash_state, None)

    t = tracer.Tracer(binary_path, b"\x00" * 20)

    # will except if failed
    result_state, crash_state = t.run()

    nose.tools.assert_true(result_state is not None)
    nose.tools.assert_equal(crash_state, None)
Beispiel #10
0
def test_crash_detection():
    '''
    Test tracer's ability to detect where (at what address) an input truly caused a crash.
    Caused a bug in unicorn.
    '''

    t = tracer.Tracer(os.path.join(bin_location, "tests/i386/call_symbolic"),
                      "A" * 700)

    _, crash_state = t.run()

    nose.tools.assert_true(crash_state.se.symbolic(crash_state.regs.ip))
Beispiel #11
0
 def __init__(self, master, pos, dir=(0, 1), starting_orbs=15):
     Orb.__init__(self, master, pos, dir,
                  [random.randrange(100, 255) for i in range(3)])
     self.speed = self.defaultspeed
     self.tracer = tracer.Tracer(self.pos, self.dir, self.dashing_f)
     self.radius = 15
     self.children = [
         Orb(self, self.pos, self.dir, self.color)
         for i in range(starting_orbs)
     ]
     self.state = state.Flight_state(**{"head": self})
     self.action = False
    def test_inject(self):
        encoded_spans = []

        def transport_handler(encoded_span):
            encoded_spans.append(encoded_span)

        t = tracer.Tracer('test', 100, transport_handler, 9999)
        with t.start_span('test_op') as span:
            carrier = {}
            t.inject(span.context, tracer.Format.HTTP_HEADERS, carrier)

            new_span = t.extract(tracer.Format.HTTP_HEADERS, carrier)
            self.assertEqual(span.context, new_span)
Beispiel #13
0
def test_allocation_base_continuity():
    '''
    Make sure the heap base is correct in angr after concrete heap manipulation
    '''

    correct_out = 'prepare for a challenge\nb7fff000\nb7ffe000\nb7ffd000\nb7ffc000\nb7ffb000\nb7ffa000\nb7ff9000\nb7ff8000\nb7ff7000\nb7ff6000\nb7ff5000\nb7ff4000\nb7ff3000\nb7ff2000\nb7ff1000\nb7ff0000\nb7fef000\nb7fee000\nb7fed000\nb7fec000\ndeallocating b7ffa000\na: b7ffb000\nb: b7fff000\nc: b7ff5000\nd: b7feb000\ne: b7fe8000\ne: b7fa8000\na: b7ffe000\nb: b7ffd000\nc: b7ff7000\nd: b7ff6000\ne: b7ff3000\ne: b7f68000\nallocate: 3\na: b7fef000\n'

    t = tracer.Tracer(os.path.join(bin_location, "tests/i386/cgc_allocations"),
                      "")

    path, _ = t.run()

    nose.tools.assert_equal(path.state.posix.dumps(1), correct_out)
Beispiel #14
0
    def _prep_challenge_response(self, format_infos=None):

        # need to re-trace the binary with stdin symbolic

        remove_options = {so.SUPPORT_FLOATING_POINT}
        self._tracer = tracer.Tracer(self.binary,
                                     self.payload,
                                     remove_options=remove_options)
        ChallRespInfo.prep_tracer(self._tracer, format_infos)

        assert self.causes_leak(
        ), "challenge did not cause leak when trying to recover challenge-response"

        return self.attempt_pov(enabled_chall_resp=True)
Beispiel #15
0
def broken_cache_stall():
    # test a valid palindrome
    t = tracer.Tracer(
        os.path.join(bin_location, "tests/cgc/CROMU_00071"),
        bytes.fromhex(
            "0c0c492a53acacacacacacacacacacacacac000100800a0b690e0aef6503697d660a0059e20afc0a0a332f7d66660a0059e20afc0a0a332f7fffffff16fb1616162516161616161616166a7dffffff7b0e0a0a6603697d660a0059e21c"
        ))
    ZenPlugin.prep_tracer(t.simgr.one_active)
    crash_path, crash_state = t.run()

    nose.tools.assert_not_equal(crash_path, None)
    nose.tools.assert_not_equal(crash_state, None)

    # load it again
    t = tracer.Tracer(
        os.path.join(bin_location, "tests/cgc/CROMU_00071"),
        bytes.fromhex(
            "0c0c492a53acacacacacacacacacacacacac000100800a0b690e0aef6503697d660a0059e20afc0a0a332f7d66660a0059e20afc0a0a332f7fffffff16fb1616162516161616161616166a7dffffff7b0e0a0a6603697d660a0059e21c"
        ))
    ZenPlugin.prep_tracer(t.simgr.one_active)
    crash_path, crash_state = t.run()

    nose.tools.assert_not_equal(crash_path, None)
    nose.tools.assert_not_equal(crash_state, None)
Beispiel #16
0
def test():
    # worker = tracer.Tracer("key_construction", "ffffffff812cf16b")
    # worker = tracer.Tracer("key_restriction", "ffffffff812cbc03")
    # worker = tracer.Tracer("pipe_buffer", "ffffffff811965ec")
    # worker = tracer.Tracer("ext4_ext_path", "ffffffff8120762e")
    # worker = tracer.Tracer("mnt_namespace", "ffffffff811ac50a")
    # worker = tracer.Tracer("snd_seq_queue", "ffffffff816f0934")
    # worker = tracer.Tracer("eventpoll", "ffffffff811ce648")
    # worker = tracer.Tracer("pipe_inode_info", "ffffffff81195ad5")
    # worker = tracer.Tracer("file_lock", "ffffffff811d5d72")
    # worker = tracer.Tracer("mount", "ffffffff811acf2a")
    # worker = tracer.Tracer("uts_namespace", "ffffffff810e1f79")
    # worker = tracer.Tracer("listeners", "ffffffff8175a62c")
    # worker = tracer.Tracer("snd_seq_timer", "ffffffff816f2177")
    worker = tracer.Tracer("vmap_area", "ffffffff811cddef")
    worker.analyze()
Beispiel #17
0
 def __init__(self, cols, rows, size):
     self._cols = cols
     self._rows = rows
     self._size = size
     self._surface = pygame.Surface([self.get_width(), self.get_height()])
     self._board = [[(0, 0, 0) for i in range(cols)] for i in range(rows)]
     self._colored = [[(0, 0, 0) for i in range(cols)] for i in range(rows)]
     self._guessed = [[False for i in range(cols)] for i in range(rows)]
     self._queue = []
     self._tracer = tracer.Tracer(self._board)
     self._active = False
     self._colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0)]
     for i in range(len(self._colored)):
         for j in range(len(self._colored[i])):
             self._colored[i][j] = self._colors[random.randint(0, 3)]
     self._ticks = 0
    def test_start_span(self):
        encoded_spans = []

        def transport_handler(encoded_span):
            encoded_spans.append(encoded_span)

        t = tracer.Tracer('test', 100, transport_handler, 9999)
        with t.start_span('test_op') as span:
            pass

        self.assertEqual(1, len(encoded_spans))

        encoded_spans = []
        with t.start_span('outer_op') as outer_span:
            with t.start_span('inner_op', outer_span) as inner_span:
                pass

        self.assertEqual(2, len(encoded_spans))
Beispiel #19
0
    def __init__(self, binary, payload, format_infos=None):
        """
        :param binary: path to the binary which is suspect of leaking
        :param payload: concrete input string to feed to the binary
        :param format_infos: a list of atoi FormatInfo objects that should be used when analyzing the crash
        """

        self.binary = binary
        self.payload = payload

        if not os.access(self.binary, os.X_OK):
            raise ValueError(
                "\"%s\" binary does not exist or is not executable" %
                self.binary)

        # will be set by causes_leak
        self._leak_path = None

        remove_options = {so.SUPPORT_FLOATING_POINT}
        self._tracer = tracer.Tracer(binary,
                                     payload,
                                     preconstrain_input=False,
                                     remove_options=remove_options)
        ZenPlugin.prep_tracer(self._tracer)

        e_path = self._tracer.simgr.active[0]

        backing = SimSymbolicMemory(memory_id='file_colorguard')
        backing.set_state(e_path)
        backing.store(0, e_path.se.BVV(payload))

        e_path.posix.files[0] = SimFile('/dev/stdin',
                                        'r',
                                        content=backing,
                                        size=len(payload))

        # will be overwritten by _concrete_difference if the input was filtered
        # this attributed is used exclusively for testing at the moment
        self._no_concrete_difference = not self._concrete_difference()

        self.leak_ast = None
Beispiel #20
0
#!/usr/bin/env python

import sys
import types
import tracer

if __name__ == '__main__':
    import countinst
    mainpyfile = sys.argv[1]
    tr = tracer.Tracer()
    with open(mainpyfile, "rb") as fp:
        cmd = "exec(compile(%r, %r, 'exec'))" % \
                        (fp.read(), mainpyfile)

    tr.execfilename(cmd, mainpyfile)
 def test_init(self):
     t = tracer.Tracer('test', 100, None, 9999)
Beispiel #22
0
    def __init__(self,
                 binary,
                 crash=None,
                 pov_file=None,
                 aslr=None,
                 constrained_addrs=None,
                 crash_state=None,
                 prev_path=None,
                 hooks=None,
                 format_infos=None,
                 rop_cache_tuple=None,
                 use_rop=True,
                 explore_steps=0,
                 angrop_object=None):
        '''
        :param binary: path to the binary which crashed
        :param crash: string of input which crashed the binary
        :param pov_file: CGC PoV describing a crash
        :param aslr: analyze the crash with aslr on or off
        :param constrained_addrs: list of addrs which have been constrained during exploration
        :param crash_state: an already traced crash state
        :param prev_path: path leading up to the crashing block
        :param hooks: dictionary of simprocedure hooks, addresses to simprocedures
        :param format_infos: a list of atoi FormatInfo objects that should be used when analyzing the crash
        :param rop_cache_tuple: a angrop tuple to load from
        :param use_rop: whether or not to use rop
        :param explore_steps: number of steps which have already been explored, should only set by exploration methods
        :param angrop_object: an angrop object, should only be set by exploration methods
        '''

        self.binary = binary
        self.crash = crash
        self.pov_file = pov_file
        self.constrained_addrs = [] if constrained_addrs is None else constrained_addrs
        self.hooks = hooks
        self.explore_steps = explore_steps

        if self.explore_steps > 10:
            raise CannotExploit(
                "Too many steps taken during crash exploration")

        self.project = angr.Project(binary)

        # we search for ROP gadgets now to avoid the memory exhaustion bug in pypy
        # hash binary contents for rop cache name
        binhash = hashlib.md5(open(self.binary).read()).hexdigest()
        rop_cache_path = os.path.join(
            "/tmp", "%s-%s-rop" % (os.path.basename(self.binary), binhash))

        if use_rop:
            if angrop_object is not None:
                self.rop = angrop_object
            else:
                self.rop = self.project.analyses.ROP()
                if rop_cache_tuple is not None:
                    l.info("loading rop gadgets from cache tuple")
                    self.rop._load_cache_tuple(rop_cache_tuple)
                elif os.path.exists(rop_cache_path):
                    l.info("loading rop gadgets from cache '%s'",
                           rop_cache_path)
                    self.rop.load_gadgets(rop_cache_path)
                else:
                    self.rop.find_gadgets(show_progress=False)
                    self.rop.save_gadgets(rop_cache_path)
        else:
            self.rop = None

        self.os = self.project.loader.main_object.os

        # determine the aslr of a given os and arch
        if aslr is None:
            if self.os == "cgc":  # cgc has no ASLR, but we don't assume a stackbase
                self.aslr = False
            else:  # we assume linux is going to enfore stackbased aslr
                self.aslr = True
        else:
            self.aslr = aslr

        if crash_state is None:
            # run the tracer, grabbing the crash state
            remove_options = {
                so.TRACK_REGISTER_ACTIONS, so.TRACK_TMP_ACTIONS,
                so.TRACK_JMP_ACTIONS, so.ACTION_DEPS,
                so.TRACK_CONSTRAINT_ACTIONS, so.LAZY_SOLVES
            }
            add_options = {
                so.MEMORY_SYMBOLIC_BYTES_MAP, so.TRACK_ACTION_HISTORY,
                so.CONCRETIZE_SYMBOLIC_WRITE_SIZES,
                so.CONCRETIZE_SYMBOLIC_FILE_READ_SIZES
            }

            # faster place to check for non-crashing inputs

            # optimized crash check
            if self.project.loader.main_object.os == 'cgc':

                if not tracer.Runner(binary, input=self.crash).crash_mode:
                    if not tracer.Runner(binary,
                                         input=self.crash,
                                         report_bad_args=True).crash_mode:
                        l.warning("input did not cause a crash")
                        raise NonCrashingInput

            self._tracer = tracer.Tracer(binary,
                                         input=self.crash,
                                         pov_file=self.pov_file,
                                         resiliency=False,
                                         hooks=self.hooks,
                                         add_options=add_options,
                                         remove_options=remove_options,
                                         keep_predecessors=2)
            ChallRespInfo.prep_tracer(self._tracer, format_infos)
            ZenPlugin.prep_tracer(self._tracer)
            prev, crash_state = self._tracer.run(constrained_addrs)

            # if there was no crash we'll have to use the previous path's state
            if crash_state is None:
                self.state = prev
            else:
                # the state at crash time
                self.state = crash_state

            zp = self.state.get_plugin('zen_plugin')
            if crash_state is None and (zp is not None
                                        and len(zp.controlled_transmits) == 0):
                l.warning("input did not cause a crash")
                raise NonCrashingInput

            l.debug("done tracing input")
            # a path leading up to the crashing basic block
            self.prev = prev

        else:
            self.state = crash_state
            self.prev = prev_path
            self._tracer = None

        # list of actions added during exploitation, probably better object for this attribute to belong to
        self.added_actions = []

        # hacky trick to get all bytes
        #memory_writes = [ ]
        #for var in self.state.memory.mem._name_mapping.keys():
        #    memory_writes.extend(self.state.memory.addrs_for_name(var))

        memory_writes = sorted(self.state.memory.mem.get_symbolic_addrs())
        l.debug("filtering writes")
        memory_writes = [m for m in memory_writes if m / 0x1000 != 0x4347c]
        user_writes = [
            m for m in memory_writes if any(
                "stdin" in v for v in self.state.memory.load(m, 1).variables)
        ]
        flag_writes = [
            m for m in memory_writes if any(
                v.startswith("cgc-flag")
                for v in self.state.memory.load(m, 1).variables)
        ]
        l.debug("done filtering writes")

        self.symbolic_mem = self._segment(user_writes)
        self.flag_mem = self._segment(flag_writes)

        # crash type
        self.crash_types = []
        # action (in case of a bad write or read) which caused the crash
        self.violating_action = None

        l.debug("triaging crash")
        self._triage_crash()
Beispiel #23
0
def test_crash_addr_detection():
    t = tracer.Tracer(os.path.join(bin_location, "tests/i386/call_symbolic"), b"A" * 700)
    _, crash_state = t.run()

    nose.tools.assert_true(crash_state.solver.symbolic(crash_state.regs.ip))
Beispiel #24
0
    def __init__(self,
                 binary,
                 crash=None,
                 pov_file=None,
                 aslr=None,
                 constrained_addrs=None,
                 crash_state=None,
                 prev_path=None,
                 hooks=None,
                 format_infos=None,
                 rop_cache_tuple=None,
                 use_rop=True,
                 explore_steps=0,
                 angrop_object=None):
        '''
        :binary: path to the binary which crashed   
        :crash: string of input which crashed the binary  
        :pov_file: CGC PoV describing a crash   
        :aslr: analyze the crash with aslr on or off   
        :constrained_addrs: list of addrs which have been constrained during exploration  
        :crash_state: an already traced crash state       
        :prev_path: path leading up to the crashing block      
        :hooks: dictionary of simprocedure hooks, addresses to simprocedures    
        :format_infos: a list of atoi FormatInfo objects that should be used when analyzing the crash  
        :rop_cache_tuple: a angrop tuple to load from        
        rop_cache_tuple:angrop——rop gadget finder and chain builder     
        :use_rop: whether or not to use rop           
        :explore_steps: number of steps which have already been explored, should only set by exploration methods       
        :angrop_object: an angrop object, should only be set by exploration methods      
        '''
        # some info from prev path, in order to execute prev path but bypass the crash point.
        self.binary = binary
        self.crash = crash
        self.pov_file = pov_file
        self.constrained_addrs = [] if constrained_addrs is None else constrained_addrs
        self.hooks = hooks
        self.explore_steps = explore_steps
        if self.explore_steps > 10:
            raise CannotExploit(
                "Too many steps taken during crash exploration")

        self.project = angr.Project(binary)

        # we search for ROP gadgets now to avoid the memory exhaustion bug in pypy
        # hash binary contents for rop cache name
        # executable file --(md5)--> short string
        binhash = hashlib.md5(open(self.binary).read()).hexdigest()
        # store the result in /tmp
        rop_cache_path = os.path.join(
            "/tmp", "%s-%s-rop" % (os.path.basename(self.binary), binhash))

        if use_rop:
            # angrop is a rop gadget finder and chain builder. automatically generate rot chains.
            if angrop_object is not None:
                self.rop = angrop_object
            else:
                self.rop = self.project.analyses.ROP()
            if rop_cache_tuple is not None:
                l.info("loading rop gadgets from cache tuple")
                self.rop._load_cache_tuple(rop_cache_tuple)
            elif os.path.exists(rop_cache_path):
                l.info("loading rop gadgets from cache '%s'", rop_cache_path)
                self.rop.load_gadgets(rop_cache_path)
            else:
                self.rop.find_gadgets()
                self.rop.save_gadgets(rop_cache_path)
        else:
            self.rop = None

        # system info
        self.os = self.project.loader.main_bin.os

        #determine the alsr of a given os and arch
        #we assume linux is going to enfore statckbased aslr
        if aslr is None:
            self.aslr = True
        else:
            self.aslr = aslr

        # first explore by the input
        if crash_state is None:
            #run the tracer, grabbing the crash state
            remove_options = {
                so.TRACK_REGISTER_ACTIONS, so.TRACK_TMP_ACTIONS,
                so.TRACK_JMP_ACTIONS, so.ACTION_DEPS,
                so.TRACK_CONSTRAINT_ACTIONS
            }
            add_options = {
                so.MEMORY_SYMBOLIC_BYTES_MAP, so.TRACK_ACTION_HISTORY,
                so.CONCRETIZE_SYMBOLIC_WRITE_SIZES,
                so.CONCRETIZE_SYMBOLIC_FILE_READ_SIZES
            }

            # use tracer to get path info at crash point.
            self._tracer = tracer.Tracer(binary,
                                         input=self.crash,
                                         pov_file=self.pov_file,
                                         resiliency=False,
                                         hooks=self.hooks,
                                         add_options=add_options,
                                         remove_options=remove_options)
            ChallRespInfo.prep_tracer(self._tracer, format_infos)
            ZenPlugin.prep_tracer(self._tracer)
            # crash_state is the state of crash instruction; prev is the previous state of crash state
            prev, crash_state = self._tracer.run(constrained_addrs)

            # if there was no crash we'll have to use the previous path's state
            if crash_state is None:
                self.state = prev.state
            else:
                # the state at crash time
                self.state = crash_state

            zp = self.state.get_plugin('zen_plugin')
            if crash_state is None and (zp is not None
                                        and len(zp.controlled_transmits) == 0):
                l.warning(
                    "input did not cause a crash, please check your input carefully!"
                )
                raise NonCrashingInput

            l.debug("done tracing input")
            self.prev = prev

        else:
            self.state = crash_state
            self.prev = prev_path
            self._tracer = None

        # list of actions added during exploitation, probably better object for this attribute to belong to
        self.added_actions = []

        # hacky trick to get all bytes
        memory_writes = sorted(self.state.memory.mem.get_symbolic_addrs())
        l.debug("filtering writes")
        memory_writes = [m for m in memory_writes
                         if m / 0x1000 != 0x4347c]  # start of pages
        user_writes = [
            m for m in memory_writes if any(
                "stdin" in v for v in self.state.memory.load(m, 1).variables)
        ]  # memory controlled by user
        # flag_writes = [m for m in memory_writes if any(v.startswith("cgc-flag") for v in self.state.memory.load(m, 1).variables)] # cgc-flag control
        l.debug("done filtering writes")

        self.symbolic_mem = self._segment(user_writes)
        # self.flag_mem = self._segment(flag_writes)

        # crash type
        self.crash_types = []
        # action (in case of a bad write or read) which caused the crash
        self.violating_action = None

        l.debug("triaging crash")
        self._triage_crash()
def test_recursion():
    t = tracer.Tracer(os.path.join(bin_location, "cgc", "CROMU_00071"),
                      open('crash2731').read())

    t.run()
Beispiel #26
0
# IPython log file

import tracer
data = open('./12130252971812747651385316796.seed').read()
t = tracer.Tracer(
    '/home/lukas/lukas/tools/angr-dev/cyborg-generator/bins/challenges_qualifiers/CROMU_00008/bin/CROMU_00008',
    data)
tracer.tracer.l.setLevel('DEBUG')
p = t.run()[0]
Beispiel #27
0
    def _drill_input(self):
        '''
        symbolically step down a path with a tracer, trying to concretize inputs for unencountered
        state transitions.
        '''

        # initialize the tracer
        t = tracer.Tracer(self.binary, self.input, hooks=self._hooks)

        self._set_concretizations(t)
        self._set_simproc_limits(t)

        # update encounters with known state transitions
        self._encounters.update(izip(t.trace, islice(t.trace, 1, None)))

        l.debug("drilling into %r", self.input)
        l.debug("input is %r", self.input)

        # used for finding the right index in the fuzz_bitmap
        prev_loc = 0

        branches = t.next_branch()
        while len(branches.active) > 0 and t.bb_cnt < len(t.trace):

            # check here to see if a crash has been found
            if self.redis and self.redis.sismember(
                    self.identifier + "-finished", True):
                return

            # mimic AFL's indexing scheme
            if len(branches.missed) > 0:
                prev_addr = branches.missed[0].addr_trace[-1]  # a bit ugly
                prev_loc = prev_addr
                prev_loc = (prev_loc >> 4) ^ (prev_loc << 8)
                prev_loc &= self.fuzz_bitmap_size - 1
                prev_loc = prev_loc >> 1
                for path in branches.missed:
                    cur_loc = path.addr
                    cur_loc = (cur_loc >> 4) ^ (cur_loc << 8)
                    cur_loc &= self.fuzz_bitmap_size - 1

                    hit = bool(
                        ord(self.fuzz_bitmap[cur_loc ^ prev_loc]) ^ 0xff)

                    transition = (prev_addr, path.addr)

                    l.debug("found %x -> %x transition", transition[0],
                            transition[1])

                    if not hit and not self._has_encountered(
                            transition) and not self._has_false(path):
                        t.remove_preconstraints(path)

                        if path.state.satisfiable():
                            # a completely new state transitions, let's try to accelerate AFL
                            # by finding  a number of deeper inputs
                            l.info(
                                "found a completely new transition, exploring to some extent"
                            )
                            w = self._writeout(prev_addr, path)
                            if w is not None:
                                yield w
                            for i in self._symbolic_explorer_stub(path):
                                yield i
                        else:
                            l.debug("path to %#x was not satisfiable",
                                    transition[1])

                    else:
                        l.debug("%x -> %x has already been encountered",
                                transition[0], transition[1])

            try:
                branches = t.next_branch()
            except IndexError:
                branches.active = []