def test_submitted_and_unsubmitted_patches(self):
        r0 = Round.create(num=0)
        team = Team.create(name=Team.OUR_NAME)
        cs = ChallengeSet.create(name="foo")
        cs.rounds = [r0]
        cbn = ChallengeBinaryNode.create(name="cbn", cs=cs, blob="aaa1")
        patchtype1 = PatchType.create(name="PatchType1",
                                      functionality_risk=0,
                                      exploitability=0)
        patchtype2 = PatchType.create(name="PatchType2",
                                      functionality_risk=0,
                                      exploitability=0)

        patch1 = ChallengeBinaryNode.create(name="patch1",
                                            patch_type=patchtype1,
                                            cs=cs,
                                            root=cbn,
                                            blob="aaa2")
        patch2 = ChallengeBinaryNode.create(name="patch2",
                                            patch_type=patchtype2,
                                            cs=cs,
                                            root=cbn,
                                            blob="aaa3")

        assert_equals(len(cbn.unsubmitted_patches), 2)
        assert_in(patch1, cbn.unsubmitted_patches)
        assert_in(patch2, cbn.unsubmitted_patches)
        assert_equals(len(cbn.submitted_patches), 0)

        ChallengeSetFielding.create_or_update_submission(team=team,
                                                         cbns=[patch1, patch2],
                                                         round=r0)
        assert_equals(len(cbn.submitted_patches), 2)
        assert_equals(len(cbn.unsubmitted_patches), 0)
    def test_is_multi_cbn(self):
        r0 = Round.create(num=0)
        our_team = Team.create(name=Team.OUR_NAME)
        # CS single binary
        cs = ChallengeSet.create(name="single")
        cs.rounds = [r0]
        cbn = ChallengeBinaryNode.create(name="foo", cs=cs, blob="aaa1")
        # CS multi binary
        cs_multi = ChallengeSet.create(name="multi")
        cs_multi.rounds = [r0]
        cbn1 = ChallengeBinaryNode.create(name="foo1",
                                          cs=cs_multi,
                                          blob="aaa2")
        cbn2 = ChallengeBinaryNode.create(name="foo2",
                                          cs=cs_multi,
                                          blob="aaa3")
        # create fielding entries
        ChallengeSetFielding.create(cs=cs,
                                    cbns=[cbn],
                                    team=our_team,
                                    available_round=r0)
        ChallengeSetFielding.create(cs=cs_multi,
                                    cbns=[cbn1, cbn2],
                                    team=our_team,
                                    available_round=r0)

        assert_false(cs.is_multi_cbn)
        assert_true(cs_multi.is_multi_cbn)
