Exemple #1
0
    def post(self, request):
        if not config.get('enable_flag_submission') or \
                (not config.get('enable_flag_submission_after_competition') and time.time() > config.get('end_time')):
            return FormattedResponse(m='flag_submission_disabled',
                                     status=HTTP_403_FORBIDDEN)
        team = Team.objects.get(id=request.user.team.id)
        user = get_user_model().objects.get(id=request.user.id)
        flag = request.data.get('flag')
        challenge_id = request.data.get('challenge')
        if not flag or not challenge_id:
            return FormattedResponse(status=HTTP_400_BAD_REQUEST)

        challenge = get_object_or_404(Challenge.objects.select_for_update(),
                                      id=challenge_id)
        solve_set = Solve.objects.filter(challenge=challenge)
        if not solve_set.filter(team=team, correct=True).exists():
            return FormattedResponse(m='havent_solved_challenge',
                                     status=HTTP_403_FORBIDDEN)

        plugin = plugins.plugins['flag'][challenge.flag_type](challenge)

        if not plugin.check(flag, user=user, team=team):
            return FormattedResponse(d={'correct': False}, m='incorrect_flag')

        ret = {'correct': True}
        if challenge.post_score_explanation:
            ret["explanation"] = challenge.post_score_explanation
        return FormattedResponse(d=ret, m='correct_flag')
Exemple #2
0
 def post(self, request):
     if not config.get('enable_team_join'):
         return FormattedResponse(m='join_disabled',
                                  status=HTTP_403_FORBIDDEN)
     name = request.data.get('name')
     password = request.data.get('password')
     team_join_attempt.send(sender=self.__class__,
                            user=request.user,
                            name=name)
     if name and password:
         try:
             team = get_object_or_404(Team, name=name, password=password)
         except Http404:
             team_join_reject.send(sender=self.__class__,
                                   user=request.user,
                                   name=name)
             raise Http404
         team_size = config.get('team_size')
         if team_size > 0 and team.members.count() >= config.get(
                 'team_size'):
             return FormattedResponse(m='team_full',
                                      status=HTTP_403_FORBIDDEN)
         request.user.team = team
         request.user.save()
         team_join.send(sender=self.__class__, user=request.user, team=team)
         return FormattedResponse()
     return FormattedResponse(m='joined_team', status=HTTP_400_BAD_REQUEST)
Exemple #3
0
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data,
                                           context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        if user is None:
            return FormattedResponse(status=HTTP_401_UNAUTHORIZED,
                                     d={'reason': 'login_failed'},
                                     m='login_failed')

        if not user.has_2fa():
            return FormattedResponse(status=HTTP_401_UNAUTHORIZED,
                                     d={'reason': '2fa_not_enabled'},
                                     m='2fa_not_enabled')

        token = serializer.data['tfa']

        if len(token) == 6:
            if user.totp_device is not None and user.totp_device.validate_token(
                    token):
                return self.issue_token(user)
        elif len(token) == 8:
            for code in user.backup_codes:
                if token == code.code:
                    code.delete()
                    return self.issue_token(user)

        return self.issue_token(user)
Exemple #4
0
 def post(self, request):
     serializer = UseHintSerializer(data=request.data)
     serializer.is_valid(raise_exception=True)
     hint_id = serializer.validated_data["id"]
     hint = get_object_or_404(Hint, id=hint_id)
     if not hint.challenge.is_unlocked(request.user):
         return FormattedResponse(m="challenge_not_unlocked",
                                  s=False,
                                  status=HTTP_403_FORBIDDEN)
     if HintUse.objects.filter(hint=hint, team=request.user.team).exists():
         return FormattedResponse(m="hint_already_used",
                                  s=False,
                                  status=HTTP_403_FORBIDDEN)
     use_hint.send(sender=self.__class__,
                   user=request.user,
                   team=request.user.team,
                   hint=hint)
     HintUse(
         hint=hint,
         team=request.user.team,
         user=request.user,
         challenge=hint.challenge,
     ).save()
     serializer = FullHintSerializer(hint, context={"request": request})
     return FormattedResponse(d=serializer.data)
