Пример #1
0
def private():
    infos = get_infos()
    errors = get_errors()

    user = get_current_user()

    if config.is_scoreboard_frozen():
        infos.append("Scoreboard has been frozen")

    return render_template(
        "users/private.html",
        user=user,
        account=user.account,
        infos=infos,
        errors=errors,
    )
Пример #2
0
def get_user_challenge_by_id(challenge_id):
    if is_admin():
        return Challenges.query.filter_by(id=challenge_id).first_or_404()
    else:
        user = get_current_user()
        return (Challenges.query.outerjoin(
            Solves, Challenges.id == Solves.challenge_id).filter(
                and_(
                    Challenges.id == challenge_id,
                    Challenges.state != "hidden",
                    Challenges.state != "locked",
                    or_(
                        Challenges.is_secret == False,
                        Solves.account_id == user.account_id,
                    ),
                ), ).first_or_404())
Пример #3
0
    def get(self):
        user = get_current_user()
        fails = user.get_fails(admin=True)

        view = "user" if not is_admin() else "admin"
        response = SubmissionSchema(view=view, many=True).dump(fails)
        if response.errors:
            return {"success": False, "errors": response.errors}, 400

        if is_admin():
            data = response.data
        else:
            data = []
        count = len(response.data)

        return {"success": True, "data": data, "meta": {"count": count}}
Пример #4
0
    def patch(self):
        user = get_current_user()
        data = request.get_json()
        schema = UserSchema(view="self", instance=user, partial=True)
        response = schema.load(data)
        if response.errors:
            return {"success": False, "errors": response.errors}, 400

        db.session.commit()

        response = schema.dump(response.data)
        db.session.close()

        clear_standings()

        return {"success": True, "data": response.data}
Пример #5
0
def join():
    if request.method == 'GET':
        return render_template('teams/join_team.html')
    if request.method == 'POST':
        teamname = request.form.get('name')
        passphrase = request.form.get('password', '').strip()

        team = Teams.query.filter_by(name=teamname).first()
        user = get_current_user()
        if team and verify_password(passphrase, team.password):
            user.team_id = team.id
            db.session.commit()
            return redirect(url_for('challenges.listing'))
        else:
            errors = ['That information is incorrect']
            return render_template('teams/join_team.html', errors=errors)
Пример #6
0
def private():
    user = get_current_user()

    solves = user.get_solves()
    awards = user.get_awards()

    place = user.place
    score = user.score

    return render_template('users/private.html',
                           solves=solves,
                           awards=awards,
                           user=user,
                           score=score,
                           place=place,
                           score_frozen=config.is_scoreboard_frozen())
Пример #7
0
def status():
    try:
        cid = request.args['challenge_id']
        uid = get_current_user().id
        now = time.time()
        con = models.query_container(cid, uid)

        # 检查该用户是否真的部署了container
        if con:
            left_time = str(int(3600 - (now - con.start_time)))  # 返回剩余时间
            con_url = con.url
            return 'Success ' + con_url + ' ' + left_time
        else:
            return 'No'
    except:
        return 'Error'
Пример #8
0
 def view_target():
     if authed():
         user = get_current_user()
         if not login_info.has_key(user.id):
             randomvalue = uuid4().hex[0:16]
             url_prefix = randomvalue[:8]
             login_info[user.id] = url % (url_prefix)
             random_port_internal = random.randint(1000, 9999)
             command = create_container % (random_port_internal, login_info[
                 user.id], login_info[user.id], random_port_internal)
             system(command)
             print(command)
         return_data = return_info % (login_info[user.id])
         return render_template('page.html', content=return_data)
     else:
         return redirect(url_for('auth.login'))
Пример #9
0
        def wrapper(*args, **kwargs):
            result = f(*args, **kwargs)

            if not ctftime():
                return result

            if isinstance(result, JSONMixin):
                data = result.json
                if (isinstance(data, dict) and data.get("success") == True
                        and isinstance(data.get("data"), dict)
                        and data.get("data").get("status") == "correct"):
                    if request.content_type != "application/json":
                        request_data = request.form
                    else:
                        request_data = request.get_json()

                    challenge_id = request_data.get("challenge_id")
                    challenge = Challenges.query.filter_by(
                        id=challenge_id).first_or_404()

                    solvers = Solves.query.filter_by(challenge_id=challenge.id)
                    solvers = solvers.filter(Solves.user.has(hidden=False))
                    num_solves = solvers.count()

                    limit = app.config["DISCORD_WEBHOOK_FIRST_SOLVES"]
                    if limit and num_solves > int(limit):
                        return result

                    webhook = DiscordWebhook(
                        url=app.config["DISCORD_WEBHOOK_URL"])
                    user = get_current_user()

                    format_args = {
                        "user": sanitize(user.name),
                        "challenge": sanitize(challenge.name),
                        "solves": num_solves,
                        "fsolves": ordinal(num_solves),
                        "category": sanitize(challenge.category),
                        "points": challenge.value,
                    }

                    message = app.config["DISCORD_WEBHOOK_MESSAGE"].format(
                        **format_args)
                    embed = DiscordEmbed(description=message)
                    webhook.add_embed(embed)
                    webhook.execute()
            return result