Exemple #3
0
def create_round(args):
    if not len(args.challenge_sets):
        fielded = [cs.name for cs in CS.fielded_in_round()]
    else:
        fielded = args.challenge_sets
    new_round = Round.create(
        num=args.number if args.number is not None else Round.current_round() +
        1)

    for f in fielded:
        cs = CS.select().where(CS.name == f).get()
        CSF.create(cs=cs, team=Team.get_our(), available_round=new_round)
    def test_has_submissions_in_round(self):
        r0 = Round.create(num=0)
        r1 = Round.create(num=1)
        cs = ChallengeSet.create(name="foo")
        cbn = ChallengeBinaryNode.create(name="foo1", cs=cs, blob="aaa")
        our_team = Team.create(name=Team.OUR_NAME)
        other_team = Team.create(name="enemy")

        ChallengeSetFielding.create(cs=cs,
                                    cbns=[cbn],
                                    team=our_team,
                                    submission_round=r1)
        assert_false(cs.has_submissions_in_round(r0))
        assert_true(cs.has_submissions_in_round(r1))

        ChallengeSetFielding.create(cs=cs,
                                    cbns=[cbn],
                                    team=other_team,
                                    submission_round=r0)
        assert_false(cs.has_submissions_in_round(r0))

        ChallengeSetFielding.create(cs=cs,
                                    cbns=[cbn],
                                    team=our_team,
                                    submission_round=r0)
        assert_true(cs.has_submissions_in_round(r0))
    def test_has_type1(self):
        from farnsworth.models.pov_test_result import PovTestResult
        pov_type = 'type1'
        cs = ChallengeSet.create(name="foo")
        job = AFLJob.create(cs=cs)
        Exploit.create(cs=cs,
                       job=job,
                       pov_type=pov_type,
                       blob=BLOB,
                       c_code="code",
                       reliability=0)
        assert_false(cs.has_type1)

        Exploit.create(cs=cs,
                       job=job,
                       pov_type=pov_type,
                       blob=BLOB,
                       c_code="code",
                       reliability=1)
        assert_true(cs.has_type1)

        # if not first condition is not met
        r2 = Round.create(num=2)
        cs2 = ChallengeSet.create(name="bar")
        job2 = AFLJob.create(cs=cs2)
        cbn2 = ChallengeBinaryNode.create(name="bar", cs=cs2, blob="aaa")
        team2 = Team.create(name=Team.OUR_NAME)
        exploit2 = Exploit.create(cs=cs2,
                                  job=job2,
                                  pov_type=pov_type,
                                  blob=BLOB,
                                  c_code="code",
                                  reliability=0)
        csf2 = ChallengeSetFielding.create_or_update_available(team=team2,
                                                               cbn=cbn2,
                                                               round=r2)
        pov_result2 = PovTestResult.create(exploit=exploit2,
                                           cs_fielding=csf2,
                                           num_success=0)
        assert_false(cs2.has_type1)

        pov_result2.num_success = 10
        pov_result2.save()
        assert_true(cs2.has_type1)
Exemple #6
0
def download_cbns(args):
    cs = CS.get(CS.name == args.cs)
    dir_name = 'binaries-cs-%s' % cs.name
    quiet_mkdir(dir_name)

    first = True
    shas = set()
    tm = CSF.cbns.get_through_model()
    for fielding in (CSF.select(
            CSF, Team, Round, tm).join(Team).switch(CSF).join(
                Round, on=(Round.id == CSF.available_round
                           )).switch(CSF).join(tm).join(CBN).where(
                               CSF.cs == cs).order_by(Round.created_at)):
        if first:
            name = "original"
            first = False
        else:
            name = "team-%s" % fielding.team.name

        quiet_mkdir(os.path.join(dir_name, name))

        print "before loop..."
        for cbn in fielding.cbns:
            print "in loop"
            if cbn.sha256 in shas:
                print "already saw this one!"
                continue

            with open(
                    os.path.join(
                        dir_name, name,
                        name + "_round-%s-" % fielding.available_round.num +
                        cbn.name.replace('/', '_')), 'wb') as f:
                f.write(cbn.blob)
            shas.add(cbn.sha256)

    our_patches = os.path.join(dir_name, 'our-patches')
    quiet_mkdir(our_patches)
    for cbn in CBN.select().where(CBN.cs == cs, ~(CBN.sha256.in_(shas))):
        with open(
                os.path.join(our_patches,
                             cbn.name.replace('/', '_') + "-" + cbn.sha256),
                'wb') as f:
            f.write(cbn.blob)
