Beispiel #1
0
	def __init__(self,conf,init=False):
		self.game_started = False
		self.conf = conf
		self.usenix_conf = conf.getSection("USENIX_CONFIG")
		self.servicebot_conf = conf.getSection("SERVICE_BOT")
		self.scoring = UsenixPrivateScoring(self.conf)

		self.usenix_resetbot_dispatcher = None
		self.exploitbot_dispatcher = None
		self.servicebot_dispatcher = None
		self.usenix_scoreboard_dispatcher = None
		self.usenix_reportbot_dispatcher = None

		self.partial_round = 0
		self.service_round = 0
		self.exploit_round = 0
		self.current_round = 1

		self.logger = self.conf.buildLogger("UsenixLogic")
		self.fm = self.conf.buildFlagManager()

		self.team_scores = [0.0] * self.conf.numTeams()
		self.recent_service_results = None

		self.exploit_to_service_map = [-1]*len(self.usenix_conf.exploits)
		for exploit in self.usenix_conf.exploits:
			for service in self.servicebot_conf.services:
				if(exploit.service == service.name):
					self.exploit_to_service_map[exploit.id] = service.id
					break

			assert(self.exploit_to_service_map[exploit.id] != -1),"Exploit %s - No valid service named %s" % (
				exploit.name,
				exploit.service)

		persistance_path = os.path.join(self.usenix_conf.data_dir,"usenix.dat")
		self.logger.debug("Persistance path: %s",persistance_path)
		self.shelf = shelve.open(persistance_path)

		if(init == True):
			self.shelf["PARTIAL"] = self.partial_round
			self.shelf["ROUND"] = self.current_round
			self.shelf["SCORES"] = self.team_scores
			self.shelf.sync()
		else:
			self.partial_round = self.shelf["PARTIAL"]
			self.current_round = self.shelf["ROUND"]
			self.team_scores = self.shelf["SCORES"]
Beispiel #2
0
    def __init__(self, conf, init=False):
        self.game_started = False
        self.conf = conf
        self.usenix_conf = conf.getSection("USENIX_CONFIG")
        self.servicebot_conf = conf.getSection("SERVICE_BOT")
        self.scoring = UsenixPrivateScoring(self.conf)

        self.usenix_resetbot_dispatcher = None
        self.exploitbot_dispatcher = None
        self.servicebot_dispatcher = None
        self.usenix_scoreboard_dispatcher = None
        self.usenix_reportbot_dispatcher = None

        self.partial_round = 0
        self.service_round = 0
        self.exploit_round = 0
        self.current_round = 1

        self.logger = self.conf.buildLogger("UsenixLogic")
        self.fm = self.conf.buildFlagManager()

        self.team_scores = [0.0] * self.conf.numTeams()
        self.recent_service_results = None

        self.exploit_to_service_map = [-1] * len(self.usenix_conf.exploits)
        for exploit in self.usenix_conf.exploits:
            for service in self.servicebot_conf.services:
                if exploit.service == service.name:
                    self.exploit_to_service_map[exploit.id] = service.id
                    break

            assert self.exploit_to_service_map[exploit.id] != -1, "Exploit %s - No valid service named %s" % (
                exploit.name,
                exploit.service,
            )

        persistance_path = os.path.join(self.usenix_conf.data_dir, "usenix.dat")
        self.logger.debug("Persistance path: %s", persistance_path)
        self.shelf = shelve.open(persistance_path)

        if init == True:
            self.shelf["PARTIAL"] = self.partial_round
            self.shelf["ROUND"] = self.current_round
            self.shelf["SCORES"] = self.team_scores
            self.shelf.sync()
        else:
            self.partial_round = self.shelf["PARTIAL"]
            self.current_round = self.shelf["ROUND"]
            self.team_scores = self.shelf["SCORES"]