Пример #10
0
def join():
    infos = get_infos()
    errors = get_errors()
    if request.method == "GET":
        team_size_limit = get_config("team_size", default=0)
        if team_size_limit:
            plural = "" if team_size_limit == 1 else "s"
            infos.append(
                "Команды могут содержать не больше {limit} участников".format(
                    limit=team_size_limit, plural=plural))
        return render_template("teams/join_team.html",
                               infos=infos,
                               errors=errors)

    if request.method == "POST":
        teamname = request.form.get("name")
        passphrase = request.form.get("password", "").strip()

        team = Teams.query.filter_by(name=teamname).first()

        if team and verify_password(passphrase, team.password):
            team_size_limit = get_config("team_size", default=0)
            if team_size_limit and len(team.members) >= team_size_limit:
                errors.append(
                    "Команда {name} уже достигла лимит в {limit} участников".
                    format(name=team.name, limit=team_size_limit))
                return render_template("teams/join_team.html",
                                       infos=infos,
                                       errors=errors)

            user = get_current_user()
            user.team_id = team.id
            db.session.commit()

            if len(team.members) == 1:
                team.captain_id = user.id
                db.session.commit()

            clear_user_session(user_id=user.id)
            clear_team_session(team_id=team.id)

            return redirect(url_for("challenges.listing"))
        else:
            errors.append("Такая информация некорректна")
            return render_template("teams/join_team.html",
                                   infos=infos,
                                   errors=errors)
Пример #11
0
    def view_quiz_finish(quiz):
        user_quest = Quiz.query.filter_by(quiz=quiz,
                                          user=get_current_user().id).all()[-1]

        quiz_data = get_quiz_data_or_404(quiz)

        user_progress = json.loads(user_quest.data)
        answered_question_count = len(user_progress['questions'])

        if answered_question_count < quiz_data['questionsToAskCount']:
            return redirect('/quiz/{}'.format(quiz))

        quiz_data = get_quiz_data_or_404(quiz)
        challenge_quiz = ChallengeQuiz.query.filter_by(quiz=quiz).first()

        challenge = Challenges.query.filter_by(
            id=challenge_quiz.challenge).first()
        user_quest_json_data = json.loads(user_quest.data)

        correct_answer = 0
        for question in user_quest_json_data['questions']:
            original_question = list(
                filter(lambda i: i['content'] == question,
                       quiz_data['questions']))[0]
            if type(original_question['correctAnswer']) == int:
                original = {original_question['correctAnswer']}
            else:
                original = set(original_question['correctAnswer'])

            user_answer = set(user_quest_json_data['questions'][question])

            if original == user_answer:
                correct_answer += 1

        if correct_answer >= quiz_data['goalCount']:
            user_quest.status = QuizStatusEnum.passed
        else:
            user_quest.status = QuizStatusEnum.failed

        db.session.add(user_quest)
        db.session.commit()

        return render_template('quiz-plugin/finish.html',
                               name=quiz,
                               quiz=quiz_data,
                               challenge=challenge,
                               correct=correct_answer)
Пример #12
0
    def add_container():
        user_id = current_user.get_current_user().id
        redis_util = RedisUtils(app=app, user_id=user_id)

        if not redis_util.acquire_lock():
            return json.dumps({'success': False, 'msg': 'Request Too Fast!'})

        if ControlUtil.frequency_limit():
            return json.dumps({
                'success':
                False,
                'msg':
                'Frequency limit, You should wait at least 1 min.'
            })

        ControlUtil.remove_container(app, user_id)
        challenge_id = request.args.get('challenge_id')
        ControlUtil.check_challenge(challenge_id, user_id)

        configs = DBUtils.get_all_configs()
        current_count = DBUtils.get_all_alive_container_count()
        if int(configs.get("docker_max_container_count")) <= int(
                current_count):
            return json.dumps({
                'success': False,
                'msg': 'Max container count exceed.'
            })

        dynamic_docker_challenge = DynamicDockerChallenge.query \
            .filter(DynamicDockerChallenge.id == challenge_id) \
            .first_or_404()
        flag = "flag{" + str(uuid.uuid4()) + "}"
        if dynamic_docker_challenge.redirect_type == "http":
            ControlUtil.add_container(app=app,
                                      user_id=user_id,
                                      challenge_id=challenge_id,
                                      flag=flag)
        else:
            port = redis_util.get_available_port()
            ControlUtil.add_container(app=app,
                                      user_id=user_id,
                                      challenge_id=challenge_id,
                                      flag=flag,
                                      port=port)

        redis_util.release_lock()
        return json.dumps({'success': True})