Exemple #7
0
    def patch_decision(target_cs):
        """
        Determines the CBNs to submit. Returns None if no submission should be made.
        """
        fielding = ChallengeSetFielding.latest(target_cs, Team.get_our())
        fielded_patch_type = fielding.cbns[0].patch_type
        current_cbns = list(fielding.cbns)

        all_patches = target_cs.cbns_by_patch_type()
        allowed_patches = {
            k: v
            for k, v in all_patches.items() if not CBSubmitter.blacklisted(v)
        }

        if not allowed_patches:
            # All of the patches are blacklisted, or none exist -- submit the originals
            if not CBSubmitter.same_cbns(target_cs.cbns_original,
                                         current_cbns):
                return list(target_cs.cbns_original)
            else:
                return

        allowed_patch_type = fielded_patch_type in allowed_patches.keys()
        if allowed_patch_type:
            enough_data = len(allowed_patches[fielded_patch_type]
                              [0].fieldings) > MIN_ROUNDS_ONLINE
            if not enough_data:
                LOG.debug("Old patch (%s) too fresh on %s, leaving it in.",
                          fielded_patch_type.name, target_cs.name)
                return

        to_submit_patch_type, _ = sorted(
            allowed_patches.items(),
            key=lambda i: CBSubmitter.cb_score(i[1][0]),
            reverse=True)[0]

        if to_submit_patch_type is fielded_patch_type:
            return

        new_cbns = all_patches[to_submit_patch_type]
        if not CBSubmitter.same_cbns(new_cbns, current_cbns):
            return new_cbns
Exemple #8
0
    def _submit_patches(self, cable):
        patches = [
            (str(cbn.root.name) if cbn.root is not None else str(cbn.name),
             str(cbn.blob)) for cbn in cable.cbns
        ]
        result = self._cgc.uploadRCB(str(cable.cs.name), *patches)
        LOG.debug("Submitted RB! Response: %s", result)

        submission_round, status = Round.get_or_create_latest(
            num=result['round'])

        if status == Round.FIRST_GAME:
            LOG.error("Submission in first round of first game (round #%d)",
                      submission_round.num)
        elif status == Round.NEW_GAME:
            LOG.info("Submission in first round of new game (round #%d)",
                     submission_round.num)
        elif status == Round.NEW_ROUND:
            LOG.info("Submission beginning of new round #%d",
                     submission_round.num)

        return ChallengeSetFielding.create_or_update_submission(
            cbns=cable.cbns, team=Team.get_our(), round=submission_round)
    def test_cbns_original(self):
        r0 = Round.create(num=0)
        r1 = Round.create(num=1)
        our_team = Team.create(name=Team.OUR_NAME)
        other_team = Team.create(name="opponent")
        cs = ChallengeSet.create(name="foo")
        cs.rounds = [r0, r1]
        cbn = ChallengeBinaryNode.create(name="foo", cs=cs, blob="aaa1")
        cbn_patched = ChallengeBinaryNode.create(name="foo",
                                                 cs=cs,
                                                 patch_type=PatchType.create(
                                                     name="patch1",
                                                     functionality_risk=0,
                                                     exploitability=1,
                                                 ),
                                                 blob="aaa2")
        cbn_other_team = ChallengeBinaryNode.create(name="foo",
                                                    cs=cs,
                                                    blob="aaa3")
        ChallengeSetFielding.create(cs=cs,
                                    cbns=[cbn],
                                    team=our_team,
                                    available_round=r0)
        ChallengeSetFielding.create(cs=cs,
                                    cbns=[cbn_patched],
                                    team=our_team,
                                    submission_round=r0).save()
        ChallengeSetFielding.create(cs=cs,
                                    cbns=[cbn_other_team],
                                    team=other_team,
                                    available_round=r0).save()

        assert_equals(len(cs.cbns_original), 1)
        assert_in(cbn, cs.cbns_original)
        assert_not_in(cbn_patched, cs.cbns_original)
        assert_not_in(cbn_other_team, cs.cbns_original)
