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)
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)
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!"}')
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!"}')