Пример #13
0
def join():
    infos = get_infos()
    errors = get_errors()
    if request.method == "GET":
        team_size_limit = get_config("team_size", default=0)
        if team_size_limit:
            plural = "" if team_size_limit == 1 else "s"
            infos.append(
                "Teams are limited to {limit} member{plural}".format(
                    limit=team_size_limit, plural=plural
                )
            )
        return render_template("teams/join_team.html", infos=infos, errors=errors)

    if request.method == "POST":
        teamname = request.form.get("name")
        passphrase = request.form.get("password", "").strip()

        team = Teams.query.filter_by(name=teamname).first()

        if team and verify_password(passphrase, team.password):
            team_size_limit = get_config("team_size", default=0)
            if team_size_limit and len(team.members) >= team_size_limit:
                errors.append(
                    "{name} has already reached the team size limit of {limit}".format(
                        name=team.name, limit=team_size_limit
                    )
                )
                return render_template(
                    "teams/join_team.html", infos=infos, errors=errors
                )

            user = get_current_user()
            user.team_id = team.id
            db.session.commit()

            if len(team.members) == 1:
                team.captain_id = user.id
                db.session.commit()

            clear_user_session(user_id=user.id)
            clear_team_session(team_id=team.id)

            return redirect(url_for("challenges.listing"))
        else:
            errors.append("That information is incorrect")
            return render_template("teams/join_team.html", infos=infos, errors=errors)
Пример #14
0
    def post(self):
        req = request.get_json()
        user = get_current_user()

        req["user_id"] = user.id
        req["team_id"] = user.team_id

        Model = get_class_by_tablename(req["type"])
        target = Model.query.filter_by(id=req["target"]).first_or_404()

        if target.cost > user.score:
            return (
                {
                    "success": False,
                    "errors": {
                        "score":
                        "You do not have enough points to unlock this hint"
                    },
                },
                400,
            )

        schema = UnlockSchema()
        response = schema.load(req, session=db.session)

        if response.errors:
            return {"success": False, "errors": response.errors}, 400

        db.session.add(response.data)

        award_schema = AwardSchema()
        award = {
            "user_id": user.id,
            "team_id": user.team_id,
            "name": target.name,
            "description": target.description,
            "value": (-target.cost),
            "category": target.category,
        }

        award = award_schema.load(award)
        db.session.add(award.data)
        db.session.commit()

        response = schema.dump(response.data)

        return {"success": True, "data": response.data}
Пример #15
0
def destroy():
    try:
        cid = request.form['challenge_id']
        uid = get_current_user().id

        # 检查该用户是否真的部署了container
        if models.query_container(cid, uid):
            fish_challenge = models.query_FishChallengeTable(cid)
            if fish_challenge:
                url = fish_challenge.url
                passcode = fish_challenge.passcode
                if utils.do_destroy(url, uid, passcode):
                    models.delete_containter(cid, uid)
                    return 'Success'
        return 'Error'
    except:
        return 'Error'
Пример #16
0
def settings():
    user = get_current_user()
    name = user.name
    email = user.email
    student_id = user.student_id
    real_name = user.real_name
    contact = user.contact
    prevent_name_change = get_config('prevent_name_change')
    confirm_email = get_config('verify_emails') and not user.verified
    return render_template('settings.html',
                           name=name,
                           email=email,
                           student_id=student_id,
                           real_name=real_name,
                           prevent_name_change=prevent_name_change,
                           confirm_email=confirm_email,
                           contact=contact)
Пример #17
0
    def post(self):
        req = request.get_json()
        expiration = req.get("expiration")
        if expiration:
            expiration = datetime.datetime.strptime(expiration, "%Y-%m-%d")

        user = get_current_user()
        token = generate_user_token(user, expiration=expiration)

        # Explicitly use admin view so that user's can see the value of their token
        schema = TokenSchema(view="admin")
        response = schema.dump(token)

        if response.errors:
            return {"success": False, "errors": response.errors}, 400

        return {"success": True, "data": response.data}
