def load(app):
    app.db.create_all()
    CHALLENGE_CLASSES["manual"] = ManualGradingChallenge
    register_plugin_assets_directory(
        app, base_path="/plugins/manual-challenges/assets/")

    app.register_blueprint(manual)
def load(app):
    # upgrade()
    app.db.create_all()
    CHALLENGE_CLASSES["steam"] = SteamChallenge
    register_plugin_assets_directory(
        app, base_path="/plugins/steam_challenge/assets/"
    )

    register_user_page_menu_bar("Steam Keys", "steamkeys")
    blueprint = Blueprint(
        "steam_challenge",
        __name__,
        template_folder="templates",
        static_folder="assets"
    )
    @blueprint.route("/steamkeys", methods=["GET", "POST"])
    @require_verified_emails
    @authed_only
    def view_keys():
        user = get_current_user()
        chals = SteamChallengeModel.query.filter_by(first_solver=user.account_id).order_by(SteamChallengeModel.id.asc()).all()
        my_keys = []
        for chal in chals:
            d = SteamChallenge.read(chal)
            d["steam_key"] = chal.steam_key
            d["steam_gamename"] = chal.steam_gamename
            my_keys.append(d)

        return render_template("steamkeys.html", keys=my_keys)
    app.register_blueprint(blueprint)
def load(app):
    # upgrade()
    app.db.create_all()
    CHALLENGE_CLASSES["dynamic_wp"] = WriteupDynamicValueChallenge
    register_plugin_assets_directory(
        app, base_path="/plugins/dynamic_challenges_wp/assets/")
    app.register_blueprint(routes.writeup_blueprint)
def load(app):
    """
    Hook for CTFd to load the plugin

    :app: CTFd flask insert
    :return: None
    """
    # Basic Setup
    config = load_config()
    check_debug_mode(string_to_bool(config["debug"]))
    log.debug("Loaded config: [{}]".format(config))

    # OAuth setup
    setup_oauth(config)

    # Get plugin asset path
    base_asset_path = os.path.dirname(
        os.path.realpath(__file__)) + "/../assets/"
    register_plugin_assets_directory(app, base_path=base_asset_path)

    # DB Setup
    app.db.create_all()

    # Registration
    override_page(base_asset_path, "login.html")
    override_page(base_asset_path, "users/private.html")
    app.register_blueprint(discord_blueprint)
    log.info("Discord OAuth2 URL -> https://{}/discord/oauth_callback".format(
        config["domain"]))
예제 #5
0
def load(app):
    app.db.create_all()
    KEY_CLASSES['online'] = OnlineKey
    CHALLENGE_CLASSES['online'] = OnlineTypeChallenge
    app.register_blueprint(online)
    register_plugin_assets_directory(
        app, base_path='/plugins/CTFdOnlineChallenge/assets')
예제 #6
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')
예제 #7
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)
예제 #8
0
def load(app):
    register_plugin_assets_directory(app, base_path='/plugins/toastee/assets/')

    sio = SocketIO()  # Server-side broadcast SocketIO

    # Route for the toast feed.
    @app.route('/toasts', methods=['GET'])
    def toasts():
        with open(os.path.dirname(os.path.realpath(__file__)) + '/assets/toastee.html', 'rb') as f:
            # Hacky workaround to keep the HTML in its own file...
            TEMPLATE = f.read().decode()
            return TEMPLATE

    @app.route('/toast', methods=['GET'])
    @admins_only
    def toast():
        import random
        data = {
            "user": '******',
            "team": '',
            "chal": 'Fake Challenge',
            "pts": random.randint(0, 50)
        }
        sio.emit('solve', data, broadcast=True)
        return 'OK'

    for (k, v) in CHALLENGE_CLASSES.items():
        CHALLENGE_CLASSES[k] = WrappedChallenge(v, sio)

    sio.init_app(app, cors_allowed_origins='*')
예제 #9
0
def load(app):
    app.db.create_all()
    CHALLENGE_CLASSES["virtual_machine_challenges"] = VMChallenge
    register_plugin_assets_directory(
        app, base_path="/plugins/virtual_machine_challenges/assets/"
    )
    register_admin_plugin_menu_bar(title="Guacamole", route="/guac")

    @app.route("/vm_control/<challenge_id>")
    @authed_only
    def vm_control_start_status(challenge_id):
        challenge = VMChallengesModel.query.filter_by(id=challenge_id).first()
        return start_status_for_user(challenge,get_current_user())

    @app.route("/vm_control/<challenge_id>/end")
    @authed_only
    def vm_control_end(challenge_id):
        challenge = VMChallengesModel.query.filter_by(id=challenge_id).first()
        return end_for_user(challenge,get_current_user())

    @app.route('/guac')
    def login_to_guac():
        add_current_user_to_guac()
        return redirect('/guacamole')


    @app.route('/getusername')
    def getusername():
       return get_current_user().name
