Ejemplo n.º 1
0
def load(app):
    print("Loading.........................")
    dir_path = os.path.dirname(os.path.realpath(__file__))
    template_path = os.path.join(dir_path, 'confirm_override.html')
    override_template('confirm.html', open(template_path).read())
    template_path = os.path.join(dir_path, 'register_override.html')
    override_template('register.html', open(template_path).read())
Ejemplo n.º 2
0
def load(app):
    dir_path = os.path.dirname(os.path.realpath(__file__))
    template_path = os.path.join(dir_path, 'assets', 'register.html')
    override_template('register.html', open(template_path).read())
    app.view_functions['auth.register'] = register
    register_plugin_assets_directory(app,
                                     base_path='/plugins/<DIR HERE>/assets/js')
Ejemplo n.º 3
0
def load(app):
    #register_plugin_assets_directory(app, base_path='/plugins/scenario_user_reports/assets/')

    dir_path = os.path.dirname(os.path.realpath(__file__))
    template_path = os.path.join(dir_path, 'custom_user.html')
    override_template('admin/users/user.html', open(template_path).read())

    app.view_functions['admin.users_detail'] = custom_users_detail
Ejemplo n.º 4
0
def test_override_template():
    """Does override_template work properly for regular themes"""
    app = create_ctfd()
    with app.app_context():
        override_template("login.html", "LOGIN OVERRIDE")
        with app.test_client() as client:
            r = client.get("/login")
            assert r.status_code == 200
            output = r.get_data(as_text=True)
            assert "LOGIN OVERRIDE" in output
    destroy_ctfd(app)
Ejemplo n.º 5
0
def test_admin_override_template():
    """Does override_template work properly for the admin panel"""
    app = create_ctfd()
    with app.app_context():
        override_template("admin/users/user.html", "ADMIN TEAM OVERRIDE")
        client = login_as_user(app, name="admin", password="******")
        r = client.get("/admin/users/1")
        assert r.status_code == 200
        output = r.get_data(as_text=True)
        assert "ADMIN TEAM OVERRIDE" in output
    destroy_ctfd(app)
Ejemplo n.º 6
0
def load(app):
    dir_path = os.path.dirname(os.path.realpath(__file__))

    db.create_all()

    register_plugin_assets_directory(
        app, base_path="/plugins/CTFd-pwn-college-plugin/assets/")

    CHALLENGE_CLASSES["docker"] = DockerChallenge

    FLAG_CLASSES["user"] = UserFlag

    ssh_key_template_path = os.path.join(dir_path, "assets", "ssh_key",
                                         "settings.html")
    override_template("settings.html", open(ssh_key_template_path).read())
    app.view_functions["views.settings"] = ssh_key_settings
    Forms.keys = {"SSHKeyForm": SSHKeyForm}

    scoreboard_template_path = os.path.join(dir_path, "assets", "scoreboard",
                                            "scoreboard.html")
    override_template("scoreboard.html", open(scoreboard_template_path).read())
    app.view_functions["scoreboard.listing"] = scoreboard_listing

    blueprint = Blueprint("pwncollege_api", __name__)
    api = Api(blueprint,
              version="v1",
              doc=current_app.config.get("SWAGGER_UI"))
    api.add_namespace(docker_namespace, "/docker")
    api.add_namespace(user_flag_namespace, "/user_flag")
    api.add_namespace(ssh_key_namespace, "/ssh_key")
    api.add_namespace(download_namespace, "/download")
    api.add_namespace(terminal_namespace, "/terminal")
    api.add_namespace(binary_ninja_namespace, "/binary_ninja")
    api.add_namespace(belts_namespace, "/belts")
    app.register_blueprint(blueprint, url_prefix="/pwncollege_api/v1")

    app.register_blueprint(download)

    app.register_blueprint(terminal)
    register_user_page_menu_bar("Terminal", "/terminal")

    app.register_blueprint(grades)
    register_user_page_menu_bar("Grades", "/grades")
    register_admin_plugin_menu_bar("Grades", "/grades/all")