Пример #18
0
    def add_container():
        if ControlUtil.frequency_limit():
            return json.dumps({
                'success':
                False,
                'msg':
                'Frequency limit, You should wait at least 1 min.'
            })

        user_id = current_user.get_current_user().id
        ControlUtil.remove_container(user_id)
        challenge_id = request.args.get('challenge_id')
        ControlUtil.check_challenge(challenge_id, user_id)

        configs = DBUtils.get_all_configs()
        current_count = DBUtils.get_all_alive_container_count()
        if int(configs.get("docker_max_container_count")) <= int(
                current_count):
            return json.dumps({
                'success': False,
                'msg': 'Max container count exceed.'
            })

        dynamic_docker_challenge = DynamicDockerChallenge.query \
            .filter(DynamicDockerChallenge.id == challenge_id) \
            .first_or_404()
        flag = "flag{" + str(uuid.uuid4()) + "}"
        if dynamic_docker_challenge.redirect_type == "http":
            ControlUtil.add_container(user_id=user_id,
                                      challenge_id=challenge_id,
                                      flag=flag)
        else:
            port = random.randint(int(configs.get("frp_direct_port_minimum")),
                                  int(configs.get("frp_direct_port_maximum")))
            while True:
                if DBUtils.get_container_by_port(port) is None:
                    break
                port = random.randint(
                    int(configs.get("frp_direct_port_minimum")),
                    int(configs.get("frp_direct_port_maximum")))
            ControlUtil.add_container(user_id=user_id,
                                      challenge_id=challenge_id,
                                      flag=flag,
                                      port=port)

        return json.dumps({'success': True})
Пример #19
0
def settings():
    user = get_current_user()
    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('settings.html',
                           name=name,
                           email=email,
                           website=website,
                           affiliation=affiliation,
                           country=country,
                           prevent_name_change=prevent_name_change,
                           confirm_email=confirm_email)
Пример #20
0
    def delete(self, user_id):
        # import time; time.sleep(60)
        if get_current_user().id == user_id:
            return {'success': False, 'data': 'Cannot delete own account'}
        Notifications.query.filter_by(user_id=user_id).delete()
        Awards.query.filter_by(user_id=user_id).delete()
        Unlocks.query.filter_by(user_id=user_id).delete()
        Submissions.query.filter_by(user_id=user_id).delete()
        Solves.query.filter_by(user_id=user_id).delete()
        Tracking.query.filter_by(user_id=user_id).delete()
        Users.query.filter_by(id=user_id).delete()
        db.session.commit()
        db.session.close()

        clear_standings()

        return {"success": True}
Пример #21
0
 def patch():
     user_id = current_user.get_current_user().id
     challenge_id = request.args.get('challenge_id')
     docker_max_renew_count = int(
         get_config("whale:docker_max_renew_count", 5))
     container = DBContainer.get_current_containers(user_id)
     if container is None:
         abort(403, 'Instance not found.', success=False)
     if int(container.challenge_id) != int(challenge_id):
         abort(
             403,
             f'Container started but not from this challenge({container.challenge.name})',
             success=False)
     if container.renew_count >= docker_max_renew_count:
         abort(403, 'Max renewal count exceed.', success=False)
     result, message = ControlUtil.try_renew_container(user_id=user_id)
     return {'success': result, 'message': message}
Пример #22
0
def settings():
    infos = get_infos()
    errors = get_errors()

    user = get_current_user()
    name = user.name
    email = user.email
    website = user.website
    affiliation = user.affiliation
    country = user.country

    if is_teams_mode() and get_current_team() is None:
        team_url = url_for("teams.private")
        infos.append(
            markup(
                f'In order to participate you must either <a href="{team_url}">join or create a team</a>.'
            )
        )

    tokens = UserTokens.query.filter_by(user_id=user.id).all()

    prevent_name_change = get_config("prevent_name_change")

    if get_config("verify_emails") and not user.verified:
        confirm_url = markup(url_for("auth.confirm"))
        infos.append(
            markup(
                "Your email address isn't confirmed!<br>"
                "Please check your email to confirm your email address.<br><br>"
                f'To have the confirmation email resent please <a href="{confirm_url}">click here</a>.'
            )
        )

    return render_template(
        "settings.html",
        name=name,
        email=email,
        website=website,
        affiliation=affiliation,
        country=country,
        tokens=tokens,
        prevent_name_change=prevent_name_change,
        infos=infos,
        errors=errors,
    )