Beispiel #3
0
class UsenixLogic(GameStateLogic):

    STATE_PRE_GAME_START = 0
    STATE_ROUND_RUNNING = 1
    STATE_EXPLOITS_RUNNING = 2
    STATE_UPDATE_SCOREBOARD = 3

    def __init__(self, conf, init=False):
        self.game_started = False
        self.conf = conf
        self.usenix_conf = conf.getSection("USENIX_CONFIG")
        self.servicebot_conf = conf.getSection("SERVICE_BOT")
        self.scoring = UsenixPrivateScoring(self.conf)

        self.usenix_resetbot_dispatcher = None
        self.exploitbot_dispatcher = None
        self.servicebot_dispatcher = None
        self.usenix_scoreboard_dispatcher = None
        self.usenix_reportbot_dispatcher = None

        self.partial_round = 0
        self.service_round = 0
        self.exploit_round = 0
        self.current_round = 1

        self.logger = self.conf.buildLogger("UsenixLogic")
        self.fm = self.conf.buildFlagManager()

        self.team_scores = [0.0] * self.conf.numTeams()
        self.recent_service_results = None

        self.exploit_to_service_map = [-1] * len(self.usenix_conf.exploits)
        for exploit in self.usenix_conf.exploits:
            for service in self.servicebot_conf.services:
                if exploit.service == service.name:
                    self.exploit_to_service_map[exploit.id] = service.id
                    break

            assert self.exploit_to_service_map[exploit.id] != -1, "Exploit %s - No valid service named %s" % (
                exploit.name,
                exploit.service,
            )

        persistance_path = os.path.join(self.usenix_conf.data_dir, "usenix.dat")
        self.logger.debug("Persistance path: %s", persistance_path)
        self.shelf = shelve.open(persistance_path)

        if init == True:
            self.shelf["PARTIAL"] = self.partial_round
            self.shelf["ROUND"] = self.current_round
            self.shelf["SCORES"] = self.team_scores
            self.shelf.sync()
        else:
            self.partial_round = self.shelf["PARTIAL"]
            self.current_round = self.shelf["ROUND"]
            self.team_scores = self.shelf["SCORES"]

    def setup(self, bot_server):
        self.bot_server = bot_server

    def handleBotMessage(self, msg, dispatcher):
        if msg.type == "CLIENT_HELLO":
            self.__handleNewClient(msg.data, dispatcher)
            if self.__checkStart():
                self.logger.info("Game Started")
                self.servicebot_dispatcher.sendMsg(BotMessage("EXECUTE_ROUND", self.partial_round))
                self.service_round += 1
                self.partial_round += 1

        elif msg.type == "SERVICE_RESULTS":
            partial_count = self.usenix_conf.getServiceRoundCount()
            self.recent_service_results = msg.data

            self.scoring.updateRoundResults(msg.data)
            if self.partial_round % (partial_count + 1) != partial_count:
                self.servicebot_dispatcher.sendMsg(BotMessage("EXECUTE_ROUND", self.service_round))
                self.service_round += 1
            else:
                self.exploitbot_dispatcher.sendMsg(BotMessage("EXECUTE_ROUND", self.exploit_round))
                self.exploit_round += 1
            self.partial_round += 1

        elif msg.type == "USENIX_EXPLOIT_RESULTS":
            self.logger.debug("Received exploit results!")
            sla_scores = self.scoring.getServiceSLA(self.usenix_conf.getServiceRoundCount())
            self.__updateTeamScores(msg.data, sla_scores)

            self.logger.info("=== End of Round %d ===" % self.current_round)
            for team in self.conf.teams:
                self.logger.info("Team %s: %f" % (team.name, self.team_scores[team.id]))

            if self.__endOfGame() == False:
                self.current_round += 1
                # Store round data..
                self.shelf["PARTIAL"] = self.partial_round
                self.shelf["ROUND"] = self.current_round
                self.shelf["SCORES"] = self.team_scores
                self.shelf.sync()

                self.logger.info("=== Reset Team Systems ===")
                reboot_thread = RebootThread(self)
                reboot_thread.daemon = True
                reboot_thread.start()
                """
				for team in self.conf.teams:
					subprocess.call([
						'/usr/bin/ssh',
						'-i/home/scorebot/.ssh/id_rsa',
						'root@'+team.host,
						'reboot'
						'&'],close_fds=True, shell=True)

				self.logger.debug("Wating for team systems to restart..")
				time.sleep(self.usenix_conf.rebootTime())

				self.servicebot_dispatcher.sendMsg(BotMessage("EXECUTE_ROUND",self.service_round))
				self.service_round += 1
				self.partial_round += 1
				"""

        elif msg.type == "REQUEST_REPORT":
            results = self.__buildReportResult()
            self.usenix_reportbot_dispatcher.sendMsg(BotMessage("REQUEST_REPORT_RESULT", results))

        else:
            self.logger.error("Unknown Message! Going to stop game! %s %s" % (msg.type, str(msg.data)))
            self.__stopGame()

    def __updateTeamScores(self, exploit_results, sla_scores):
        for exploit_result in exploit_results:
            exploitId, exploit_result_list = exploit_result
            serviceId = self.exploit_to_service_map[exploitId]
            service = self.servicebot_conf.getServiceInfoById(serviceId)
            exploit = self.usenix_conf.getExploitById(exploitId)
            for teamId, exploit_success, flags in exploit_result_list:
                team = self.conf.getTeamInfoById(teamId)
                exploit_success = self.__checkExploitSuccess(exploitId, teamId, exploit_success, flags)
                service_sla = 0.0
                if exploit_success == True:
                    service_sla = self.__getSLA(exploitId, teamId, sla_scores) / 3.0
                else:
                    service_sla += self.__getSLA(exploitId, teamId, sla_scores)

                self.team_scores[teamId] += service_sla
                self.logger.info(
                    "Team=%s service=%s (sla=%f) exploit=%s (success=%s)"
                    % (team.name, service.name, service_sla, exploit.name, str(exploit_success))
                )

    def __getSLA(self, exploitId, teamId, sla_scores):
        serviceId = self.exploit_to_service_map[exploitId]
        return sla_scores[teamId][serviceId]

    def __checkExploitSuccess(self, exploitId, teamId, exploit_success, flags):
        exploit = self.usenix_conf.exploits[exploitId]

        if exploit.captures_flags == False and exploit_success == True:
            return True

        if exploit.captures_flags == True:
            serviceId = self.exploit_to_service_map[exploitId]
            round_count = self.usenix_conf.getServiceRoundCount()
            for flag in flags:
                f = None
                try:
                    f = self.fm.toFlag(flag)
                except Exception:
                    self.logger.info("Exploit %s captured INVALID flag! (%r)" % (exploit.name, flag))
                    continue

                if f == None:
                    continue

                if f.teamId == teamId and f.serviceId == serviceId and self.service_round - f.round <= round_count:
                    self.logger.info("Exploit %s captured VALID flag!" % (exploit.name))
                    return True

                else:
                    self.logger.debug(
                        "INVALID flag! tid (%d,%d) sid(%d,%d) Current round=%d, flag round=%d total=%d"
                        % (f.teamId, teamId, f.serviceId, serviceId, self.service_round, f.round, round_count)
                    )

        return False

    def __stopGame(self):
        if self.exploitbot_dispatcher != None:
            self.exploitbot_dispatcher.sendMsg(BotMessage("TERMINATE", None))

        if self.servicebot_dispatcher != None:
            self.servicebot_dispatcher.sendMsg(BotMessage("TERMINATE", None))

        if self.usenix_scoreboard_dispatcher != None:
            self.usenix_scoreboard_dispatcher.sendMsg(BotMessage("TERMINATE", None))

        if self.usenix_resetbot_dispatcher != None:
            self.usenix_resetbot_dispatcher.sendMsg(BotMessage("TERMINATE", None))

        self.bot_server.close()

    def __handleNewClient(self, name, dispatcher):
        self.logger.info("New client: %s", name)

        if name == "USENIX_EXPLOIT_BOT":
            self.exploitbot_dispatcher = dispatcher

        if name == "SERVICE_BOT":
            self.servicebot_dispatcher = dispatcher

        if name == "USENIX_REPORT_BOT":
            self.usenix_reportbot_dispatcher = dispatcher

    def __checkStart(self):
        if self.exploitbot_dispatcher == None:
            return False

        if self.servicebot_dispatcher == None:
            return False

        if self.usenix_reportbot_dispatcher == None:
            return False

        return True

    def __endOfGame(self):
        if self.current_round == self.usenix_conf.getTotalGameRounds():
            self.logger.info("End of game!")
            self.__stopGame()
            return True
        return False

    def __buildReportResult(self):

        # { "team_name" : (team_score, [ (service_name, service status)] ) }

        results = {}
        service_stats = None
        if self.recent_service_results != None:
            round, service_stats = self.recent_service_results

        for team in self.conf.teams:
            service_result_list = []
            for service in self.servicebot_conf.services:
                if service_stats != None:
                    service_result_list.append((service.name, service_stats[team.id][service.id]))
                else:
                    service_result_list.append((service.name, "e"))

            results[team.name] = (self.team_scores[team.id], service_result_list)

        self.logger.debug("REPORT REQUEST RESULT: %r" % results)
        return results