예제 #10
0
def load(app):
    CTFd_API_v1.add_namespace(cases_namespace, '/cases')

    @app.route('/submission')
    @admins_only
    def list_submission():
        return json.dumps(submission_list())

    @app.route('/submission/<sub_id>')
    @admins_only
    def get_submission(sub_id):
        username = Submissions.query.filter_by(provided=sub_id).first().user
        res = api.query_details(sub_id)['content']
        try:
            res['result'] = json.loads(res['result'])
            res['result'] = json.dumps(res['result'], indent=4)
        except:
            pass
        return render_template_string(submission_template,
                                      user=username,
                                      code=res['code'],
                                      lang=res['lang'],
                                      additional=res['result'])

    app.db.create_all()
    CHALLENGE_CLASSES["icpc_dynamic"] = DynICPCChallenge
    register_plugin_assets_directory(
        app, base_path="/plugins/CTFd_ICPC_Challenges/assets/")
예제 #11
0
def load(app):
    """load overrides for yarachallenge plugin to work properly"""
    app.db.create_all()
    register_plugin_assets_directory(
        app, base_path='/plugins/CTFd-yarachallenge/assets/')
    challenges.CHALLENGE_CLASSES["yarachallenge"] = CTFdYaraChallenge
    app.view_functions['challenges.get_chal_class'] = get_chal_class
예제 #12
0
def load(app):
    """load overrides for smart_city to work properly"""
    logger.setLevel(app.logger.getEffectiveLevel())
    app.db.create_all()
    register_plugin_assets_directory(
        app, base_path='/plugins/CTFd_SmartCity/assets')
    challenges.CHALLENGE_CLASSES['smart_city'] = SmartCity

    dir_path = os.path.dirname(os.path.realpath(__file__))
    template_path = os.path.join(dir_path, 'new-register.html')
    override_template('register.html', open(template_path).read())
    template_path = os.path.join(dir_path, 'new-admin-team.html')
    override_template('admin/teams.html', open(template_path).read())
    template_path = os.path.join(dir_path, 'new-setup.html')
    override_template('setup.html', open(template_path).read())
    template_path = os.path.join(dir_path, 'new-team.html')
    override_template('teams.html', open(template_path).read())
    template_path = os.path.join(dir_path, 'new-base.html')
    override_template('base.html', open(template_path).read())
    app.view_functions['auth.register'] = register_smart
    app.view_functions['challenges.chal'] = chal_custom
    app.view_functions['admin_teams.delete_team'] = delete_team_custom
    app.view_functions[
        'admin_teams.admin_create_team'] = admin_create_team_custom
    app.view_functions[
        'admin_teams.admin_teams_view'] = admin_teams_view_custom
    app.view_functions['views.setup'] = setup_custom
    app.view_functions['views.teams'] = teams_custom
예제 #13
0
def load(app):
    """load overrides for multianswer plugin to work properly"""
    app.db.create_all()
    register_plugin_assets_directory(app, base_path='/plugins/CTFd-multi-answer/assets/')
    challenges.CHALLENGE_CLASSES["multianswer"] = CTFdMultiAnswerChallenge
    KEY_CLASSES["wrong"] = CTFdWrongKey
    KEY_CLASSES["correct"] = CTFdCorrectKey
예제 #14
0
def load(app):
    register_script(
        'https://cdn.pubnub.com/sdk/javascript/pubnub.4.21.7.min.js')
    register_script('/plugins/pubnub/assets/pubnub.js')
    register_plugin_assets_directory(app, base_path='/plugins/pubnub/assets/')

    @app.route('/realtime', methods=['GET'])
    @during_ctf_time_only
    @check_challenge_visibility
    def get_challenge_token():
        if authed() is False:
            abort(404)

        # Does the challenge exist? If not, 404.
        challenge_id = request.values.get('challenge_id')
        Challenges.query.filter_by(id=challenge_id).first_or_404()

        team = get_current_team()

        return hmac.new(os.environ.get('SECRET'), ','.join(
            (str(challenge_id), str(team.id))), sha1).hexdigest()

    @app.route('/pn-uuid', methods=['GET'])
    def get_user_info():
        if authed() is False:
            abort(404)

        return json.dumps({
            "uuid": get_current_user().name,
            "subKey": os.environ.get('PUBNUB_SUB')
        })
