def admin_create_chal(): if request.method == 'POST': files = request.files.getlist('files[]') # Create challenge chal = Challenges(request.form['name'], request.form['desc'], request.form['value'], request.form['category'], int(request.form['chaltype'])) if 'hidden' in request.form: chal.hidden = True else: chal.hidden = False db.session.add(chal) db.session.flush() flag = Keys(chal.id, request.form['key'], int(request.form['key_type[0]'])) if request.form.get('keydata'): flag.data = request.form.get('keydata') db.session.add(flag) db.session.commit() for f in files: upload_file(file=f, chalid=chal.id) db.session.commit() db.session.close() return redirect(url_for('admin_challenges.admin_chals')) else: return render_template('admin/chals/create.html')
def admin_keys_view(keyid): if request.method == 'GET': if keyid: saved_key = Keys.query.filter_by(id=keyid).first_or_404() key_class = get_key_class(saved_key.type) json_data = { 'id': saved_key.id, 'key': saved_key.flag, 'data': saved_key.data, 'chal': saved_key.chal, 'type': saved_key.type, 'type_name': key_class.name, 'templates': key_class.templates, } return jsonify(json_data) elif request.method == 'POST': chal = request.form.get('chal') flag = request.form.get('key') key_type = request.form.get('key_type') if not keyid: k = Keys(chal, flag, key_type) db.session.add(k) else: k = Keys.query.filter_by(id=keyid).first() k.flag = flag k.type = key_type db.session.commit() db.session.close() return '1'
def create(request): """ This method is used to process the challenge creation request. :param request: :return: """ # Create challenge chal = AnonymousChallenge( name=request.form['name'], value=request.form['value'], category=request.form['category'], type=request.form['chaltype'], ) chal.hidden = True # The challenge should always be hidden chal.max_attempts = 0 # Unlimited attempts for this type of challenge db.session.add(chal) db.session.commit() flag = Keys(chal.id, request.form['key'], 'static') # request.form['key_type[0]']) if request.form.get('keydata'): flag.data = request.form.get('keydata') db.session.add(flag) db.session.commit() files = request.files.getlist('files[]') for f in files: utils.upload_file(file=f, chalid=chal.id) db.session.commit()
def admin_create_chal(): if request.method == 'POST': files = request.files.getlist('files[]') # Create challenge chal = Challenges(request.form['name'], request.form['desc'], request.form['value'], request.form['category'], int(request.form['chaltype'])) if 'hidden' in request.form: chal.hidden = True else: chal.hidden = False max_attempts = request.form.get('max_attempts') if max_attempts and max_attempts.isdigit(): chal.max_attempts = int(max_attempts) db.session.add(chal) db.session.flush() flag = Keys(chal.id, request.form['key'], int(request.form['key_type[0]'])) if request.form.get('keydata'): flag.data = request.form.get('keydata') db.session.add(flag) db.session.commit() for f in files: utils.upload_file(file=f, chalid=chal.id) db.session.commit() db.session.close() return redirect(url_for('admin_challenges.admin_chals')) else: return render_template('admin/chals/create.html')
def create(request): """ This method is used to process the challenge creation request. :param request: :return: """ files = request.files.getlist('files[]') # Create challenge chal = BonusChallenges( name=request.form['name'], description=request.form['desc'], value=request.form['value'], category='Bonus Flag', type=request.form['chaltype'], ) chal.hidden = True db.session.add(chal) db.session.commit() flag = Keys(chal.id, request.form['key'], request.form['key_type[0]']) if request.form.get('keydata'): flag.data = request.form.get('keydata') db.session.add(flag) db.session.commit()
def create(request): """ This method is used to process the challenge creation request. :param request: :return: """ files = request.files.getlist('files[]') keys = {} for i in range(len(request.form)): key_name = 'key_name[{}]'.format(i) key_sol = 'key_solution[{}]'.format(i) key_type = 'key_type[{}]'.format(i) if key_name in request.form: keys[request.form[key_name]] = { 'key': request.form[key_sol], 'type': request.form[key_type] } else: break # Create challenge chal = MultiQuestionChallengeModel( name=request.form['name'], description=request.form['description'], value=request.form['value'], category=request.form['category'], type=request.form['chaltype']) if 'hidden' in request.form: chal.hidden = True else: chal.hidden = False max_attempts = request.form.get('max_attempts') if max_attempts and max_attempts.isdigit(): chal.max_attempts = int(max_attempts) db.session.add(chal) db.session.commit() for key, value in keys.iteritems(): flag = Keys(chal.id, value['key'], value['type']) flag.data = json.dumps({key: False}) db.session.add(flag) db.session.commit() for f in files: utils.upload_file(file=f, chalid=chal.id) db.session.commit() db.session.close()
def create(request): """ This method is used to process the challege creation request. :param request: :return: """ buildingList = [] for item in request.form: if "buildingId" in item: buildingList.append(request.form[item]) buildingListString = [str(x) for x in buildingList] print(buildingListString) files = request.files.getlist('files[]') chal = SmartCityChallenge(name=request.form['name'], category=request.form['category'], description=request.form['description'], value=request.form['value'], buildingId=str(buildingListString), soundId=request.form['soundId'], type=request.form['chaltype']) if 'hidden' in request.form: chal.hidden = True else: chal.hidden = False max_attempts = request.form.get('max_attempts') if max_attempts and max_attempts.isdigit(): chal.max_attempts = int(max_attempts) #logger.debug("Genereted buildingId " + chal.buildingId + " for challenge " + chal.name) db.session.add(chal) db.session.commit() flag = Keys(chal.id, request.form['key'], request.form['key_type[0]']) if request.form.get('keydata'): flag.data = request.form.get('keydata') db.session.add(flag) db.session.commit() for f in files: utils.upload_file(file=f, chalid=chal.id) db.session.commit()
def admin_create_chal(): files = request.files.getlist('files[]') # Create challenge chal = Challenges(request.form['name'], request.form['desc'], request.form['value'], request.form['category']) db.session.add(chal) db.session.commit() # Add keys key = Keys(chal.id, request.form['key'], request.form['key_type[0]']) db.session.add(key) db.session.commit() for f in files: filename = secure_filename(f.filename) if len(filename) <= 0: continue md5hash = hashlib.md5(filename).hexdigest() if not os.path.exists(os.path.join(os.path.normpath(app.config['UPLOAD_FOLDER']), md5hash)): os.makedirs(os.path.join(os.path.normpath(app.config['UPLOAD_FOLDER']), md5hash)) f.save(os.path.join(os.path.normpath(app.config['UPLOAD_FOLDER']), md5hash, filename)) db_f = Files(chal.id, os.path.join(os.path.normpath(app.config['UPLOAD_FOLDER']), md5hash, filename)) db.session.add(db_f) db.session.commit() db.session.close() return redirect('/admin/chals')
def admin_keys(chalid): if request.method == 'GET': keys = Keys.query.filter_by(chal=chalid).all() json = {'keys': []} for x in keys: json['keys'].append({ 'id': x.id, 'key': x.flag, 'type': x.key_type }) return jsonify(json) elif request.method == 'POST': keys = Keys.query.filter_by(chal=chalid).all() for x in keys: db.session.delete(x) newkeys = request.form.getlist('keys[]') newvals = request.form.getlist('vals[]') for flag, val in zip(newkeys, newvals): key = Keys(chalid, flag, val) db.session.add(key) db.session.commit() db.session.close() return '1'
def create(request): files = request.files.getlist('files[]') # Create challenge chal = GenFlagCDBM( name=request.form['name'], value=request.form['value'], category=request.form['category'], type=request.form['chaltype'], generator=request.form['generator'] ) if 'hidden' in request.form: chal.hidden = True else: chal.hidden = False max_attempts = request.form.get('max_attempts') if max_attempts and max_attempts.isdigit(): chal.max_attempts = int(max_attempts) gen = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(6)) chal.key = "generated_flag_" + gen db.session.add(chal) db.session.commit() flag = Keys(chal.id, chal.key, 'static') db.session.add(flag) db.session.commit() for f in files: utils.upload_file(file=f, chalid=chal.id) db.session.commit()
def create(request): """ This method is used to process the challenge creation request. :param request: :return: """ # Create challenge chal = Challenges( name=request.form['name'], description=request.form['description'], value=request.form['value'], category=request.form['category'], type=request.form['chaltype'], penalty = request.form['penalty'] ) if 'hidden' in request.form: chal.hidden = True else: chal.hidden = False max_attempts = request.form.get('max_attempts') if max_attempts and max_attempts.isdigit(): chal.max_attempts = int(max_attempts) db.session.add(chal) db.session.commit() flag = Keys(chal.id, request.form['key'], request.form['key_type[0]']) if request.form.get('keydata'): flag.data = request.form.get('keydata') db.session.add(flag) db.session.commit() files = request.files.getlist('files[]') for f in files: utils.upload_file(file=f, chalid=chal.id) file_generators = request.files.getlist('file_generators[]') for g in file_generators: utils.upload_file(file=g, chalid=chal.id, isgenerator=True) db.session.commit()
def admin_keys_view(keyid): print repr(keyid) if request.method == 'GET': if keyid: saved_key = Keys.query.filter_by(id=keyid).first_or_404() json_data = { 'id': saved_key.id, 'key': saved_key.flag, 'data': saved_key.data, 'chal': saved_key.chal, 'type': saved_key.key_type, 'type_name': get_key_class(saved_key.key_type).name } return jsonify(json_data) elif request.method == 'POST': chal = request.form.get('chal') flag = request.form.get('key') data = request.form.get('keydata') key_type = int(request.form.get('key_type')) if not keyid: k = Keys(chal, flag, key_type) k.data = data db.session.add(k) else: k = Keys.query.filter_by(id=keyid).first() k.chal = chal k.flag = flag k.data = data k.key_type = key_type db.session.commit() db.session.close() return '1'
def create(request): """ This method is used to process the challenge creation request. :param request: :return: """ # Create challenge chal = CommunityChallengeModel(name=request.form['name'], description=request.form['description'], value=request.form['value'], category=request.form['category'], type=request.form['chaltype'], owner=session['id']) # Never hide Community challenges chal.hidden = False max_attempts = request.form.get('max_attempts') if max_attempts and max_attempts.isdigit(): chal.max_attempts = int(max_attempts) db.session.add(chal) db.session.commit() flag = Keys(chal.id, request.form['key'], request.form['key_type[0]']) if request.form.get('keydata'): flag.data = request.form.get('keydata') db.session.add(flag) db.session.commit() files = request.files.getlist('files[]') for f in files: utils.upload_file(file=f, chalid=chal.id) db.session.commit()
def admin_create_chal(): if request.method == 'POST': print("[DEBUG] Post request sent to my modified admin_create_chal") files = request.files.getlist('files[]') # Create challenge chal = Challenges( name=request.form['name'], description=request.form['desc'], value=request.form['value'], category=request.form['category'], type=request.form['chaltype'], ) if 'hidden' in request.form: chal.hidden = True else: chal.hidden = False max_attempts = request.form.get('max_attempts') if max_attempts and max_attempts.isdigit(): chal.max_attempts = int(max_attempts) db.session.add(chal) db.session.flush() # This if added by me print("[DEBUG] chal.id: " + str(chal.id)) if chal.type == 'ethereum': solidity = request.form['solidity'] test_func = request.form['test_func'] args = request.form['args'] starting_ether = request.form['starting-ether'] flag = request.form['key'] print("[DEBUG] Type is ethereum!") if ethereumctf.compile_contract(str(chal.id), solidity, test_func, ast.literal_eval(args), starting_ether, flag): print("[DEBUG] successful compile!") else: db.session.rollback() print("[DEBUG] failed compile") return redirect( url_for('admin_challenges.admin_create_chal') ) # TODO: Fail better db.session.commit() flag = Keys(chal.id, request.form['key'], int(request.form['key_type[0]'])) if request.form.get('keydata'): flag.data = request.form.get('keydata') db.session.add(flag) db.session.commit() for f in files: utils.upload_file(file=f, chalid=chal.id) db.session.commit() db.session.close() return redirect(url_for('admin_challenges.admin_chals')) else: return render_template('admin/chals/create.html')
def random_date(start, end): return start + datetime.timedelta( seconds=random.randint(0, int((end - start).total_seconds()))) if __name__ == '__main__': with app.app_context(): db = app.db # Generating Challenges print("GENERATING CHALLENGES") for x in range(CHAL_AMOUNT): word = gen_word() db.session.add(Challenges(word, gen_sentence(), gen_value(), gen_category())) db.session.commit() db.session.add(Keys(x + 1, word, 'static')) db.session.commit() # Generating Files print("GENERATING FILES") AMT_CHALS_WITH_FILES = int(CHAL_AMOUNT * (3.0 / 4.0)) for x in range(AMT_CHALS_WITH_FILES): chal = random.randint(1, CHAL_AMOUNT) filename = gen_file() md5hash = hashlib.md5(filename.encode('utf-8')).hexdigest() db.session.add(Files(chal, md5hash + '/' + filename)) db.session.commit() # Generating Users print("GENERATING USERS")
return start + datetime.timedelta( seconds=random.randint(0, int((end - start).total_seconds()))) if __name__ == '__main__': with app.app_context(): db = app.db # Generating Challenges print("GENERATING CHALLENGES") for x in range(CHAL_AMOUNT): word = gen_word() db.session.add( Challenges(word, gen_sentence(), gen_value(), gen_category())) db.session.commit() db.session.add(Keys(x + 1, word, 0)) db.session.commit() # Generating Files print("GENERATING FILES") AMT_CHALS_WITH_FILES = int(CHAL_AMOUNT * (3.0 / 4.0)) for x in range(AMT_CHALS_WITH_FILES): chal = random.randint(1, CHAL_AMOUNT) filename = gen_file() md5hash = hashlib.md5(filename.encode('utf-8')).hexdigest() db.session.add(Files(chal, md5hash + '/' + filename)) db.session.commit() # Generating Users print("GENERATING USERS")
def import_challenges(in_file, dst_attachments, exit_on_error=True, move=False): from CTFd.models import db, Challenges, Keys, Tags, Files, Hints, Unlocks with open(in_file, 'r') as in_stream: chals = yaml.safe_load_all(in_stream) for chal in chals: # ensure all required fields are present before adding or updating a challenge try: validate_yaml(chal) except MissingFieldError as err: if exit_on_error: raise else: print "Skipping challenge: " + str(err) continue # if the challenge already exists, update it chal_db = Challenges.query.filter_by(name=chal['name']).first() if chal_db is not None: print "Updating {}".format(chal['name'].encode('utf8')) chal_db.description = chal['description'] chal_db.value = chal['value'] chal_db.category = chal['category'] else: print "Adding {}".format(chal['name'].encode('utf8')) chal_db = Challenges( chal['name'], chal['description'], chal['value'], chal['category']) chal_db.type = chal['type'] chal_db.hidden = chal['hidden'] db.session.add(chal_db) db.session.commit() # delete all tags and re-add them Tags.query.filter_by(chal=chal_db.id).delete() for tag in chal['tags']: tag_dbobj = Tags(chal_db.id, tag) db.session.add(tag_dbobj) # delete all flags and re-add them Keys.query.filter_by(chal=chal_db.id).delete() for flag in chal['flags']: flag_db = Keys(chal_db.id, flag['flag'], flag['type']) db.session.add(flag_db) # delete or update existing hints hints = {h['id']: h for h in chal['hints']} hints_db = Hints.query.filter_by(chal=chal_db.id).all() for hint_db in hints_db: if hint_db.type in hints: # the hint is being updated hint_db.hint = hints[hint_db.type]['hint'] hint_db.cost = hints[hint_db.type]['cost'] del hints[hint_db.type] else: # the hint is being deleted - delete the hint and any related unlocks print " Removing hint {:d}".format(hint_db.type) Unlocks.query.filter_by(model='hints', itemid=hint_db.id).delete() Hints.query.filter_by(id=hint_db.id).delete() # add new hints for hint in hints.values(): print " Adding hint {:d}".format(hint['id']) hint_db = Hints(chal_db.id, hint['hint'], cost=hint['cost'], type=hint['id']) db.session.add(hint_db) # hash and compare existing files with the new uploaded files hashes_db = {} files_db = Files.query.filter_by(chal=chal_db.id).all() for file_db in files_db: with open(os.path.join(dst_attachments, file_db.location), 'rb') as f: h = hashlib.md5(f.read()).digest() hashes_db[h] = file_db to_upload = [] for file in chal['files']: path = os.path.join(os.path.dirname(in_file), file) with open(path, "rb") as f: h = hashlib.md5(f.read()).digest() if h in hashes_db and os.path.basename(file) == os.path.basename(hashes_db[h].location): # the file is up to date del hashes_db[h] else: # the file has changed name or content to_upload.append(path) # remove out of date files and add new uploads for file_db in hashes_db.values(): print " Removing file {}".format(file_db.location) utils.delete_file(file_db.id) for path in to_upload: basename = os.path.basename(path) print " Adding file {}".format(basename) with open(path, "rb") as f: f = FileStorage(stream=f, filename=basename) utils.upload_file(file=f, chalid=chal_db.id) if move: os.unlink(path) db.session.commit() db.session.commit() db.session.close()
return start + datetime.timedelta( seconds=random.randint(0, int((end - start).total_seconds()))) if __name__ == '__main__': with app.app_context(): db = app.db # Generating Challenges print("GENERATING CHALLENGES") for x in range(1, len(challenge) + 1): db.session.add( Challenges(get_name(x), get_desc(x), get_value(x), get_category(x), get_hint(x))) db.session.commit() db.session.add(Keys(x, get_flag(x), 0)) db.session.commit() db.session.close() # Generating Users print("GENERATING USERS") used = [] count = 0 while count < USER_AMOUNT: name = gen_name() if name not in used: used.append(name) team = Teams(None, None, None, None, None, name, name.lower() + gen_email(), 'password', 's') team.verified = True db.session.add(team) count += 1
def import_challenges(in_file, dst_attachments, exit_on_error=True, move=False): from CTFd.models import db, Challenges, Keys, Tags, Files chals = [] with open(in_file, 'r') as in_stream: chals = yaml.safe_load_all(in_stream) for chal in chals: skip = False for req_field in REQ_FIELDS: if req_field not in chal: if exit_on_error: raise MissingFieldError(req_field) else: print "Skipping challenge: Missing field '{}'".format(req_field) skip = True break if skip: continue for flag in chal['flags']: if 'flag' not in flag: if exit_on_error: raise MissingFieldError('flag') else: print "Skipping flag: Missing field 'flag'" continue flag['flag'] = flag['flag'].strip() if 'type' not in flag: flag['type'] = "static" # We ignore traling and leading whitespace when importing challenges chal_dbobj = Challenges( chal['name'].strip(), chal['description'].strip(), chal['value'], chal['category'].strip() ) if 'hidden' in chal and chal['hidden']: chal_dbobj.hidden = True matching_chals = Challenges.query.filter_by( name=chal_dbobj.name, description=chal_dbobj.description, value=chal_dbobj.value, category=chal_dbobj.category, hidden=chal_dbobj.hidden ).all() for match in matching_chals: if 'tags' in chal: tags_db = [tag.tag for tag in Tags.query.add_columns('tag').filter_by(chal=match.id).all()] if all([tag not in tags_db for tag in chal['tags']]): continue if 'files' in chal: files_db = [f.location for f in Files.query.add_columns('location').filter_by(chal=match.id).all()] if len(files_db) != len(chal['files']): continue hashes = [] for file_db in files_db: with open(os.path.join(dst_attachments, file_db), 'r') as f: hash = hashlib.md5(f.read()).digest() hashes.append(hash) mismatch = False for file in chal['files']: filepath = os.path.join(os.path.dirname(in_file), file) with open(filepath, 'r') as f: hash = hashlib.md5(f.read()).digest() if hash in hashes: hashes.remove(hash) else: mismatch = True break if mismatch: continue flags_db = Keys.query.filter_by(chal=match.id).all() for flag in chal['flags']: for flag_db in flags_db: if flag['flag'] != flag_db.flag: continue if flag['type'] != flag_db.key_type: continue skip = True break if skip: print "Skipping {}: Duplicate challenge found in DB".format(chal['name'].encode('utf8')) continue print "Adding {}".format(chal['name'].encode('utf8')) db.session.add(chal_dbobj) db.session.commit() if 'tags' in chal: for tag in chal['tags']: tag_dbobj = Tags(chal_dbobj.id, tag) db.session.add(tag_dbobj) for flag in chal['flags']: flag_db = Keys(chal_dbobj.id, flag['flag'], flag['type']) db.session.add(flag_db) if 'files' in chal: for file in chal['files']: filename = os.path.basename(file) dst_filename = secure_filename(filename) dst_dir = None while not dst_dir or os.path.exists(dst_dir): md5hash = hashlib.md5(os.urandom(64)).hexdigest() dst_dir = os.path.join(dst_attachments, md5hash) os.makedirs(dst_dir) dstpath = os.path.join(dst_dir, dst_filename) srcpath = os.path.join(os.path.dirname(in_file), file) if move: shutil.move(srcpath, dstpath) else: shutil.copy(srcpath, dstpath) file_dbobj = Files(chal_dbobj.id, os.path.relpath(dstpath, start=dst_attachments)) db.session.add(file_dbobj) db.session.commit() db.session.close()
__name__ = 'CTFd' app = create_app() with app.app_context(): db = app.db data = json.load(open(filename)) # Clean before update db.session.query(Challenges).delete() for challenge in data["challenges"]: name = challenge["name"] message = challenge["message"] value = challenge["value"] category = challenge["category"] keys = challenge["key"] files = challenge["files"] challenge_obj = Challenges(name, message, value, category) db.session.add(challenge_obj) db.session.commit() for key in keys: key_obj = Keys(challenge_obj.id, key["flag"], key["type"]) db.session.add(key_obj) for path in files: db.session.add(Files(challenge_obj.id, path)) db.session.commit()
def create(request): """ This method is used to process the challenge creation request. :param request: :return: """ files = request.files.getlist('files[]') # Liste de tuples de 3 éléments : # - solution (le flag à trouver) # - type ("static" ou "regex") # - data (JSON string) keys = [] index_key = 0 while ('key_solution[%s]' % index_key) in request.form: key_solution = request.form['key_solution[%s]' % index_key] if key_solution: key_type = request.form.get('key_type[%s]' % index_key, '') if key_type not in ('static', 'regex'): key_type = 'static' award = request.form.get('award_interm[%s]' % index_key, 0) try: award = int(award) except ValueError: award = 0 congrat_msg = request.form.get('congrat_msg[%s]' % index_key, '') congrat_img_url = request.form.get( 'congrat_img_url[%s]' % index_key, '') doc_filename = request.form.get('doc_filename[%s]' % index_key, '') is_public = request.form.get('public[%s]' % index_key, '') == 'yes' cancel_score = request.form.get('cancel_score[%s]' % index_key, '') == 'yes' key_data = { 'congrat_msg': congrat_msg, 'congrat_img_url': congrat_img_url, 'doc_filename': doc_filename, 'award': award, 'public': is_public, 'cancel_score': cancel_score, } key_data = json.dumps(key_data) key_infos = (key_solution, key_type, key_data) keys.append(key_infos) index_key += 1 # Create challenge chal = IntermediateFlagChallengeModel( name=request.form['name'], description=request.form['description'], value=request.form['value'], category=request.form['category'], type=request.form['chaltype']) chal.hidden = 'hidden' in request.form max_attempts = request.form.get('max_attempts') if max_attempts and max_attempts.isdigit(): chal.max_attempts = int(max_attempts) db.session.add(chal) db.session.commit() for key_solution, key_type, key_data in keys: record_key = Keys(chal.id, key_solution, key_type) record_key.data = key_data db.session.add(record_key) db.session.commit() for f in files: utils.upload_file(file=f, chalid=chal.id) db.session.commit() db.session.close()