def admin_update_chal():
    challenge = Challenges.query.filter_by(
        id=request.form['id']).first_or_404()
    if challenge.hidden == True:
        chal_class = get_chal_class(challenge.type)
        chal_class.update(challenge, request)
        if not 'hidden' in request.form:
            t = datetime.datetime.fromtimestamp(
                time.time()).strftime('%c').split(' ')[3]
            broadcast(t + ": Thử thách " + request.form['category'] + " " +
                      request.form['value'] + ": " + request.form['name'] +
                      " đã được mở!")
    else:
        chal_class = get_chal_class(challenge.type)
        chal_class.update(challenge, request)
        if not 'hidden' in request.form:
            t = datetime.datetime.fromtimestamp(
                time.time()).strftime('%c').split(' ')[3]
            broadcast(t + " Thử thách " + request.form['category'] + " " +
                      request.form['value'] + ": " + request.form['name'] +
                      " đã được update")
        else:
            t = datetime.datetime.fromtimestamp(
                time.time()).strftime('%c').split(' ')[3]
            broadcast(t + ": Thử thách " + request.form['category'] + " " +
                      request.form['value'] + ": " + request.form['name'] +
                      " đã được đóng")
    return redirect(url_for('admin_challenges.admin_chals'))
Beispiel #2
0
def admin_update_chal():
    challenge = Challenges.query.filter_by(
        id=request.form['id']).first_or_404()
    chal_class = get_chal_class(challenge.type)

    old_description = challenge.description
    challenge_name = challenge.name
    chal_class.update(challenge, request)
    new_description = request.form["description"]
    if old_description != new_description and not 'hidden' in request.form:
        chal_url = url_for("challenges.challenges_view",
                           _anchor=challenge_name,
                           _external=True)
        description = ":pencil: [{0}]({1}) has been updated!\n```{2}```".format(
            challenge_name, chal_url, new_description or "No description")
        embeds = [{
            "description":
            description,
            "color":
            10553667,
            "timestamp":
            datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%SZ')
        }]
        utils.send_discord_webhook(embeds)

    return redirect(url_for('admin_challenges.admin_chals'))
Beispiel #3
0
def admin_create_chal():
    if request.method == 'POST':
        chal_type = request.form['chaltype']
        chal_class = get_chal_class(chal_type)
        chal = chal_class.create(request)

        if not chal.hidden:
            chal_url = url_for("challenges.challenges_view",
                               _anchor=chal.name,
                               _external=True)
            description = ":new: [{0}]({1}) ({2}) has been created!".format(
                chal.name, chal_url, chal.value, chal.description)
            if chal.description:
                description += "\n```{0}```".format(chal.description)
            embeds = [{
                "description":
                description,
                "color":
                10553667,
                "timestamp":
                datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%SZ')
            }]
            utils.send_discord_webhook(embeds)
        return redirect(url_for('admin_challenges.admin_chals'))
    else:
        return render_template('admin/chals/create.html')
Beispiel #4
0
def test_admin_chal_detail_returns_proper_data():
    """Test that the /admin/chals/<int:chalid> endpoint returns the proper data"""
    app = create_ctfd()
    with app.app_context():
        client = login_as_user(app, name="admin", password="******")

        chal = gen_challenge(app.db)
        chal_class = get_chal_class(chal.type)
        data = {
            'id': chal.id,
            'name': chal.name,
            'value': chal.value,
            'description': chal.description,
            'category': chal.category,
            'hidden': chal.hidden,
            'max_attempts': chal.max_attempts,
            'type': chal.type,
            'type_data': {
                'id': chal_class.id,
                'name': chal_class.name,
                'templates': chal_class.templates,
                'scripts': chal_class.scripts,
            }
        }

        assert Challenges.query.count() == 1

        r = client.get('/admin/chal/1')
        response = json.loads(r.get_data(as_text=True))

        assert data == response

    destroy_ctfd(app)
Beispiel #5
0
 def post(self):
     data = request.form or request.get_json()
     challenge_type = data["type"]
     challenge_class = get_chal_class(challenge_type)
     challenge = challenge_class.create(request)
     response = challenge_class.read(challenge)
     return {"success": True, "data": response}