Пример #23
0
    def attempt(challenge, request):

        data = request.form or request.get_json()
        submission = data['submission'].strip()

        chal = KeyedChallenge.query.filter_by(id=challenge.id).first()

        box = nacl.secret.SecretBox(
            nacl.encoding.Base64Encoder.decode(chal.key))
        salt = nacl.encoding.Base64Encoder.decode(chal.salt)

        if len(submission) < 7:
            return False, 'Invalid format'

        if submission[:5] != 'flag(':
            return False, 'Invalid format'

        if submission[-1:] != ')':
            return False, 'Invalid format'

        submission = submission[5:-1]

        try:
            flag = nacl.encoding.Base64Encoder.decode(submission)
        except TypeError:
            return False, 'Invalid format'

        try:
            decrypted_flag = box.decrypt(flag)
        except nacl.exceptions.CryptoError:
            # Verification failed
            return False, 'Incorrect decrypt'

        user = get_current_user()
        team = get_current_team()

        user_id = user.id,
        team_id = team.id if team else None,

        stored_flag = 'U' + str(user_id) + 'T' + str(team_id) + 'F' + salt

        if decrypted_flag == stored_flag:
            return True, 'Correct'
        else:
            return False, 'Incorrect'
Пример #24
0
def view_grades():
    user_id = get_current_user().id
    if request.args.get("id") and is_admin():
        try:
            user_id = int(request.args.get("id"))
        except ValueError:
            pass

    when = request.args.get("when")
    if when:
        when = datetime.datetime.fromtimestamp(int(when))

    grades = compute_grades(user_id, when)

    for grade in grades:
        grade["grade"] = f'{grade["grade"] * 100.0:.2f}%'

    return render_template("grades.html", grades=grades)
Пример #25
0
    def validate_email(self, data):
        email = data.get('email')
        if email is None:
            return

        existing_user = Users.query.filter_by(email=email).first()
        user_id = data.get('id')

        if user_id and is_admin():
            if existing_user and existing_user.id != user_id:
                raise ValidationError('Email address has already been used', field_names=['email'])
        else:
            current_user = get_current_user()
            if email == current_user.email:
                return data
            else:
                if existing_user:
                    raise ValidationError('Email address has already been used', field_names=['email'])
Пример #26
0
    def validate_name(self, data):
        name = data.get('name')
        if name is None:
            return

        existing_user = Users.query.filter_by(name=name).first()
        user_id = data.get('id')

        if user_id and is_admin():
            if existing_user and existing_user.id != user_id:
                raise ValidationError('User name has already been taken', field_names=['name'])
        else:
            current_user = get_current_user()
            if name == current_user.name:
                return data
            else:
                if existing_user:
                    raise ValidationError('User name has already been taken', field_names=['name'])
Пример #27
0
    def post(self, challenge_id):
        if authed() is False:
            return {
                'success': True,
                'data': {
                    'status': "authentication_required",
                }
            }, 403

        user = get_current_user()
        like = Likes.checkUserLike(challenge_id)
        if like.count():
            db.session.delete(like.first())
        else:
            like = Likes(user_id=user.id, challenge_id=challenge_id)
            db.session.add(like)
        db.session.commit()
        return {'success': True}
Пример #28
0
    def validate_password_confirmation(self, data):
        password = data.get('password')
        confirm = data.get('confirm')
        target_user = get_current_user()
        user_id = data.get('id')

        if is_admin():
            pass
        else:
            if password and (confirm is None):
                raise ValidationError('Please confirm your current password', field_names=['confirm'])

            if password and confirm:
                test = verify_password(plaintext=confirm, ciphertext=target_user.password)
                if test is True:
                    return data
                else:
                    raise ValidationError('Your previous password is incorrect', field_names=['confirm'])
Пример #29
0
    def get(self):
        user = get_current_user()
        awards = user.get_awards(admin=True)

        view = "user" if not is_admin() else "admin"
        response = AwardSchema(view=view, many=True).dump(awards)

        if response.errors:
            return {"success": False, "errors": response.errors}, 400

        count = len(response.data)
        return {
            "success": True,
            "data": response.data,
            "meta": {
                "count": count
            }
        }
Пример #30
0
    def _frequency_limited(*args, **kwargs):
        if is_admin():
            return func(*args, **kwargs)
        redis_util = RedisUtils(app=current_app, user_id=get_current_user().id)
        if not redis_util.acquire_lock():
            abort(403, 'Request Too Fast!')

        if "limit" not in session:
            session["limit"] = int(time.time())
        else:
            if int(time.time()) - session["limit"] < 60:
                abort(403, 'Frequency limit, You should wait at least 1 min.')
        session["limit"] = int(time.time())

        result = func(*args, **kwargs)
        redis_util.release_lock(
        )  # if any exception is raised, lock will not be released
        return result