예제 #15
0
def load(app):
    # upgrade()
    app.db.create_all()
    CHALLENGE_CLASSES["dynamic"] = DynamicValueChallenge
    register_plugin_assets_directory(
        app, base_path="/plugins/dynamic_challenges/assets/"
    )
예제 #16
0
def load(app):
    base_path = 'plugins/site_info/assets/'
    register_plugin_assets_directory(app, base_path=base_path)

    @app.route('/robots.txt')
    @app.route('/sitemap.xml')
    def site_info():
        return send_from_directory(base_path.strip("/"), request.path[1:])
예제 #17
0
def load(app):
    app.db.create_all()
    register_plugin_assets_directory(app, base_path=f"{PLUGIN_PATH}/assets")

    bp = load_bp(CONFIG["route"], CONFIG["base_route"], PLUGIN_PATH)
    app.register_blueprint(bp)

    print("Write-Ups plugin is ready!")
예제 #18
0
def load(app):
    app.db.create_all()
    CHALLENGE_CLASSES['naumachia'] = NaumachiaChallenge

    # Create logger
    logger.setLevel(logging.INFO)

    log_dir = app.config.get('LOG_FOLDER', path.join(path.dirname(__file__), 'logs'))
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    log_file = os.path.join(log_dir, 'naumachia.log')

    if not os.path.exists(log_file):
        open(log_file, 'a').close()

    handler = logging.handlers.RotatingFileHandler(log_file, maxBytes=10000)
    logger.addHandler(handler)
    logger.propagate = 0

    @app.route('/naumachia/config/<int:chalid>', methods=['GET'])
    def registrar(chalid):
        if user_can_get_config():
            chal = NaumachiaChallengeModel.query.filter_by(id=chalid).first_or_404()
            if chal.hidden:
                logger.info("[404] User {0} requested config for hidden challenge {1}".format(session['username'], chal.name))
                abort(404)
            
            escaped_username = quote(session['username'])
            escaped_chalname = quote(chal.naumachia_name, safe='')
            host = "{0}:{1}".format(registrar_host, registrar_port)

            try:
                resp = send_config(host, escaped_chalname, escaped_username)
                logger.info("[200] User {0} requested config for challenge {1}".format(session['username'], chal.name))
                return resp
            except HTTPError as err:
                if err.code != 404:
                    logger.info("[500] Config retrival failed for challenge {0}".format(chal.name))
                    raise

                try:
                    # The certs had not been generated yet. Generate them now
                    url = "http://{0}/{1}/add?cn={2}".format(host, escaped_chalname, escaped_username)
                    logger.debug("Requesting: {0}".format(url))
                    urlopen(url, timeout=10)

                    resp = send_config(host, escaped_chalname, escaped_username)
                    logger.info("[200] User {0} requested new config for challenge {1}".format(session['username'], chal.name))
                    return resp
                except HTTPError:
                    logger.info("[500] Config creation failed for challenge {0}".format(chal.name))
                    raise
        else:
            logger.info("[403] User {0} requested config for challenge {1}: Not authorized".format(session.get('username', '<not authed>'), chalid))
            abort(403)
    
    register_plugin_assets_directory(app, base_path='/plugins/{0}/assets/'.format(plugin_dirname))
예제 #19
0
def load(app):
    app.db.create_all()
    app.jinja_env.filters.update(ordinalize=ordinalize)
    CHALLENGE_CLASSES["firstblood"] = FirstBloodValueChallenge
    register_plugin_assets_directory(
        app, base_path="/plugins/CTFd_first_blood/assets/")
    register_stylesheet("/plugins/CTFd_first_blood/assets/award-icons.css")
    register_admin_stylesheet(
        "/plugins/CTFd_first_blood/assets/award-icons.css")
예제 #20
0
def load(app):
    # Create new locking_challenge table if necessary
    app.db.create_all()
    # Register new challenge type
    CHALLENGE_CLASSES["locking"] = CTFdLockingChallenge
    # Register plugin assets
    register_plugin_assets_directory(app, base_path='/plugins/ctfd_lockingChallenges/assets/')
    # Decorate /chals route
    app.view_functions['challenges.chals'] = chal_decorator(app.view_functions['challenges.chals'])