Beispiel #6
0
def admin_chal_detail(chalid):
    chal = Challenges.query.filter_by(id=chalid).first_or_404()
    chal_class = get_chal_class(chal.type)

    if request.method == 'POST':
        status, message = chal_class.attempt(chal, request)
        if status:
            return jsonify({'status': 1, 'message': message})
        else:
            return jsonify({'status': 0, 'message': message})
    elif request.method == 'GET':
        obj, data = chal_class.read(chal)

        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()
        ]
        hints = []
        for hint in Hints.query.filter_by(chal=chal.id).all():
            hints.append({'id': hint.id, 'cost': hint.cost, 'hint': hint.hint})

        data['tags'] = tags
        data['files'] = files
        data['hints'] = hints

        return jsonify(data)
Beispiel #7
0
def challenges_detail(challenge_id):
    challenges = dict(
        Challenges.query.with_entities(Challenges.id, Challenges.name).all())
    challenge = Challenges.query.filter_by(id=challenge_id).first_or_404()
    solves = Solves.query.filter_by(challenge_id=challenge.id).all()
    flags = Flags.query.filter_by(challenge_id=challenge.id).all()
    challenge_class = get_chal_class(challenge.type)

    with open(
            os.path.join(app.root_path,
                         challenge_class.templates['update'].lstrip('/')),
            'rb') as update:
        tpl = update.read()
        if six.PY3 and isinstance(tpl, binary_type):
            tpl = tpl.decode('utf-8')
        update_j2 = render_template_string(tpl, challenge=challenge)

    update_script = url_for(
        'views.static_html',
        route=challenge_class.scripts['update'].lstrip('/'))
    return render_template('admin/challenges/challenge.html',
                           update_template=update_j2,
                           update_script=update_script,
                           challenge=challenge,
                           challenges=challenges,
                           solves=solves,
                           flags=flags)
Beispiel #8
0
def chal_view(chal_id):
    teamid = session.get('id')

    chal = Challenges.query.filter_by(id=chal_id).first_or_404()
    if chal.hidden:
        abort(404)
    chal_class = get_chal_class(chal.type)

    tags = [
        tag.tag
        for tag in Tags.query.add_columns('tag').filter_by(chal=chal.id).all()
    ]
    files = [
        str(f.location) for f in Files.query.filter_by(chal=chal.id).all()
    ]
    unlocked_hints = set([
        u.itemid for u in Unlocks.query.filter_by(model='hints', teamid=teamid)
    ])
    hints = []

    for hint in Hints.query.filter_by(chal=chal.id).all():
        if hint.id in unlocked_hints or utils.ctf_ended():
            hints.append({'id': hint.id, 'cost': hint.cost, 'hint': hint.hint})
        else:
            hints.append({'id': hint.id, 'cost': hint.cost})

    challenge, response = chal_class.read(challenge=chal)

    response['files'] = files
    response['tags'] = tags
    response['hints'] = hints

    db.session.close()
    return jsonify(response)
Beispiel #9
0
def chals():
    db_category = db.session.query(Challenges.category,func.count(Challenges.category)).group_by(Challenges.category).order_by(Challenges.category).all()
    if(len(db_category) > 1):
        first_category = db_category[0][0]
        db_chals = Challenges.query.filter(or_(Challenges.hidden != True, Challenges.hidden == None)).filter(Challenges.category == first_category).order_by(Challenges.value).all()
    else:
        db_chals = [];
    response = {'game': [],'category':db_category}

    for chal in db_chals:
        tags = [tag.tag for tag in Tags.query.add_columns('tag').filter_by(chal=chal.id).all()]
        chal_type = get_chal_class(chal.type)
        response['game'].append({
            'id': chal.id,
            'type': chal_type.name,
            'name': chal.name,
            'value': chal.value,
            'category': chal.category,
            'tags': tags,
            'template': chal_type.templates['modal'],
            'script': chal_type.scripts['modal'],
        })

    db.session.close()
    return jsonify(response)
