Пример #1
0
def test_admin_config():
    """Does admin config return a 200 by default"""
    app = create_ctfd()
    with app.app_context():
        client = login_as_user(app, name="admin", password="******")
        r = client.get('/admin/config')
        assert r.status_code == 200
Пример #2
0
def test_admin_panel():
    """Does the admin panel return a 200 by default"""
    app = create_ctfd()
    with app.app_context():
        client = login_as_user(app, name="admin", password="******")
        r = client.get('/admin')
        assert r.status_code == 302
        r = client.get('/admin/graphs')
        assert r.status_code == 200
Пример #3
0
def test_accessing_hidden_teams():
    """Hidden teams should not give any data from /teams or /api/v1/teams"""
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        register_user(app)
        register_user(app,
                      name="visible_user",
                      email="*****@*****.**")
        with login_as_user(app, name="visible_user") as client:
            user = Users.query.filter_by(id=2).first()
            team = gen_team(app.db, name="visible_team", hidden=True)
            team.members.append(user)
            user.team_id = team.id
            app.db.session.commit()

            assert client.get("/teams/1").status_code == 404
            assert client.get("/api/v1/teams/1").status_code == 404
            assert client.get("/api/v1/teams/1/solves").status_code == 404
            assert client.get("/api/v1/teams/1/fails").status_code == 404
            assert client.get("/api/v1/teams/1/awards").status_code == 404
    destroy_ctfd(app)
Пример #4
0
def test_api_user_change_verify_email():
    """Test that users are marked unconfirmed if they change their email and verify_emails is turned on"""
    app = create_ctfd()
    with app.app_context():
        set_config("verify_emails", True)
        register_user(app)
        user = Users.query.filter_by(id=2).first()
        user.verified = True
        app.db.session.commit()
        with login_as_user(app) as client:
            r = client.patch(
                "/api/v1/users/me",
                json={"email": "*****@*****.**", "confirm": "password"},
            )
            assert r.status_code == 200
            resp = r.get_json()
            assert resp["data"]["email"] == "*****@*****.**"
            assert resp["success"] is True
            user = Users.query.filter_by(id=2).first()
            assert user.verified is False
    destroy_ctfd(app)
Пример #5
0
def test_anonymous_users_view_public_challenges_without_team():
    """Test that if challenges are public, users without team can still view them"""
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        register_user(app)
        gen_challenge(app.db)
        with app.test_client() as client:
            r = client.get("/challenges")
            assert r.status_code == 302
            assert r.location.startswith("http://localhost/login")

        set_config("challenge_visibility", "public")
        with app.test_client() as client:
            r = client.get("/challenges")
            assert r.status_code == 200

        with login_as_user(app) as client:
            r = client.get("/challenges")
            assert r.status_code == 302
            assert r.location.startswith("http://localhost/team")
    destroy_ctfd(app)
Пример #6
0
def test_user_can_unlock_hint():
    """Test that a user can unlock a hint if they have enough points"""
    app = create_kmactf()
    with app.app_context():
        with app.test_client():
            register_user(app, name="user1", email="*****@*****.**")

            chal = gen_challenge(app.db, value=100)
            chal_id = chal.id

            gen_flag(app.db, challenge_id=chal.id, content="flag")

            hint = gen_hint(app.db, chal_id, cost=10)
            hint_id = hint.id

            gen_award(app.db, user_id=2, value=15)

            client = login_as_user(app, name="user1", password="******")

            user = Users.query.filter_by(name="user1").first()
            assert user.score == 15

            with client.session_transaction():
                r = client.get("/api/v1/hints/{}".format(hint_id))
                resp = r.get_json()
                assert resp["data"].get("content") is None

                params = {"target": hint_id, "type": "hints"}

                r = client.post("/api/v1/unlocks", json=params)
                resp = r.get_json()
                assert resp["success"] is True

                r = client.get("/api/v1/hints/{}".format(hint_id))
                resp = r.get_json()
                assert resp["data"].get("content") == "This is a hint"

                user = Users.query.filter_by(name="user1").first()
                assert user.score == 5
    destroy_kmactf(app)
Пример #7
0
def test_unlocking_hints_with_cost_before_ctf():
    """Test that hints are not unlocked if the CTF hasn't begun"""
    app = create_ctfd()
    with app.app_context():
        register_user(app)
        chal = gen_challenge(app.db)
        chal_id = chal.id
        gen_hint(app.db, chal_id)
        gen_award(app.db, user_id=2)

        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-1"):
            client = login_as_user(app)

            r = client.get('/api/v1/hints/1')
            assert r.status_code == 403
            assert r.get_json().get('data') is None

            r = client.post('/api/v1/unlocks',
                            json={
                                'target': 1,
                                'type': 'hints'
                            })
            assert r.status_code == 403
            assert r.get_json().get('data') is None

            r = client.get('/api/v1/hints/1')
            assert r.get_json().get('data') is None
            assert r.status_code == 403

            user = Users.query.filter_by(id=2).first()

            assert user.score == 100
            assert Unlocks.query.count() == 0
    destroy_ctfd(app)