예제 #21
0
def load(app):
	app.db.create_all()
	CHALLENGE_CLASSES['docker'] = DockerChallengeType
	register_plugin_assets_directory(app, base_path='/plugins/docker_challenges/assets')
	define_docker_admin(app)
	define_docker_status(app)
	CTFd_API_v1.add_namespace(docker_namespace, '/docker')
	CTFd_API_v1.add_namespace(container_namespace, '/container')
	CTFd_API_v1.add_namespace(active_docker_namespace, '/docker_status')
	CTFd_API_v1.add_namespace(kill_container, '/nuke')
예제 #22
0
def load(app):
    #    def wrap_method(name, wrapper):
    #        old = app.view_functions[name]
    #        app.view_functions[name] = wrapper(old)

    app.db.create_all()

    app.register_blueprint(plugin_blueprint)
    register_plugin_assets_directory(
        app, base_path="/plugins/ctfd-time_limit-plugin/assets/")
    create_if_not_exists_time_limit()
예제 #23
0
def load(app):
    # upgrade()
    app.db.create_all()
    CHALLENGE_CLASSES['lah'] = LahChallengeClass
    register_plugin_assets_directory(app, base_path='/plugins/lah_challenges/assets/')
    global APP_REF
    APP_REF = app
    scheduler.start()
    atexit.register(lambda: scheduler.shutdown())

    app.register_blueprint(lah_print)
    register_user_page_menu_bar("Unlocking", "/unlock")
    register_plugin_script("/plugins/lah_challenges/assets/lah_challenge_injector.js")
예제 #24
0
def load(app):
    app.db.create_all()

    CHALLENGE_CLASSES["chad"] = models.CHADChallenge

    register_plugin_assets_directory(app, base_path="/plugins/STACY/assets/")

    app.register_blueprint(api.blueprint)

    with open(
            os.path.join(os.path.dirname(os.path.realpath(__file__)), 'assets',
                         'challenges.html')) as template:
        override_template('challenges.html', template.read())
예제 #25
0
def load(app):
    #https://github.com/blueimp/JavaScript-MD5/
    #https://github.com/Caligatio/jsSHA
    #https://github.com/beatgammit/base64-js/
    register_plugin_assets_directory(app,
                                     base_path='/plugins/CTFd-hasher/assets/')

    #abc - only works on modified server.
    #register_user_page_menu_bar(name='Hasher', route='/CTFd-hasher', target='_blank')
    register_user_page_menu_bar(name='Hasher', route='/CTFd-hasher')

    @app.route('/CTFd-hasher', methods=['GET'])
    def hash():
        return render_template('page.html',
                               content="""
<script src='/themes/original/static/js/vendor/jquery.min.js' type='text/javascript'></script>
<script src='/plugins/CTFd-hasher/assets/md5.min.js' type='text/javascript'></script>
<script src='/plugins/CTFd-hasher/assets/base64js.min.js' type='text/javascript'></script>
<script src='/plugins/CTFd-hasher/assets/sha.js' type='text/javascript'></script>
<h1>Hash a value</h1>
<input id='valuetohash' style='width: 80%;'></input>&nbsp;
<button id='hash'>go</button><br/><br/>
<textarea id='output' style='width: 80%;'></textarea>&nbsp;
<button id='copy' style='position:relative; top: -8px;'>copy</button>
<script>
    $(function() {
        $('#hash').click( function()
            {
                var val = $('#valuetohash').val().trim();
                //var hash = md5(val);
                var shaObj = new jsSHA('SHA-256', 'TEXT');
                shaObj.update(val);
                var hash = shaObj.getHash('B64');
                $('#output').html(hash);
            }
        );

        $('#copy').click( function()
            {
                var $temp = $('<input>');
                $('body').append($temp);
                $temp.val($('#output').text()).select();
                document.execCommand('copy');
                $temp.remove();
            }
        );
    });
</script>
""")

    utils.hasher = hash
