예제 #1
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)
예제 #2
0
 def test_cbns_by_patch_type(self):
     cs = ChallengeSet.create(name="foo")
     cbn = ChallengeBinaryNode.create(name="foo", cs=cs, blob="aaa")
     patch0 = PatchType.create(
         name="patch0",
         functionality_risk=0,
         exploitability=1,
     )
     patch1 = PatchType.create(
         name="patch1",
         functionality_risk=0,
         exploitability=1,
     )
     cbn1 = ChallengeBinaryNode.create(name="foo1",
                                       cs=cs,
                                       patch_type=patch0,
                                       blob="aaa1")
     cbn2 = ChallengeBinaryNode.create(name="foo2",
                                       cs=cs,
                                       patch_type=patch0,
                                       blob="aaa2")
     cbn3 = ChallengeBinaryNode.create(name="foo3",
                                       cs=cs,
                                       patch_type=patch1,
                                       blob="aaa3")
     assert_in(patch0, cs.cbns_by_patch_type().keys())
     assert_in(patch1, cs.cbns_by_patch_type().keys())
     assert_in(cbn1, cs.cbns_by_patch_type()[patch0])
     assert_in(cbn2, cs.cbns_by_patch_type()[patch0])
     assert_in(cbn3, cs.cbns_by_patch_type()[patch1])
    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)
예제 #4
0
    def test_get_or_create(self):
        r = Round.create(num=0)
        cs = ChallengeSet.create(name="foo")
        cbn1 = ChallengeBinaryNode.create(name="foo1", cs=cs, blob="aaa1")
        cbn2 = ChallengeBinaryNode.create(name="foo1", cs=cs, blob="aaa2")
        ids = IDSRule.create(cs=cs, rules="aaa", sha256="sum")

        cbl1, crtd1 = CSSubmissionCable.get_or_create(cs=cs,
                                                      ids=ids,
                                                      cbns=[cbn1],
                                                      round=r)
        assert_true(crtd1)

        cbl2, crtd2 = CSSubmissionCable.get_or_create(cs=cs,
                                                      ids=ids,
                                                      cbns=[cbn1],
                                                      round=r)
        assert_false(crtd2)
        assert_equals(cbl1.id, cbl2.id)

        cbl3, crtd3 = CSSubmissionCable.get_or_create(cs=cs,
                                                      ids=ids,
                                                      cbns=[cbn1, cbn2],
                                                      round=r)
        assert_true(crtd3)

        cbl4, crtd4 = CSSubmissionCable.get_or_create(cs=cs,
                                                      ids=ids,
                                                      cbns=[cbn1, cbn2],
                                                      round=r)
        assert_false(crtd4)
        assert_equals(cbl3.id, cbl4.id)
예제 #5
0
def upload_cbns(args):
    cs = CS.select().where(CS.name == args.cs)

    patch_type, _ = PT.get_or_create(name="manual",
                                     functionality_risk=1.0,
                                     exploitability=0.0)

    cbns = []
    for patched_file in args.patched_files:
        with open(patched_file) as f:
            content = f.read()
        try:
            cbn = CBN.create(cs=cs,
                             blob=content,
                             name=patched_file,
                             patch_type=patch_type)
        except peewee.IntegrityError:
            print "CBN already exists. Fetching."
            cbn = CBN.select().where(CBN.name == args.patched_file,
                                     CBN.cs == cs, CBN.blob == content)
        cbns.append(cbn)

    if args.field:
        ids = IDSRule.get_or_create(cs=target_cs, rules='')
        CSSubmissionCable.get_or_create(cs=target_cs,
                                        cbns=cbns,
                                        ids=ids,
                                        round=Round.current_round())

    if args.eF is not None and args.eT is not None and args.eM is not None and cbn.patch_type is not None:
        perf_score = {
            'score': {
                'ref': {
                    'task_clock': 1.0,
                    'rss': 1.0,
                    'flt': 1.0,
                    'file_size': 1.0
                },
                'rep': {
                    'task_clock': args.eT,
                    'file_size': args.size_overhead,
                    'rss': args.eM,
                    'flt': args.eM,
                }
            }
        }
        PS.create(cs=cs,
                  perf_score=perf_score,
                  patch_type=cbn.patch_type,
                  has_failed_polls=args.eF != 0,
                  failed_polls=args.eF)
    if args.pT is not None and args.pM is not None and args.pS is not None:
        csf.poll_feedback = PF.create(cs=cs,
                                      round_id=Round.current_round().id,
                                      success=args.pS,
                                      time_overhead=args.pT,
                                      memory_overhead=args.pM,
                                      size_overhead=args.size_overhead)
        csf.save()
