Esempio n. 1
0
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'))
Esempio n. 2
0
def file_handler(path):
    f = Files.query.filter_by(location=path).first_or_404()
    if f.chal:
        if not utils.is_admin():
            if not utils.ctftime():
                if utils.view_after_ctf() and utils.ctf_started():
                    pass
                else:
                    abort(403)
    upload_folder = os.path.join(app.root_path, app.config['UPLOAD_FOLDER'])
    return send_file(safe_join(upload_folder, f.location))
Esempio n. 3
0
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=text_type('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 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
Esempio n. 5
0
def file_handler(path):
    f = Files.query.filter_by(location=path).first_or_404()
    if f.chal:
        if not utils.is_admin():
            if not utils.ctftime():
                if utils.view_after_ctf() and utils.ctf_started():
                    pass
                else:
                    abort(403)
    upload_folder = os.path.join(app.root_path, app.config['UPLOAD_FOLDER'])
    return send_file(safe_join(upload_folder, f.location))
Esempio n. 6
0
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': 'Not enough points'})
                unlock = Unlocks(model='hints',
                                 teamid=session['id'],
                                 itemid=hint.id)
                award = Awards(teamid=session['id'],
                               name=text_type('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():  # 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)
Esempio n. 7
0
def test_ctf_started():
    '''Tests that the ctf_started function returns the correct value'''
    app = create_ctfd()
    with app.app_context():
        assert ctf_started() == True

        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_started() == False

        with freeze_time("2017-10-5"):
            assert ctf_started() == True

        with freeze_time("2017-10-7"):
            assert ctf_started() == True
    destroy_ctfd(app)
Esempio n. 8
0
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'):
        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('chals.html',
                               errors=errors,
                               start=int(start),
                               end=int(end))
    else:
        return redirect(url_for('auth.login', next='challenges'))
Esempio n. 9
0
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)
Esempio n. 10
0
    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)
Esempio n. 11
0
    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()):
            chals = Challenges.query.filter(or_(Challenges.hidden != True, Challenges.hidden == None)).order_by(Challenges.value).all()

            # Only one line in chals() needed to add for Challenge Discovery
	    # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 
	    chals = discovery(chals) if len(chals)!=0 else chals
	    # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-   

            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 = []
                if utils.authed():
                    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})
                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)
Esempio n. 12
0
def chals():
    if not is_admin():
        if not ctftime():
            if view_after_ctf():
                pass
            else:
                return redirect(url_for('views.index'))
    if user_can_view_challenges() and (ctf_started() or is_admin()):
        chals = Challenges.query.filter(
            or_(Challenges.hidden != True,
                Challenges.hidden == None)).order_by(Challenges.value).all()

        json = {'game': []}
        for chal in chals:
            tags = [
                tag.tag for tag in Tags.query.filter_by(chal=chal.id).all()
            ]
            files = [
                str(f.location)
                for f in Files.query.filter_by(chal=chal.id).all()
            ]
            hints = [{
                'title': hint.title,
                'description': hint.description
            } for hint in Announcements.query.filter_by(
                chalid=chal.id).order_by(Announcements.date.asc()).all()]
            notepad = Notepads.query.filter_by(teamid=session['id'],
                                               chalid=chal.id).first()
            notepad = notepad.content if notepad else ''
            json['game'].append({
                'id': chal.id,
                'name': chal.name,
                'value': chal.value,
                'description': chal.description,
                'category': chal.category,
                'down': chal.down,
                'files': files,
                'tags': tags,
                'hints': hints,
                'notepad': notepad,
            })

        db.session.close()
        return jsonify(json)
    else:
        db.session.close()
        return redirect(url_for('auth.login', next='chals'))
Esempio n. 13
0
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'))
Esempio n. 14
0
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))
Esempio n. 15
0
def chals():
    if not is_admin():
        if not ctftime():
            if view_after_ctf():
                pass
            else:
                return redirect(url_for('views.static_html'))
    if user_can_view_challenges() and (ctf_started() or is_admin()):
        chals = Challenges.query.filter(
            or_(Challenges.hidden != True,
                Challenges.hidden == None)).add_columns(
                    'id', 'name', 'value', 'description',
                    'category').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[1]).all()
            ]
            files = [
                str(f.location)
                for f in Files.query.filter_by(chal=x.id).all()
            ]
            json['game'].append({
                'id': x[1],
                'name': x[2],
                'value': x[3],
                'description': x[4],
                'category': x[5],
                'files': files,
                'tags': tags
            })

        db.session.close()
        return jsonify(json)
    else:
        db.session.close()
        return redirect(url_for('auth.login', next='chals'))