Пример #8
0
def test_boolean_checkbox_field():
    app = create_ctfd()
    with app.app_context():
        gen_field(app.db, name="CustomField1", field_type="boolean", required=False)

        with app.test_client() as client:
            r = client.get("/register")
            resp = r.get_data(as_text=True)

            # We should have rendered a checkbox input
            assert "checkbox" in resp

            with client.session_transaction() as sess:
                data = {
                    "name": "user",
                    "email": "*****@*****.**",
                    "password": "******",
                    "nonce": sess.get("nonce"),
                    "fields[1]": "y",
                }
            client.post("/register", data=data)
            with client.session_transaction() as sess:
                assert sess["id"]

        assert UserFieldEntries.query.count() == 1
        assert UserFieldEntries.query.filter_by(id=1).first().value is True

        with login_as_user(app) as client:
            r = client.get("/settings")
            resp = r.get_data(as_text=True)
            assert "CustomField1" in resp
            assert "checkbox" in resp

            r = client.patch(
                "/api/v1/users/me", json={"fields": [{"field_id": 1, "value": False}]}
            )
            assert r.status_code == 200
            assert UserFieldEntries.query.count() == 1
            assert UserFieldEntries.query.filter_by(id=1).first().value is False
    destroy_ctfd(app)
Пример #9
0
def test_teams_join_post():
    """Can a user post /teams/join"""
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        gen_user(app.db, name="user")
        gen_team(app.db, name="team")
        with login_as_user(app) as client:
            r = client.get('/teams/join')
            assert r.status_code == 200
            with client.session_transaction() as sess:
                data = {
                    "name": "team",
                    "password": "******",
                    "nonce": sess.get('nonce')
                }
            r = client.post('/teams/join', data=data)
            assert r.status_code == 302
            incorrect_data = data
            incorrect_data['password'] = ""
            r = client.post('/teams/join', data=incorrect_data)
            assert r.status_code == 200
    destroy_ctfd(app)
Пример #10
0
def test_unlocking_hints_with_cost_during_ctf_with_points():
    """Test that hints with a cost are unlocked if you have the points"""
    app = create_kmactf()
    with app.app_context():
        register_user(app)
        chal = gen_challenge(app.db)
        chal_id = chal.id
        gen_hint(app.db, chal_id, cost=10)
        gen_award(app.db, user_id=2)

        client = login_as_user(app)
        r = client.get("/api/v1/hints/1")
        assert r.get_json()["data"].get("content") is None

        client.post("/api/v1/unlocks", json={"target": 1, "type": "hints"})

        r = client.get("/api/v1/hints/1")
        assert r.get_json()["data"].get("content") == "This is a hint"

        user = Users.query.filter_by(id=2).first()
        assert user.score == 90
    destroy_kmactf(app)
Пример #11
0
def test_api_hint_404():
    """Are admin protected resources accessible by admins/non-admins"""
    app = create_ctfd()
    endpoints = ['/api/v1/configs/{}',
                 '/api/v1/challenges/types',
                 '/api/v1/statistics/teams',
                 '/api/v1/flags/{}',
                 '/api/v1/statistics/users/{}',
                 '/api/v1/configs',
                 '/api/v1/statistics/challenges/solves/percentages',
                 '/api/v1/tags/{}',
                 '/api/v1/pages',
                 '/api/v1/files/{}',
                 '/api/v1/challenges/{}/tags',
                 '/api/v1/hints',
                 '/api/v1/challenges/{}/files',
                 '/api/v1/flags',
                 '/api/v1/submissions/{}',
                 '/api/v1/challenges/{}/flags',
                 '/api/v1/awards/{}',
                 '/api/v1/unlocks',
                 '/api/v1/challenges/{}/hints',
                 '/api/v1/statistics/submissions/{}',
                 '/api/v1/flags/types/{}',
                 '/api/v1/tags',
                 '/api/v1/statistics/challenges/{}',
                 '/api/v1/files',
                 '/api/v1/flags/types',
                 '/api/v1/submissions',
                 '/api/v1/pages/{}']

    with app.app_context():
        register_user(app)
        client = login_as_user(app)
        for endpoint in endpoints:
            r = client.get(endpoint.format(1))
            assert r.status_code == 302
            assert r.location.startswith('http://localhost/login')
    destroy_ctfd(app)
