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)
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)
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)
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()
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)
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)
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())
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())
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)
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()
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
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)
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 ""
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)
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)
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)
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)
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)
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:]))
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 = []
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))
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])
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