Exemple #10
0
    def _jobs(self):
        for cs in self.challenge_sets():
            # Unlike Rex, there's only 1 kind of crash we can exploit
            # We do not schedule if we already have a type1 exploit
            if not cs.has_type1:
                ordered_crashes = cs.crashes.select(Crash.id) \
                                            .where(Crash.kind == Vulnerability.IP_OVERWRITE) \
                                            .order_by(fn.octet_length(Crash.blob).asc())

                sliced = islice(ordered_crashes, FEED_LIMIT)
                for priority, crash in self._normalize_sort(
                        BASE_PRIORITY, sliced):
                    job = PovFuzzer1Job(cs=cs,
                                        payload={
                                            'crash_id': crash.id,
                                            'target_cs_fld': None,
                                            'target_ids_fld': None
                                        },
                                        request_cpu=1,
                                        limit_memory=4096,
                                        limit_time=5 * 60)
                    LOG.debug(
                        "Yielding PovFuzzer1Job for %s with crash %s priority %d",
                        cs.name, crash.id, priority)
                    yield (job, priority)
            else:
                # Schedule pov_fuzzers against other teams
                # We will schedule at most 3 exploits
                longest = list(
                    cs.exploits.select(Exploit.crash).join(Crash).where(
                        Exploit.method == "fuzzer", Exploit.reliability > 0,
                        Exploit.pov_type == "type1").order_by(
                            fn.octet_length(Crash.blob).desc()).limit(3))

                for team in Team.opponents():
                    target_cs_fld = ChallengeSetFielding.latest(cs, team)

                    if target_cs_fld is not None:  # Are there any CS fielded?
                        target_ids_fld = IDSRuleFielding.latest(cs, team)

                        # See if there are successful PoVs for this
                        # fielded CS and IDS. If yes, no need to
                        # schedule Pov Testing Jobs
                        pov_test_results = PovTestResult.best(
                            target_cs_fld, target_ids_fld)

                        if pov_test_results is None or pov_test_results.num_success < 3:
                            # We do not have any strong PoVs for the
                            # current fielded CS. Schedule 3 pov_fuzzers
                            for exploit in longest:
                                if target_ids_fld is not None:
                                    target_ids_id = target_ids_fld.id
                                else:
                                    target_ids_id = None

                                payload = {
                                    'crash_id': exploit.crash.id,
                                    'target_cs_fld': target_cs_fld.id,
                                    'target_ids_fld': target_ids_id
                                }
                                job = PovFuzzer1Job(cs=cs,
                                                    payload=payload,
                                                    request_cpu=1,
                                                    limit_memory=2048,
                                                    limit_time=5 * 60)
                                priority = 80
                                LOG.debug(
                                    "Yielding targeted PovFuzzer1Job for %s "
                                    "with crash %s priority %d team %d",
                                    cs.name, exploit.crash.id, priority,
                                    team.id)
                                yield (job, priority)
Exemple #11
0
def fieldings(args):
    for cs in CSF.select().join(CS.fielded_in_round(round_=args.round)).where(
            CSF.submission_round):
        pass
Exemple #12
0
if job is None:
    raise Exception("Couldn't find job %d", job_id)

cs_fielding_id = job.payload['target_cs_fld']
ids_fielding_id = job.payload['target_ids_fld']

# get the cbnp for the originals if there isn't a fielding id
if cs_fielding_id is None:
    ids_rules = None
    if job.cs.is_multi_cbn:
        cbnp = map(lambda c: c.path, job.cs.cbns_original)
    else:
        cbnp = job.cs.cbns_original[0].path
# otherwise get the cs's in the fielding
else:
    cbnp = map(lambda c: c.path, ChallengeSetFielding.get(id=cs_fielding_id).cbns)
    # if the ids_fielding id is not None get it
    ids_rules = None
    if ids_fielding_id is not None:
        ids_rules_obj = IDSRuleFielding.get(id=ids_fielding_id).ids_rule
        if ids_rules_obj is not None and ids_rules_obj.rules is not None and len(str(ids_rules_obj.rules).strip()) > 0:
            ids_rules = str(ids_rules_obj.rules)

crash = job.input_crash

crash_payload = str(crash.blob)
time_limit = job.limit_time-10

l.info("Pov fuzzer 1 beginning to exploit crash %d for challenge %s", crash.id, job.cs.name)
try:
    pov_fuzzer = pov_fuzzing.Type1CrashFuzzer(cbnp, crash=crash_payload, ids_rules=ids_rules, time_limit=time_limit)