Beispiel #10
0
 def get(self, level_id):
     challenges = (Challenges.query.filter(
         Challenges.level == level_id)).all()
     response = []
     tag_schema = TagSchema(view="user", many=True)
     comp_schema = CompetenceSchema(view="user", many=True)
     for challenge in challenges:
         challenge_type = get_chal_class(challenge.type)
         response.append({
             "id":
             challenge.id,
             "type":
             challenge_type.name,
             "name":
             challenge.name,
             "value":
             challenge.value,
             "category":
             challenge.category,
             "result":
             challenge.result,
             "level":
             challenge.level,
             "tags":
             tag_schema.dump(challenge.tags).data,
             "competences":
             comp_schema.dump(challenge.competences).data,
             "template":
             challenge_type.templates["view"],
             "script":
             challenge_type.scripts["view"],
         })
     db.session.close()
     return {"success": True, "data": response}
Beispiel #11
0
 def post(self):
     data = request.form or request.get_json()
     challenge_type = data['type']
     challenge_class = get_chal_class(challenge_type)
     challenge = challenge_class.create(request)
     response = challenge_class.read(challenge)
     return {'success': True, 'data': response}
Beispiel #12
0
def challenges_detail(challenge_id):
    challenges = dict(
        Challenges.query.with_entities(Challenges.id, Challenges.name).all())
    challenge = Challenges.query.filter_by(id=challenge_id).first_or_404()
    solves = (Solves.query.filter_by(challenge_id=challenge.id).order_by(
        Solves.date.asc()).all())
    flags = Flags.query.filter_by(challenge_id=challenge.id).all()

    try:
        challenge_class = get_chal_class(challenge.type)
    except KeyError:
        abort(
            500,
            f"The underlying challenge type ({challenge.type}) is not installed. This challenge can not be loaded.",
        )

    update_j2 = render_template(
        challenge_class.templates["update"].lstrip("/"), challenge=challenge)

    update_script = url_for(
        "views.static_html",
        route=challenge_class.scripts["update"].lstrip("/"))
    return render_template(
        "admin/challenges/challenge.html",
        update_template=update_j2,
        update_script=update_script,
        challenge=challenge,
        challenges=challenges,
        solves=solves,
        flags=flags,
    )
Beispiel #13
0
    def get(self):
        # This can return None (unauth) if visibility is set to public
        user = get_current_user()

        challenges = (Challenges.query.filter(
            and_(Challenges.state != "hidden",
                 Challenges.state != "locked")).order_by(
                     Challenges.value).all())

        if user:
            solve_ids = (Solves.query.with_entities(
                Solves.challenge_id).filter_by(
                    account_id=user.account_id).order_by(
                        Solves.challenge_id.asc()).all())

            if is_admin():
                pass
            else:
                if config.is_teams_mode() and get_current_team() is None:
                    abort(403)
        else:
            solve_ids = []

        response = []
        tag_schema = TagSchema(view="user", many=True)
        for challenge in challenges:
            if challenge.requirements:
                requirements = challenge.requirements.get("prerequisites", [])
                anonymize = challenge.requirements.get("anonymize")
                if compare(requirements, solve_ids):
                    pass
                else:
                    if anonymize:
                        response.append({
                            "id": challenge.id,
                            "type": "hidden",
                            "name": "???",
                            "value": 0,
                            "category": "???",
                            "tags": [],
                            "template": "",
                            "script": "",
                        })
                    # Fallthrough to continue
                    continue

            challenge_type = get_chal_class(challenge.type)
            response.append({
                "id": challenge.id,
                "type": challenge_type.name,
                "name": challenge.name,
                "value": challenge.value,
                "category": challenge.category,
                "tags": tag_schema.dump(challenge.tags).data,
                "template": challenge_type.templates["view"],
                "script": challenge_type.scripts["view"],
            })

        db.session.close()
        return {"success": True, "data": response}
