예제 #1
0
 def save(self, *args, **kwargs):
     if self.team is not None:
         if self.ip is not None:
             try:
                 host_find = self.team.hosts.all().get(ip=self.ip)
                 if host_find.id != self.id:
                     raise ValidationError({
                         'ip':
                         'Hosts on a Team cannot have the same IP address!'
                     })
                 del host_find
             except Host.DoesNotExist:
                 pass
             except Host.MultipleObjectsReturned:
                 raise ValidationError({
                     'ip':
                     'Hosts on a Team cannot have the same IP address!'
                 })
         else:
             api_warning(
                 'BACKEND',
                 'Host "%s" has a null value IP address and will not receive beacon scoring!'
                 % self.fqdn)
     if self.name is None or len(self.name) == 0:
         if '.' in self.fqdn:
             self.name = self.fqdn.split('.')[0]
         else:
             self.name = self.fqdn
     super(Host, self).save(*args, **kwargs)
예제 #2
0
 def save(self, *args, **kwargs):
     if '/' not in self.subnet:
         self.subnet = '%s/24' % self.subnet
         api_warning(
             'BACKEND',
             'Team "%s" subnet is not in slash notation, setting to class /24!'
             % self.get_canonical_name())
     if self.score is None:
         self.score = score_create_new()
     if self.token is None:
         self.token = token_create_new(90)
     super(GameTeam, self).save(*args, **kwargs)
예제 #3
0
 def api_purchase(request, team_id=None):
     if request.method == METHOD_GET:
         api_debug('STORE',
                   'Requesting the exchange rate for Team "%s"' % team_id,
                   request)
         if team_id is None:
             api_error('STORE', 'Attempted to use Null Team ID!', request)
             return HttpResponseNotFound(
                 '{"message": "SBE API: Team could not be found!"}')
         try:
             team = GameTeam.objects.get(
                 store=int(team_id), game__status=CONST_GAME_GAME_RUNNING)
         except ValueError:
             api_error(
                 'STORE',
                 'Attempted to use an invalid Team ID "%s"!' % str(team_id),
                 request)
             return HttpResponseNotFound(
                 '{"message": "SBE API: Invalid Team ID!"}')
         except GameTeam.DoesNotExist:
             api_error(
                 'STORE', 'Attempted to use an non-existent Team ID "%s"!' %
                 str(team_id), request)
             return HttpResponseNotFound(
                 '{"message": "SBE API: Team could not be found!"}')
         except GameTeam.MultipleObjectsReturned:
             api_error(
                 'STORE',
                 'Attempted to use a Team ID which returned multiple Teams!',
                 request)
             return HttpResponseNotFound(
                 '{"message": "SBE API: Team could not be found!"}')
         rate = float(team.game.get_option('score_exchange_rate')) / 100.0
         api_debug(
             'STORE', 'The exchange rate for Team "%s" is "%.2f"!' %
             (team.get_canonical_name(), rate), request)
         return HttpResponse(status=200, content='{"rate": %.2f}' % rate)
     if request.method == METHOD_POST:
         try:
             decoded_data = request.body.decode('UTF-8')
         except UnicodeDecodeError:
             api_error('STORE', 'Data submitted is not encoded properly!',
                       request)
             return HttpResponseBadRequest(
                 content=
                 '{"message": "SBE API: Incorrect encoding, please use UTF-8!"}'
             )
         try:
             json_data = json.loads(decoded_data)
             del decoded_data
         except json.decoder.JSONDecodeError:
             api_error('STORE',
                       'Data submitted is not in correct JSON format!',
                       request)
             return HttpResponseBadRequest(
                 content=
                 '{"message": "SBE API: Not in a valid JSON format!"]')
         if 'team' not in json_data or 'order' not in json_data:
             api_error('STORE', 'Data submitted is missing JSON fields!',
                       request)
             return HttpResponseBadRequest(
                 content=
                 '{"message": "SBE API: Not in a valid JSON format!"}')
         try:
             team = GameTeam.objects.get(
                 store=int(json_data['team']),
                 game__status=CONST_GAME_GAME_RUNNING)
         except ValueError:
             api_error(
                 'STORE',
                 'Attempted to use an invalid Team ID "%s"!' % str(team_id),
                 request)
             return HttpResponseNotFound(
                 '{"message": "SBE API: Invalid Team ID!"}')
         except GameTeam.DoesNotExist:
             api_error(
                 'STORE', 'Attempted to use an non-existent Team ID "%s"!' %
                 str(team_id), request)
             return HttpResponseNotFound(
                 '{"message": "SBE API: Team could not be found!"}')
         except GameTeam.MultipleObjectsReturned:
             api_error(
                 'STORE',
                 'Attempted to use a Team ID which returned multiple Teams!',
                 request)
             return HttpResponseNotFound(
                 '{"message": "SBE API: Team could not be found!"}')
         api_info(
             'STORE', 'Attempting to add Purchase records for Team "%s".' %
             team.get_canonical_name(), request)
         if not isinstance(json_data['order'], list):
             api_error('STORE',
                       'Data submitted is missing the "oreer" array!',
                       request)
             return HttpResponseBadRequest(
                 content='{"message": "SBE API: Not in valid JSON format!"}'
             )
         for order in json_data['order']:
             if 'item' in order and 'price' in order:
                 try:
                     with atomic():
                         purchase = Purchase()
                         purchase.team = team
                         purchase.amount = int(
                             float(order['price']) * (float(
                                 team.game.get_option(
                                     'score_exchange_rate')) / 100.0))
                         purchase.item = (order['item']
                                          if len(order['item']) < 150 else
                                          order['item'][:150])
                         team.set_uptime(-1 * purchase.amount)
                         purchase.save()
                         api_score(team.id, 'PURCHASE',
                                   team.get_canonical_name(),
                                   purchase.amount, purchase.item)
                         api_debug(
                             'STORE',
                             'Processed order of "%s" "%d" for team "%s"!' %
                             (purchase.item, purchase.amount,
                              team.get_canonical_name()), request)
                         del purchase
                 except ValueError:
                     api_warning(
                         'STORE',
                         'Order "%s" has invalid integers for amount!!' %
                         str(order), request)
             else:
                 api_warning(
                     'STORE',
                     'Order "%s" does not have the correct format!' %
                     str(order), request)
         return HttpResponse(status=200, content='{"message": "processed"}')
     return HttpResponseBadRequest(
         content='{"message": "SBE API: Not a supported method type!"}')