Exemple #5
0
 def post(self, request):
     if not config.get('enable_team_leave'):
         return FormattedResponse(m='leave_disabled', status=HTTP_403_FORBIDDEN)
     if Solve.objects.filter(solved_by=request.user).exists():
         return FormattedResponse(m='challenge_solved', status=HTTP_403_FORBIDDEN)
     request.user.team = None
     request.user.save()
     return FormattedResponse()
Exemple #6
0
 def patch(self, request, name):
     if "value" not in request.data:
         return FormattedResponse(status=HTTP_400_BAD_REQUEST)
     if config.get(name) is not None and isinstance(config.get(name), list):
         config.set("name", config.get(name).append(request.data["value"]))
         return FormattedResponse()
     config.set(name, request.data.get("value"))
     return FormattedResponse()
Exemple #7
0
 def get(self, request, name=None):
     if name is None:
         if request.user.is_superuser:
             return FormattedResponse(config.get_all())
         return FormattedResponse(config.get_all_non_sensitive())
     if not config.is_sensitive(name) or request.is_superuser:
         return FormattedResponse(config.get(name))
     return FormattedResponse(status=HTTP_403_FORBIDDEN)
Exemple #8
0
 def get(self, request):
     challenge = get_object_or_404(Challenge,
                                   id=request.data.get("challenge"))
     feedback = ChallengeFeedback.objects.filter(challenge=challenge)
     if request.user.is_staff:
         return FormattedResponse(
             ChallengeFeedbackSerializer(feedback, many=True).data)
     return FormattedResponse(
         ChallengeFeedbackSerializer(
             feedback.filter(user=request.user).first()).data)
Exemple #9
0
 def post(self, request):
     if request.user.totp_device is not None and request.user.totp_device.validate_token(
             request.data["otp"]):
         request.user.totp_device.verified = True
         request.user.totp_device.save()
         backup_codes = BackupCode.generate(request.user)
         verify_2fa.send(sender=self.__class__, user=request.user)
         return FormattedResponse({
             "valid": True,
             "backup_codes": backup_codes
         })
     return FormattedResponse({"valid": False})
Exemple #10
0
def full(request):
    challenge_data = {}
    for challenge in Challenge.objects.all():
        challenge_data[challenge.id] = {}
        challenge_data[challenge.id]["correct"] = challenge.solves.filter(
            correct=True).count()
        challenge_data[challenge.id]["incorrect"] = challenge.solves.filter(
            correct=False).count()

    point_distribution = {}
    for team in Team.objects.all():
        if not point_distribution.get(team.points):
            point_distribution[team.points] = 0
        point_distribution[team.points] += 1

    return FormattedResponse({
        "users": {
            "all":
            get_user_model().objects.count(),
            "confirmed":
            get_user_model().objects.filter(email_verified=True).count()
        },
        "teams":
        Team.objects.count(),
        "ips":
        UserIP.objects.count(),
        "total_points":
        Score.objects.all().aggregate(Sum('points'))["points__sum"],
        "challenges":
        challenge_data,
        "team_point_distribution":
        point_distribution
    })
Exemple #11
0
 def post(self, request):
     totp_secret = pyotp.random_base32()
     request.user.totp_secret = totp_secret
     request.user.totp_status = TOTPStatus.VERIFYING
     request.user.save()
     add_2fa.send(sender=self.__class__, user=request.user)
     return FormattedResponse({'totp_secret': totp_secret})
Exemple #12
0
 def post(self, request):
     request.user.totp_device.delete()
     request.user.save()
     remove_2fa.send(sender=self.__class__, user=request.user)
     send_email(request.user.email, "RACTF - 2FA Has Been Disabled",
                "2fa_removed")
     return FormattedResponse()