Beispiel #14
0
    def get(self):
        # This can return None (unauth) if visibility is set to public
        user = get_current_user()

        challenges = Challenges.query.filter(
            and_(Challenges.state != 'hidden', Challenges.state != 'locked')
        ).order_by(Challenges.value).all()

        if user:
            solve_ids = Solves.query\
                .with_entities(Solves.challenge_id)\
                .filter_by(account_id=user.account_id)\
                .order_by(Solves.challenge_id.asc())\
                .all()
            solve_ids = set([value for value, in solve_ids])
        else:
            solve_ids = set()

        response = []
        tag_schema = TagSchema(view='user', many=True)
        for challenge in challenges:
            if challenge.requirements:
                requirements = challenge.requirements.get('prerequisites', [])
                anonymize = challenge.requirements.get('anonymize')
                prereqs = set(requirements)
                if solve_ids >= prereqs:
                    pass
                else:
                    if anonymize:
                        response.append({
                            'id': challenge.id,
                            'type': 'hidden',
                            'name': '???',
                            'value': 0,
                            'category': '???',
                            'tags': [],
                            'template': '',
                            'script': ''
                        })
                    # Fallthrough to continue
                    continue

            challenge_type = get_chal_class(challenge.type)
            response.append({
                'id': challenge.id,
                'type': challenge_type.name,
                'name': challenge.name,
                'value': challenge.value,
                'category': challenge.category,
                'tags': tag_schema.dump(challenge.tags).data,
                'template': challenge_type.templates['view'],
                'script': challenge_type.scripts['view'],
            })

        db.session.close()
        return {
            'success': True,
            'data': response
        }
def admin_chal_detail(chalid):
    if request.method == 'POST':
        pass
    elif request.method == 'GET':
        chal = Challenges.query.filter_by(id=chalid).first_or_404()
        chal_class = get_chal_class(chal.type)
        obj, data = chal_class.read(chal)
        return jsonify(data)
Beispiel #16
0
    def delete(self, challenge_id):
        challenge = Challenges.query.filter_by(id=challenge_id).first_or_404()
        chal_class = get_chal_class(challenge.type)
        chal_class.delete(challenge)

        return {
            'success': True,
        }
Beispiel #17
0
def admin_create_chal():
    if request.method == 'POST':
        chal_type = request.form['chaltype']
        chal_class = get_chal_class(chal_type)
        chal_class.create(request)
        return redirect(url_for('admin_challenges.admin_chals'))
    else:
        return render_template('admin/chals/create.html')
Beispiel #18
0
def chals_contest(contestid):
    contest = Contests.query.filter_by(id=contestid).first()

    if not utils.is_admin():
        if not utils.ctftime(contest=contest):
            if utils.view_after_ctf(contest=contest):
                pass
            else:
                return redirect(url_for('views.static_html'))
    if utils.user_can_view_challenges(contest=contest) and (
            utils.ctf_started(contest=contest) or utils.is_admin()):
        chals = Challenges.query.filter(
            and_(or_(Challenges.hidden != True, Challenges.hidden == None),
                 Challenges.contestid == contestid)).order_by(
                     Challenges.value).all()
        json = {'game': []}
        for x in chals:
            tags = [
                tag.tag for tag in Tags.query.add_columns('tag').filter_by(
                    chal=x.id).all()
            ]
            files = [
                str(f.location)
                for f in Files.query.filter_by(chal=x.id).all()
            ]
            unlocked_hints = set([
                u.itemid for u in Unlocks.query.filter_by(model='hints',
                                                          teamid=session['id'])
            ])
            hints = []
            for hint in Hints.query.filter_by(chal=x.id).all():
                if hint.id in unlocked_hints or utils.ctf_ended():
                    hints.append({
                        'id': hint.id,
                        'cost': hint.cost,
                        'hint': hint.hint
                    })
                else:
                    hints.append({'id': hint.id, 'cost': hint.cost})
            # hints = [{'id':hint.id, 'cost':hint.cost} for hint in Hints.query.filter_by(chal=x.id).all()]
            chal_type = get_chal_class(x.type)
            json['game'].append({
                'id': x.id,
                'type': chal_type.name,
                'name': x.name,
                'value': x.value,
                'description': x.description,
                'category': x.category,
                'files': files,
                'tags': tags,
                'hints': hints
            })

        db.session.close()
        return jsonify(json)
    else:
        db.session.close()
        return redirect(url_for('auth.login', next='chals'))