예제 #6
0
    def test_all(self):
        r1 = Round.create(num=0)
        cs = ChallengeSet.create(name="foo")
        cs.rounds = [r1]
        cbn1 = ChallengeBinaryNode.create(name="foo", cs=cs, blob="blob1")
        cbn2 = ChallengeBinaryNode.create(name="bar", cs=cs, blob="blob2")

        assert_equals(len(ChallengeBinaryNode.all()), 2)
        assert_equals(ChallengeBinaryNode.all()[0], cbn1)
        assert_equals(ChallengeBinaryNode.all()[1], cbn2)
예제 #7
0
    def test_get_or_create(self):
        cs = ChallengeSet.create(name="foo")
        cbn = ChallengeBinaryNode.create(name="foo", cs=cs, blob="aaa")
        job1, job1_created = RexJob.get_or_create(cbn=cbn, payload={'something': 'xxx'})
        job2, job2_created = AFLJob.get_or_create(cbn=cbn, payload={'something': 'xxx'})

        assert_not_equal(job1.id, job2.id)
        assert_true(job1_created)
        assert_true(job2_created)

        Job.delete().execute()
        ChallengeBinaryNode.delete().execute()
        ChallengeSet.delete().execute()
        Job._meta.database.commit()
    def test_root_association(self):
        cs = ChallengeSet.create(name="foo")
        root_cbn = ChallengeBinaryNode.create(name="root", cs=cs, blob=BLOB3)
        cbn1 = ChallengeBinaryNode.create(name="test1",
                                          cs=cs,
                                          root=root_cbn,
                                          blob=BLOB4)
        cbn2 = ChallengeBinaryNode.create(name="test2",
                                          cs=cs,
                                          root=root_cbn,
                                          blob=BLOB5)

        assert_equals(cbn1.root, root_cbn)
        assert_equals(len(root_cbn.descendants), 2)
        assert_in(cbn1, root_cbn.descendants)
        assert_in(cbn2, root_cbn.descendants)
예제 #9
0
    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_all_descendants(self):
        cs = ChallengeSet.create(name="foo")
        cbn1 = ChallengeBinaryNode.create(name="root1",
                                          cs=cs,
                                          blob=BLOB,
                                          sha256="sum1")
        cbn2 = ChallengeBinaryNode.create(name="root2",
                                          cs=cs,
                                          blob=BLOB,
                                          sha256="sum2")
        cbn3 = ChallengeBinaryNode.create(name="child",
                                          cs=cs,
                                          blob=BLOB,
                                          root=cbn1,
                                          sha256="sum3")

        assert_equals(len(ChallengeBinaryNode.all_descendants()), 1)
        assert_in(cbn3, ChallengeBinaryNode.all_descendants())
예제 #11
0
def field_cbns(args):
    cs = CS.select().where(CS.name == args.cs)
    # i know i could use one query for this, but then we might get duplicate CBNs and more than we want
    cbns = [
        CBN.get(CBN.cs == cs, CBN.sha256 == sha) for sha in args.patched_shas
    ]
    ids, _ = IDSRule.get_or_create(cs=cs, rules='')
    CSSubmissionCable.get_or_create(cs=cs,
                                    cbns=cbns,
                                    ids=ids,
                                    round=Round.current_round())
예제 #12
0
    def test_save(self):
        r1 = Round.create(num=0)
        cs = ChallengeSet.create(name="foo")
        cs.rounds = [r1]
        cbn = ChallengeBinaryNode.create(name="foo", cs=cs, blob="asdf")
        job = Job(cbn=cbn, worker='basemodel')

        updated_at = job.updated_at
        job.worker = '#aftersave'
        job.save()
        assert_greater(job.updated_at, updated_at)
예제 #13
0
 def setup(self):
     farnsworth.test_support.truncate_tables()
     self.cbn = ChallengeBinaryNode.create(blob=open(
         os.path.join(cbs_path, 'qualifier_event/ccf3d301/ccf3d301_01'),
         'rb').read(),
                                           name='ccf3d301_01',
                                           cs_id='ccf3d301')
     self.job = AFLJob.create(limit_cpu=4,
                              limit_memory=1,
                              limit_time=10,
                              cbn=self.cbn)
     self.aw = worker.AFLWorker()