Ejemplo n.º 7
0
    def view_single_rank():
        # override templates
        dir_path = os.path.dirname(os.path.realpath(__file__))
        template_path = os.path.join(dir_path, 'assets')
        template_path = os.path.join(template_path, 'scoreboard.html')
        override_template("scoreboard.html", open(template_path).read())

        # get categories
        categories = get_all_categories()

        # load scores
        standings = get_standings()

        ranks = []
        for index1, category in enumerate(categories):
            ranks.append([])
            for standing in standings:
                account_id = standing.account_id
                name = standing.name
                oauth_id = standing.oauth_id
                score = get_user_scores_for_each_category(
                    standing.account_id, categories)[index1]
                ranks[index1].append([account_id, name, oauth_id, score])
            ranks[index1] = sorted(ranks[index1],
                                   key=(lambda x: x[3]),
                                   reverse=True)

        # rank[0] account_id
        # rank[1] name
        # rank[2] oauth_id
        # rank[3] score

        return render_template("scoreboard.html",
                               categories=categories,
                               enumerate=enumerate,
                               ranks=ranks,
                               standings=standings,
                               score_frozen=config.is_scoreboard_frozen())
Ejemplo n.º 8
0
def load(app):
    # get plugin location
    dir_path = os.path.dirname(os.path.realpath(__file__))
    dir_name = os.path.basename(dir_path)

    register_plugin_assets_directory(app,
                                     base_path="/plugins/" + dir_name +
                                     "/assets/",
                                     endpoint="split_scoreboard_assets")

    # Admin Pages
    override_template(
        'split_scoreboard_attr.html',
        open(os.path.join(dir_path,
                          'assets/admin/split_scoreboard_attr.html')).read())

    # Admin Modals
    override_template(
        'admin_ss_form.html',
        open(os.path.join(dir_path,
                          'assets/admin/modals/admin_ss_form.html')).read())

    # Team settings page override
    override_template(
        'scoreboard.html',
        open(os.path.join(dir_path, 'assets/teams/scoreboard.html')).read())

    # Team Modals
    app.view_functions['scoreboard.listing'] = view_split_scoreboard

    # Blueprint used to access the static_folder directory.
    blueprint = Blueprint("split_scores",
                          __name__,
                          template_folder="templates",
                          static_folder="assets")

    api = Blueprint("split_scoreboard_api", __name__, url_prefix="/api/v1")
    Split_Scores_API_v1 = Api(api,
                              version="v1",
                              doc=app.config.get("SWAGGER_UI"))
    Split_Scores_API_v1.add_namespace(split_scores_namespace, "/split_scores")
    app.register_blueprint(api)