Beispiel #19
0
 def patch(self, challenge_id):
     challenge = Challenges.query.filter_by(id=challenge_id).first_or_404()
     challenge_class = get_chal_class(challenge.type)
     challenge = challenge_class.update(challenge, request)
     response = challenge_class.read(challenge)
     return {
         'success': True,
         'data': response
     }
Beispiel #20
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()):
        teamid = session.get('id')
        chals = Challenges.query.filter(
            or_(Challenges.hidden != True,
                Challenges.hidden == None)).order_by(Challenges.value).all()
        json = {'game': []}
        for x in chals:
            tags = [
                tag.tag for tag in Tags.query.add_columns('tag').filter_by(
                    chal=x.id).all()
            ]
            files = [
                str(f.location)
                for f in Files.query.filter_by(chal=x.id).all()
            ]
            unlocked_hints = set([
                u.itemid
                for u in Unlocks.query.filter_by(model='hints', teamid=teamid)
            ])
            hints = []
            for hint in Hints.query.filter_by(chal=x.id).all():
                if hint.id in unlocked_hints or utils.ctf_ended():
                    hints.append({
                        'id': hint.id,
                        'cost': hint.cost,
                        'hint': hint.hint
                    })
                else:
                    hints.append({'id': hint.id, 'cost': hint.cost})
            chal_type = get_chal_class(x.type)
            json['game'].append({
                'id': x.id,
                'type': chal_type.name,
                'name': x.name,
                'value': x.value,
                'description': x.description,
                'category': x.category,
                'files': files,
                'tags': tags,
                'hints': hints,
                'template': chal_type.templates['modal'],
                'script': chal_type.scripts['modal'],
            })

        db.session.close()
        return jsonify(json)
    else:
        db.session.close()
        abort(403)
    def chal_view_linearunlocked(chal_id):
        teamid = session.get('id')

        chal = Challenges.query.filter_by(id=chal_id).first_or_404()
        chal_class = get_chal_class(chal.type)

        # Get solved challenge ids
        solves = []
        if utils.is_admin():
            solves = Solves.query.filter_by(teamid=session['id']).all()
        elif utils.user_can_view_challenges():
            if utils.authed():
                solves = Solves.query\
                    .join(Teams, Solves.teamid == Teams.id)\
                    .filter(Solves.teamid == session['id'])\
                    .all()
        solve_ids = []
        for solve in solves:
            solve_ids.append(solve.chalid)

        # Return nothing if there is at least one linear unlocking requirement not solved
        lu_entries = LinearUnlockingEntry.query.filter_by(chalid=chal.id).all()
        for lu_entry in lu_entries:
            if lu_entry.requires_chalid > -1 and lu_entry.requires_chalid not in solve_ids:
                return jsonify([])

        tags = [
            tag.tag for tag in Tags.query.add_columns('tag').filter_by(
                chal=chal.id).all()
        ]
        files = [
            str(f.location) for f in Files.query.filter_by(chal=chal.id).all()
        ]
        unlocked_hints = set([
            u.itemid
            for u in Unlocks.query.filter_by(model='hints', teamid=teamid)
        ])
        hints = []

        for hint in Hints.query.filter_by(chal=chal.id).all():
            if hint.id in unlocked_hints or utils.ctf_ended():
                hints.append({
                    'id': hint.id,
                    'cost': hint.cost,
                    'hint': hint.hint
                })
            else:
                hints.append({'id': hint.id, 'cost': hint.cost})

        challenge, response = chal_class.read(challenge=chal)

        response['files'] = files
        response['tags'] = tags
        response['hints'] = hints

        db.session.close()
        return jsonify(response)
