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"]))
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')
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')
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)
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='*')
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
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/")
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
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
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
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') })
def load(app): # upgrade() app.db.create_all() CHALLENGE_CLASSES["dynamic"] = DynamicValueChallenge register_plugin_assets_directory( app, base_path="/plugins/dynamic_challenges/assets/" )
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:])
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!")
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))
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")
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'])
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')
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()
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")
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())
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> <button id='hash'>go</button><br/><br/> <textarea id='output' style='width: 80%;'></textarea> <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
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)
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
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
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/')