Exemple #13
0
    def test_patch_selection(self):
        t = Team.create(name=Team.OUR_NAME)
        r0 = Round.create(num=0)
        cs = CS.create(name='x')

        # Set up a CBN for it, with some feedback
        cbn_orig = CBN.create(cs=cs, name="unpatched", blob="XXXX")
        pf_orig = PF.create(cs=cs,
                            round=r0,
                            success=1.0,
                            timeout=0,
                            connect=0,
                            function=0,
                            time_overhead=0.0,
                            memory_overhead=0.0)

        # Field the default CBN
        CSF.create(cs=cs,
                   cbns=[cbn_orig],
                   team=t,
                   available_round=r0,
                   poll_feedback=pf_orig)

        # Make sure we properly handle the case when there are no patches
        assert_is_none(scriba.submitters.cb.CBSubmitter.patch_decision(cs))

        # And patch it
        pt = PT.create(name="a_patch",
                       functionality_risk=0.,
                       exploitability=0.)
        cbn_p1 = CBN.create(cs=cs, name="patch1", blob="XXXYZ", patch_type=pt)
        PS.create(cs=cs,
                  patch_type=pt,
                  num_polls=10,
                  has_failed_polls=False,
                  failed_polls=0,
                  round=r0,
                  perf_score={
                      'score': {
                          'ref': {
                              'task_clock': 1.0,
                              'rss': 1.0,
                              'flt': 1.0,
                              'file_size': 1.0
                          },
                          'rep': {
                              'task_clock': 1.1,
                              'file_size': 1.1,
                              'rss': 1.1,
                              'flt': 1.1,
                          }
                      }
                  })

        # Make sure we choose this patch
        assert_equals(scriba.submitters.cb.CBSubmitter.patch_decision(cs),
                      [cbn_p1])

        # Field the patch - we're down the first round
        r1 = Round.create(num=1)
        pf1 = PF.create(cs=cs,
                        round=r1,
                        success=0.0,
                        timeout=0,
                        connect=0,
                        function=0,
                        time_overhead=0.0,
                        memory_overhead=0.0)
        CSF.create(cs=cs,
                   cbns=[cbn_p1],
                   team=t,
                   available_round=r1,
                   poll_feedback=pf1)

        r2 = Round.create(num=2)
        pf2 = PF.create(cs=cs,
                        round=r1,
                        success=1.0,
                        timeout=0,
                        connect=0,
                        function=0,
                        time_overhead=1.3,
                        memory_overhead=1.3)
        CSF.create(cs=cs,
                   cbns=[cbn_p1],
                   team=t,
                   available_round=r2,
                   poll_feedback=pf2)

        # Make sure we revert
        assert_equals(scriba.submitters.cb.CBSubmitter.patch_decision(cs),
                      [cbn_orig])