Beispiel #22
0
    def attempt_single(self, request, request_data, user, team, kpm,
                       challenge):
        challenge_id = challenge.id

        if challenge.state == "hidden":
            return False, ''

        if challenge.state == "locked":
            return False, ''

        if challenge.requirements:
            requirements = challenge.requirements.get("prerequisites", [])
            solve_ids = (Solves.query.with_entities(
                Solves.challenge_id).filter_by(
                    account_id=user.account_id).order_by(
                        Solves.challenge_id.asc()).all())
            solve_ids = set([solve_id for solve_id, in solve_ids])
            prereqs = set(requirements)
            if solve_ids >= prereqs:
                pass
            else:
                return False, ''

        chal_class = get_chal_class(challenge.type)

        solves = Solves.query.filter_by(account_id=user.account_id,
                                        challenge_id=challenge_id).first()

        # Challenge not solved yet
        if not solves:
            status, message = chal_class.attempt(challenge, request)
            if status:  # The challenge plugin says the input is right
                if ctftime() or current_user.is_admin():
                    chal_class.solve(user=user,
                                     team=team,
                                     challenge=challenge,
                                     request=request)
                    clear_standings()

                log(
                    "submissions",
                    "[{date}] {name} submitted {submission} with kpm {kpm} [CORRECT]",
                    submission=request_data["submission"].encode("utf-8"),
                    kpm=kpm,
                )
                return True, message
            else:  # The challenge plugin says the input is wrong
                if ctftime() or current_user.is_admin():
                    clear_standings()

                return False, message

        # Challenge already solved
        else:
            return False, ''
Beispiel #23
0
def test_challenges_model_access_plugin_class():
    """
    Test that the Challenges model can access its plugin class
    """
    app = create_ctfd()

    with app.app_context():
        from CTFd.plugins.challenges import get_chal_class

        chal = gen_challenge(app.db)
        assert chal.plugin_class == get_chal_class("standard")
    destroy_ctfd(app)
Beispiel #24
0
    def get(self, challenge_id):
        if is_admin():
            chal = Challenges.query.filter(Challenges.id == challenge_id).first_or_404()
        else:
            chal = Challenges.query.filter(
                Challenges.id == challenge_id, and_(Challenges.state != 'hidden', Challenges.state != 'locked')
            ).first_or_404()

        chal_class = get_chal_class(chal.type)

        tags = [
            tag['value'] for tag in TagSchema(
                "user", many=True).dump(
                chal.tags).data]
        files = [f.location for f in chal.files]

        unlocked_hints = set()
        hints = []
        if authed():
            user = get_current_user()
            unlocked_hints = set([u.target for u in HintUnlocks.query.filter_by(
                type='hints', account_id=user.account_id)])

        for hint in Hints.query.filter_by(challenge_id=chal.id).all():
            if hint.id in unlocked_hints or ctf_ended():
                hints.append({'id': hint.id, 'cost': hint.cost,
                              'content': hint.content})
            else:
                hints.append({'id': hint.id, 'cost': hint.cost})

        response = chal_class.read(challenge=chal)

        Model = get_model()

        if scores_visible() is True and accounts_visible() is True:
            solves = Solves.query\
                .join(Model, Solves.account_id == Model.id)\
                .filter(Solves.challenge_id == chal.id, Model.banned == False, Model.hidden == False)\
                .count()
            response['solves'] = solves
        else:
            response['solves'] = None

        response['files'] = files
        response['tags'] = tags
        response['hints'] = hints

        db.session.close()
        return {
            'success': True,
            'data': response
        }
Beispiel #25
0
def admin_chal_detail(chalid):
    chal = Challenges.query.filter_by(id=chalid).first_or_404()
    chal_class = get_chal_class(chal.type)

    if request.method == 'POST':
        status, message = chal_class.attempt(chal, request)
        if status:
            return jsonify({'status': 1, 'message': message})
        else:
            return jsonify({'status': 0, 'message': message})
    elif request.method == 'GET':
        obj, data = chal_class.read(chal)
        return jsonify(data)
