def topusers(count): if get_config('view_scoreboard_if_authed') and not authed(): return redirect(url_for('auth.login', next=request.path)) try: count = int(count) except: count = 10 if count > 20 or count < 0: count = 10 json = {'scores':{}} standings = get_standings(count=count) for user in standings: solves = Solves.query.filter_by(userid=user.userid).all() awards = Awards.query.filter_by(userid=user.userid).all() json['scores'][user.name] = [] scores = [] for x in solves: json['scores'][user.name].append({ 'chal': x.chalid, 'user': x.userid, 'value': x.chal.value, 'time': unix_time(x.date) }) for award in awards: json['scores'][user.name].append({ 'chal': None, 'user': award.userid, 'value': award.value, 'time': unix_time(award.date) }) json['scores'][user.name] = sorted(json['scores'][user.name], key=lambda k: k['time']) return jsonify(json)
def user(userid): if get_config('view_scoreboard_if_authed') and not authed(): return redirect(url_for('auth.login', next=request.path)) user = Users.query.filter_by(id=userid).first_or_404() solves = Solves.query.filter_by(userid=userid) awards = Awards.query.filter_by(userid=userid).all() score = user.score() place = user.place() db.session.close() if request.method == 'GET': return render_template('user.html', solves=solves, awards=awards, user=user, score=score, place=place) elif request.method == 'POST': json = {'solves': []} for x in solves: json['solves'].append({ 'id': x.id, 'chal': x.chalid, 'user': x.userid }) return jsonify(json)
def topusers(count): if get_config('view_scoreboard_if_authed') and not authed(): return redirect(url_for('auth.login', next=request.path)) try: count = int(count) except: count = 10 if count > 20 or count < 0: count = 10 json = {'scores': {}} standings = get_standings(count=count) for user in standings: solves = Solves.query.filter_by(userid=user.userid).all() awards = Awards.query.filter_by(userid=user.userid).all() json['scores'][user.name] = [] scores = [] for x in solves: json['scores'][user.name].append({ 'chal': x.chalid, 'user': x.userid, 'value': x.chal.value, 'time': unix_time(x.date) }) for award in awards: json['scores'][user.name].append({ 'chal': None, 'user': award.userid, 'value': award.value, 'time': unix_time(award.date) }) json['scores'][user.name] = sorted(json['scores'][user.name], key=lambda k: k['time']) return jsonify(json)
def scores(): if get_config('view_scoreboard_if_authed') and not authed(): return redirect(url_for('auth.login', next=request.path)) standings = get_standings() json = {'standings':[]} for i, x in enumerate(standings): json['standings'].append({'pos':i+1, 'id':x.userid, 'user':x.name,'score':int(x.score)}) return jsonify(json)
def scores(): if get_config('view_scoreboard_if_authed') and not authed(): return redirect(url_for('auth.login', next=request.path)) standings = get_standings() json = {'standings': []} for i, x in enumerate(standings): json['standings'].append({ 'pos': i + 1, 'id': x.userid, 'user': x.name, 'score': int(x.score) }) return jsonify(json)
def confirm_user(data=None): if not get_config('verify_emails'): return redirect(url_for('challenges.challenges_view')) if data and request.method == "GET": ## User is confirming email account try: s = Signer(app.config['SECRET_KEY']) email = s.unsign(data.decode('base64')) except BadSignature: return render_template('confirm.html', errors=['Your confirmation link seems wrong']) user = Users.query.filter_by(email=email).first() user.verified = True db.session.commit() db.session.close() if authed(): return redirect(url_for('challenges.challenges_view')) return redirect(url_for('auth.login')) if not data and request.method == "GET": ## User has been directed to the confirm page because his account is not verified user = Users.query.filter_by(id=session['id']).first() if user.verified: return redirect(url_for('views.profile')) return render_template('confirm.html', user=user)
def confirm_user(data=None): if not get_config('verify_emails'): return redirect(url_for('challenges.challenges_view')) if data and request.method == "GET": ## User is confirming email account try: s = Signer(app.config['SECRET_KEY']) email = s.unsign(data.decode('base64')) except BadSignature: return render_template( 'confirm.html', errors=['Your confirmation link seems wrong']) user = Users.query.filter_by(email=email).first() user.verified = True db.session.commit() db.session.close() if authed(): return redirect(url_for('challenges.challenges_view')) return redirect(url_for('auth.login')) if not data and request.method == "GET": ## User has been directed to the confirm page because his account is not verified user = Users.query.filter_by(id=session['id']).first() if user.verified: return redirect(url_for('views.profile')) return render_template('confirm.html', user=user)
def solves(userid=None): solves = None awards = None if userid is None: if is_admin(): solves = Solves.query.filter_by(userid=session['id']).all() elif authed(): solves = Solves.query.join(Users, Solves.userid == Users.id).filter( Solves.userid == session['id'], Users.banned == False).all() else: return redirect(url_for('auth.login', next='solves')) else: solves = Solves.query.filter_by(userid=userid).all() awards = Awards.query.filter_by(userid=userid).all() db.session.close() json = {'solves': []} for solve in solves: json['solves'].append({ 'chal': solve.chal.name, 'chalid': solve.chalid, 'user': solve.userid, 'value': solve.chal.value, 'category': solve.chal.category, 'time': unix_time(solve.date) }) if awards: for award in awards: json['solves'].append({ 'chal': award.name, 'chalid': None, 'user': award.userid, 'value': award.value, 'category': award.category, 'time': unix_time(award.date) }) json['solves'].sort(key=lambda k: k['time']) return jsonify(json)
def solves(userid=None): solves = None awards = None if userid is None: if is_admin(): solves = Solves.query.filter_by(userid=session['id']).all() elif authed(): solves = Solves.query.join(Users, Solves.userid == Users.id).filter(Solves.userid == session['id'], Users.banned == False).all() else: return redirect(url_for('auth.login', next='solves')) else: solves = Solves.query.filter_by(userid=userid).all() awards = Awards.query.filter_by(userid=userid).all() db.session.close() json = {'solves':[]} for solve in solves: json['solves'].append({ 'chal': solve.chal.name, 'chalid': solve.chalid, 'user': solve.userid, 'value': solve.chal.value, 'category': solve.chal.category, 'time': unix_time(solve.date) }) if awards: for award in awards: json['solves'].append({ 'chal': award.name, 'chalid': None, 'user': award.userid, 'value': award.value, 'category': award.category, 'time': unix_time(award.date) }) json['solves'].sort(key=lambda k: k['time']) return jsonify(json)
def logout(): if authed(): session.clear() return redirect(url_for('views.static_html'))
def scoreboard_view(): if get_config('view_scoreboard_if_authed') and not authed(): return redirect(url_for('auth.login', next=request.path)) standings = get_standings() return render_template('scoreboard.html', users=standings)
def profile(): if authed(): if request.method == "POST": errors = [] name = request.form.get('name') email = request.form.get('email') website = request.form.get('website') affiliation = request.form.get('affiliation') country = request.form.get('country') user = Users.query.filter_by(id=session['id']).first() if not get_config('prevent_name_change'): names = Users.query.filter_by(name=name).first() name_len = len(request.form['name']) == 0 emails = Users.query.filter_by(email=email).first() valid_email = re.match("[^@]+@[^@]+\.[^@]+", 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 get_config('prevent_name_change' ) and names and name != session['username']: errors.append('That user name is already taken') if emails and emails.id != session['id']: errors.append('That email has already been used') if not get_config('prevent_name_change') and name_len: errors.append('Pick a longer user name') if website.strip() and not validate_url(website): errors.append("That doesn't look like a valid URL") if len(errors) > 0: return render_template('profile.html', name=name, email=email, website=website, affiliation=affiliation, country=country, errors=errors) else: user = Users.query.filter_by(id=session['id']).first() if not get_config('prevent_name_change'): user.name = name if user.email != email.lower(): user.email = email.lower() if get_config('verify_emails'): user.verified = False session['username'] = user.name if 'password' in request.form.keys() and not len( request.form['password']) == 0: user.password = bcrypt_sha256.encrypt( request.form.get('password')) user.website = website user.affiliation = affiliation user.country = country db.session.commit() db.session.close() return redirect(url_for('views.profile')) else: user = Users.query.filter_by(id=session['id']).first() name = user.name email = user.email website = user.website affiliation = user.affiliation country = user.country prevent_name_change = get_config('prevent_name_change') confirm_email = get_config('verify_emails') and not user.verified return render_template('profile.html', name=name, email=email, website=website, affiliation=affiliation, country=country, prevent_name_change=prevent_name_change, confirm_email=confirm_email) else: return redirect(url_for('auth.login'))
def chal(chalid): if not ctftime(): return redirect(url_for('challenges.challenges_view')) if authed(): fails = WrongKeys.query.filter_by(userid=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: 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(userid=session['id'], chalid=chalid).first() # Challange not solved yet if not solves: chal = Challenges.query.filter_by(id=chalid).first() key = str(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(): solve = Solves(chalid=chalid, userid=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(str(x['flag']), key, re.IGNORECASE) if res and res.group() == key: solve = Solves(chalid=chalid, userid=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'}) 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 not ctftime(): return redirect(url_for('challenges.challenges_view')) if authed(): fails = WrongKeys.query.filter_by(userid=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: 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(userid=session['id'], chalid=chalid).first() # Challange not solved yet if not solves: chal = Challenges.query.filter_by(id=chalid).first() key = str(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(): solve = Solves(chalid=chalid, userid=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(str(x['flag']), key, re.IGNORECASE) if res and res.group() == key: solve = Solves(chalid=chalid, userid=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'}) 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"