def fetch(team, issue_no, config, token=None): repo_owner = config['repo_owner'] repo_name = config['teams'][team]['repo_name'] github = Github(config["player"], token) _, submitter, create_time, content = \ get_github_issue(repo_owner, repo_name, issue_no, github) # Write the fetched issue content to temp file tmpfile = "/tmp/gitctf_%s.issue" % random_string(6) with open(tmpfile, "w") as f: f.write(content) # Decrypt the exploit out_dir = "exploit-%s-%s" % (submitter, create_time) prompt_rmdir_warning(out_dir) rmdir(out_dir) mkdir(out_dir) team = config["player_team"] out_dir = decrypt_exploit(tmpfile, config, team, out_dir, submitter) if out_dir is not None: print "Exploit fetched into %s" % out_dir # Clean up rmfile(tmpfile)
def process_issue(repo_name, num, id, config, gen_time, github, scoreboard): repo_owner = config['repo_owner'] if is_closed(repo_owner, repo_name, num, github): mark_as_read(id, github) return title, _, _, _ = get_github_issue(repo_owner, repo_name, num, github) create_label(repo_owner, repo_name, "eval", "9466CB", \ "Exploit is under review.", github) update_label(repo_owner, repo_name, num, github, "eval") defender = get_defender(config, repo_name) if defender is None: print '[*] Fatal error: unknown target %s.' % repo_name sys.exit() return branch, commit, attacker, log = verify_issue(defender, repo_name, num, \ config, github) if branch is None: log = "```\n" + log + "```" failure_action(repo_owner, repo_name, num, \ log + '\n\n[*] The exploit did not work.', id, github) return if config['individual'][attacker]['team'] == defender: failure_action(repo_owner, repo_name, num, \ '[*] Self-attack is not allowed: %s.' % attacker, \ id, github) return create_label(repo_owner, repo_name, branch, "DA0019", \ "Exploit for %s" % branch , github) update_label(repo_owner, repo_name, num, github, branch) #XXX: We should fix this logic and scoreboard representation if branch == "master": kind = commit else: kind = branch info = {'attacker': attacker, 'defender': defender, 'bugkind': kind} sync_scoreboard(scoreboard) if kind.startswith('bug'): process_intended(repo_name, num, config, gen_time, info, scoreboard, \ id, github) else: process_unintended(repo_name, num, config, gen_time, info, scoreboard, id, github)
def process_issue(repo_name, num, id, config, gen_time, github, scoreboard): repo_owner = config['repo_owner'] if is_closed(repo_owner, repo_name, num, github): mark_as_read(id, github) return title, _, _, _ = get_github_issue(repo_owner, repo_name, num, github) create_label(repo_owner, repo_name, "eval", "DA0019", \ "Exploit is under review.", github) update_label(repo_owner, repo_name, num, github, "eval") defender = get_defender(config, repo_name) if defender is None: print('[*] Fatal error: unknown target %s.' % repo_name) sys.exit() return branch, commit, attacker, log = verify_issue(defender, repo_name, num, \ config, github) if branch is None: log = "```\n" + log + "```" failure_action(repo_owner, repo_name, num, \ log + '\n\n[*] The exploit did not work.', id, github) return if config['individual'][attacker]['team'] == defender: failure_action(repo_owner, repo_name, num, \ '[*] Self-attack is not allowed: %s.' % attacker, \ id, github) return create_label(repo_owner, repo_name, "verified", "9466CB", \ "Successfully verified.", github) update_label(repo_owner, repo_name, num, github, "verified") create_comment(repo_owner, repo_name, num, "This submission has been verified. Well done!", github) kind = commit info = { 'attacker': attacker, 'defender': defender, 'branch': branch, 'bugkind': kind } sync_scoreboard(scoreboard) process_unintended(repo_name, num, config, gen_time, info, scoreboard, id, github, repo_owner)
def verify_issue(defender, repo_name, issue_no, config, github, target_commit=None): timeout = config["exploit_timeout"]["exercise_phase"] repo_owner = config['repo_owner'] title, submitter, create_time, content = \ get_github_issue(repo_owner, repo_name, issue_no, github) # Issue convention: "exploit-[branch_name]" target_branch = title[8:] clone(repo_owner, repo_name) # Write the fetched issue content to temp file tmpfile = "/tmp/gitctf_%s.issue" % random_string(6) tmpdir = "/tmp/gitctf_%s.dir" % random_string(6) with open(tmpfile, "w") as f: f.write(content) # Decrypt the exploit mkdir(tmpdir) team = defender decrypt_exploit(tmpfile, config, team, tmpdir, submitter) rmfile(tmpfile) # Now iterate through branches and verify exploit # zchn: not sure about this, was: branches = list_branches(repo_name) bug_branches = config['teams'][team]['bug_branches'] branches = bug_branches + ['master'] if len(bug_branches) > 0 \ else list_branches(repo_name) candidates = [] if (target_branch in branches) and (target_commit is None): # Iterate through branches and collect candidates commit = get_latest_commit_hash(repo_name, create_time, target_branch) candidates.append((target_branch, commit)) verified_branch = None verified_commit = None log = 'About %s (exploit-service branch)\n' % title for (branch, commit) in candidates: if branch in title: result, log = verify_exploit(tmpdir, repo_name, commit, timeout, \ config, log=log) else: result, _ = verify_exploit(tmpdir, repo_name, commit, timeout, \ config) if result: verified_branch = branch verified_commit = commit break rmdir(tmpdir) rmdir(repo_name) if verified_branch is None: print("[*] The exploit did not work against branch '%s'" % \ target_branch) else: print("[*] The exploit has been verified against branch '%s'" % verified_branch) return (verified_branch, verified_commit, submitter, log)