예제 #14
0
    def _run(self, job):
        input_file = job.cbn.path
        patch_type = job.payload["patch_type"]
        pm = PatchMaster(input_file)
        patched_bin, ids_rule = pm.create_one_patch(patch_type)

        if patched_bin == None:
            LOG.warning("unable to generate patch")
            return
        else:
            name = "{}_patched_{}".format(job.cbn.name, patch_type)
            ids = IDSRule.get_by_sha256_or_create(rules=ids_rule, cs=job.cbn.cs)
            pt = PatchType.get(name=patch_type)
            ChallengeBinaryNode.create(
                root=job.cbn,
                cs=job.cbn.cs,
                name=name,
                patch_type=pt,
                blob=patched_bin,
                sha256=hashlib.sha256(patched_bin).hexdigest(),
                ids_rule=ids,
            )
    def test_binary_is_created_and_deleted_properly(self):
        cs = ChallengeSet.create(name=str(time.time()))
        cbn = ChallengeBinaryNode.create(name="mybin-%s" % cs.name,
                                         cs=cs,
                                         blob=BLOB)
        binpath = cbn._path

        assert_false(os.path.isfile(binpath))
        cbn.path

        assert_true(os.path.isfile(binpath))
        assert_equals(open(cbn.path, 'rb').read(), BLOB)
        cbn = None
예제 #16
0
    def test_unprocessed_submission_cables(self):
        r = Round.create(num=0)
        cs = ChallengeSet.create(name="foo")
        cbn = ChallengeBinaryNode.create(name="foo1", cs=cs, blob="aaa")
        ids = IDSRule.create(cs=cs, rules="aaa", blob="aaa")
        cable1 = CSSubmissionCable.create(cs=cs, ids=ids, cbns=[cbn], round=r)
        cable2 = CSSubmissionCable.create(cs=cs, ids=ids, cbns=[], round=r)

        assert_equals(len(cs.unprocessed_submission_cables()), 2)
        assert_equals(cable1, cs.unprocessed_submission_cables()[0])
        assert_equals(cable2, cs.unprocessed_submission_cables()[1])

        cable1.process()
        assert_equals(len(cs.unprocessed_submission_cables()), 1)
예제 #17
0
def list_patches(args):
    wanted_fields = (CBN.name, CBN.size, CBN.sha256, CBN.patch_type,
                     CBN.is_blacklisted)
    q = CBN.select(*wanted_fields)

    if args.cs is not None:
        cs = CS.select().where(CS.name == args.cs)
        for patch in q.where(CBN.cs == cs):
            print format_patch(patch)
    else:
        for cs in CS.fielded_in_round():
            print "CS {}:".format(cs.name)
            for patch in q.where(CBN.cs == cs):
                print format_patch(patch)
            print ""
예제 #18
0
    def test_to_job_type(self):
        cs = ChallengeSet.create(name="foo")
        cbn = ChallengeBinaryNode.create(name="foo", cs=cs, blob="aaa")
        afl_job = AFLJob.create(cbn=cbn)
        driller_job = DrillerJob.create(cbn=cbn)
        patcherex_job = PatcherexJob.create(cbn=cbn)
        rex_job = RexJob.create(cbn=cbn)
        tester_job = TesterJob.create(cbn=cbn)

        jobs = Job.select().order_by(Job.id.asc())
        job_types = [AFLJob, DrillerJob, PatcherexJob, RexJob, TesterJob]
        for i in range(len(job_types)):
            job_type = to_job_type(jobs[i]).__class__
            assert_in(job_type, job_types)
            job_types.remove(job_type)
 def test_cs_name_and_sha256_uniqueness(self):
     cs1 = ChallengeSet.create(name="foo")
     cs2 = ChallengeSet.create(name="bar")
     # first binary is ok
     ChallengeBinaryNode.create(name="test1", cs=cs1, blob=BLOB)
     # same binary with different name is ok
     ChallengeBinaryNode.create(name="test2", cs=cs1, blob=BLOB)
     # same binary with different cs is ok
     ChallengeBinaryNode.create(name="test1", cs=cs2, blob=BLOB)
     # same cs and name but different binary is ok
     ChallengeBinaryNode.create(name="test1", cs=cs2, blob=BLOB2)
     # same cs, name and binary raises error
     assert_raises(IntegrityError,
                   ChallengeBinaryNode.create,
                   name="test1",
                   cs=cs1,
                   blob=BLOB)
예제 #20
0
    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)
예제 #21
0
    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)
예제 #22
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)
예제 #23
0
    def test_added_completed(self):
        class GenericJob(Job):
            worker = CharField(default='generic_job')

        cs = ChallengeSet.create(name="foo")
        cbn = ChallengeBinaryNode.create(name="foo", cs=cs, blob="aaa")
        job = GenericJob(cbn=cbn)
        assert_raises(GenericJob.DoesNotExist, GenericJob.get, GenericJob.cbn == cbn)

        useless_job = RexJob(cbn=cbn)
        assert_raises(GenericJob.DoesNotExist, GenericJob.get, GenericJob.cbn == cbn)

        job.save()
        job = GenericJob.get(GenericJob.cbn == cbn)

        job.completed_at = datetime.datetime.now()
        job.save()
        assert_raises(GenericJob.DoesNotExist, GenericJob.get,
                      GenericJob.cbn == cbn,
                      GenericJob.completed_at == None)