Exemple #13
0
 def post(self, request, id):
     with transaction.atomic():
         user = get_object_or_404(
             get_user_model().objects.select_for_update(), id=id
         )
         recalculate_user(user)
     return FormattedResponse()
Exemple #14
0
    def get(self, request):
        connection_info = []

        redis_status, redis_details = self.test_redis_connection()
        connection_info.append({
            "name": "Redis",
            "status": redis_status,
            "details": redis_details
        })

        postgres_status, postgres_details = self.test_postgresql_connection()
        connection_info.append({
            "name": "PostgreSQL",
            "status": postgres_status,
            "details": postgres_details
        })

        andromeda_status, andromeda_details = self.get_andromeda_status()
        connection_info.append({
            "name": "Andomeda",
            "status": andromeda_status,
            "details": andromeda_details
        })

        if settings.SEND_MAIL:
            mailusv_status, mailusv_details = self.test_mailusv_connection()
            connection_info.append({
                "name": "Mail Daemon",
                "status": mailusv_status,
                "details": mailusv_details
            })

        return FormattedResponse(connection_info)
Exemple #15
0
def handle_exception(exc, context):
    if settings.DEBUG:
        traceback.print_exc()
    if isinstance(exc, FormattedException):
        return FormattedResponse(s=False, d=exc.d, m=exc.m, status=exc.status_code)
    response = exception_handler(exc, context)
    if isinstance(exc, Http404):
        response.data = {'s': False, 'm': 'not_found', 'd': ''}
    elif isinstance(exc, PermissionDenied):
        response.data = {'s': False, 'm': 'permission_denied', 'd': ''}
    elif isinstance(exc, exceptions.APIException):
        if isinstance(exc.detail, list):
            response.data = {'s': False, 'm': exc.detail[0].code, 'd': exc.detail}
        elif isinstance(exc.detail, dict):
            errors = []
            for detail in exc.detail:
                for error in exc.detail[detail]:
                    errors.append(error.code)
            response.data = {'s': False, 'm': errors[0], 'd': exc.detail}
        else:
            response.data = {'s': False, 'm': exc.detail.code, 'd': ''}
    else:
        response = Response({"s": False, 'm': str(exc), 'd': ''}, status=HTTP_500_INTERNAL_SERVER_ERROR)

    return response
Exemple #16
0
 def post(self, request):
     email = request.data["email"]
     email_validator = EmailValidator()
     email_validator(email)
     # prevent timing attack - is this necessary?
     try:
         user = get_user_model().objects.get(email=email,
                                             email_verified=True)
         token = PasswordResetToken(user=user, token=secrets.token_hex())
         token.save()
         uid = user.id
         token = token.token
         password_reset_start.send(sender=self.__class__, user=user)
     except get_user_model().DoesNotExist:
         password_reset_start_reject.send(sender=self.__class__,
                                          email=email)
         uid = -1
         token = ""
         email = "*****@*****.**"
     send_email(
         email,
         "RACTF - Reset Your Password",
         "password_reset",
         url=settings.FRONTEND_URL +
         "password_reset?id={}&secret={}".format(uid, token),
     )
     return FormattedResponse()
Exemple #17
0
 def post(self, request):
     serializer = self.serializer_class(data=request.data,
                                        context={'request': request})
     if not serializer.is_valid():
         return FormattedResponse(m='invalid_token_or_uid',
                                  d=serializer.errors,
                                  status=HTTP_400_BAD_REQUEST)
     user = serializer.validated_data['user']
     user.email_verified = True
     user.is_visible = True
     user.save()
     verify_email.send(sender=self.__class__, user=user)
     if user.can_login():
         return FormattedResponse({'token': user.issue_token()})
     else:
         return FormattedResponse()
Exemple #18
0
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data,
                                           context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        if user is None:
            return FormattedResponse(status=HTTP_401_UNAUTHORIZED,
                                     d={'reason': 'login_failed'},
                                     m='login_failed')

        if user.has_2fa():
            return FormattedResponse(status=HTTP_401_UNAUTHORIZED,
                                     d={'reason': '2fa_required'},
                                     m='2fa_required')

        token = providers.get_provider('token').issue_token(user)
        return FormattedResponse({'token': token})
