def challenges_view(): infos = [] errors = [] start = utils.get_config('start') or 0 end = utils.get_config('end') or 0 if utils.ctf_paused(): infos.append('{} is paused'.format(utils.ctf_name())) if not utils.ctftime(): # It is not CTF time if utils.view_after_ctf( ): # But we are allowed to view after the CTF ends pass else: # We are NOT allowed to view after the CTF ends if utils.get_config('start') and not utils.ctf_started(): errors.append('{} has not started yet'.format( utils.ctf_name())) if (utils.get_config('end') and utils.ctf_ended()) and not utils.view_after_ctf(): errors.append('{} has ended'.format(utils.ctf_name())) return render_template('challenges.html', infos=infos, errors=errors, start=int(start), end=int(end)) return render_template('challenges.html', infos=infos, errors=errors, start=int(start), end=int(end))
def challenges_view(): infos = [] errors = [] start = utils.get_config('start') or 0 end = utils.get_config('end') or 0 if utils.ctf_paused(): infos.append('{} is paused'.format(utils.ctf_name())) if not utils.is_admin(): # User is not an admin if not utils.ctftime(): # It is not CTF time if utils.view_after_ctf(): # But we are allowed to view after the CTF ends pass else: # We are NOT allowed to view after the CTF ends if utils.get_config('start') and not utils.ctf_started(): errors.append('{} has not started yet'.format(utils.ctf_name())) if (utils.get_config('end') and utils.ctf_ended()) and not utils.view_after_ctf(): errors.append('{} has ended'.format(utils.ctf_name())) return render_template('challenges.html', infos=infos, errors=errors, start=int(start), end=int(end)) if utils.get_config('verify_emails'): if utils.authed(): if utils.is_admin() is False and utils.is_verified() is False: # User is not confirmed return redirect(url_for('auth.confirm_user')) if utils.user_can_view_challenges(): # Do we allow unauthenticated users? if utils.get_config('start') and not utils.ctf_started(): errors.append('{} has not started yet'.format(utils.ctf_name())) if (utils.get_config('end') and utils.ctf_ended()) and not utils.view_after_ctf(): errors.append('{} has ended'.format(utils.ctf_name())) return render_template('challenges.html', infos=infos, errors=errors, start=int(start), end=int(end)) else: return redirect(url_for('auth.login', next='challenges'))
def team(teamid): if utils.get_config('workshop_mode'): abort(404) if utils.get_config('view_scoreboard_if_utils.authed') and not utils.authed(): return redirect(url_for('auth.login', next=request.path)) infos = [] errors = [] if utils.ctf_paused(): infos.append('{} is paused'.format(utils.ctf_name())) if not utils.ctftime(): # It is not CTF time if utils.view_after_ctf(): # But we are allowed to view after the CTF ends pass else: # We are NOT allowed to view after the CTF ends if utils.get_config('start') and not utils.ctf_started(): errors.append('{} has not started yet'.format(utils.ctf_name())) if (utils.get_config('end') and utils.ctf_ended()) and not utils.view_after_ctf(): errors.append('{} has ended'.format(utils.ctf_name())) freeze = utils.get_config('freeze') user = Teams.query.filter_by(id=teamid).first_or_404() solves = Solves.query.filter_by(teamid=teamid) awards = Awards.query.filter_by(teamid=teamid) place = user.place() score = user.score() if freeze: freeze = utils.unix_time_to_utc(freeze) if teamid != session.get('id'): solves = solves.filter(Solves.date < freeze) awards = awards.filter(Awards.date < freeze) solves = solves.all() awards = awards.all() db.session.close() if utils.hide_scores() and teamid != session.get('id'): errors.append('Scores are currently hidden') else: # banned is a synonym for hidden :/ if not utils.is_admin() and (user.admin or user.banned): errors.append('Scores are currently hidden') if errors: return render_template('team.html', team=user, infos=infos, errors=errors) if request.method == 'GET': return render_template('team.html', solves=solves, awards=awards, team=user, score=score, place=place, score_frozen=utils.is_scoreboard_frozen(), infos=infos) elif request.method == 'POST': json = {'solves': []} for x in solves: json['solves'].append({'id': x.id, 'chal': x.chalid, 'team': x.teamid}) return jsonify(json)
def chals(): if not utils.is_admin(): if not utils.ctftime(): if utils.view_after_ctf(): pass elif utils.ctf_paused(): abort(make_response('{} paused'.format(utils.ctf_name()), 503)) else: abort( make_response( 'These are not the challenges you are looking for', 403)) if utils.get_config('verify_emails'): if utils.authed(): if utils.is_admin() is False and utils.is_verified( ) is False: # User is not confirmed abort(403) if utils.user_can_view_challenges() and (utils.ctf_started() or utils.is_admin()): teamid = session.get('id') chals = Challenges.query.filter( or_(Challenges.hidden != True, Challenges.hidden == None)).order_by(Challenges.value).all() json = {'game': []} for x in chals: tags = [ tag.tag for tag in Tags.query.add_columns('tag').filter_by( chal=x.id).all() ] files = [ str(f.location) for f in Files.query.filter_by(chal=x.id).all() ] unlocked_hints = set([ u.itemid for u in Unlocks.query.filter_by(model='hints', teamid=teamid) ]) hints = [] for hint in Hints.query.filter_by(chal=x.id).all(): if hint.id in unlocked_hints or utils.ctf_ended(): hints.append({ 'id': hint.id, 'cost': hint.cost, 'hint': hint.hint }) else: hints.append({'id': hint.id, 'cost': hint.cost}) chal_type = get_chal_class(x.type) json['game'].append({ 'id': x.id, 'type': chal_type.name, 'name': x.name, 'value': x.value, 'description': x.description, 'category': x.category, 'files': files, 'tags': tags, 'hints': hints, 'template': chal_type.templates['modal'], 'script': chal_type.scripts['modal'], }) db.session.close() return jsonify(json) else: db.session.close() abort(403)
def chal(chalid): if utils.ctf_paused(): return jsonify({ 'status': 3, 'message': '{} is paused'.format(utils.ctf_name()) }) if (utils.authed() and utils.is_verified() and (utils.ctf_started() or utils.view_after_ctf())) or utils.is_admin(): team = Teams.query.filter_by(id=session['id']).first() fails = WrongKeys.query.filter_by(teamid=session['id'], chalid=chalid).count() logger = logging.getLogger('keys') data = (time.strftime("%m/%d/%Y %X"), session['username'].encode('utf-8'), request.form['key'].encode('utf-8'), utils.get_kpm(session['id'])) print("[{0}] {1} submitted {2} with kpm {3}".format(*data)) chal = Challenges.query.filter_by(id=chalid).first_or_404() if chal.hidden: abort(404) chal_class = get_chal_class(chal.type) # Anti-bruteforce / submitting keys too quickly if utils.get_kpm(session['id']) > 10: if utils.ctftime(): chal_class.fail(team=team, chal=chal, request=request) logger.warn( "[{0}] {1} submitted {2} with kpm {3} [TOO FAST]".format( *data)) # return '3' # Submitting too fast return jsonify({ 'status': 3, 'message': "You're submitting keys too fast. Slow down." }) solves = Solves.query.filter_by(teamid=session['id'], chalid=chalid).first() # Challange not solved yet if not solves: provided_key = request.form['key'].strip() saved_keys = Keys.query.filter_by(chal=chal.id).all() # Hit max attempts max_tries = chal.max_attempts if max_tries and fails >= max_tries > 0: return jsonify({ 'status': 0, 'message': "You have 0 tries remaining" }) status, message = chal_class.attempt(chal, request) if status: # The challenge plugin says the input is right if utils.ctftime() or utils.is_admin(): chal_class.solve(team=team, chal=chal, request=request) logger.info( "[{0}] {1} submitted {2} with kpm {3} [CORRECT]".format( *data)) return jsonify({'status': 1, 'message': message}) else: # The challenge plugin says the input is wrong if utils.ctftime() or utils.is_admin(): chal_class.fail(team=team, chal=chal, request=request) logger.info( "[{0}] {1} submitted {2} with kpm {3} [WRONG]".format( *data)) # return '0' # key was wrong if max_tries: attempts_left = max_tries - fails - 1 # Off by one since fails has changed since it was gotten tries_str = 'tries' if attempts_left == 1: tries_str = 'try' if message[ -1] not in '!().;?[]\{\}': # Add a punctuation mark if there isn't one message = message + '.' return jsonify({ 'status': 0, 'message': '{} You have {} {} remaining.'.format( message, attempts_left, tries_str) }) else: return jsonify({'status': 0, 'message': message}) # Challenge already solved else: logger.info( "{0} submitted {1} with kpm {2} [ALREADY SOLVED]".format( *data)) # return '2' # challenge was already solved return jsonify({'status': 2, 'message': 'You already solved this'}) else: return jsonify({ 'status': -1, 'message': "You must be logged in to solve a challenge" })
def challenges_view(compid): infos = [] errors = [] start = utils.get_config('start') or 0 end = utils.get_config('end') or 0 comp = Competitions.query.filter(Competitions.id == compid).first() if utils.ctf_paused(): infos.append('{} is paused'.format(utils.ctf_name())) if not utils.is_admin(): # User is not an admin if not utils.ctftime(): # It is not CTF time if utils.view_after_ctf( ): # But we are allowed to view after the CTF ends pass else: # We are NOT allowed to view after the CTF ends if utils.get_config('start') and not utils.ctf_started(): errors.append('{} has not started yet'.format( utils.ctf_name())) if (utils.get_config('end') and utils.ctf_ended()) and not utils.view_after_ctf(): errors.append('{} has ended'.format(utils.ctf_name())) if comp is None: errors.append('no such competition') start = False if comp.startTime > datetime.datetime.utcnow(): errors = append('{} 尚未开始,敬请期待'.format(comp.title)) start = False return render_template('comp_challenges.html', infos=infos, errors=errors, start=int(start), end=int(end), comp=comp) if utils.get_config('verify_emails'): if utils.authed(): if utils.is_admin() is False and utils.is_verified( ) is False: # User is not confirmed return redirect(url_for('auth.confirm_user')) if utils.user_can_view_challenges(): # Do we allow unauthenticated users? if utils.get_config('start') and not utils.ctf_started(): errors.append('{} has not started yet'.format(utils.ctf_name())) if (utils.get_config('end') and utils.ctf_ended()) and not utils.view_after_ctf(): errors.append('{} has ended'.format(utils.ctf_name())) if comp is None: errors.append('no such competition') start = False if comp.startTime > datetime.datetime.utcnow(): errors.append('{} 尚未开始,敬请期待'.format(comp.title)) start = False return render_template('comp_challenges.html', infos=infos, errors=errors, start=int(start), end=int(end), comp=comp) else: return redirect(url_for('auth.login', next=request.path))
def anonchal(): if utils.ctf_paused(): return jsonify({ 'status': 3, 'message': '{} is paused'.format(utils.ctf_name()) }) if utils.is_admin() or (utils.authed() and utils.is_verified() and (utils.ctf_started() or utils.view_after_ctf())): team = Teams.query.filter_by(id=session['id']).first() provided_key = request.form['key'].strip() logger = logging.getLogger('keys') data = (time.strftime("%m/%d/%Y %X"), session['username'].encode('utf-8'), provided_key.encode('utf-8'), utils.get_kpm(session['id'])) # Anti-bruteforce / KPM is based on last failed key (not logged), so sleep instead. time.sleep(2) # Find challenge by looking up the provided flag key = db.session.query(Keys).\ join(AnonymousChallenge).\ filter(Keys.flag == provided_key).first() if not key: logger.info( "[{0}] {1} submitted {2} with kpm {3} [WRONG]".format( *data)) return jsonify({'status': 0, 'message': 'Invalid Flag'}) chal = AnonymousChallenge.query.filter_by(id=key.chal).first() chal_class = get_chal_class(chal.type) solves = Solves.query.filter_by(teamid=session['id'], chalid=chal.id).first() # If team hasn't solved challenge yet, save the solve if not solves: # We already know the flag is correct because we checked it already chal_class.solve(team=team, chal=chal, request=request) logger.info( "[{0}] {1} submitted {2} with kpm {3} [CORRECT]".format( *data)) return jsonify({'status': 1, 'message': "Correct"}) # Otherwise, raise an error else: logger.info( "{0} submitted {1} with kpm {2} [ALREADY SOLVED]".format( *data)) return jsonify({ 'status': 2, 'message': 'You already solved this' }) else: return jsonify({ 'status': -1, 'message': "You must be logged in to solve a challenge" })