Beispiel #4
0
class UsenixLogic(GameStateLogic):

	STATE_PRE_GAME_START = 0
	STATE_ROUND_RUNNING = 1
	STATE_EXPLOITS_RUNNING = 2
	STATE_UPDATE_SCOREBOARD = 3

	def __init__(self,conf,init=False):
		self.game_started = False
		self.conf = conf
		self.usenix_conf = conf.getSection("USENIX_CONFIG")
		self.servicebot_conf = conf.getSection("SERVICE_BOT")
		self.scoring = UsenixPrivateScoring(self.conf)

		self.usenix_resetbot_dispatcher = None
		self.exploitbot_dispatcher = None
		self.servicebot_dispatcher = None
		self.usenix_scoreboard_dispatcher = None
		self.usenix_reportbot_dispatcher = None

		self.partial_round = 0
		self.service_round = 0
		self.exploit_round = 0
		self.current_round = 1

		self.logger = self.conf.buildLogger("UsenixLogic")
		self.fm = self.conf.buildFlagManager()

		self.team_scores = [0.0] * self.conf.numTeams()
		self.recent_service_results = None

		self.exploit_to_service_map = [-1]*len(self.usenix_conf.exploits)
		for exploit in self.usenix_conf.exploits:
			for service in self.servicebot_conf.services:
				if(exploit.service == service.name):
					self.exploit_to_service_map[exploit.id] = service.id
					break

			assert(self.exploit_to_service_map[exploit.id] != -1),"Exploit %s - No valid service named %s" % (
				exploit.name,
				exploit.service)

		persistance_path = os.path.join(self.usenix_conf.data_dir,"usenix.dat")
		self.logger.debug("Persistance path: %s",persistance_path)
		self.shelf = shelve.open(persistance_path)

		if(init == True):
			self.shelf["PARTIAL"] = self.partial_round
			self.shelf["ROUND"] = self.current_round
			self.shelf["SCORES"] = self.team_scores
			self.shelf.sync()
		else:
			self.partial_round = self.shelf["PARTIAL"]
			self.current_round = self.shelf["ROUND"]
			self.team_scores = self.shelf["SCORES"]

	def setup(self,bot_server):
		self.bot_server = bot_server

	def handleBotMessage(self,msg,dispatcher):
		if(msg.type == "CLIENT_HELLO"):
			self.__handleNewClient(msg.data,dispatcher)
			if(self.__checkStart()):
				self.logger.info("Game Started")
				self.servicebot_dispatcher.sendMsg(BotMessage("EXECUTE_ROUND",self.partial_round))
				self.service_round += 1
				self.partial_round += 1

		elif(msg.type == "SERVICE_RESULTS"):
			partial_count = self.usenix_conf.getServiceRoundCount()
			self.recent_service_results = msg.data

			self.scoring.updateRoundResults(msg.data)
			if(self.partial_round % (partial_count+1) != partial_count):
				self.servicebot_dispatcher.sendMsg(BotMessage("EXECUTE_ROUND",self.service_round))
				self.service_round += 1
			else:
				self.exploitbot_dispatcher.sendMsg(BotMessage("EXECUTE_ROUND",self.exploit_round))
				self.exploit_round += 1
			self.partial_round += 1

		elif(msg.type == "USENIX_EXPLOIT_RESULTS"):
			self.logger.debug("Received exploit results!")
			sla_scores = self.scoring.getServiceSLA(self.usenix_conf.getServiceRoundCount())
			self.__updateTeamScores(msg.data,sla_scores)
			
			self.logger.info("=== End of Round %d ===" % self.current_round)
			for team in self.conf.teams:
				self.logger.info("Team %s: %f" % (team.name,self.team_scores[team.id]))

			if(self.__endOfGame() == False):
				self.current_round += 1
				#Store round data..
				self.shelf["PARTIAL"] = self.partial_round
				self.shelf["ROUND"] = self.current_round
				self.shelf["SCORES"] = self.team_scores
				self.shelf.sync()

				self.logger.info("=== Reset Team Systems ===")
				reboot_thread = RebootThread(self)
				reboot_thread.daemon = True
				reboot_thread.start()
				"""
				for team in self.conf.teams:
					subprocess.call([
						'/usr/bin/ssh',
						'-i/home/scorebot/.ssh/id_rsa',
						'root@'+team.host,
						'reboot'
						'&'],close_fds=True, shell=True)

				self.logger.debug("Wating for team systems to restart..")
				time.sleep(self.usenix_conf.rebootTime())

				self.servicebot_dispatcher.sendMsg(BotMessage("EXECUTE_ROUND",self.service_round))
				self.service_round += 1
				self.partial_round += 1
				"""

		elif(msg.type == "REQUEST_REPORT"):
			results = self.__buildReportResult()
			self.usenix_reportbot_dispatcher.sendMsg(BotMessage("REQUEST_REPORT_RESULT",results))

		else:
			self.logger.error("Unknown Message! Going to stop game! %s %s" % (msg.type,str(msg.data)))
			self.__stopGame()

	def __updateTeamScores(self,exploit_results,sla_scores):
		for exploit_result in exploit_results:
			exploitId, exploit_result_list = exploit_result
			serviceId = self.exploit_to_service_map[exploitId]
			service = self.servicebot_conf.getServiceInfoById(serviceId)
			exploit = self.usenix_conf.getExploitById(exploitId)
			for teamId,exploit_success,flags in exploit_result_list:
				team = self.conf.getTeamInfoById(teamId)
				exploit_success = self.__checkExploitSuccess(exploitId,teamId,exploit_success,flags)
				service_sla = 0.0
				if(exploit_success == True):
					service_sla = self.__getSLA(exploitId,teamId,sla_scores)/3.0
				else:
					service_sla += self.__getSLA(exploitId,teamId,sla_scores)

				self.team_scores[teamId] += service_sla
				self.logger.info("Team=%s service=%s (sla=%f) exploit=%s (success=%s)" % (
					team.name,
					service.name,
					service_sla,
					exploit.name,
					str(exploit_success)))

	def __getSLA(self,exploitId,teamId,sla_scores):
		serviceId = self.exploit_to_service_map[exploitId]
		return sla_scores[teamId][serviceId]

	def __checkExploitSuccess(self,exploitId,teamId,exploit_success,flags):
		exploit = self.usenix_conf.exploits[exploitId]

		if(exploit.captures_flags == False and exploit_success == True):
			return True

		if(exploit.captures_flags == True):
			serviceId = self.exploit_to_service_map[exploitId]
			round_count = self.usenix_conf.getServiceRoundCount()
			for flag in flags:
				f = None
				try: 
					f = self.fm.toFlag(flag)
				except Exception:
					self.logger.info("Exploit %s captured INVALID flag! (%r)" % (exploit.name,flag))
					continue

				if(f == None):
					continue

				if(	f.teamId == teamId and 
					f.serviceId == serviceId and
					self.service_round - f.round <= round_count):
					self.logger.info("Exploit %s captured VALID flag!" % (exploit.name))
					return True

				else:
					self.logger.debug("INVALID flag! tid (%d,%d) sid(%d,%d) Current round=%d, flag round=%d total=%d" % (
						f.teamId,teamId,
						f.serviceId,serviceId,
						self.service_round, f.round,round_count))
				
		return False

	def __stopGame(self):
		if(self.exploitbot_dispatcher != None):
			self.exploitbot_dispatcher.sendMsg(BotMessage("TERMINATE",None))

		if(self.servicebot_dispatcher != None):
			self.servicebot_dispatcher.sendMsg(BotMessage("TERMINATE",None))

		if(self.usenix_scoreboard_dispatcher != None):
			self.usenix_scoreboard_dispatcher.sendMsg(BotMessage("TERMINATE",None))

		if(self.usenix_resetbot_dispatcher != None):
			self.usenix_resetbot_dispatcher.sendMsg(BotMessage("TERMINATE",None))

		self.bot_server.close()

	def __handleNewClient(self,name,dispatcher):
		self.logger.info("New client: %s",name)

		if name == "USENIX_EXPLOIT_BOT":
			self.exploitbot_dispatcher = dispatcher

		if name == "SERVICE_BOT":
			self.servicebot_dispatcher = dispatcher

		if name == "USENIX_REPORT_BOT":
			self.usenix_reportbot_dispatcher = dispatcher

	def __checkStart(self):
		if(self.exploitbot_dispatcher == None):
			return False

		if(self.servicebot_dispatcher == None):
			return False

		if(self.usenix_reportbot_dispatcher == None):
			return False

		return True

	def __endOfGame(self):
		if(self.current_round == self.usenix_conf.getTotalGameRounds()):
			self.logger.info("End of game!")
			self.__stopGame()
			return True
		return False

	def __buildReportResult(self):

		# { "team_name" : (team_score, [ (service_name, service status)] ) }

		results = {}
		service_stats = None
		if(self.recent_service_results != None):
			round,service_stats =  self.recent_service_results

		for team in self.conf.teams:
			service_result_list = []
			for service in self.servicebot_conf.services:
				if(service_stats != None):
					service_result_list.append((service.name,service_stats[team.id][service.id]))
				else:
					service_result_list.append((service.name,'e'))

			results[team.name] = (self.team_scores[team.id],service_result_list)

		self.logger.debug("REPORT REQUEST RESULT: %r" % results)
		return results