Exemple #14
0
    def test_simple_selector(self):
        try:
            t = Team.get_our()
        except Team.DoesNotExist:
            t = Team.create(name=Team.OUR_NAME)
        cs = CS.create(name='x')

        # Set up a CBN for it, with some feedback
        cbn_orig = CBN.create(cs=cs, name="unpatched", blob="XXXX")

        # Field the default CBN
        r0 = Round.create(num=0)
        pf_r0 = PF.create(cs=cs,
                          round=r0,
                          success=1.0,
                          timeout=0,
                          connect=0,
                          function=0,
                          time_overhead=0.0,
                          memory_overhead=0.0)
        cs.seen_in_round(r0)
        CSF.create(cs=cs,
                   cbns=[cbn_orig],
                   team=t,
                   available_round=r0,
                   poll_feedback=pf_r0)

        # make sure we don't submit on round 0
        assert_is_none(
            scriba.submitters.cb.CBSubmitter.patch_decision_simple(cs, r0))

        # tick the round
        r1 = Round.create(num=1)
        pf_r1 = PF.create(cs=cs,
                          round=r1,
                          success=1.0,
                          timeout=0,
                          connect=0,
                          function=0,
                          time_overhead=0.0,
                          memory_overhead=0.0)
        cs.seen_in_round(r1)
        CSF.create(cs=cs,
                   cbns=[cbn_orig],
                   team=t,
                   available_round=r1,
                   poll_feedback=pf_r1)

        # make sure we don't submit on round 0
        assert_is_none(
            scriba.submitters.cb.CBSubmitter.patch_decision_simple(cs, r1))

        # tick the round
        r2 = Round.create(num=2)
        pf_r2 = PF.create(cs=cs,
                          round=r2,
                          success=1.0,
                          timeout=0,
                          connect=0,
                          function=0,
                          time_overhead=0.0,
                          memory_overhead=0.0)
        cs.seen_in_round(r2)
        CSF.create(cs=cs,
                   cbns=[cbn_orig],
                   team=t,
                   available_round=r2,
                   poll_feedback=pf_r2)

        # Make sure we properly handle the case when there are no patches
        assert_is_none(
            scriba.submitters.cb.CBSubmitter.patch_decision_simple(cs, r0))

        # And patch it, without feedback
        pt1 = PT.create(name="a_patch",
                        functionality_risk=0.,
                        exploitability=0.4)
        cbn_p1 = CBN.create(cs=cs, name="patch1", blob="XXXYZ", patch_type=pt1)
        pt2 = PT.create(name="b_patch",
                        functionality_risk=0.,
                        exploitability=0.3)
        cbn_p2 = CBN.create(cs=cs, name="patch2", blob="XXXZZ", patch_type=pt2)

        # Make sure we grab the "best" patch
        assert_items_equal(
            scriba.submitters.cb.CBSubmitter.patch_decision_simple(cs, r2),
            [cbn_p2])

        # emulate the ambassador submitting this f****r
        csf0s = CSF.create(cs=cs, cbns=[cbn_p2], team=t, submission_round=r2)

        # add a new, better patch
        pt3 = PT.create(name="c_patch",
                        functionality_risk=0.,
                        exploitability=0.2)
        cbn_p3 = CBN.create(cs=cs, name="patch3", blob="XXXXZ", patch_type=pt3)

        # make sure we select the new patch, because it's still the right round
        assert_items_equal(
            scriba.submitters.cb.CBSubmitter.patch_decision_simple(cs, r2),
            [cbn_p3])
        csf0s.cbns = [cbn_p3]
        csf0s.save()

        # make sure we are now happy
        assert_is_none(
            scriba.submitters.cb.CBSubmitter.patch_decision_simple(cs, r2))

        # down a round
        r3 = Round.create(num=3)
        pf_r3 = PF.create(cs=cs,
                          round=r3,
                          success=0,
                          timeout=0,
                          connect=0,
                          function=0,
                          time_overhead=0.0,
                          memory_overhead=0.0)
        cs.seen_in_round(r3)
        CSF.create(cs=cs,
                   cbns=[cbn_p3],
                   team=t,
                   available_round=r3,
                   poll_feedback=pf_r3)

        # tick the round
        r4 = Round.create(num=4)
        pf_r4 = PF.create(cs=cs,
                          round=r4,
                          success=1.0,
                          timeout=0,
                          connect=0,
                          function=0,
                          time_overhead=0.05,
                          memory_overhead=0.05)
        cs.seen_in_round(r4)
        CSF.create(cs=cs,
                   cbns=[cbn_p3],
                   team=t,
                   available_round=r4,
                   poll_feedback=pf_r4)

        # make sure we don't choose to change the selection
        assert_is_none(
            scriba.submitters.cb.CBSubmitter.patch_decision_simple(cs, r4))

        # now find a better patch
        pt4 = PT.create(name="d_patch",
                        functionality_risk=0.,
                        exploitability=0.1)
        cbn_p4 = CBN.create(cs=cs, name="patch4", blob="XXXYX", patch_type=pt4)

        # too late, man
        assert_is_none(
            scriba.submitters.cb.CBSubmitter.patch_decision_simple(cs, r4))

        # now we get the baaaad news
        r5 = Round.create(num=5)
        pf_r5 = PF.create(cs=cs,
                          round=r5,
                          success=0.8,
                          timeout=0,
                          connect=0,
                          function=0.2,
                          time_overhead=0.05,
                          memory_overhead=0.05)
        cs.seen_in_round(r5)
        CSF.create(cs=cs,
                   cbns=[cbn_p3],
                   team=t,
                   available_round=r5,
                   poll_feedback=pf_r5)

        # Make sure we properly roll back
        assert_items_equal(
            scriba.submitters.cb.CBSubmitter.patch_decision_simple(cs, r5),
            cs.cbns_original)
        CSF.create(cs=cs, cbns=cs.cbns_original, team=t, submission_round=r5)

        # down a round
        r6 = Round.create(num=6)
        pf_r6 = PF.create(cs=cs,
                          round=r4,
                          success=0,
                          timeout=0,
                          connect=0,
                          function=0,
                          time_overhead=0.0,
                          memory_overhead=0.0)
        cs.seen_in_round(r6)
        CSF.create(cs=cs,
                   cbns=[cbn_orig],
                   team=t,
                   available_round=r6,
                   poll_feedback=pf_r6)

        # that worked
        r7 = Round.create(num=7)
        pf_r7 = PF.create(cs=cs,
                          round=r7,
                          success=1.0,
                          timeout=0,
                          connect=0,
                          function=0,
                          time_overhead=0.0,
                          memory_overhead=0.0)
        cs.seen_in_round(r7)
        CSF.create(cs=cs,
                   cbns=[cbn_orig],
                   team=t,
                   available_round=r7,
                   poll_feedback=pf_r7)

        # make sure we're happy staying unpatched
        assert_is_none(
            scriba.submitters.cb.CBSubmitter.patch_decision_simple(cs, r7))