Esempio n. 16
0
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'))
Esempio n. 17
0
def file_handler(path):
    f = Files.query.filter_by(location=path).first_or_404()
    if f.chal:
        if not utils.is_admin():
            if not utils.ctftime():
                if utils.view_after_ctf() and utils.ctf_started():
                    pass
                else:
                    abort(403)
    upload_folder = os.path.join(app.root_path, app.config['UPLOAD_FOLDER'])
    if not f.dynamic:
        return send_file(safe_join(upload_folder, f.location))
    filedir_path = safe_join(upload_folder, f.location.split('/')[0])
    m = hashlib.md5()
    m.update(session['token'])
    teamfile_name = m.hexdigest() + ".zip"
    teamfile_path = safe_join(filedir_path, teamfile_name)
    if not os.path.exists(teamfile_path):
        os.system("python %s %s %s %s" %
                  (safe_join(upload_folder, f.location), filedir_path,
                   session['token'], app.root_path))
    return send_file(teamfile_path, cache_timeout=0)
Esempio n. 18
0
def competitions():
    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()):
        competitions = Competitions.query.all()
        json = {'competitions': []}
        for x in competitions:
            json['competitions'].append({
                'id': x.id,
                'title': x.title,
                'description': x.description
            })
        db.session.close()
        return jsonify(json)
    else:
        db.session.close()
        abort(403)
Esempio n. 19
0
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)
Esempio n. 20
0
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"
                })

            chal_name = chal.name
            chal_value = chal.value
            team_id = team.id
            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))

                team_url = url_for("views.team",
                                   teamid=team_id,
                                   _external=True)
                chal_url = url_for("challenges.challenges_view",
                                   _anchor=chal_name,
                                   _external=True)
                description = ":white_check_mark: [{0}]({1}) solved [{2}]({3}) ({4})".format(
                    session['username'].encode('utf-8'), team_url, chal_name,
                    chal_url, chal_value)
                embeds = [{
                    "description":
                    description,
                    "color":
                    10553667,
                    "timestamp":
                    datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%SZ')
                }]
                utils.send_discord_webhook(embeds)

                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"
        })
Esempio n. 21
0
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)
Esempio n. 22
0
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))
Esempio n. 23
0
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': "你提交答案过快,请稍后再试"})

        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': "你已经没有机会再试了"
                })

            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': '你已经做过本题了'})
    else:
        return jsonify({
            'status': -1,
            'message': "必须先登陆才能解题"
        })
Esempio n. 24
0
def chals(chalid=None):
    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()):
        json = {'game': [], 'nonce': ''}
        if chalid is None:
            chals = Challenges.query.order_by(Challenges.value).all()
            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()
                ]
                chal_type = get_chal_class(x.type)
                if x.hidden:
                    json['game'].append({
                        'id': x.id,
                        'name': x.name,
                        'value': x.value,
                        'category': x.category,
                        'hidden': True
                    })
                else:
                    file_data = []
                    for i in range(len(files)):
                        file_data.append(
                            [str(files[i]).split('/')[1],
                             str(files[i])])

                    json['game'].append({
                        'id': x.id,
                        'type': chal_type.name,
                        'name': x.name,
                        'value': x.value,
                        'description': x.description,
                        'category': x.category,
                        'files': file_data,
                        'tags': tags,
                        'hint': x.hint
                    })

                    json["nonce"] = session["nonce"]
        else:
            chal = Challenges.query.filter_by(id=chalid).all()[0]
            if chal is None or chal.hidden:
                json = {"locked": True}
            else:
                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()
                ]

                chal_type = get_chal_class(chal.type)
                json = {
                    'id': chal.id,
                    'type': chal_type.name,
                    'name': chal.name,
                    'value': chal.value,
                    'description': chal.description,
                    'category': chal.category,
                    'files': files,
                    'tags': tags,
                    'hint': chal.hint
                }

        db.session.close()
        return jsonify(json)
    else:
        db.session.close()
        return redirect(url_for('auth.login', next='chals'))
Esempio n. 25
0
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"
        })
Esempio n. 26
0
    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)
Esempio n. 27
0
    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"
            })
Esempio n. 28
0
def chal_custom(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))

                if "SmartCity" in str(chal_class):
                    print(session['id'])
                    smart_color = SmartCityTeam.query.filter_by(
                        teamId=session['id']).first().color
                    smart_buildingId = SmartCityChallenge.query.filter_by(
                        id=chalid).first().buildingId
                    smart_soundId = SmartCityChallenge.query.filter_by(
                        id=chalid).first().soundId
                    smart_image = SmartCityTeam.query.filter_by(
                        teamId=session['id']).first().image
                    b = smart_buildingId.split('\', \'')
                    b[0] = b[0][2:]
                    b[-1] = b[-1][:-2]
                    print("Team with color " + str(smart_color) +
                          " and image " + str(smart_image) +
                          " solved challenege with buildingId " + str(b) +
                          "and sound " + smart_soundId)
                    smartSession = SmartTable(b, smart_color, smart_image,
                                              smart_soundId)
                    createSmartCityTableSession2(smartSession)

                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"
        })
Esempio n. 29
0
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"
Esempio n. 30
0
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"
        })
Esempio n. 31
0
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"
        })