def challenges_view(): errors = [] start = get_config('start') or 0 end = get_config('end') or 0 if not is_admin(): # User is not an admin if not ctftime(): # It is not CTF time if 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 get_config('start') and not ctf_started(): errors.append('{} has not started yet'.format(ctf_name())) if (get_config('end') and ctf_ended()) and not view_after_ctf(): errors.append('{} has ended'.format(ctf_name())) return render_template('chals.html', errors=errors, start=int(start), end=int(end)) if get_config('verify_emails' ) and not is_verified(): # User is not confirmed return redirect(url_for('auth.confirm_user')) if user_can_view_challenges(): # Do we allow unauthenticated users? if get_config('start') and not ctf_started(): errors.append('{} has not started yet'.format(ctf_name())) if (get_config('end') and ctf_ended()) and not view_after_ctf(): errors.append('{} has ended'.format(ctf_name())) return render_template('chals.html', errors=errors, start=int(start), end=int(end)) else: return redirect(url_for('auth.login', next='challenges'))
def challenges_view(): errors = [] start = utils.get_config('start') or 0 end = utils.get_config('end') or 0 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('chals.html', errors=errors, start=int(start), end=int(end)) if utils.get_config('verify_emails') and not utils.is_verified(): # 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('chals.html', errors=errors, start=int(start), end=int(end)) else: return redirect(url_for('auth.login', next='challenges'))
def hints_view(hintid): if utils.ctf_started() is False: if utils.is_admin() is False: abort(403) hint = Hints.query.filter_by(id=hintid).first_or_404() chal = Challenges.query.filter_by(id=hint.chal).first() unlock = Unlocks.query.filter_by(model='hints', itemid=hintid, teamid=session['id']).first() if request.method == 'GET': if unlock: return jsonify({ 'hint': hint.hint, 'chal': hint.chal, 'cost': hint.cost }) else: return jsonify({'chal': hint.chal, 'cost': hint.cost}) elif request.method == 'POST': if unlock is None: # The user does not have an unlock. if utils.ctftime() or ( utils.ctf_ended() and utils.view_after_ctf()) or utils.is_admin() is True: # It's ctftime or the CTF has ended (but we allow views after) team = Teams.query.filter_by(id=session['id']).first() if team.score() < hint.cost: return jsonify({'errors': get_tip('NOT_ENOUGH_POINT')}) unlock = Unlocks(model='hints', teamid=session['id'], itemid=hint.id) award = Awards(teamid=session['id'], name=text_type( get_tip('HIT_FOR').format(chal.name)), value=(-hint.cost)) db.session.add(unlock) db.session.add(award) db.session.commit() json_data = { 'hint': hint.hint, 'chal': hint.chal, 'cost': hint.cost } db.session.close() return jsonify(json_data) elif utils.ctf_ended(): # The CTF has ended. No views after. abort(403) else: # The user does have an unlock, we should give them their hint. json_data = { 'hint': hint.hint, 'chal': hint.chal, 'cost': hint.cost } db.session.close() return jsonify(json_data)
def chal_view(chal_id): teamid = session.get('id') chal = Challenges.query.filter_by(id=chal_id).first_or_404() if chal.hidden: abort(404) chal_class = get_chal_class(chal.type) tags = [ tag.tag for tag in Tags.query.add_columns('tag').filter_by(chal=chal.id).all() ] files = [ str(f.location) for f in Files.query.filter_by(chal=chal.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=chal.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}) challenge, response = chal_class.read(challenge=chal) response['files'] = files response['tags'] = tags response['hints'] = hints db.session.close() return jsonify(response)
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 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_contest(contestid): contest = Contests.query.filter_by(id=contestid).first() if not utils.is_admin(): if not utils.ctftime(contest=contest): if utils.view_after_ctf(contest=contest): pass else: return redirect(url_for('views.static_html')) if utils.user_can_view_challenges(contest=contest) and ( utils.ctf_started(contest=contest) or utils.is_admin()): chals = Challenges.query.filter( and_(or_(Challenges.hidden != True, Challenges.hidden == None), Challenges.contestid == contestid)).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=session['id']) ]) 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}) # hints = [{'id':hint.id, 'cost':hint.cost} for hint in Hints.query.filter_by(chal=x.id).all()] 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 }) db.session.close() return jsonify(json) else: db.session.close() return redirect(url_for('auth.login', next='chals'))
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(get_tip('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( get_tip('NOT_START').format(utils.ctf_name())) if (utils.get_config('end') and utils.ctf_ended()) and not utils.view_after_ctf(): errors.append(get_tip('HAS_END').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(get_tip('NOT_START').format(utils.ctf_name())) if (utils.get_config('end') and utils.ctf_ended()) and not utils.view_after_ctf(): errors.append(get_tip('HAS_END').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 chal_view_linearunlocked(chal_id): teamid = session.get('id') chal = Challenges.query.filter_by(id=chal_id).first_or_404() chal_class = get_chal_class(chal.type) # Get solved challenge ids solves = [] if utils.is_admin(): solves = Solves.query.filter_by(teamid=session['id']).all() elif utils.user_can_view_challenges(): if utils.authed(): solves = Solves.query\ .join(Teams, Solves.teamid == Teams.id)\ .filter(Solves.teamid == session['id'])\ .all() solve_ids = [] for solve in solves: solve_ids.append(solve.chalid) # Return nothing if there is at least one linear unlocking requirement not solved lu_entries = LinearUnlockingEntry.query.filter_by(chalid=chal.id).all() for lu_entry in lu_entries: if lu_entry.requires_chalid > -1 and lu_entry.requires_chalid not in solve_ids: return jsonify([]) tags = [ tag.tag for tag in Tags.query.add_columns('tag').filter_by( chal=chal.id).all() ] files = [ str(f.location) for f in Files.query.filter_by(chal=chal.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=chal.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}) challenge, response = chal_class.read(challenge=chal) response['files'] = files response['tags'] = tags response['hints'] = hints db.session.close() return jsonify(response)
def chals(): if not utils.is_admin(): if not utils.ctftime(): if utils.view_after_ctf(): pass else: 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 test_ctf_ended(): '''Tests that the ctf_ended function returns the correct value''' app = create_ctfd() with app.app_context(): assert ctf_ended() == False set_config('start', '1507089600') # Wednesday, October 4, 2017 12:00:00 AM GMT-04:00 DST set_config('end', '1507262400') # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST with freeze_time("2017-10-3"): assert ctf_ended() == False with freeze_time("2017-10-5"): assert ctf_ended() == False with freeze_time("2017-10-7"): assert ctf_ended() == True destroy_ctfd(app)
def challenges_view_contest(contest_slug): contest = Contests.query.filter_by(slug=contest_slug).first() errors = [] start = contest.starttime or 0 end = contest.endtime or 0 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.ctf_started(contest=contest): errors.append('{} has not started yet'.format( contest.name)) if utils.ctf_ended( contest=contest) and not utils.view_after_ctf(): errors.append('{} has ended'.format(contest.name)) return render_template('chals.html', errors=errors, start=start, end=end) if utils.get_config('verify_emails') and not utils.is_verified( ): # User is not confirmed return redirect(url_for('auth.confirm_user')) if utils.user_can_view_challenges( contest=contest): # Do we allow unauthenticated users? if not utils.ctf_started(contest=contest): errors.append('{} has not started yet'.format(contest.name)) if utils.ctf_ended( contest=contest) and not utils.view_after_ctf(contest=contest): errors.append('{} has ended'.format(contest.name)) contest = Contests.query.filter_by(slug=contest_slug).first() contest_dict = vars(contest) contest_dict.pop('_sa_instance_state', None) return render_template('chals.html', errors=errors, start=start, end=end, contest=contest_dict) else: return redirect( url_for("contests.contest_participate", contest_slug=contest_slug))
def hints_view_contest(contestid, hintid): contest = Contests.query.filter_by(id=contestid).first() if not utils.ctf_started(contest=contest): abort(403) hint = Hints.query.filter_by(id=hintid).first_or_404() chal = Challenges.query.filter_by(id=hint.chal).first() unlock = Unlocks.query.filter_by(model='hints', itemid=hintid, teamid=session['id']).first() if request.method == 'GET': if unlock: return jsonify({ 'hint': hint.hint, 'chal': hint.chal, 'cost': hint.cost }) else: return jsonify({'chal': hint.chal, 'cost': hint.cost}) elif request.method == 'POST': if not unlock and utils.ctftime(contest=contest): team = Teams.query.filter_by(id=session['id']).first() if team.score() < hint.cost: return jsonify({'errors': 'Not enough points'}) unlock = Unlocks(model='hints', teamid=session['id'], itemid=hint.id) award = Awards(teamid=session['id'], name='Hint for {}'.format(chal.name), value=(-hint.cost), contestid=contestid) db.session.add(unlock) db.session.add(award) db.session.commit() json_data = { 'hint': hint.hint, 'chal': hint.chal, 'cost': hint.cost } db.session.close() return jsonify(json_data) elif utils.ctf_ended(contest=contest): json_data = { 'hint': hint.hint, 'chal': hint.chal, 'cost': hint.cost } db.session.close() return jsonify(json_data) else: json_data = { 'hint': hint.hint, 'chal': hint.chal, 'cost': hint.cost } db.session.close() return jsonify(json_data)
def user_can_get_config(): if utils.is_admin(): return True if not (utils.authed() and utils.is_verified()): return False if not utils.user_can_view_challenges(): return False if not (utils.ctf_started() and (utils.ctf_ended() or utils.view_after_ctf())): return False return True
def hints_view(hintid): if not utils.ctf_started(): abort(403) hint = Hints.query.filter_by(id=hintid).first_or_404() chal = Challenges.query.filter_by(id=hint.chal).first() unlock = Unlocks.query.filter_by(model='hints', itemid=hintid, teamid=session['id']).first() if request.method == 'GET': if unlock: return jsonify({ 'hint': hint.hint, 'chal': hint.chal, 'cost': hint.cost }) else: return jsonify({ 'chal': hint.chal, 'cost': hint.cost }) elif request.method == 'POST': if not unlock and utils.ctftime(): team = Teams.query.filter_by(id=session['id']).first() if team.score() < hint.cost: return jsonify({'errors': 'Not enough points'}) unlock = Unlocks(model='hints', teamid=session['id'], itemid=hint.id) award = Awards(teamid=session['id'], name='Hint for {}'.format(chal.name), value=(-hint.cost)) db.session.add(unlock) db.session.add(award) db.session.commit() json_data = { 'hint': hint.hint, 'chal': hint.chal, 'cost': hint.cost } db.session.close() return jsonify(json_data) elif utils.ctf_ended(): json_data = { 'hint': hint.hint, 'chal': hint.chal, 'cost': hint.cost } db.session.close() return jsonify(json_data) else: json_data = { 'hint': hint.hint, 'chal': hint.chal, 'cost': hint.cost } db.session.close() return jsonify(json_data)
def during_ctf_time_only_wrapper(*args, **kwargs): if utils.ctftime() or utils.is_admin(): return f(*args, **kwargs) else: if utils.ctf_ended(): if utils.view_after_ctf(): return f(*args, **kwargs) else: error = '{} has ended'.format(utils.ctf_name()) abort(403, description=error) if utils.ctf_started() is False: error = '{} has not started yet'.format(utils.ctf_name()) abort(403, description=error)
def challenges_view(): errors = [] start = get_config('start') or 0 end = get_config('end') or 0 if not is_admin(): # User is not an admin if not ctftime(): # It is not CTF time if start > time.time( ): # We are NOT allowed to view after the CTF ends errors.append('{} challenges will be posted soon!'.format( ctf_name())) elif not view_after_ctf(): errors.append('{} has ended.'.format(ctf_name())) return render_template('chals.html', errors=errors, start=int(start), end=int(end)) if get_config('verify_emails' ) and not is_verified(): # User is not confirmed return redirect(url_for('auth.confirm_user')) if user_can_view_challenges(): # Do we allow unauthenticated users? if get_config('start') and not ctf_started(): errors.append('{} has not started yet'.format(ctf_name())) if (get_config('end') and ctf_ended()) and not view_after_ctf(): errors.append('{} has ended'.format(ctf_name())) if not is_on_team(): errors.append('You are not on a team!') return render_template('chals.html', errors=errors, start=int(start), end=int(end)) else: if not is_on_team(): errors.append( 'You must create or join a team before you can start playing') return render_template('chals.html', errors=errors, start=int(start), end=int(end)) return redirect(url_for('auth.login', next='challenges'))
def chals(): if not utils.is_admin(): if not utils.ctftime(): if utils.view_after_ctf(): pass else: return redirect(url_for('views.static_html')) if utils.user_can_view_challenges() and (utils.ctf_started() or utils.is_admin()): 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=session['id'])]) 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}) # hints = [{'id':hint.id, 'cost':hint.cost} for hint in Hints.query.filter_by(chal=x.id).all()] 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 }) db.session.close() return jsonify(json) else: db.session.close() return redirect(url_for('auth.login', next='chals'))
def chals(): if not utils.is_admin(): if not utils.ctftime(): if utils.view_after_ctf(): pass else: abort(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) if chal_type == CommunityChallenge: owner_id = CommunityChallengeModel.query.filter( CommunityChallengeModel.id == x.id).first().owner else: owner_id = 1 owner = Teams.query.filter(Teams.id == owner_id).first().name own = (owner_id == session['id']) chal_data = { '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, 'owner': owner, 'own': own, 'template': chal_type.templates['modal'], 'script': chal_type.scripts['modal'] } if own == True: chal_data.update({'nonce': session.get('nonce')}) json['game'].append(chal_data) db.session.close() return jsonify(json) else: db.session.close() abort(403)
def chal(chalid): if utils.ctf_ended() and not utils.view_after_ctf(): abort(403) if not utils.user_can_view_challenges(): return redirect(url_for('auth.login', next=request.path)) 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)) # Anti-bruteforce / submitting keys too quickly if utils.get_kpm(session['id']) > 10: if utils.ctftime(): wrong = WrongKeys(teamid=session['id'], chalid=chalid, ip=utils.get_ip(), flag=request.form['key'].strip()) db.session.add(wrong) db.session.commit() db.session.close() 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: chal = Challenges.query.filter_by(id=chalid).first_or_404() 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" }) chal_class = get_chal_class(chal.type) 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 comp_challenges(compid): if not utils.is_admin(): if not utils.ctftime(): if utils.view_after_ctf(): pass else: abort(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') comp = Competitions.query.filter(Competitions.id == compid).first() if comp is None: abort(403) if comp.startTime > datetime.datetime.utcnow(): abort(403) #chals=comp.chals json = { 'competition': { 'id': comp.id, 'title': comp.title, 'description': comp.description, 'startTime': comp.startTime, 'endTime': comp.endTime }, 'game': [] } for x in comp.chals: chal = Challenges.query.filter(Challenges.id == x.chalid).first() if chal is None: abort(502) tags = [ tag.tag for tag in Tags.query.add_columns('tag').filter( Tags.chal == chal.id).all() ] files = [ str(f.location) for f in Files.query.filter(Files.chal == chal.id).all() ] unlocked_hints = set([ u.itemid for u in Unlocks.query.filter( Unlocks.model == 'hints', Unlocks.teamid == teamid) ]) hints = [] for hint in Hints.query.filter(Hints.chal == chal.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(chal.type) json['game'].append({ 'id': chal.id, 'type': chal_type.name, 'name': chal.name, 'value': chal.value, 'description': chal.description, 'category': chal.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 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 chal(chalid): if ctf_ended() and not view_after_ctf(): return redirect(url_for('challenges.challenges_view')) if not user_can_view_challenges(): return redirect(url_for('auth.login', next=request.path)) if authed() and is_verified() and (ctf_started() or view_after_ctf()): 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'), get_kpm(session['id'])) print("[{0}] {1} submitted {2} with kpm {3}".format(*data)) # Anti-bruteforce / submitting keys too quickly if get_kpm(session['id']) > 10: if ctftime(): wrong = WrongKeys(session['id'], chalid, request.form['key']) db.session.add(wrong) db.session.commit() db.session.close() 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: chal = Challenges.query.filter_by(id=chalid).first() key = unicode(request.form['key'].strip().lower()) keys = json.loads(chal.flags) # Hit max attempts max_tries = int(get_config("max_tries")) if fails >= max_tries > 0: return jsonify({ 'status': '0', 'message': "You have 0 tries remaining" }) for x in keys: if x['type'] == 0: #static key print(x['flag'], key.strip().lower()) if x['flag'] and x['flag'].strip().lower() == key.strip( ).lower(): if ctftime(): solve = Solves(chalid=chalid, teamid=session['id'], ip=get_ip(), flag=key) db.session.add(solve) db.session.commit() db.session.close() logger.info( "[{0}] {1} submitted {2} with kpm {3} [CORRECT]". format(*data)) # return "1" # key was correct return jsonify({'status': '1', 'message': 'Correct'}) elif x['type'] == 1: #regex res = re.match(x['flag'], key, re.IGNORECASE) if res and res.group() == key: if ctftime(): solve = Solves(chalid=chalid, teamid=session['id'], ip=get_ip(), flag=key) db.session.add(solve) db.session.commit() db.session.close() logger.info( "[{0}] {1} submitted {2} with kpm {3} [CORRECT]". format(*data)) # return "1" # key was correct return jsonify({'status': '1', 'message': 'Correct'}) if ctftime(): wrong = WrongKeys(session['id'], chalid, request.form['key']) db.session.add(wrong) db.session.commit() db.session.close() 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 tries_str = 'tries' if attempts_left == 1: tries_str = 'try' return jsonify({ 'status': '0', 'message': 'Incorrect. You have {} {} remaining.'.format( attempts_left, tries_str) }) else: return jsonify({'status': '0', 'message': 'Incorrect'}) # 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 "-1"
def chal(chalid): if utils.ctf_ended() and not utils.view_after_ctf(): return redirect(url_for('challenges.challenges_view')) if not utils.user_can_view_challenges(): return redirect(url_for('auth.login', next=request.path)) if utils.authed() and utils.is_verified() and (utils.ctf_started() or utils.view_after_ctf()): 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)) # Anti-bruteforce / submitting keys too quickly if utils.get_kpm(session['id']) > 10: if utils.ctftime(): wrong = WrongKeys(session['id'], chalid, request.form['key']) db.session.add(wrong) db.session.commit() db.session.close() 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: chal = Challenges.query.filter_by(id=chalid).first_or_404() 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" }) chal_class = get_chal_class(chal.type) if chal_class.solve(chal, provided_key): if utils.ctftime(): solve = Solves(chalid=chalid, teamid=session['id'], ip=utils.get_ip(), flag=provided_key) db.session.add(solve) db.session.commit() db.session.close() logger.info("[{0}] {1} submitted {2} with kpm {3} [CORRECT]".format(*data)) return jsonify({'status': 1, 'message': 'Correct'}) if utils.ctftime(): wrong = WrongKeys(teamid=session['id'], chalid=chalid, flag=provided_key) db.session.add(wrong) db.session.commit() db.session.close() 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' return jsonify({'status': 0, 'message': 'Incorrect. You have {} {} remaining.'.format(attempts_left, tries_str)}) else: return jsonify({'status': 0, 'message': 'Incorrect'}) # 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 chal(chalid): if utils.ctf_ended() and not utils.view_after_ctf(): return redirect(url_for('challenges.challenges_view')) if not utils.user_can_view_challenges(): return redirect(url_for('auth.login', next=request.path)) if utils.authed() and utils.is_verified() and (utils.ctf_started() or utils.view_after_ctf()): 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)) # Anti-bruteforce / submitting keys too quickly if utils.get_kpm(session['id']) > 10: if utils.ctftime(): wrong = WrongKeys(session['id'], chalid, request.form['key']) db.session.add(wrong) db.session.commit() db.session.close() 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: chal = Challenges.query.filter_by(id=chalid).first_or_404() provided_key = unicode(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" }) chal_class = get_chal_class(chal.type) if chal_class.solve(chal, provided_key): if utils.ctftime(): solve = Solves(chalid=chalid, teamid=session['id'], ip=utils.get_ip(), flag=provided_key) db.session.add(solve) db.session.commit() db.session.close() logger.info( "[{0}] {1} submitted {2} with kpm {3} [CORRECT]".format( *data)) return jsonify({'status': '1', 'message': 'Correct'}) if utils.ctftime(): wrong = WrongKeys(teamid=session['id'], chalid=chalid, flag=provided_key) db.session.add(wrong) db.session.commit() db.session.close() 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' return jsonify({ 'status': '0', 'message': 'Incorrect. You have {} {} remaining.'.format( attempts_left, tries_str) }) else: return jsonify({'status': '0', 'message': 'Incorrect'}) # 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" })