Ejemplo n.º 9
0
def load(app):
    dir_path = os.path.dirname(os.path.realpath(__file__))
    template_path = os.path.join(dir_path, 'reddit-signin.html')
    override_template('login.html', open(template_path).read())

    template_path = os.path.join(dir_path, 'reddit-register.html')
    override_template('register.html', open(template_path).read())

    template_path = os.path.join(dir_path, 'reddit-scoreboard.html')
    override_template('scoreboard.html', open(template_path).read())

    template_path = os.path.join(dir_path, 'reddit-scoreboard.html')
    override_template('scoreboard.html', open(template_path).read())

    template_path = os.path.join(dir_path, 'reddit-users.html')
    override_template('users.html', open(template_path).read())

    template_path = os.path.join(dir_path, 'reddit-public.html')
    override_template('public.html', open(template_path).read())

    @app.route("/reddit")
    def reddit_login():
        endpoint = (get_app_config("REDDIT_AUTHORIZATION_ENDPOINT")
                    or get_config("reddit_authorization_endpoint")
                    or "https://ssl.reddit.com/api/v1/authorize")

        client_id = get_app_config("REDDIT_CLIENT_ID") or get_config(
            "reddit_client_id")
        callback_url = get_app_config("REDDIT_CALLBACK_URL") or get_config(
            "reddit_callback_url")

        if client_id is None:
            error_for(
                endpoint="reddit.login",
                message="Reddit OAuth Settings not configured. "
                "Ask your CTF administrator to configure Reddit integration.",
            )
            return redirect(url_for("auth.login"))

        redirect_url = "{endpoint}?client_id={client_id}&response_type=code&state={state}&redirect_uri={callback_url}&duration=temporary&scope=identity".format(
            endpoint=endpoint,
            client_id=client_id,
            state=session["nonce"],
            callback_url=callback_url)
        return redirect(redirect_url)

    @app.route("/reddit/callback", methods=["GET"])
    @ratelimit(method="GET", limit=10, interval=60)
    def oauth_redirect():
        oauth_code = request.args.get("code")
        state = request.args.get("state")
        if session["nonce"] != state:
            log("logins", "[{date}] {ip} - OAuth State validation mismatch")
            error_for(endpoint="auth.login",
                      message="OAuth State validation mismatch.")
            return redirect(url_for("auth.login"))

        if oauth_code:
            url = (get_app_config("REDDIT_TOKEN_ENDPOINT")
                   or get_config("reddit_token_endpoint")
                   or "https://ssl.reddit.com/api/v1/access_token")

            client_id = get_app_config("REDDIT_CLIENT_ID") or get_config(
                "reddit_client_id")
            client_secret = get_app_config(
                "REDDIT_CLIENT_SECRET") or get_config("reddit_client_secret")
            reddit_user_agent = get_app_config(
                "REDDIT_USER_AGENT") or get_config("reddit_user_agent")
            callback_url = get_app_config("REDDIT_CALLBACK_URL") or get_config(
                "reddit_callback_url")
            client_auth = requests.auth.HTTPBasicAuth(client_id, client_secret)

            headers = {
                "content-type": "application/x-www-form-urlencoded",
                "User-Agent": reddit_user_agent
            }

            token_request = requests.post(url,
                                          auth=client_auth,
                                          data={
                                              "grant_type":
                                              "authorization_code",
                                              "code": oauth_code,
                                              "redirect_uri": callback_url
                                          },
                                          headers=headers)

            if token_request.status_code == requests.codes.ok:
                token = token_request.json()["access_token"]
                user_url = (get_app_config("REDDIT_API_ENDPOINT")
                            or get_config("reddit_api_endpoint")
                            or "https://oauth.reddit.com/api/v1/me")

                headers = {
                    "Authorization": "Bearer " + str(token),
                    "User-Agent": reddit_user_agent
                }
                api_response = requests.get(url=user_url, headers=headers)
                log("logins", str(api_response))
                api_data = api_response.json()

                user_id = api_data["id"]
                user_name = api_data["name"]
                user_email = api_data["name"] + "@reddit.com"

                user = Users.query.filter_by(name=user_name).first()
                if user is None:
                    # Check if we are allowing registration before creating users
                    if registration_visible():
                        user = Users(
                            name=user_name,
                            email=user_email,
                            oauth_id=user_id,
                            verified=True,
                        )
                        db.session.add(user)
                        db.session.commit()
                    else:
                        log(
                            "logins",
                            "[{date}] {ip} - Public registration via Reddit blocked"
                        )
                        error_for(
                            endpoint="auth.login",
                            message=
                            "Public registration is disabled. Please try again later.",
                        )
                        return redirect(url_for("auth.login"))

                if get_config("user_mode") == TEAMS_MODE:
                    team_id = api_data["team"]["id"]
                    team_name = api_data["team"]["name"]

                    team = Teams.query.filter_by(oauth_id=team_id).first()
                    if team is None:
                        team = Teams(name=team_name,
                                     oauth_id=team_id,
                                     captain_id=user.id)
                        db.session.add(team)
                        db.session.commit()

                    team_size_limit = get_config("team_size", default=0)
                    if team_size_limit and len(
                            team.members) >= team_size_limit:
                        plural = "" if team_size_limit == 1 else "s"
                        size_error = "Teams are limited to {limit} member{plural}.".format(
                            limit=team_size_limit, plural=plural)
                        error_for(endpoint="auth.login", message=size_error)
                        return redirect(url_for("auth.login"))

                    team.members.append(user)
                    db.session.commit()

                if user.oauth_id is None:
                    user.oauth_id = user_id
                    user.verified = True
                    db.session.commit()

                login_user(user)

                return redirect(url_for("challenges.listing"))
            else:
                log("logins", "[{date}] {ip} - OAuth token retrieval failure")
                log("logins", str(token_request))
                log("logins", str(token_request.status_code))
                log("logins", token_request.json()["access_token"])
                error_for(endpoint="auth.login",
                          message="OAuth token retrieval failure.")
                return redirect(url_for("auth.login"))
        else:
            log("logins",
                "[{date}] {ip} - Received redirect without OAuth code")
            error_for(endpoint="auth.login",
                      message="Received redirect without OAuth code.")
            return redirect(url_for("auth.login"))
