def scoreboard_view(): if utils.get_config('view_scoreboard_if_authed') and not utils.authed(): return redirect(url_for('auth.login', next=request.path)) if utils.hide_scores(): return render_template('scoreboard.html', errors=['Scores are currently hidden']) standings = get_standings() return render_template('scoreboard.html', teams=standings, score_frozen=utils.is_scoreboard_frozen())
def profile(): if utils.authed(): if request.method == "POST": errors = [] name = request.form.get('name') email = request.form.get('email') user = Teams.query.filter_by(id=session['id']).first() if not utils.get_config('prevent_name_change'): names = Teams.query.filter_by(name=name).first() name_len = len(request.form['name']) == 0 emails = Teams.query.filter_by(email=email).first() valid_email = re.match(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", email) if ('password' in request.form.keys() and not len(request.form['password']) == 0) and \ (not bcrypt_sha256.verify(request.form.get('confirm').strip(), user.password)): errors.append("Your old password doesn't match what we have.") if not valid_email: errors.append("That email doesn't look right") if not utils.get_config('prevent_name_change') and names and name != session['username']: errors.append('That team name is already taken') if emails and emails.id != session['id']: errors.append('That email has already been used') if not utils.get_config('prevent_name_change') and name_len: errors.append('Pick a longer team name') if len(errors) > 0: return render_template('profile.html', name=name, email=email, errors=errors) else: team = Teams.query.filter_by(id=session['id']).first() if not utils.get_config('prevent_name_change'): team.name = name if team.email != email.lower(): team.email = email.lower() if utils.get_config('verify_emails'): team.verified = False session['username'] = team.name if 'password' in request.form.keys() and not len(request.form['password']) == 0: team.password = bcrypt_sha256.encrypt(request.form.get('password')) db.session.commit() db.session.close() return redirect(url_for('views.profile')) else: user = Teams.query.filter_by(id=session['id']).first() name = user.name email = user.email prevent_name_change = utils.get_config('prevent_name_change') confirm_email = utils.get_config('verify_emails') and not user.verified return render_template('profile.html', name=name, email=email, prevent_name_change=prevent_name_change, confirm_email=confirm_email) else: return redirect(url_for('auth.login'))
def solves(teamid=None): solves = None awards = None if teamid is None: 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'], Teams.banned == False).all() else: return jsonify({'solves': []}) else: return redirect(url_for('auth.login', next='solves')) else: solves = Solves.query.filter_by(teamid=teamid) awards = Awards.query.filter_by(teamid=teamid) freeze = utils.get_config('freeze') 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() json = {'solves': []} for solve in solves: json['solves'].append({ 'chal': solve.chal.name, 'chalid': solve.chalid, 'team': solve.teamid, 'value': solve.chal.value, 'category': solve.chal.category, 'time': utils.unix_time(solve.date) }) if awards: for award in awards: json['solves'].append({ 'chal': award.name, 'chalid': None, 'team': award.teamid, 'value': award.value, 'category': award.category or "Award", 'time': utils.unix_time(award.date) }) json['solves'].sort(key=lambda k: k['time']) return jsonify(json)
def topteams(count): json = {'scores': {}} if utils.get_config('view_scoreboard_if_authed') and not utils.authed(): return redirect(url_for('auth.login', next=request.path)) if utils.hide_scores(): return jsonify(json) if count > 20 or count < 0: count = 10 standings = get_standings(count=count) for team in standings: solves = Solves.query.filter_by(teamid=team.teamid) awards = Awards.query.filter_by(teamid=team.teamid) freeze = utils.get_config('freeze') if freeze: solves = solves.filter( Solves.date < utils.unix_time_to_utc(freeze)) awards = awards.filter( Awards.date < utils.unix_time_to_utc(freeze)) solves = solves.all() awards = awards.all() json['scores'][team.name] = [] for x in solves: json['scores'][team.name].append({ 'chal': x.chalid, 'team': x.teamid, 'value': x.chal.value, 'time': utils.unix_time(x.date) }) for award in awards: json['scores'][team.name].append({ 'chal': None, 'team': award.teamid, 'value': award.value, 'time': utils.unix_time(award.date) }) json['scores'][team.name] = sorted(json['scores'][team.name], key=lambda k: k['time']) return jsonify(json)
def scores(): json = {'standings': []} if utils.get_config('view_scoreboard_if_authed') and not utils.authed(): return redirect(url_for('auth.login', next=request.path)) if utils.hide_scores(): return jsonify(json) standings = get_standings() for i, x in enumerate(standings): json['standings'].append({ 'pos': i + 1, 'id': x.teamid, 'team': x.name, 'score': int(x.score) }) return jsonify(json)
def team(teamid): if utils.get_config('view_scoreboard_if_utils.authed') and not utils.authed(): return redirect(url_for('auth.login', next=request.path)) errors = [] 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') if errors: return render_template('team.html', team=user, 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()) 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 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" })