Ejemplo n.º 1
0
def test_export_ctf():
    """Test that CTFd can export the database"""
    app = create_ctfd()
    if not app.config.get("SQLALCHEMY_DATABASE_URI").startswith("sqlite"):
        with app.app_context():
            register_user(app)
            chal1 = gen_challenge(app.db, name=text_type("🐺"))
            gen_challenge(app.db,
                          name=text_type("🐺"),
                          requirements={"prerequisites": [1]})
            chal_id = chal1.id
            gen_hint(app.db, chal_id)

            client = login_as_user(app)
            with client.session_transaction():
                data = {"target": 1, "type": "hints"}
            r = client.post("/api/v1/unlocks", json=data)
            output = r.get_data(as_text=True)
            json.loads(output)
            app.db.session.commit()
            backup = export_ctf()

            with open("export.test_export_ctf.zip", "wb") as f:
                f.write(backup.read())

            export = zipfile.ZipFile("export.test_export_ctf.zip", "r")
            data = json.loads(export.read("db/challenges.json"))
            assert data["results"][1]["requirements"] == {"prerequisites": [1]}

            os.remove("export.test_export_ctf.zip")
    destroy_ctfd(app)
Ejemplo n.º 2
0
 def penalty(team1, team2, chal, request):
     provided_key = request.form['key'].strip()
     cp1 = CheatPenalty(teamid=team1.id, chalid=chal.id, ip=utils.get_ip(request), flag=provided_key, penalty=chal.penalty)
     cp2 = CheatPenalty(teamid=team2.id, chalid=chal.id, ip=utils.get_ip(request), flag=provided_key, penalty=chal.penalty)
     award1 = Awards(teamid=team1.id, name=text_type('Cheating Penalty for {}'.format(chal.name)), value=(-chal.penalty))
     award2 = Awards(teamid=team2.id, name=text_type('Cheating Penalty for {}'.format(chal.name)), value=(-chal.penalty))  
     db.session.add(award1)
     db.session.add(award2)
     db.session.add(cp1)
     db.session.add(cp2)
     db.session.commit()
     db.session.close()
def test_that_view_challenges_unregistered_works():
    """Test that view_challenges_unregistered works"""
    app = create_ctfd()
    with app.app_context():
        chal = gen_challenge(app.db, name=text_type("ЁЯР║"))
        chal_id = chal.id
        gen_hint(app.db, chal_id)

        client = app.test_client()
        r = client.get("/api/v1/challenges", json="")
        assert r.status_code == 403
        r = client.get("/api/v1/challenges")
        assert r.status_code == 302

        set_config("challenge_visibility", "public")

        client = app.test_client()
        r = client.get("/api/v1/challenges")
        assert r.get_json()["data"]

        r = client.get("/api/v1/challenges/1/solves")
        assert r.get_json().get("data") is not None

        data = {"submission": "not_flag", "challenge_id": chal_id}
        r = client.post("/api/v1/challenges/attempt", json=data)
        assert r.status_code == 403
        assert r.get_json().get("data").get(
            "status") == "authentication_required"
        assert r.get_json().get("data").get("message") is None
    destroy_ctfd(app)
Ejemplo n.º 4
0
    def solve(team, chal, request):
        """
        This method is used to insert Solves into the database in order to mark a challenge as solved.
        :param team: The Team object from the database
        :param chal: The Challenge object from the database
        :param request: The request the user submitted
        :return:
        """
        chal = CommunityChallengeModel.query.filter_by(id=chal.id).first()
        solve_count = Solves.query.join(Teams,
                                        Solves.teamid == Teams.id).filter(
                                            Solves.chalid == chal.id,
                                            Teams.banned == False).count()

        # if this is the first validation, we give the bonus points to the chal's owner
        if solve_count == 0:
            award = Awards(
                teamid=chal.owner,
                name=text_type(
                    'Bonus points for submitting challenge {}'.format(
                        chal.name)),
                value=chal.value)
            db.session.add(award)

        provided_key = request.form['key'].strip()
        solve = Solves(teamid=team.id,
                       chalid=chal.id,
                       ip=utils.get_ip(req=request),
                       flag=provided_key)
        db.session.add(solve)
        db.session.commit()
        db.session.close()
Ejemplo n.º 5
0
def test_that_view_challenges_unregistered_works():
    '''Test that view_challenges_unregistered works'''
    app = create_ctfd()
    with app.app_context():
        chal = gen_challenge(app.db, name=text_type('ЁЯР║'))
        chal_id = chal.id
        gen_hint(app.db, chal_id)

        client = app.test_client()
        r = client.get('/api/v1/challenges', json='')
        assert r.status_code == 403
        r = client.get('/api/v1/challenges')
        assert r.status_code == 302

        set_config('challenge_visibility', 'public')

        client = app.test_client()
        r = client.get('/api/v1/challenges')
        assert r.get_json()['data']

        r = client.get('/api/v1/challenges/1/solves')
        assert r.get_json().get('data') is not None

        data = {
            "submission": 'not_flag',
            "challenge_id": chal_id
        }
        r = client.post('/api/v1/challenges/attempt'.format(chal_id), json=data)
        assert r.status_code == 403
        assert r.get_json().get('data').get('status') == "authentication_required"
        assert r.get_json().get('data').get('message') is None
    destroy_ctfd(app)
Ejemplo n.º 6
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)
Ejemplo n.º 7
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': get_tip('NOT_ENOUGH_POINT')})
                unlock = Unlocks(model='hints',
                                 teamid=session['id'],
                                 itemid=hint.id)
                award = Awards(teamid=session['id'],
                               name=text_type(
                                   get_tip('HIT_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)
Ejemplo n.º 8
0
def test_unlocking_hint_for_unicode_challenge():
    """Test that hints for challenges with unicode names can be unlocked"""
    app = create_ctfd()
    with app.app_context():
        register_user(app)
        chal = gen_challenge(app.db, name=text_type('🐺'))
        chal_id = chal.id
        gen_hint(app.db, chal_id)

        client = login_as_user(app)

        r = client.get('/api/v1/hints/1')
        assert r.status_code == 200
        resp = r.get_json()['data']
        assert resp.get('content') == 'This is a hint'
    destroy_ctfd(app)
Ejemplo n.º 9
0
def test_export_ctf():
    """Test that CTFd can export the database"""
    app = create_ctfd()
    if not app.config.get('SQLALCHEMY_DATABASE_URI').startswith('sqlite'):
        with app.app_context():
            register_user(app)
            chal = gen_challenge(app.db, name=text_type('🐺'))
            chal_id = chal.id
            gen_hint(app.db, chal_id)

            client = login_as_user(app)
            with client.session_transaction():
                data = {"target": 1, "type": "hints"}
            r = client.post('/api/v1/unlocks', json=data)
            output = r.get_data(as_text=True)
            json.loads(output)
            app.db.session.commit()
            backup = export_ctf()

            with open('export.zip', 'wb') as f:
                f.write(backup.read())
            os.remove('export.zip')
    destroy_ctfd(app)