def get_port(self, team, port): try: number = int(port) if number <= 0: raise ValueError() except ValueError: General.error( 'Team "%s" attempted to open port "%s" which is not a valid integer!' % (team.get_path(), str(port))) return HttpResponseBadRequest(content=TEAM_MESSAGE_PORT_INVALID) try: self.get(port=number) except (ObjectDoesNotExist, MultipleObjectsReturned): pass else: return HttpResponse(status=418) openport = new('Port', False) openport.port = number openport.save() team.game.ports.add(openport) team.game.save() General.info('Team "%s" attempted to opened Beacon Port "%d"!' % (team.get_path(), number)) del openport return HttpResponse(status=201, content=TEAM_MESSAGE_PORT.format(port=port))
def get_setting(self, name): General.error('Setting: "%s" requested!' % name) if self.settings is not None: try: return getattr(self.settings, name) except AttributeError: pass return GAME_SETTING_DEFAULT.get(name, None)
def flag(request): if request.method == HTTP_POST: team, data, _, err = PlayerTeam.objects.get_team_json(request, field='token', offensive=True) if err is not None: return err client = ip(request) if 'flag' not in data: General.error( '[%s] Client attempted to submit a Flag without the "flag" value!' % client) return HttpResponseBadRequest(content=MESSAGE_MISSING_FIELD.format( field='flag')) flag = Flag.objects.get_flag_query(team, data['flag']) del data if flag is None: General.error( '[%s] Team "%s" attempted to submit a Flag that does not exist!' % (client, team.get_path())) return HttpResponseNotFound(content=FLAG_MESSAGE_NOT_EXIST) if flag.stolen is not None: General.error( '[%s] Team "%s" attempted to submit a Flag "%s" that was already captured!' % (client, team.get_path(), flag.get_path())) return HttpResponse(status=204, content=FLAG_MESSAGE_STOLEN) hint, captured = flag.capture(team) if not captured: General.error( '[%s] Team "%s" attempted to submit a Flag "%s" that was already captured!' % (client, team.get_path(), flag.get_path())) return HttpResponse(status=204, content=FLAG_MESSAGE_STOLEN) return HttpResponse(status=200, content=FLAG_MESSAGE_HINT.format(hint=str(hint))) return HttpResponseBadRequest(content=MESSAGE_INVALID_METHOD)
def beacon(request): if request.method == HTTP_POST: team, data, token, err = PlayerTeam.objects.get_team_json( request, field='token', offensive=True, beacon=True) if err is not None: return err client = ip(request) if 'address' not in data: General.error( '[%s] Client attempted to submit a Beacon without the "address" value!' % client) return HttpResponseBadRequest(content=MESSAGE_MISSING_FIELD.format( field='address')) return Host.objects.get_beacon(team, token, data['address']) return HttpResponseBadRequest(content=MESSAGE_INVALID_METHOD)
def get_flag(self, team, value): if team.game.__bool__(): try: return self.exclude(host__range__team=team).get( flag__enabled=True, host__enabled=True, host__range__enabled=True, flag__exact=value, stolen__isnull=True) except ObjectDoesNotExist: pass except MultipleObjectsReturned as err: General.error( 'Team "%s" submitted Flag value "%s" seems to be in use by multiple Flags, cannot submit!' % (team.path(), value), err) return None
def ports(request): if request.method == HTTP_GET: return HttpResponse(content=TEAM_MESSAGE_PORT_LIST.format( list=','.join(Port.objects.get_list()))) elif request.method == HTTP_POST: team, data, _, err = PlayerTeam.objects.get_team_json(request, field='token', offensive=True) if err is not None: return err if 'port' not in data: General.error( '[%s] Client attempted to open a Beacon Port without the "port" value!!' % ip(request)) return HttpResponseBadRequest(content=MESSAGE_MISSING_FIELD.format( field='port')) return Port.objects.get_port(team, data['port']) return HttpResponseBadRequest(content=MESSAGE_INVALID_METHOD)
def get_beacon(self, team, token, address): try: target = IPv4Address(address) except ValueError: General.error( 'Team "%s" reported a Beacon for an invalid IP address "%s"!' % (team.get_path(), address)) return HttpResponseBadRequest(content=HOST_MESSAGE_INVALID_IP) General.info( 'Received a Beacon request by Team "%s" for address "%s"!' % (team.get_path(), address)) host = None ghost = False try: host = self.exclude(range__team=team).get(ip=address) except MultipleObjectsReturned: General.error( 'Team "%s" reported a Beacon for an invalid IP address "%s" that matches multiple Hosts!' % (team.get_path(), address)) return HttpResponseBadRequest(content=HOST_MESSAGE_INVALID_IP) except ObjectDoesNotExist: ghost = True try: host = get('BeaconHost').objects.exclude(range__team=team).get( ip=address) except (ObjectDoesNotExist, MultipleObjectsReturned): pass if host is None: General.info( 'Beacon request by Team "%s" for address "%s" does not match a known host, will attempt to match!' % (team.get_path(), address)) victim = None for match in team.get_game().teams.exclude(id=team.id): match_playing = match.get_playingteam() if match_playing is None or match_playing.assets is None: continue try: network = IPv4Network(match_playing.assets.subnet) except ValueError: General.warning( 'Team "%s" does not have a valid subnet entered for it\'s range "%s"!' % (match.get_path(), match_playing.assets.subnet)) continue else: if target in network: victim = match_playing break finally: del match_playing if victim is None: General.error( 'Beacon request by Team "%s" for address "%s" does not match a known host or Team subnet range!' % (team.get_path(), address)) return HttpResponseNotFound(content=HOST_MESSAGE_NO_HOST) General.debug( 'Creating BeaconHost due to Beacon request by Team "%s" for address "%s" that matches Team "%s" ' 'range!' % (team.get_path(), address, victim.get_path())) host = new('BeaconHost', False) host.ip = address host.range = victim.assets host.save() del victim del target General.debug('Received Beacon request by Team "%s" for Host "%s"!' % (team.get_path(), host.get_path())) if not host.get_game().__bool__(): General.error( 'Received Beacon request by Team "%s" for Host "%s" for a non-running Game!' % (team.get_path(), host.get_path())) return HttpResponseBadRequest(content=MESSAGE_GAME_NO_RUNNING) if host.get_game().id != team.get_game().id: General.error( 'Received Beacon request by Team "%s" for Host "%s" not in the same Game!' % (team.get_path(), host.get_path())) return HttpResponseBadRequest(content=HOST_MESSAGE_NO_HOST) try: beacon = host.beacons.get(end__isnull=True, owner=team) except MultipleObjectsReturned: General.warning( 'Received Beacon request by Team "%s" for Host "%s" attempting to add multiple Beacons!' % (team.get_path(), host.get_path())) return HttpResponseForbidden(content=HOST_MESSAGE_BEACON_EXISTS) except ObjectDoesNotExist: Events.info( 'Created a new Beacon on Host "%s" owned by Team "%s" from "%s"!' % (host.get_path(), host.get_team().get_path(), team.get_path())) General.info( 'Created a new Beacon on Host "%s" owned by Team "%s" from "%s"!' % (host.get_path(), host.get_team().get_path(), team.get_path())) team.get_game().event( '%s has compromised a Host on %s\'s network!' % (team.get_name(), host.get_team().get_name())) beacon = new('Beacon', False) beacon.owner = team if ghost: beacon.ghost = host else: beacon.host = host beacon.update = now() beacon.token = token beacon.save() return HttpResponse(status=201)
def get_team_json(self, request, field=TEAM_DEFAULT_FIELD, beacon=False, offensive=False): client = ip(request) try: json_str = request.body.decode('UTF-8') except UnicodeDecodeError: General.error( '[%s] Client attempted to submit an improperly encoded request!' & client) return None, None, None, HttpResponseBadRequest( content=MESSAGE_INVALID_ENCODING) try: json_data = loads(json_str) except JSONDecodeError: General.error( '[%s] Client attempted to submit an improperly JSON formatted request!' & client) return None, None, None, HttpResponseBadRequest( content=MESSAGE_INVALID_FORMAT) finally: del json_str if field not in json_data: General.error( '[%s] Data submitted by client is missing requested field "%s"!' & (client, field)) return None, None, None, HttpResponseBadRequest( content=TEAM_MESSAGE_MISSING_FIELD.format(field=field)) General.debug( '[%s] Client connected with token "%s" to request a Team.' % (client, str(request.auth.token.uid))) team, token = self.get_team_token(uuid=json_data[field], beacon=beacon) if team is None: General.info( '[%s] Client attempted to use value "%s" to request a non-existant Team!' % (client, json_data[field])) return None, None, None, HttpResponseBadRequest( content=TEAM_MESSAGE_NO_TEAM) General.debug( '[%s] Client connected and requested Team "%s" with Token "%s".' % (client, team.get_path(), json_data[field])) if not team.token.__bool__(): General.error( '[%s] Client attempted to use token "%s" that has expired!' % (client, str(team.token.uid))) return None, None, None, HttpResponseBadRequest( content=TEAM_MESSAGE_EXPIRED) if offensive: team = team.get_playingteam() if team is None or not team.offensive: General.error( '[%s] Client connected and requested Team "%s" with Token "%s", but Team is not marked Offensive!' % (client, team.get_path(), json_data[field])) return None, None, None, HttpResponseBadRequest( content=TEAM_MESSAGE_NOT_OFFENSIVE) if not team.get_game().__bool__(): General.error( '[%s] Client connected and requested Team "%s" that is not currently in a running Game!' % (client, team.get_path())) return HttpResponseBadRequest(content=MESSAGE_GAME_NO_RUNNING) return team, json_data, token, None