Exemple #15
0
    raise Exception("Couldn't find job %d", job_id)

cs_fielding_id = job.payload['target_cs_fld']
ids_fielding_id = job.payload['target_ids_fld']

# get the cbnp for the originals if there isn't a fielding id
if cs_fielding_id is None:
    ids_rules = None
    if job.cs.is_multi_cbn:
        cbnp = map(lambda c: c.path, job.cs.cbns_original)
    else:
        cbnp = job.cs.cbns_original[0].path
# otherwise get the cs's in the fielding
else:
    cbnp = map(lambda c: c.path,
               ChallengeSetFielding.get(id=cs_fielding_id).cbns)
    # if the ids_fielding id is not None get it
    ids_rules = None
    if job.payload['target_ids_fld'] is not None:
        ids_rules_obj = IDSRuleFielding.get(id=ids_fielding_id).ids_rule
        if ids_rules_obj is not None and ids_rules_obj.rules is not None and len(
                str(ids_rules_obj.rules).strip()) > 0:
            ids_rules = str(ids_rules_obj.rules)

crash = job.input_crash

crash_payload = str(crash.blob)
time_limit = job.limit_time - 10

l.info("Pov fuzzer 2 beginning to exploit crash %d for challenge %s", crash.id,
       job.cs.name)
Exemple #16
0
    def patch_decision_simple(target_cs, round_):
        """
        Determines the CBNs to submit. Returns None if no submission should be made.
        We only submit 1 patch type per CS.
        """
        LOG.info("CB SUBMISSION START: %s (round %d)", target_cs.name,
                 round_.num)

        # make sure that this binary is not new this round
        if not (target_cs.id
                in [cs.id for cs in ChallengeSet.fielded_in_round(round_)]
                and Round.prev_round() is not None and target_cs.id in [
                    cs.id
                    for cs in ChallengeSet.fielded_in_round(Round.prev_round())
                ]):
            LOG.info("%s - not patching in the first round", target_cs.name)
            return

        current_fielding = ChallengeSetFielding.latest(cs=target_cs,
                                                       team=Team.get_our(),
                                                       round=round_)

        # Fielding should always be not None, or we are in a
        # race condition and do not want to do anything right
        # now, we will be run again, at which point fieldings
        # should be set.
        if current_fielding is None:
            LOG.warning(
                "%s - hit the race condition for latest fielding being None",
                target_cs.name)
            return

        LOG.info("%s - current patch type: %s", target_cs.name,
                 (current_fielding.cbns[0].patch_type.name if
                  current_fielding.cbns[0].patch_type is not None else "None"))

        # if we just submitted, wait a round before making any decisions
        if current_fielding.poll_feedback is not None and (
                current_fielding.poll_feedback.timeout +
                current_fielding.poll_feedback.success +
                current_fielding.poll_feedback.function +
                current_fielding.poll_feedback.connect == 0):
            LOG.warning("%s - skipping 'downed' round", target_cs.name)
            return

        # if we don't have any patches ready, let's wait
        all_patches = target_cs.cbns_by_patch_type()
        if len(all_patches) == 0:
            return

        best_patch_type = sorted(all_patches.keys(),
                                 key=lambda pt: pt.exploitability)[0]
        has_feedback = {
            k: v
            for k, v in all_patches.iteritems() if len(v[0].poll_feedbacks) > 0
        }
        pull_back = any(cbns[0].min_cb_score is not None
                        and cbns[0].min_cb_score < MIN_CB_SCORE
                        for cbns in all_patches.values())

        for k, v in has_feedback.items():
            LOG.info("%s - minimum score of patch %s is %s", target_cs.name,
                     k.name, v[0].min_cb_score)

        if pull_back:
            LOG.info("%s - pulling back the patch :-(", target_cs.name)
            new_cbns = target_cs.cbns_original
        else:
            # if we've already patched, and we're not pulling back, forget about it
            if best_patch_type.name != 'manual' and not CBSubmitter.same_cbns(
                    current_fielding.cbns, target_cs.cbns_original):
                LOG.info("%s - already patched -- aborting!", target_cs.name)
                return

            LOG.info("%s - chose %s patch type!", target_cs.name,
                     best_patch_type.name)
            new_cbns = all_patches[best_patch_type]

        # Check if we have submitted in this round?
        submitted_fielding = ChallengeSetFielding.submissions(
            cs=target_cs, team=Team.get_our(), round=round_)

        if submitted_fielding is not None:
            LOG.info("%s - we have an earlier submission this round...",
                     target_cs.name)
            prior_submission = list(submitted_fielding.cbns)
        else:
            LOG.info("%s - submitting for the first time this round...",
                     target_cs.name)
            prior_submission = list(current_fielding.cbns)

        # if we submitted an exploit for the first time this round, let's not patch
        if not pull_back and ExploitSubmissionCable.select(
        ).join(Exploit).where(
            (ExploitSubmissionCable.cs == target_cs)
                & (ExploitSubmissionCable.processed_at != None)
                & (ExploitSubmissionCable.processed_at >= round_.created_at)
                & (Exploit.method != "backdoor")).exists(
                ) and not ExploitSubmissionCable.select().join(Exploit).where(
                    (ExploitSubmissionCable.cs == target_cs)
                    & (ExploitSubmissionCable.processed_at != None)
                    & (ExploitSubmissionCable.processed_at < round_.created_at)
                    & (Exploit.method != "backdoor")).exists():
            LOG.info(
                "%s - not submitting because we first found an exploit last round",
                target_cs.name)
            new_cbns = list(current_fielding.cbns)

        if CBSubmitter.same_cbns(new_cbns, prior_submission):
            LOG.info("%s - nothing to do, this would be a resubmission",
                     target_cs.name)
            return
        else:
            LOG.info("%s - we have not yet submitted these CBNs this round!",
                     target_cs.name)

        return new_cbns