Пример #12
0
def test_api_topics_get_admin():
    """Can a user get /api/v1/topics if admin"""
    app = create_ctfd()
    with app.app_context():
        gen_challenge(app.db)
        gen_topic(app.db, challenge_id=1)
        gen_topic(app.db, challenge_id=1, value="topic2")
        with login_as_user(app, name="admin") as client:
            r = client.get("/api/v1/topics")
            assert r.status_code == 200
            assert r.get_json() == {
                "success":
                True,
                "data": [{
                    "id": 1,
                    "value": "topic"
                }, {
                    "id": 2,
                    "value": "topic2"
                }],
            }
    destroy_ctfd(app)
Пример #13
0
def test_api_topics_non_admin():
    """Can a user interact with /api/v1/topics if not admin"""
    app = create_ctfd()
    with app.app_context():
        gen_challenge(app.db)
        gen_topic(app.db, challenge_id=1)
        with app.test_client() as client:
            r = client.get("/api/v1/topics", json="")
            assert r.status_code == 403
            """Can a user post /api/v1/topics if not admin"""
            r = client.post("/api/v1/topics")
            assert r.status_code == 403
            """Can a user delete /api/v1/topics if not admin"""
            r = client.delete("/api/v1/topics")
            assert r.status_code == 403
            """Can a user get /api/v1/topics/<topic_id> if not admin"""
            r = client.get("/api/v1/topics/1", json="")
            assert r.status_code == 403
            """Can a user delete /api/v1/topics/<topic_id> if not admin"""
            r = client.delete("/api/v1/topics/1", json="")
            assert r.status_code == 403

        register_user(app)
        with login_as_user(app) as client:
            r = client.get("/api/v1/topics", json="")
            assert r.status_code == 403
            """Can a user post /api/v1/topics if not admin"""
            r = client.post("/api/v1/topics")
            assert r.status_code == 403
            """Can a user delete /api/v1/topics if not admin"""
            r = client.delete("/api/v1/topics")
            assert r.status_code == 403
            """Can a user get /api/v1/topics/<topic_id> if not admin"""
            r = client.get("/api/v1/topics/1", json="")
            assert r.status_code == 403
            """Can a user delete /api/v1/topics/<topic_id> if not admin"""
            r = client.delete("/api/v1/topics/1", json="")
            assert r.status_code == 403
    destroy_ctfd(app)
Пример #14
0
def test_challenges_cannot_be_solved_while_paused():
    """Test that challenges cannot be solved when the CTF is paused"""
    app = create_ctfd()
    with app.app_context():
        set_config('paused', True)

        register_user(app)
        client = login_as_user(app)

        r = client.get('/challenges')
        assert r.status_code == 200

        # Assert that there is a paused message
        data = r.get_data(as_text=True)
        assert 'paused' in data

        chal = gen_challenge(app.db)
        gen_flag(app.db, challenge_id=chal.id, content='flag')

        data = {
            "submission": 'flag',
            "challenge_id": chal.id
        }
        r = client.post('/api/v1/challenges/attempt', json=data)

        # Assert that the JSON message is correct
        resp = r.get_json()['data']
        assert r.status_code == 403
        assert resp['status'] == 'paused'
        assert resp['message'] == 'CTFd is paused'

        # There are no solves saved
        solves = Solves.query.count()
        assert solves == 0

        # There are no wrong keys saved
        wrong_keys = Fails.query.count()
        assert wrong_keys == 0
    destroy_ctfd(app)
Пример #15
0
def test_hidden_challenge_is_unreachable():
    """Test that hidden challenges return 404 and do not insert a solve or wrong key"""
    app = create_ctfd()
    with app.app_context():
        register_user(app)
        client = login_as_user(app)
        chal = gen_challenge(app.db, state='hidden')
        gen_flag(app.db, challenge_id=chal.id, content='flag')
        chal_id = chal.id

        assert Challenges.query.count() == 1

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

        r = client.get('/api/v1/challenges/1', json='')
        assert r.status_code == 404
        data = r.get_json().get('data')
        assert data is None

        data = {
            "submission": 'flag',
            "challenge_id": chal_id
        }

        r = client.post('/api/v1/challenges/attempt', json=data)
        assert r.status_code == 404

        r = client.post('/api/v1/challenges/attempt?preview=true', json=data)
        assert r.status_code == 404
        assert r.get_json().get('data') is None

        solves = Solves.query.count()
        assert solves == 0

        wrong_keys = Fails.query.count()
        assert wrong_keys == 0
    destroy_ctfd(app)