def start_game(self): self.status = GAME_RUNNING self.start = now() self.save() Events.info('Game "%s" was started!' % self.name) General.info('Game "%s" was started!' % self.name) self.event('Game %s has been started!' % self.name)
def capture(self, team): if not self.__bool__(): General.warning( 'Team "%s" attempted to capture Flag "%s" which is not enabled!!' % (team.path(), self.path())) return None if self.stolen is not None: General.warning( 'Team "%s" attempted to capture Flag "%s" owned by "%s" which was already captured by "%s"!' % (team.path(), self.path(), self.team().path(), self.stolen.path())) return None self.stolen = team result = new('TransactionFlag', save=False) result.flag = self result.value = self.value result.destination = team result.source = self.team() result.save() team.append(result) self.team().append(result.reverse()) self.save() del result self.game().event('%s stole a Flag from %s!' % (self.stolen.get_name(), self.get_team().get_name())) Events.info('Flag "%s" owned by "%s" was captured by "%s"!' % (self.path(), self.team().path(), self.stolen.path())) return Flag.objects.get_next(team)
def update(self): #if if self.end is None and self.scored is None: transaction = new('TransactionBeacon', False) transaction.beacon = self transaction.destination = self.owner transaction.source = self.get_host().get_team() transaction.value = int( self.get_game().get_setting('beacon_score')) transaction.save() transaction.destination.add_transaction(transaction) reverse = new('TransactionBeacon', False) reverse.beacon = self reverse.destination = self.owner reverse.source = self.get_host().get_team() reverse.value = transaction.value * -1 reverse.save() General.info( 'Scored a Beacon by "%s" on Host "%s" owned by "%s" for "%d" PTS!' % (self.owner.get_path(), self.get_host().get_path(), transaction.source.get_path(), transaction.value)) transaction.source.add_transaction(reverse) del reverse del transaction self.scored = now() self.save()
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 mapper(request, gid): if request.method == HTTP_GET: General.debug( '[%s] Client is request UUID mappings for Game ID "%s"!' % (ip(request), gid)) try: game = Game.objects.get(id=int(gid), status=GAME_RUNNING) except (ObjectDoesNotExist, MultipleObjectsReturned, ValueError): return HttpResponseNotFound() return HttpResponse(status=200, content=dumps(game.get_team_list())) return HttpResponseBadRequest(content=MESSAGE_INVALID_METHOD)
def expire(self): General.info( 'Beacon by "%s" on Host "%s" has expired after "%d" seconds!' % (self.owner.get_path(), self.get_host().get_path(), self.__len__())) Events.info( 'Beacon by "%s" on Host "%s" has expired after "%d" seconds!' % (self.owner.get_path(), self.get_host().get_path(), self.__len__())) self.end = now() self.save()
def get_job(self, monitor, request): Jobs.info('AssignedMonitor "%s": Attempting to submit a Job!' % monitor.name) try: job_str = request.body.decode('UTF-8') except UnicodeDecodeError: Jobs.error( 'AssignedMonitor "%s": Attempted to submit a Job with an invaid encoding scheme!' % (monitor.name)) return HttpResponseBadRequest(content=MESSAGE_INVALID_ENCODING) else: try: job_json = loads(job_str) if not isinstance( job_json, dict ) or 'id' not in job_json or 'host' not in job_json: Jobs.error( 'AssignedMonitor "%s": Attempted to submit a Job with an invaid JSON format!' % (monitor.name)) return HttpResponseBadRequest( content=MESSAGE_INVALID_FORMAT) try: job = self.get(id=int(job_json['id'])) if job.end is not None: Jobs.error( 'AssignedMonitor "%s": Attempted to submit a Job that was already completed!' % (monitor.name)) return HttpResponseBadRequest( content=JOB_MESSAGE_INVALID_JOB) Jobs.error( 'AssignedMonitor "%s": Submitted Job "%d" for processing.' % (monitor.name, job.id)) General.debug( 'AssignedMonitor "%s": Submitted Job "%d" for processing.' % (monitor.name, job.id)) return job.process_job(monitor, job_json['host']) except (KeyError, TypeError, ValueError, ObjectDoesNotExist, MultipleObjectsReturned) as err: Jobs.error( 'AssignedMonitor "%s": Attempted to submit a Job that does not exist or invalid! %s' % (monitor, str(err))) return HttpResponseBadRequest( content=JOB_MESSAGE_INVALID_JOB) finally: del job del job_json except JSONDecodeError: Jobs.error( 'AssignedMonitor "%s": Attempted to submit a Job with an invaid JSON format!' % (monitor.get_name())) return HttpResponseBadRequest(content=MESSAGE_INVALID_FORMAT) finally: del job_str return HttpResponseBadRequest(content=MESSAGE_INVALID_METHOD)
def register(request): if request.method == HTTP_POST: team, _, _, err = PlayerTeam.objects.get_team_json(request, field='token', offensive=True) if err is not None: return err General.debug('[%s] Client requested a Beacon Token for "%s".' % (ip(request), team.get_path())) return HttpResponse(status=201, content=TEAM_MESSAGE_TOKEN.format( token=str(team.add_beacon_token().uid))) return HttpResponseBadRequest(content=MESSAGE_INVALID_METHOD)
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_flag_query(self, team, flag): game = team.get_game() if game.__bool__(): try: flag = self.exclude(host__range__team=team).get( host__range__team__game=game, flag__exact=flag, enabled=True, host__enabled=True) except ObjectDoesNotExist: return None except MultipleObjectsReturned: General.warning( '%s attempted to get Flag "%s", but returned multiple Flags, multiple Flags have the vaue "%s"!' % (team.get_path(), flag, flag)) else: return flag finally: del game return None
def job(request): client = ip(request) games, monitor, err = AssignedMonitor.objects.get_montiors( client, request.auth) if err is not None: return err if request.method == HTTP_GET: Authentication.debug( '[%s] AssignedMonitor "%s" connected to request a Job, assigned to "%d" running Games.' % (client, monitor.name, len(games))) General.info( '[%s] AssignedMonitor "%s" connected to request a Job, assigned to "%d" running Games.' % (client, monitor.name, len(games))) Jobs.debug( '[%s] AssignedMonitor "%s": Connected and will attempt to pick "%d" times for a valid Job.' % (client, monitor.name, len(games))) for game_num in range(0, len(games)): game = choice(games) Jobs.debug( '[%s] AssignedMonitor "%s": Selection round "%s" selected Game "%s".' % (client, monitor.name, game_num, game.game.get_name())) job = Job.objects.new_job(game) if job is not None: Jobs.info( '[%s] AssignedMonitor "%s": Job ID "%d" created for Host "%s"!' % (client, monitor.name, job.id, job.host.get_path())) return HttpResponse(status=201, content=dumps(job.get_json(), indent=4)) del game del games Jobs.debug( '[%s] AssignedMonitor "%s": Has no valid hosts to choose from!' % (client, monitor.name)) return HttpResponse(status=204, content=JOB_MESSAGE_NO_HOSTS) elif request.method == HTTP_POST: return Job.objects.get_job(monitor, request) return HttpResponseBadRequest(content=MESSAGE_INVALID_METHOD)
from scorebot_db.models.store import * from scorebot_db.models.range import * from scorebot_db.models.player import * for member in getmembers(import_module(__name__), isclass): if isinstance(member[1], ModelBase) and 'scorebot_db.' in member[1].__module__: admin = None hidden = False Models[member[0].lower()] = member[1] try: hidden = bool(getattr(member[1], 'hidden')) except AttributeError: hidden = False if not hidden: try: form = getattr(member[1], 'form') if issubclass(form, ModelForm): admin = type('%sAdmin' % member[0], (ModelAdmin,), {'form': form, 'model': member[1]}) del form except AttributeError as err: admin = None if not member[1]._meta.abstract and not hidden: site.register(member[1], admin_class=admin) General.debug('Scorebot Model "%s" loaded with Administrative Options.' % member[0]) else: General.debug('Scorebot Model "%s" loaded.' % member[0]) del admin del hidden # EOF
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