def load(app):
    app.db.create_all()
    CHALLENGE_CLASSES['time-decay'] = TimeDecayChallenge
    register_plugin_assets_directory(app, base_path='/plugins/ctfd-time-decay-plugin/assets/')

    # Monkey patching...
    Teams.score = time_decay_score
    #app.view_functions['challenges.solves_private'] = solves_private_endpoint
    app.view_functions['challenges.solves_public'] = solves_public_endpoint
    app.view_functions['views.team'] = team_endpoint
    app.view_functions['challenges.who_solved'] = who_solved_endpoint
    app.view_functions['scoreboard.topteams'] = topteams_endpoint
    app.view_functions['scoreboard.scoreboard_view'] = scoreboard_view_endpoint
    app.view_functions['scoreboard.scores'] = scores_endpoint
예제 #27
0
def test_register_plugin_assets_directory():
    """Test that plugin asset directory registration works"""
    app = create_ctfd(setup=False)
    register_plugin_assets_directory(app, base_path='/plugins/')
    app = setup_ctfd(app)
    with app.app_context():
        with app.test_client() as client:
            r = client.get('/plugins/__init__.py')
            assert len(r.get_data(as_text=True)) > 0
            assert r.status_code == 200
            r = client.get('/plugins/challenges/__init__.py')
            assert len(r.get_data(as_text=True)) > 0
            assert r.status_code == 200
    destroy_ctfd(app)
예제 #28
0
파일: __init__.py 프로젝트: nicoti44/Ctfd
def load(app):
    #@app.route('/test', methods=['GET'])
    #def view_faq():
    #   return render_template('page.html',
    #                         content="{% extends \"challenge.html\" %}<h1>COUCOU NICOLAS VOILA UN BOUTON</h1><button id=\"fdp\">eho ami</button>")
    register_plugin_assets_directory(app, base_path="/plugins/test/static/")

    @app.route('/start-vm', methods=['POST'])
    def start_vm():
        print('eho server side')
        print('ICI FAIRE DU POWERSHELL')
        # os.system('powershell')
        # os.system('KDKdpz')
        return True
예제 #29
0
def load(app):
    app.db.create_all()
    upgrade()
    CHALLENGE_CLASSES["livefire"] = LiveFireChallenge
    register_plugin_assets_directory(
        app, base_path="/plugins/livefire_challenges/assets/")

    @app.route('/admin/revert', methods=['POST', 'GET'])
    @admins_only
    def revert_chal():
        chalid = request.values.get('id')
        try:
            challenge = LiveFireChallengeModel.query.filter_by(
                id=chalid).first()
            revert(challenge.vmname)
            challenge.lastrevert = makeDateTime()
            db.session.commit()
            return render_template('page.html',
                                   content="<h1> Revert Success <h1>")
        except Exception as e:
            return render_template('page.html',
                                   content="<h1> Revert Failed <h1><br>" +
                                   str(e))

    def revert(vmname):
        context = None
        if inputs['ignore_ssl'] and hasattr(ssl, "_create_unverified_context"):
            context = ssl._create_unverified_context()
        si = connect.Connect(inputs['vcenter_ip'],
                             443,
                             inputs['vcenter_user'],
                             inputs['vcenter_password'],
                             sslContext=context)
        atexit.register(Disconnect, si)
        content = si.RetrieveContent()
        vm_name = vmname
        vm = get_obj(content, [vim.VirtualMachine], vm_name)
        if not vm:
            raise Exception("Virtual Machine %s doesn't exists" % vm_name)
        snapshot_name = inputs['snapshot_name']
        snap_obj = get_snapshots_by_name_recursively(
            vm.snapshot.rootSnapshotList, snapshot_name)
        if len(snap_obj) == 1:
            snap_obj = snap_obj[0].snapshot
            WaitForTask(snap_obj.RevertToSnapshot_Task())
            WaitForTask(vm.PowerOn())
        else:
            raise Exception(("No snapshots found with name: %s on VM: %s" %
                             (snapshot_name, vm.name)))
        return
예제 #30
0
def load(app):
    def wrap_method(name, wrapper):
        old = app.view_functions[name]
        app.view_functions[name] = satisfies_challenge_dependencies(old)

    app.db.create_all()

    app.view_functions['challenges.chals'] = get_available_challenges
    wrap_method("challenges.chal_view", satisfies_challenge_dependencies)
    wrap_method("challenges.chal", satisfies_challenge_dependencies)
    wrap_method("challenges.hints_view", satisfies_hint_dependencies)

    app.register_blueprint(plugin_blueprint)
    register_plugin_assets_directory(app, base_path='/plugins/challenge-dependencies/assets/')