def admin_create_chal(): files = request.files.getlist('files[]') ## TODO: Expand to support multiple flags flags = [{'flag':request.form['key'], 'type':int(request.form['key_type[0]'])}] # Create challenge chal = Challenges(request.form['name'], request.form['desc'], request.form['value'], request.form['category'], flags) db.session.add(chal) db.session.commit() for f in files: filename = secure_filename(f.filename) if len(filename) <= 0: continue md5hash = hashlib.md5(os.urandom(64)).hexdigest() if not os.path.exists(os.path.join(os.path.normpath(app.static_folder), 'uploads', md5hash)): os.makedirs(os.path.join(os.path.normpath(app.static_folder), 'uploads', md5hash)) f.save(os.path.join(os.path.normpath(app.static_folder), 'uploads', md5hash, filename)) db_f = Files(chal.id, os.path.join('static', 'uploads', md5hash, filename)) db.session.add(db_f) db.session.commit() db.session.close() return redirect('/admin/chals')
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 gen_file(db, location, challenge_id=None, page_id=None): if challenge_id: f = ChallengeFiles(challenge_id=challenge_id, location=location) elif page_id: f = PageFiles(page_id=page_id, location=location) else: f = Files(location=location) db.session.add(f) db.session.commit() return f
def update_generated_files(chalid, files): """ Adds any filenames given by the files list to the DB as generated files. The chalid of these new files will the the inputted chalid """ files_db_objs = Files.query.add_columns('location').filter_by(chal=chalid).all() files_db = [f.location for f in files_db_objs] for file in files: if file not in files_db: db.session.add(Files(chalid, file, True)) db.session.commit()
def admin_files(chalid): if request.method == 'GET': files = Files.query.filter_by(chal=chalid).all() json = {'files': []} for x in files: json['files'].append({'id': x.id, 'file': x.location}) return jsonify(json) if request.method == 'POST': if request.form['method'] == "delete": f = Files.query.filter_by( id=request.form['file']).first_or_404() if os.path.isfile(f.location): os.unlink(f.location) db.session.delete(f) db.session.commit() db.session.close() return "1" elif request.form['method'] == "upload": files = request.files.getlist('files[]') for f in files: filename = secure_filename(f.filename) if len(filename) <= 0: continue md5hash = hashlib.md5(os.urandom(64)).hexdigest() # BUG NEEDS TO GO TO S3 base = os.path.dirname(os.path.dirname(__file__)) ## mod_wsgi does some sad things with cwd so the upload directory needs to be shifted a bit if not os.path.exists( os.path.join(base, app.config['UPLOAD_FOLDER'], md5hash)): os.makedirs( os.path.join(base, app.config['UPLOAD_FOLDER'], md5hash)) f.save( os.path.join(base, app.config['UPLOAD_FOLDER'], md5hash, filename)) ## This needs to be relative to CTFd so doesn't nee base. db_f = Files( chalid, os.path.join(app.config['UPLOAD_FOLDER'], md5hash, filename)) db.session.add(db_f) db.session.commit() db.session.close() return redirect('/admin/chals')
def admin_files(chalid): if request.method == 'GET': files = Files.query.filter_by(chal=chalid).all() json_data = {'files': []} for x in files: json_data['files'].append({'id': x.id, 'file': x.location}) return jsonify(json_data) if request.method == 'POST': if request.form['method'] == "delete": f = Files.query.filter_by(id=request.form['file']).first_or_404() if os.path.exists( os.path.join(app.static_folder, 'uploads', f.location) ): ## Some kind of os.path.isfile issue on Windows... os.unlink( os.path.join(app.static_folder, 'uploads', f.location)) db.session.delete(f) db.session.commit() db.session.close() return "1" elif request.form['method'] == "upload": files = request.files.getlist('files[]') for f in files: filename = secure_filename(f.filename) if len(filename) <= 0: continue md5hash = hashlib.md5(os.urandom(64)).hexdigest() if not os.path.exists( os.path.join(os.path.normpath(app.static_folder), 'uploads', md5hash)): os.makedirs( os.path.join(os.path.normpath(app.static_folder), 'uploads', md5hash)) f.save( os.path.join(os.path.normpath(app.static_folder), 'uploads', md5hash, filename)) db_f = Files( chalid, os.path.join('static', 'uploads', md5hash, filename)) db.session.add(db_f) db.session.commit() db.session.close() return redirect(url_for('admin.admin_chals'))
def upload_file(file, chalid): s3, bucket = get_s3_conn(app) filename = ''.join(list(filter(clean_filename, secure_filename(file.filename).replace(' ', '_')))) if len(filename) <= 0: return False md5hash = hashlib.md5(os.urandom(64)).hexdigest() key = md5hash + '/' + filename s3.upload_fileobj(file, bucket, key) db_f = Files(chalid, key) db.session.add(db_f) db.session.commit() return db_f.id, (md5hash + '/' + filename)
def admin_files(chalid): if request.method == 'GET': files = Files.query.filter_by(chal=chalid).all() json = {'files': []} for x in files: json['files'].append({'id': x.id, 'file': x.location}) return jsonify(json) if request.method == 'POST': if request.form['method'] == "delete": f = Files.query.filter_by( id=request.form['file']).first_or_404() if os.path.isfile(f.location): os.unlink(f.location) db.session.delete(f) db.session.commit() db.session.close() return "1" elif request.form['method'] == "upload": files = request.files.getlist('files[]') for f in files: filename = secure_filename(f.filename) if len(filename) <= 0: continue md5hash = hashlib.md5(os.urandom(64)).hexdigest() # BUG NEEDS TO GO TO S3 if not os.path.exists( os.path.join(app.config['UPLOAD_FOLDER'], md5hash)): os.makedirs( os.path.join(app.config['UPLOAD_FOLDER'], md5hash)) f.save( os.path.join(app.config['UPLOAD_FOLDER'], md5hash, filename)) db_f = Files( chalid, os.path.join(app.config['UPLOAD_FOLDER'], md5hash, filename)) db.session.add(db_f) db.session.commit() db.session.close() return redirect('/admin/chals')
def upload_file(file, chalid): filename = secure_filename(file.filename) if len(filename) <= 0: return False md5hash = hashlib.md5(os.urandom(64)).hexdigest() upload_folder = os.path.join(os.path.normpath(app.root_path), app.config['UPLOAD_FOLDER']) if not os.path.exists(os.path.join(upload_folder, md5hash)): os.makedirs(os.path.join(upload_folder, md5hash)) file.save(os.path.join(upload_folder, md5hash, filename)) db_f = Files(chalid, (md5hash + '/' + filename)) db.session.add(db_f) db.session.commit() return db_f.id, (md5hash + '/' + filename)
def admin_create_chal(): files = request.files.getlist('files[]') ## TODO: Expand to support multiple flags flags = [{ 'flag': request.form['key'], 'type': int(request.form['key_type[0]']) }] # Create challenge chal = Challenges(request.form['name'], request.form['desc'], request.form['value'], request.form['category'], flags, request.form['row_order']) if 'hidden' in request.form: chal.hidden = True else: chal.hidden = False db.session.add(chal) db.session.commit() for f in files: filename = secure_filename(f.filename) if len(filename) <= 0: continue md5hash = hashlib.md5(os.urandom(64)).hexdigest() if not os.path.exists( os.path.join(os.path.normpath(app.root_path), 'uploads', md5hash)): os.makedirs( os.path.join(os.path.normpath(app.root_path), 'uploads', md5hash)) f.save( os.path.join(os.path.normpath(app.root_path), 'uploads', md5hash, filename)) db_f = Files(chal.id, (md5hash + '/' + filename)) db.session.add(db_f) db.session.commit() db.session.close() return redirect(url_for('admin.admin_chals'))
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") used = [] count = 0 while count < USER_AMOUNT: name = gen_name() if name not in used: used.append(name) team = Teams(name, name.lower() + gen_email(), 'password') 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()
db.session.add( Challenges(word, gen_sentence(), gen_value(), gen_category(), flags)) 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).hexdigest() db.session.add( Files(chal, os.path.join('static/uploads', md5hash, filename))) db.session.commit() ### Generating Users print "GENERATING USERS" used = [] count = 0 while count < USER_AMOUNT: name = gen_name() if name not in used: used.append(name) db.session.add( Teams(name, name.lower() + gen_email(), 'password')) count += 1 db.session.commit()
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).hexdigest() db.session.add( Files(chal, os.path.join('static/uploads', md5hash, filename)) ) db.session.commit() ### Generating Users print "GENERATING USERS" used = [] while len(used) < USER_AMOUNT: name = gen_name() if name not in used: used.append(name) db.session.add( Teams(name , name.lower() + gen_email(), 'password') ) db.session.commit() ### Generating Solves print "GENERATING SOLVES" base_time = datetime.datetime.utcnow() + datetime.timedelta(minutes=-2880)