Exemple #19
0
 def post(self, request):
     totp = pyotp.TOTP(request.user.totp_secret)
     valid = totp.verify(request.data['otp'], valid_window=1)
     if valid:
         request.user.totp_status = TOTPStatus.ENABLED
         request.user.save()
         verify_2fa.send(sender=self.__class__, user=request.user)
     return FormattedResponse({'valid': valid})
Exemple #20
0
 def post(self, request):
     serializer = JobSubmitSerializer(request.data)
     challenge = get_object_or_404(Challenge.objects,
                                   id=serializer.data['challenge_id'])
     response = client.submit_job(serializer.data['job_spec'])
     challenge.challenge_metadata['cserv_name'] = response['id']
     challenge.save()
     return FormattedResponse()
Exemple #21
0
 def post(self, request):
     serializer = UseHintSerializer(data=request.data)
     serializer.is_valid(raise_exception=True)
     hint_id = serializer.validated_data['id']
     hint = get_object_or_404(Hint, id=hint_id)
     using_teams = config.get('enable_teams')
     if not hint.challenge.is_unlocked(request.user):
         return FormattedResponse(m='challenge_not_unlocked', s=False, status=HTTP_403_FORBIDDEN)
     if using_teams:
         if HintUse.objects.filter(hint=hint, team=request.user.team).exists():
             return FormattedResponse(m='hint_already_used', s=False, status=HTTP_403_FORBIDDEN)
     else:
         if HintUse.objects.filter(hint=hint, user=request.user).exists():
             return FormattedResponse(m='hint_already_used', s=False, status=HTTP_403_FORBIDDEN)
     use_hint.send(sender=self.__class__, user=request.user, team=request.user.team, hint=hint)
     HintUse(hint=hint, team=request.user.team, user=request.user, challenge=hint.challenge).save()
     serializer = FullHintSerializer(hint, context={'request': request})
     return FormattedResponse(d=serializer.data)
Exemple #22
0
    def post(self, request):
        challenge = get_object_or_404(Challenge,
                                      id=request.data.get('challenge'))
        solve_set = Solve.objects.filter(challenge=challenge)

        if not solve_set.filter(team=request.user.team, correct=True).exists():
            return FormattedResponse(m='challenge_not_solved',
                                     status=HTTP_403_FORBIDDEN)

        current_vote = ChallengeVote.objects.filter(user=request.user,
                                                    challenge=challenge)
        if current_vote.exists():
            current_vote.delete()

        ChallengeVote(user=request.user,
                      challenge=challenge,
                      positive=request.data.get("positive")).save()
        return FormattedResponse(m='vote_recorded')
Exemple #23
0
 def post(self, request):
     serializer = self.serializer_class(data=request.data,
                                        context={'request': request})
     if not serializer.is_valid():
         return FormattedResponse(d=serializer.errors,
                                  m='bad_request',
                                  status=HTTP_400_BAD_REQUEST)
     data = serializer.validated_data
     user = data['user']
     password = data['password']
     user.set_password(password)
     user.password_reset_token = secrets.token_hex()
     user.save()
     password_reset.send(sender=self.__class__, user=user)
     if user.can_login():
         return FormattedResponse({'token': user.issue_token()})
     else:
         return FormattedResponse()
Exemple #24
0
    def list(self, request, *args, **kwargs):
        if not config.get('enable_scoreboard'):
            return FormattedResponse({})

        graph_members = config.get('graph_members')
        top_teams = Team.objects.filter(is_visible=True).order_by('-leaderboard_points', 'last_score')[:graph_members]
        top_users = get_user_model().objects.filter(is_visible=True).order_by('-leaderboard_points', 'last_score')[:graph_members]

        team_scores = Score.objects.filter(team__in=top_teams, leaderboard=True).select_related('team')\
            .order_by('-team__leaderboard_points', 'last_score')
        user_scores = Score.objects.filter(user__in=top_users, leaderboard=True).select_related('user')\
            .order_by('-user__leaderboard_points', 'last_score')

        user_serializer = LeaderboardUserScoreSerializer(user_scores, many=True)
        team_serializer = LeaderboardTeamScoreSerializer(team_scores, many=True)
        if config.get('enable_teams'):
            return FormattedResponse({'team': team_serializer.data, 'user': user_serializer.data})
        return FormattedResponse({'user': user_serializer.data})