예제 #4
0
 def api_beacon(request):
     if request.method == METHOD_POST:
         team, token, data, exception = game_team_from_token(
             request, 'CLI', 'token', beacon=True, fields=['address'])
         if exception is not None:
             return exception
         address_raw = data['address']
         try:
             address = IPAddress(address_raw)
         except AddrFormatError:
             api_error(
                 'BEACON', 'IP Reported by Team "%s" is invalid!' %
                 team.get_canonical_name(), request)
             return HttpResponseBadRequest(
                 content='{"message": "SBE API: Invalid IP Address!"}')
         target_team = None
         for sel_target_team in team.game.teams.all():
             try:
                 target_subnet = IPNetwork(sel_target_team.subnet)
             except AddrFormatError:
                 api_warning(
                     'BEACON',
                     'Team "%s" subnet is invalid, skipping Team!' %
                     team.get_canonical_name(), request)
                 continue
             if address in target_subnet:
                 api_debug(
                     'BEACON',
                     'Beacon from Team "%s" to Team "%s"\'s subnet!' %
                     (team.get_canonical_name(),
                      sel_target_team.get_canonical_name()), request)
                 target_team = sel_target_team
                 del target_subnet
                 break
             del target_subnet
         del address
         try:
             host = Host.objects.get(
                 ip=address_raw, team__game__status=CONST_GAME_GAME_RUNNING)
             if host.team.game.id != team.game.id:
                 api_error(
                     'BEACON',
                     'Host accessed by Team "%s" is not in the same game as "%s"!'
                     % (team.get_canonical_name(),
                        host.team.get_canonical_name()), request)
                 return HttpResponseForbidden(
                     '{"message": "SBE API: Host is not in the same Game!"}'
                 )
             try:
                 beacon = host.beacons.get(beacon__finish__isnull=True,
                                           beacon__attacker=team,
                                           beacon__token=token)
                 beacon.checkin = timezone.now()
                 beacon.save()
                 api_info(
                     'BEACON',
                     'Team "%s" updated the Beacon on Host "%s"!' %
                     (team.get_canonical_name(), host.get_canonical_name()),
                     request)
                 return HttpResponse()
             except GameCompromiseHost.MultipleObjectsReturned:
                 api_warning(
                     'BEACON',
                     'Team "%s" attempted to create multiple Beacons on a Host "%s"!'
                     %
                     (team.get_canonical_name(), host.get_canonical_name()),
                     request)
                 del host
                 del address_raw
                 return HttpResponseForbidden(
                     '{"message": "SBE API: Already a Beacon on that Host!"}'
                 )
             except GameCompromiseHost.DoesNotExist:
                 if host.beacons.filter(
                         beacon__finish__isnull=True).count() > 1:
                     api_warning(
                         'BEACON',
                         'Team "%s" attempted to create multiple Beacons on a Host "%s"!'
                         % (team.get_canonical_name(),
                            host.get_canonical_name()), request)
                     del host
                     del address_raw
                     return HttpResponseForbidden(
                         '{"message": "SBE API: Already a Beacon on that Host!"}'
                     )
                 with atomic():
                     beacon = GameCompromise()
                     beacon_host = GameCompromiseHost()
                     beacon_host.ip = address_raw
                     beacon_host.team = host.team
                     beacon_host.host = host
                     beacon.token = token
                     beacon.attacker = team
                     beacon.save()
                     beacon_host.beacon = beacon
                     beacon_host.save()
                     api_event(
                         team.game,
                         'A Host on %s\'s network was compromised by "%s" #PvJCTF #CTF #BSidesLV!'
                         % (host.team.name, team.name))
                     beacon_value = int(
                         team.game.get_option('beacon_value'))
                     team.set_beacons(beacon_value)
                     api_info(
                         'SCORING-ASYNC',
                         'Beacon score was applied to Team "%s"!' %
                         team.get_canonical_name(), request)
                     api_score(beacon.id, 'BEACON-ATTACKER',
                               team.get_canonical_name(), beacon_value,
                               beacon_host.get_fqdn())
                     del beacon_value
                     del beacon
                     del beacon_host
                     del address_raw
                     api_info(
                         'BEACON',
                         'Team "%s" added a Beacon to Host "%s"!' %
                         (team.get_canonical_name(),
                          host.get_canonical_name()), request)
                 return HttpResponse(status=201)
         except Host.DoesNotExist:
             if target_team is not None:
                 api_info(
                     'BEACON',
                     'Host accessed by Team "%s" does not exist! Attempting to create a faux Host!'
                     % team.get_canonical_name(), request)
                 if GameCompromiseHost.objects.filter(
                         ip=address_raw,
                         beacon__finish__isnull=True).count() > 0:
                     api_warning(
                         'BEACON',
                         'Team "%s" attempted to create multiple Beacons on a Host "%s"!'
                         % (team.get_canonical_name(), address_raw),
                         request)
                     del address_raw
                     return HttpResponseForbidden(
                         '{"message": "SBE API: Already a Beacon on that Host!"}'
                     )
                 with atomic():
                     beacon_host = GameCompromiseHost()
                     beacon_host.ip = address_raw
                     beacon_host.team = target_team
                     beacon = GameCompromise()
                     beacon.token = token
                     beacon.attacker = team
                     beacon.save()
                     beacon_host.beacon = beacon
                     beacon_host.save()
                     api_event(
                         team.game,
                         'A Host on %s\'s network was compromised by "%s" #PvJCTF #CTF #BSidesLV!'
                         % (target_team.name, team.name))
                     beacon_value = int(
                         team.game.get_option('beacon_value'))
                     team.set_beacons(beacon_value)
                     api_info(
                         'SCORING-ASYNC',
                         'Beacon score was applied to Team "%s"!' %
                         team.get_canonical_name(), request)
                     api_score(beacon.id, 'BEACON-ATTACKER',
                               team.get_canonical_name(), beacon_value,
                               beacon_host.get_fqdn())
                     del beacon_value
                     del beacon
                     del beacon_host
                     api_info(
                         'BEACON',
                         'Team "%s" added a Beacon to Host "%s"!' %
                         (team.get_canonical_name(), address_raw), request)
                     del address_raw
                 return HttpResponse(status=201)
             del address_raw
             api_error(
                 'BEACON',
                 'Host accessed by Team "%s" does not exist and a hosting team cannot be found!'
                 % team.get_canonical_name(), request)
             return HttpResponseNotFound(
                 '{"message": "SBE API: Host does not exist!"}')
         except Host.MultipleObjectsReturned:
             api_error(
                 'BEACON',
                 'Host accessed by Team "%s" returned multiple Hosts, invalid!'
                 % team.get_canonical_name(), request)
             return HttpResponseNotFound(
                 '{"message": "SBE API: Host does not exist!"}')
     return HttpResponseBadRequest(
         content='{"message": "SBE API: Not a supported method type!"}')