Ejemplo n.º 10
0
def load(app):
    app.db.create_all()
    ldap = Blueprint('ldap', __name__, )

    # Change these settings to correspond to your ldap server
    settings = {
        "name": "ldap server",
        "host": "example.com",
        "port": 389,
        "encryption": "none",
        "base_dn": "dc=example,dc=com",
        "type_dn": "ou=people",
        "request": "(uid={})",
        "prefix": ""
    }

    # Replaces template files
    dir_path = os.path.dirname(os.path.realpath(__file__))
    template_path = os.path.join(dir_path, 'modified_templates/login.html')
    override_template('login.html', open(template_path).read())
    template_path = os.path.join(dir_path, 'modified_templates/settings.html')
    override_template('settings.html', open(template_path).read())
    template_path = os.path.join(dir_path, 'modified_templates/base.html')
    override_template('base.html', open(template_path).read())

    def login():
        errors = get_errors()
        if request.method == "POST":
            login_info = {
                'username': request.form["name"],
                'password': request.form["password"]
            }

            # Check if the user submitted an email address or username
            if validators.validate_email(login_info['username']) is True:
                user = Users.query.filter_by(email=login_info['username']).first()
                # If this is the first time logging inn you need to use your username
                errors.append("Use your username instead of email for first login")
            else:
                user = Users.query.filter_by(name=login_info['username']).first()

            # Ldap credentials prep
            login = login_info["username"].strip().lower()
            login_dn = 'uid=' + login + ',' + settings['type_dn'] + ',' + settings['base_dn']
            password = login_info["password"]

            if password.rstrip() == "":
                errors.append("Empty passwordfield")
                db.session.close()
                return render_template("login.html", errors=errors)

            try:
                # Connect to the ldap
                print("connection to ldap")
                server = ldap3.Server(settings['host'], port=settings['port'], use_ssl=settings["encryption"] == 'ssl', get_info=ldap3.ALL)
                conn = ldap3.Connection(server, user=login_dn, password=password, auto_bind='NONE', version=3, authentication='SIMPLE', client_strategy='SYNC', auto_referrals=True, check_names=True, read_only=False, lazy=False, raise_exceptions=False)
                # Start tls for confidentiality
                conn.start_tls()
                # Check authenticity of credentials
                if not conn.bind():
                    # I'll leave this print for troubleshooting with login. Tip: if login isn't working check 'type_dn' in settings. I assume all people are registered as 'ou=people' in the system
                    # print("ERROR ", conn.result)
                    errors.append("Your username or password is incorrect")
                    log("logins", "[{date}] {ip} - submitted invalid password for {name}")
                    db.session.close()
                    return render_template("login.html", errors=errors)
                print("Connected")
            except Exception as e:
                errors.append("Can't initialze connection to " + settings['host'] + ': ' + str(e))
                db.session.close()
                return render_template("login.html", errors=errors)

            # If we have gotten to this point it means that the user credentials matched an entry in ldap

            # Check if user has logged inn before
            if user:
                session.regenerate()

                login_user(user)
                log("logins", "[{date}] {ip} - {name} logged in")

                db.session.close()
                if request.args.get("next") and validators.is_safe_url(request.args.get("next")):
                    return redirect(request.args.get("next"))
                return redirect(url_for("challenges.listing"))
            else:
                # Register the user in our system
                # First we get email from ldap
                try:
                    ldap_request = settings["request"].format(login)
                    conn.search(settings["base_dn"], ldap_request, attributes=["cn", "mail"])
                    response = conn.response
                except Exception as ex:
                    errors.append("Can't get user data : " + str(ex))
                    conn.unbind()
                    db.session.close()
                    return render_template("login.html", errors=errors)
                try:
                    # In some systems users have multiple entries on the same username, we search for one that has an email attribute.
                    for entry in response:
                        if entry["attributes"]["mail"] != []:
                            email = entry["attributes"]["mail"][0]
                            break
                    conn.unbind()
                except KeyError as e:
                    errors.append("Can't get field " + str(e) + " from your LDAP server")
                    db.session.close()
                    return render_template("login.html", errors=errors)
                except Exception as e:
                    errors.append("Can't get some user fields", e)
                    db.session.close()
                    return render_template("login.html", errors=errors)

                # Add the new user to the DB
                with app.app_context():
                    # We create a random password, this won't be used and is simply here because it is required in CTFd
                    # It is random so the account cannot be accessed by conventional loggin
                    dummy_password = randomString(28)
                    user = Users(name=login, email=email, password=dummy_password)
                    db.session.add(user)
                    db.session.commit()
                    db.session.flush()

                    login_user(user)

                log("registrations", "[{date}] {ip} - {name} registered with {email}")
                db.session.close()

                if is_teams_mode():
                    return redirect(url_for("teams.private"))
                return redirect(url_for("challenges.listing"))
        else:
            db.session.close()
            return render_template("login.html", errors=errors)

    def randomString(stringLength=28):
        letters = string.ascii_lowercase
        return ''.join(random.choice(letters) for i in range(stringLength))

    # Removes registration of regular accounts
    def register_overwrite():
        return redirect('/404')
    app.view_functions['auth.register'] = register_overwrite

    # Removes oauth login
    def oauth_overwrite():
        return redirect('/404')
    app.view_functions['auth.oauth'] = oauth_overwrite
    
    app.view_functions['auth.login'] = login
    app.register_blueprint(ldap)
