Exemplo n.º 1
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()
        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'
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
    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"
Exemplo n.º 4
0
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"
Exemplo n.º 5
0
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"
Exemplo n.º 6
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'
Exemplo n.º 7
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))
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
    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'