def attempt(chal, request): """ This method is used to check whether a given input is right or wrong. It does not make any changes and should return a boolean for correctness and a string to be shown to the user. It is also in charge of parsing the user's input from the request itself. :param chal: The Challenge object from the database :param request: The request the user submitted :return: (boolean, string) """ provided_key = request.form['key'].strip() chal_keys = Keys.query.filter_by(chal=chal.id).all() for chal_key in chal_keys: if get_key_class(chal_key.type).compare(chal_key.flag, provided_key): if chal_key.type == "correct": solves = Awards.query.filter_by(teamid=session['id'], name=chal.id, description=request.form['key'].strip()).first() try: flag_value = solves.description except AttributeError: flag_value = "" # Challenge not solved yet if provided_key != flag_value or not solves: solve = Awards(teamid=session['id'], name=chal.id, value=chal.value) solve.description = provided_key db.session.add(solve) db.session.commit() db.session.close() return True, 'Correct' # TODO Add description function call to the end of "Correct" in return elif chal_key.type == "wrong": solves = Awards.query.filter_by(teamid=session['id'], name=chal.id, description=request.form['key'].strip()).first() try: flag_value = solves.description except AttributeError: flag_value = "" # Challenge not solved yet if provided_key != flag_value or not solves: wrong_value = 0 wrong_value -= chal.value wrong = WrongKeys(teamid=session['id'], chalid=chal.id, ip=utils.get_ip(request), flag=provided_key) solve = Awards(teamid=session['id'], name=chal.id, value=wrong_value) solve.description = provided_key db.session.add(wrong) db.session.add(solve) db.session.commit() db.session.close() return False, 'Error' # TODO Add description function call to the end of "Error" in return return False, 'Incorrect'
def poll_kings(): """ Iterate over each of the hash-cracking challenges and give hold points to each king when the hold counter is zero """ global hash_crack_king_timers # TODO have a settings page where this can be manually paused and restarted in case it misbehaves # TODO On the settings page also show the status of this thread (I.E. Running/stopped) and who is king of every hill with db.app.app_context(): if not utils.dates.ctf_paused() and not utils.dates.ctf_ended(): chals = Challenges.query.filter_by(type="hash_crack_king").all() for c in chals: chal_name = c.name chal_id = c.id chal_king = c.king chal_hold = c.hold chal_cycles = c.cycles assert isinstance(c, HashCrackKingChallenge) if chal_king is None: logger.debug("There is no king for '{}'".format(chal_name)) # If the game is restarted then reset the king to "None" elif not Awards.query.filter_by(teamid=chal_king, name=chal_id).first(): logger.debug("Resetting the '{}' king".format(chal_name)) c.king = None db.session.commit() elif hash_crack_king_timers.get(chal_id, None) is None: logger.debug("Initializing '{}' timer".format(chal_name)) hash_crack_king_timers[chal_id] = 0 else: assert isinstance(chal_king, int) if hash_crack_king_timers[chal_id] < chal_cycles: logger.debug( "Incrementing '{}' timer'".format(chal_name)) hash_crack_king_timers[chal_id] += 1 if hash_crack_king_timers[chal_id] == chal_cycles: # Reset Timer logger.debug("Resetting '{}' timer".format(chal_name)) hash_crack_king_timers[chal_id] = 0 # Timer has maxed out, give points to the king logger.debug( "Giving points to team '{}' for being king of '{}'." .format(_team_name(chal_king), chal_name)) solve = Awards(teamid=chal_king, name=chal_id, value=chal_hold) solve.description = "Team '{}' is king of '{}'".format( _team_name(chal_king), chal_name) db.session.add(solve) db.session.commit() # db.session.expunge_all() logger.debug("'{}' timer is at '{}'".format( chal_name, hash_crack_king_timers.get(chal_id, 0))) else: logger.debug("Game is paused") # Save the current state of the timers in a pickle file with open(hash_crack_king_timers_pickle, 'wb+') as PICKLE: dump(hash_crack_king_timers, PICKLE, protocol=2)
def attempt(chal, request): """Attempt the user answer to see if it's right""" provided_key = request.form['key'].strip() chal_keys = Keys.query.filter_by(chal=chal.id).all() yara_results = yara_rule_tester(provided_key) result_type = {} for result in yara_results: solves = Awards.query.filter_by( teamid=session['id'], name=chal.id, description=result.strip()).first() try: flag_value = str(solves.description) except AttributeError: flag_value = "" if result != flag_value and not solves: for chal_key in chal_keys: if result == chal_key.flag: result_type[result] = chal_key.type # Challenge not solved yet if result_type[result] == "correct": solve = Awards(teamid=session['id'], name=chal.id, value=chal.value) solve.description = result db.session.add(solve) db.session.commit() elif result_type[result] == "wrong": wrong_value = 0 wrong_value -= chal.value wrong = WrongKeys(teamid=session['id'], chalid=chal.id, ip=utils.get_ip(request), flag=result) solve = Awards(teamid=session['id'], name=chal.id, value=wrong_value) solve.description = result db.session.add(wrong) db.session.add(solve) db.session.commit() db.session.close() return False, "Nothing"
def create_award(): try: teamid = request.form['teamid'] name = request.form.get('name', 'Award') value = request.form.get('value', 0) award = Awards(teamid, name, value) award.description = request.form.get('description') award.category = request.form.get('category') db.session.add(award) db.session.commit() return "1" except Exception as e: print e return "0"
def create_award(): try: studentid = request.form['studentid'] name = request.form.get('name', 'Award') value = request.form.get('value', 0) award = Awards(studentid, name, value) award.description = request.form.get('description') award.category = request.form.get('category') db.session.add(award) db.session.commit() db.session.close() return '1' except Exception as e: print(e) return '0'
def attempt(chal, request): """ This method is used to check whether a given input is right or wrong. It does not make any changes and should return a boolean for correctness and a string to be shown to the user. It is also in charge of parsing the user's input from the request itself. :param chal: The Challenge object from the database :param request: The request the user submitted :return: (boolean, string) """ provided_key = request.form['key'].strip() # Compare our hash with the hash of their provided key if chal.current_hash == get_hash(provided_key): # TODO? add the key to a publicly available list of previous keys/solves # TODO? allow [REGEX] to be replaced in a hint by the current key creation rules solves = Awards.query.filter_by( teamid=session['id'], name=chal.id, description=request.form['key'].strip()).first() chal.king = session['id'] king_name = _team_name(chal.king) # TODO check if it is time to advance to the next difficulty level/regex key = generate_key(chal.regex, chal.id) logger.debug("Generated key '{}' for challenge '{}'".format( key, chal.name)) chal.current_hash = get_hash(key) # Challenge not solved yet, give the team first capture points if not solves: solve = Awards(teamid=session['id'], name=chal.id, value=chal.value) solve.description = provided_key db.session.add(solve) logger.debug( 'First capture, {} points awarded. "{}" will receive {} points every {} minutes"' .format(chal.value, king_name, chal.hold, chal.cycles)) logger.debug( 'Another capture, "{}" is now King of the hill and will receive {} points every {} minutes' .format(king_name, chal.hold, chal.cycles)) db.session.commit() db.session.close() return True, 'Correct, "{}" is now king of the hill!'.format( king_name) db.session.close() return False, 'Incorrect, "{}" remains the king'.format( _team_name(chal.king))
def add(self, chal_key): """ Adds an award, corresponding to the chal_key in parameters. Does not check if an award for this chal_key and this team has already been given. It has to be done before. :chal_key: an object returned by a query on the Keys Model. :return: award_score. The points associated to the interm-award. (Can be negative). """ # REC FUTURE : check if the key in param is a key of the challenge. key_infos = json.loads(chal_key.data) award_score = key_infos['award'] award_name = 'plugin_intermflag_%s_%s' % (self.chal_id, chal_key.id) award = Awards(teamid=self.team_id, name=award_name, value=award_score) award.description = "Plug-in intermediate flag. TODO fill that later." db.session.add(award) db.session.commit() return award_score
def attempt(cls, chal, request): """ This method is used to check whether a given input is right or wrong. It does not make any changes and should return a boolean for correctness and a string to be shown to the user. It is also in charge of parsing the user's input from the request itself. :param chal: The Challenge object from the database :param request: The request the user submitted :return: (boolean, string) """ data = request.form or request.get_json() submission = data["submission"].strip() flags = Flags.query.filter_by(challenge_id=challenge.id).all() for flag in flags: try: if get_flag_class(flag.type).compare(flag, submission): if flag.type == "correct": solves = Awards.query.filter_by( teamid=session['id'], name=chal.id, description=submission).first() try: flag_value = solves.description except AttributeError: flag_value = "" # Challenge not solved yet if submission != flag_value or not solves: solve = Awards(teamid=session['id'], name=chal.id, value=chal.value) solve.description = submission db.session.add(solve) db.session.commit() db.session.close() return True, 'Correct' # TODO Add description function call to the end of "Correct" in return elif flag.type == "wrong": solves = Awards.query.filter_by( teamid=session['id'], name=chal.id, description=submission).first() try: flag_value = solves.description except AttributeError: flag_value = "" # Challenge not solved yet if submission != flag_value or not solves: fail_value = 0 fail_value -= chal.value fail = Fails(teamid=session['id'], chalid=chal.id, ip=utils.get_ip(request), flag=submission) solve = Awards(teamid=session['id'], name=chal.id, value=fail_value) solve.description = submission db.session.add(fail) db.session.add(solve) db.session.commit() db.session.close() return False, 'Error' # TODO Add description function call to the end of "Error" in return except FlagException as e: return False, e.message return False, 'Incorrect'