Ejemplo n.º 11
0
def load(app):
	app.db.create_all()
	# get plugin location
	dir_path = os.path.dirname(os.path.realpath(__file__))
	register_plugin_assets_directory(app, base_path="/plugins/CTFd_Team_Attributes/assets/")

	# Admin Pages 
	override_template('view_attributes.html', open(os.path.join(dir_path, 'assets/admin/view_attributes.html')).read())
	override_template('create_attribute.html', open(os.path.join(dir_path, 'assets/admin/create_attribute.html')).read())
	override_template('attribute_details.html', open(os.path.join(dir_path, 'assets/admin/attribute_details.html')).read())
	override_template('set_team_attribute.html', open(os.path.join(dir_path, 'assets/admin/set_team_attribute.html')).read())
	override_template('view_attribute_select_options.html', open(os.path.join(dir_path, 'assets/admin/view_attribute_select_options.html')).read())
	override_template('create_attribute_select_option.html', open(os.path.join(dir_path, 'assets/admin/create_attribute_select_option.html')).read())
	override_template('edit_attribute_select_option.html', open(os.path.join(dir_path, 'assets/admin/edit_attribute_select_option.html')).read())

	# Admin Modals
	override_template('attribute_form.html', open(os.path.join(dir_path, 'assets/admin/modals/attribute_form.html')).read())
	override_template('team_attribute.html', open(os.path.join(dir_path, 'assets/admin/modals/team_attribute.html')).read())
	override_template('attribute_select_option_form.html', open(os.path.join(dir_path, 'assets/admin/modals/attribute_select_option_form.html')).read())


	# Team settings page override
	register_script("/plugins/CTFd_Team_Attributes/assets/teams/js/team_attr.min.js")

	# Blueprint used to access the static_folder directory.
	blueprint = Blueprint(
		"attributes", __name__, template_folder="templates", static_folder="assets"
	)

	api = Blueprint("attributes_api", __name__, url_prefix="/api/v1")
	Attributes_API_v1 = Api(api, version="v1", doc=app.config.get("SWAGGER_UI"))
	Attributes_API_v1.add_namespace(attributes_namespace, "/attributes")
	app.register_blueprint(api)