예제 #24
0
    def test_variable_submitter(self):
        t = Team.create(name=Team.OUR_NAME)
        r0 = Round.create(num=0)

        # set up several CSes
        cses = [CS.create(name='CS_%s' % i) for i in range(10)]

        # Set up the patches
        for cs in cses:
            for pt in PT.select():
                ids = IDSRule.create(cs=cs, rules="HAHAHA")
                cbn = CBN.create(cs=cs,
                                 name=cs.name + "_" + pt.name,
                                 blob="XXXX",
                                 patch_type=pt,
                                 ids_rule=ids)

        patch_names = scriba.submitters.cb.ORIG_PATCH_ORDER

        try:
            cur_cssc_id = CSSC.select().order_by(CSSC.id.desc()).get().id
        except CSSC.DoesNotExist:
            cur_cssc_id = 0

        # run the scheduler
        for _ in scriba.submitters.cb.ORIG_PATCH_ORDER:
            for c in cses:
                scriba.submitters.cb.CBSubmitter.rotator_submission(c)

        # make sure they got rotated correctly
        for n, cs in enumerate(cses):
            cables = list(
                CSSC.select().where((CSSC.cs == cs)
                                    & (CSSC.id > cur_cssc_id)).order_by(
                                        CSSC.id.asc()))
            assert len(cables) > 0
            assert all(c.cbns[0].patch_type.name == pn
                       for c, pn in zip(cables, (patch_names * 10)[n:]))
예제 #25
0
cbnp = job.cs.cbns_original[0].path
print 'cbnp1111111111:', cbnp
#获取crash
if job.payload is not None:
    crash = job.input_crash
    crash_payload = str(crash.blob)
else:
    crash = None
    crash_payload = ""

#获取题的cs_id
cs_id = job.cs.id
l.info("pov_fuzzing_type for challenge %s", job.cs.name)

#获取题目类
challenge_node = ChallengeBinaryNode.get(ChallengeBinaryNode.cs_id == cs_id)

#获取题目ip
vm_ip = challenge_node.vm_ip

#获取题目端口
vm_port = challenge_node.vm_port

#获取题目题号
cbn_name = challenge_node.name
# whc
info = {}
lcs = {}
rop_and_index = {}
payload = []
예제 #26
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))
예제 #27
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])
예제 #28
0
def try_drilling(name, get_crashes):
    # set up the node
    cs = ChallengeSet.get_or_create(name=name.split('_')[0])
    cbn = ChallengeBinaryNode.get_create(name=name, cs=cs)
    cbn.root = cbn
    cbn.save()

    Exploit.delete().where(Exploit.cbn == cbn).execute()

    if not cbn.crashes or get_crashes:
        # Delete the testcases
        Test.delete().where(Test.cbn == cbn).execute()
        Crash.delete().where(Crash.cbn == cbn).execute()

        assert len(cbn.tests) == 0

        afl_job = AFLJob.create(cbn=cbn,
                                limit_cpu=4,
                                limit_memory=1,
                                limit_time=80)
        afl_thread = AFLThread(afl_job)
        afl_thread.start()

        for _ in range(10):
            if len(cbn.tests) == 2: break
            time.sleep(1)
        assert len(cbn.tests) == 2
        assert len(afl_thread._worker._seen) == 2
        assert len(cbn.crashes) == 0

        # schedule driller
        for i in cbn.tests:
            dj = DrillerJob.create(payload=i,
                                   cbn=cbn,
                                   limit_cpu=1,
                                   limit_memory=10)
            dw = worker.DrillerWorker()
            dw.run(dj)

            assert len(dj.tests) > 0  #pylint:disable=no-member

        for _ in range(80):
            if len(cbn.crashes) > 0: break
            time.sleep(1)
        assert len(afl_thread._worker._seen) > 2
        assert len(cbn.tests) > 2
        assert len(cbn.crashes) > 0

        afl_thread.join()

    sorted_crashes = sorted(cbn.crashes, key=lambda x: -len(str(x.blob)))
    print "Chose crash of length %d" % len(sorted_crashes[0].blob)

    rj = RexJob.create(payload=sorted_crashes[0],
                       cbn=cbn,
                       limit_cpu=1,
                       limit_memory=10)
    rw = worker.RexWorker()
    rw.run(rj)

    assert len(cbn.exploits) == 2