Exemple #25
0
 def post(self, request):
     serializer = self.serializer_class(data=request.data,
                                        context={"request": request})
     if not serializer.is_valid():
         return FormattedResponse(
             m="invalid_token_or_uid",
             d=serializer.errors,
             status=HTTP_400_BAD_REQUEST,
         )
     user = serializer.validated_data["user"]
     user.email_verified = True
     user.is_visible = True
     user.save()
     email_verified.send(sender=self.__class__, user=user)
     if user.can_login():
         return FormattedResponse({"token": user.issue_token()})
     else:
         return FormattedResponse()
Exemple #26
0
 def post(self, request):
     serializer = self.serializer_class(data=request.data,
                                        context={"request": request})
     serializer.is_valid(raise_exception=True)
     user = request.user
     password = serializer.validated_data["password"]
     user.set_password(password)
     user.save()
     change_password.send(sender=self.__class__, user=user)
     return FormattedResponse()
Exemple #27
0
    def post(self, request):
        serializer = self.serializer_class(data=request.data,
                                           context={"request": request})
        if not serializer.is_valid():
            return FormattedResponse(d=serializer.errors,
                                     m="bad_request",
                                     status=HTTP_400_BAD_REQUEST)
        data = serializer.validated_data
        user = data["user"]
        password = data["password"]
        user.set_password(password)
        user.save()

        data['reset_token'].delete()
        password_reset.send(sender=self.__class__, user=user)
        if user.can_login():
            return FormattedResponse({"token": user.issue_token()})
        else:
            return FormattedResponse()
Exemple #28
0
 def post(self, request):
     if config.get('enable_teams'):
         with transaction.atomic():
             for team in Team.objects.select_for_update().all():
                 recalculate_team(team)
     else:
         with transaction.atomic():
             for user in get_user_model().objects.all():
                 recalculate_user(user)
     return FormattedResponse()
Exemple #29
0
 def post(self, request):
     if not config.get("enable_team_join"):
         return FormattedResponse(m="join_disabled", status=HTTP_403_FORBIDDEN)
     name = request.data.get("name")
     password = request.data.get("password")
     team_join_attempt.send(sender=self.__class__, user=request.user, name=name)
     if name and password:
         try:
             team = get_object_or_404(Team, name=name, password=password)
         except Http404:
             team_join_reject.send(sender=self.__class__, user=request.user, name=name)
             raise FormattedException('invalid_team_or_password', status_code=HTTP_404_NOT_FOUND)
         team_size = int(config.get('team_size'))
         if not request.user.is_staff and not team.size_limit_exempt and 0 < team_size <= team.members.count():
             return FormattedResponse(m='team_full', status=HTTP_403_FORBIDDEN)
         request.user.team = team
         request.user.save()
         team_join.send(sender=self.__class__, user=request.user, team=team)
         return FormattedResponse()
     return FormattedResponse(m='joined_team', status=HTTP_400_BAD_REQUEST)
Exemple #30
0
 def post(self, request):
     serializer = self.serializer_class(data=request.data,
                                        context={'request': request})
     serializer.is_valid(raise_exception=True)
     bot = get_user_model()(username=serializer.data["username"],
                            email_verified=True,
                            is_visible=serializer.data["is_visible"],
                            is_staff=serializer.data["is_staff"],
                            is_superuser=serializer.data["is_superuser"])
     bot.save()
     return FormattedResponse(d={'token': bot.issue_token()})