Beispiel #26
0
def load_challenges_csv(dict_reader):
    schema = ChallengeSchema()
    errors = []

    for i, line in enumerate(dict_reader):
        # Throw away fields that we can't trust if provided
        _ = line.pop("id", None)
        _ = line.pop("requirements", None)

        flags = line.pop("flags", None)
        tags = line.pop("tags", None)
        hints = line.pop("hints", None)
        challenge_type = line.pop("type", "standard")

        # Load in custom type_data
        type_data = json.loads(line.pop("type_data", "{}") or "{}")
        line.update(type_data)

        response = schema.load(line)
        if response.errors:
            errors.append((i + 1, response.errors))
            continue

        ChallengeClass = get_chal_class(challenge_type)
        challenge = ChallengeClass.challenge_model(**line)
        db.session.add(challenge)
        db.session.commit()

        if flags:
            flags = [flag.strip() for flag in flags.split(",")]
            for flag in flags:
                f = Flags(type="static", challenge_id=challenge.id, content=flag,)
                db.session.add(f)
                db.session.commit()

        if tags:
            tags = [tag.strip() for tag in tags.split(",")]
            for tag in tags:
                t = Tags(challenge_id=challenge.id, value=tag,)
                db.session.add(t)
                db.session.commit()

        if hints:
            hints = [hint.strip() for hint in hints.split(",")]
            for hint in hints:
                h = Hints(challenge_id=challenge.id, content=hint,)
                db.session.add(h)
                db.session.commit()
    if errors:
        return errors
    return True
Beispiel #27
0
def admin_create_chal():
    if request.method == 'POST':
        chal_type = request.form['chaltype']
        chal_class = get_chal_class(chal_type)
        chal_class.create(request)
        if not 'hidden' in request.form:
            t = datetime.datetime.fromtimestamp(
                time.time()).strftime('%c').split(' ')[3]
            broadcast(t + ": Thử thách " + request.form['category'] + " " +
                      request.form['value'] + ": " + request.form['name'] +
                      " đã được mở!")
        return redirect(url_for('admin_challenges.admin_chals'))
    else:
        return render_template('admin/chals/create.html')
Beispiel #28
0
    def patch(self, challenge_id):
        data = request.get_json()

        # Load data through schema for validation but not for insertion
        schema = ChallengeSchema()
        response = schema.load(data)
        if response.errors:
            return {"success": False, "errors": response.errors}, 400

        challenge = Challenges.query.filter_by(id=challenge_id).first_or_404()
        challenge_class = get_chal_class(challenge.type)
        challenge = challenge_class.update(challenge, request)
        response = challenge_class.read(challenge)
        return {"success": True, "data": response}
Beispiel #29
0
    def post(self):
        data = request.form or request.get_json()

        # Load data through schema for validation but not for insertion
        schema = ChallengeSchema()
        response = schema.load(data)
        if response.errors:
            return {"success": False, "errors": response.errors}, 400

        challenge_type = data["type"]
        challenge_class = get_chal_class(challenge_type)
        challenge = challenge_class.create(request)
        response = challenge_class.read(challenge)
        return {"success": True, "data": response}
Beispiel #30
0
def load_challenges_csv(dict_reader):
    for line in dict_reader:
        flags = line.pop("flags", None)
        tags = line.pop("tags", None)
        hints = line.pop("hints", None)
        challenge_type = line.pop("type", "standard")

        # Load in custom type_data
        type_data = json.loads(line.pop("type_data", "{}") or "{}")
        line.update(type_data)

        ChallengeClass = get_chal_class(challenge_type)
        challenge = ChallengeClass.challenge_model(**line)
        db.session.add(challenge)
        db.session.commit()

        if flags:
            flags = [flag.strip() for flag in flags.split(",")]
            for flag in flags:
                f = Flags(
                    type="static",
                    challenge_id=challenge.id,
                    content=flag,
                )
                db.session.add(f)
                db.session.commit()

        if tags:
            tags = [tag.strip() for tag in tags.split(",")]
            for tag in tags:
                t = Tags(
                    challenge_id=challenge.id,
                    value=tag,
                )
                db.session.add(t)
                db.session.commit()

        if hints:
            hints = [hint.strip() for hint in hints.split(",")]
            for hint in hints:
                h = Hints(
                    challenge_id=challenge.id,
                    content=hint,
                )
                db.session.add(h)
                db.session.commit()
    return True
Beispiel #31
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'))
Beispiel #32
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"
        })