class SubmitBot(Process): def __init__(self,conf,init=False): Process.__init__(self) self.conf = conf self.comm = None self.init = init self.webserver = WebserverThread(self.conf) def run(self): self.webserver.start() server_info = self.conf.getGameStateServerInfo() self.comm = BotCommClient( server_info.host, server_info.port, server_info.key, server_info.iv, "SUBMIT_BOT") self.running = True collector = getSharedCollector() try: self.comm.start() while(self.running): msg = self.comm.receive() assert(msg.type == "COLLECT_FLAGS") flags = collector.collect() self.comm.send(BotMessage("COLLECT_FLAGS_RESULT",flags)) self.comm.kill() except Exception as e: print "An exception occured in submitbot"
class UsenixReportBot(Process): def __init__(self, conf, port): Process.__init__(self) self.conf = conf self.comm = None self.cmd_q = None self.port = port self.logger = conf.buildLogger("UsenixReportBot") def cmd(self, cmd, q): self.cmd_q.put((cmd, q)) def run(self): self.cmd_q = Queue.Queue() server_info = self.conf.getGameStateServerInfo() self.comm = BotCommClient(server_info.host, server_info.port, server_info.key, server_info.iv, "USENIX_REPORT_BOT") self.comm.start() report_thread = UsenixReportServerThread(self, self.port) report_thread.setDaemon(True) report_thread.start() while (True): msg = self.comm.receive(False) if (msg != None): if (msg.type == "TERMINATE"): break try: cmd, q = self.cmd_q.get(True, 1) except Queue.Empty: continue if (cmd == "SLA_REQ"): self.comm.send(BotMessage("REQUEST_SLA", None)) msg = self.comm.receive() if (msg.type == "TERMINATE"): break elif (msg.type == "REQUEST_SLA_RESULT"): q.put(msg.data) elif (cmd == "SRV_REQ"): self.comm.send(BotMessage("REQUEST_REPORT", None)) msg = self.comm.receive() if (msg.type == "TERMINATE"): break elif (msg.type == "REQUEST_REPORT_RESULT"): q.put(msg.data) self.comm.kill()
def testBasicCommRequest(self): req = BotMessage("req1",["Foo","Bar"],True) comm = BotCommClient("",424242,self.key,self.iv,"ECHO") comm.start() rcv = comm.request(req,"req_result1",1.0) comm.kill() self.assert_(rcv.type == "req_result1") self.assert_(rcv.data == ["Foo","Bar"])
def testBasicCommRequest(self): req = BotMessage("req1", ["Foo", "Bar"], True) comm = BotCommClient("", 424242, self.key, self.iv, "ECHO") comm.start() rcv = comm.request(req, "req_result1", 1.0) comm.kill() self.assert_(rcv.type == "req_result1") self.assert_(rcv.data == ["Foo", "Bar"])
def testTypes(self): msg = BotMessage("rev", ["Foo", "Bar"]) comm = BotCommClient("", 424242, self.key, self.iv, "ECHO") comm.start() comm.send(msg) rcv = comm.receive(True, 5) comm.kill() self.assert_(rcv.type == "rev") self.assert_(rcv.data == ["Bar", "Foo"])
def testTypes(self): msg = BotMessage("rev",["Foo","Bar"]) comm = BotCommClient("",424242,self.key,self.iv,"ECHO") comm.start() comm.send(msg) rcv = comm.receive(True,5) comm.kill() self.assert_(rcv.type == "rev") self.assert_(rcv.data == ["Bar","Foo"])
def testManyMessage(self): comm = BotCommClient("",424242,self.key,self.iv,"ECHO") comm.start() for i in range(0,100): msg = BotMessage("norm",["Test_%d" % i]) comm.send(msg) for i in range(0,100): rcv = comm.receive(True,1) self.assert_(rcv.data == ["Test_%d" % i]) comm.kill()
def testManyMessage(self): comm = BotCommClient("", 424242, self.key, self.iv, "ECHO") comm.start() for i in range(0, 100): msg = BotMessage("norm", ["Test_%d" % i]) comm.send(msg) for i in range(0, 100): rcv = comm.receive(True, 1) self.assert_(rcv.data == ["Test_%d" % i]) comm.kill()
def testMultiMessage(self): m1 = BotMessage("norm",["Foo","Bar"]) m2 = BotMessage("rev",["Foo","Foo"]) comm = BotCommClient("",424242,self.key,self.iv,"ECHO") comm.start() comm.send(m1) comm.send(m2) r1 = comm.receive(True,1) r2 = comm.receive(True,1) comm.kill() self.assert_(r1.data == ["Foo","Bar"]) self.assert_(r2.data == ["Foo","Foo"])
def testMultiMessage(self): m1 = BotMessage("norm", ["Foo", "Bar"]) m2 = BotMessage("rev", ["Foo", "Foo"]) comm = BotCommClient("", 424242, self.key, self.iv, "ECHO") comm.start() comm.send(m1) comm.send(m2) r1 = comm.receive(True, 1) r2 = comm.receive(True, 1) comm.kill() self.assert_(r1.data == ["Foo", "Bar"]) self.assert_(r2.data == ["Foo", "Foo"])
def terminate(self): server_info = self.conf.getGameStateServerInfo() comm = BotCommClient( server_info.host, server_info.port, server_info.key, server_info.iv, "FLAG_SUBMISSION_BOT_KILL") comm.start() time.sleep(2) comm.kill() comm.join() Process.terminate(self)
def testMultipleClients(self): echo = BotCommClient("",424242,self.key,self.iv,"ECHO") foo = BotCommClient("",424242,self.key,self.iv,"FOO") echo.start() foo.start() m1 = BotMessage("norm",["Foo","Bar"]) m2 = BotMessage("foo","A foo") echo.send(m1) foo.send(m2) r1 = echo.receive(True,1) foo.kill() echo.kill()
def testMultipleClients(self): echo = BotCommClient("", 424242, self.key, self.iv, "ECHO") foo = BotCommClient("", 424242, self.key, self.iv, "FOO") echo.start() foo.start() m1 = BotMessage("norm", ["Foo", "Bar"]) m2 = BotMessage("foo", "A foo") echo.send(m1) foo.send(m2) r1 = echo.receive(True, 1) foo.kill() echo.kill()
class SubmitBot(Process): def __init__(self,conf,init=False): Process.__init__(self) self.conf = conf self.comm = None self.init = init self.webserver = WebserverThread(self.conf) self.logger = conf.buildLogger("SubmitBot") def run(self): self.logger.debug("Starting SubmitBot webserver thread") self.webserver.start() server_info = self.conf.getGameStateServerInfo() self.comm = BotCommClient( server_info.host, server_info.port, server_info.key, server_info.iv, "SUBMIT_BOT") self.running = True collector = getSharedCollector() try: self.comm.start() while(self.running): msg = self.comm.receive() assert(msg.type == "COLLECT_FLAGS") flags = collector.collect() self.comm.send(BotMessage("COLLECT_FLAGS_RESULT",flags)) self.comm.kill() except Exception as e: self.logger.error("Exception %s" % e)
def testCommRequestExtraMessage(self): req = BotMessage("req2",["Foo","Bar"],True) comm = BotCommClient("",424242,self.key,self.iv,"ECHO") comm.start() for i in range(0,50): msg = BotMessage("norm",["Test_%d" % i]) comm.send(msg) for i in xrange(5): rcv = comm.request(req,"req_result2",1.0) self.assertEquals(rcv.type,"req_result2") self.assertEquals(rcv.data,["Foo","Bar"]) for i in range(0,50): rcv = comm.receive(True,1) self.assert_(rcv.data == ["Test_%d" % i]) for i in xrange(5): xtra = comm.receive(True,1) self.assert_(xtra != None) self.assertEquals(xtra.data,i+1) comm.kill()
def testCommRequestExtraMessage(self): req = BotMessage("req2", ["Foo", "Bar"], True) comm = BotCommClient("", 424242, self.key, self.iv, "ECHO") comm.start() for i in range(0, 50): msg = BotMessage("norm", ["Test_%d" % i]) comm.send(msg) for i in xrange(5): rcv = comm.request(req, "req_result2", 1.0) self.assertEquals(rcv.type, "req_result2") self.assertEquals(rcv.data, ["Foo", "Bar"]) for i in range(0, 50): rcv = comm.receive(True, 1) self.assert_(rcv.data == ["Test_%d" % i]) for i in xrange(5): xtra = comm.receive(True, 1) self.assert_(xtra != None) self.assertEquals(xtra.data, i + 1) comm.kill()
def testServerStatePassing(self): foo = BotCommClient("",424242,self.key,self.iv,"FOO") bar = BotCommClient("",424242,self.key,self.iv,"BAR") echo = BotCommClient("",424242,self.key,self.iv,"ECHO") foo.start() bar.start() echo.start() m1 = BotMessage("foo","A foo message") m2 = BotMessage("norm",["Foo","Bar"]) for i in range(3): foo.send(m1) echo.send(m2) r1 = echo.receive(True,1) r2 = bar.receive(True,1) self.assert_(r1.data == ["Foo","Bar"]) self.assert_(r2.data == "Got Foo?") foo.kill() bar.kill() echo.kill()
def testServerStatePassing(self): foo = BotCommClient("", 424242, self.key, self.iv, "FOO") bar = BotCommClient("", 424242, self.key, self.iv, "BAR") echo = BotCommClient("", 424242, self.key, self.iv, "ECHO") foo.start() bar.start() echo.start() m1 = BotMessage("foo", "A foo message") m2 = BotMessage("norm", ["Foo", "Bar"]) for i in range(3): foo.send(m1) echo.send(m2) r1 = echo.receive(True, 1) r2 = bar.receive(True, 1) self.assert_(r1.data == ["Foo", "Bar"]) self.assert_(r2.data == "Got Foo?") foo.kill() bar.kill() echo.kill()
class UsenixExploitBot(Process): def __init__(self, conf, init=False): Process.__init__(self) self.conf = conf self.comm = None self.logger = conf.buildLogger("UsenixExploitBot") self.usenix_conf = self.conf.getSection("USENIX_CONFIG") self.exploits = {} def run(self): self.__processConfig() server_info = self.conf.getGameStateServerInfo() self.comm = BotCommClient(server_info.host, server_info.port, server_info.key, server_info.iv, "USENIX_EXPLOIT_BOT") self.comm.start() while (True): msg = self.comm.receive() self.logger.debug("recvd msg: %s (%r)" % (msg.type, str(msg.data))) if (msg.type == "TERMINATE"): self.logger.info("Received TERM message from gameserver") break elif (msg.type == "EXECUTE_ROUND"): results = self.__executeExploits(msg.data) self.comm.send(BotMessage("USENIX_EXPLOIT_RESULTS", results)) else: assert (False), "Invalid msg type received" self.comm.kill() def __executeExploits(self, round): self.logger.info("=== Exploit Round(%d) Starting ===" % round) all_tasks = [] #Select exploits for this round for service, exploit_tasks in self.exploits.items(): exploit, exploit_task_list = random.choice(exploit_tasks) self.logger.info("Using %s against service %s" % (exploit.name, service)) all_tasks.append((exploit, exploit_task_list)) #Start selected exploits for exploit, exploit_task_list in all_tasks: for exploit_task in exploit_task_list: exploit_task.launch() #time.sleep(usenix_conf.exploit_round_time_seconds) #Run selected exploits exploit_round_time = int(self.usenix_conf.getExploitRoundTime()) for i in xrange(exploit_round_time): for exploit, exploit_task_list in all_tasks: for exploit_task in exploit_task_list: exploit_task.processOutput() time.sleep(1) #Stop selected exploits self.logger.info("=== Exploit Round(%d) Ending ===" % round) for exploit, exploit_task_list in all_tasks: for exploit_task in exploit_task_list: exploit_task.stop() exploit_task.processOutput() #Generate results results = [] for exploit, exploit_task_list in all_tasks: team_results = [] for exploit_task in exploit_task_list: team = exploit_task.getTeam() teamId = team.id flags = exploit_task.collectFlags() success = exploit_task.exploitSuccess() team_results.append((teamId, success, flags)) exploit_task.clearExploitSuccess() self.logger.debug( "Results: Exploit=%s Team=%s Success=%s Num Flags=%d" % (exploit.name, team.name, str(success), len(flags))) results.append((exploit.id, team_results)) return results def __processConfig(self): for exploit in self.usenix_conf.exploits: if (exploit.service not in self.exploits): self.exploits[exploit.service] = [] exploit_tasks = [] task_logger = self.conf.buildLogger("Exploit-%s " % exploit.name) task_path = os.path.join(self.usenix_conf.exploit_dir, exploit.name) for team in self.conf.teams: task = UsenixExploitTask(task_path, team, task_logger) exploit_tasks.append(task) self.exploits[exploit.service].append((exploit, exploit_tasks))
class StaticFlagBot(Process): def __init__(self,conf,init=False): Process.__init__(self) self.conf = conf self.comm = None self.logger = conf.buildLogger("StaticFlagBot") self.init = init self.staticFlagConf = self.conf.getSection("STATICFLAG_BOT") if self.staticFlagConf.genflags: self.logger.info("Generating Static Eggs") self._genFlags() else: self.logger.info("Not Generating Static Eggs") self.logger.info("In Static Flag Init about to start Webserver") self.webserver = WebserverThread(self.conf) self.logger.info("In Static Flag Init started Webserver") def _genFlags(self): path = os.path.relpath(os.path.dirname(__file__),sys.path[0]) f = open(path+"/eggs.txt",'w') self.flag_manager = self.conf.buildFlagManager() for i in range(0,9999): flag = Flag(99,99,9999,i) flagText = self.flag_manager.toTxt(flag) egg = "EGG"+flagText[3:] f.write(egg+"\n") f.close() def run(self): self.webserver.start() server_info = self.conf.getGameStateServerInfo() self.comm = BotCommClient( server_info.host, server_info.port, server_info.key, server_info.iv, "STATICFLAG_BOT") self.running = True collector = getSharedCollector() collectorEgg = getSharedEggCollector() try: self.comm.start() while(self.running): #comms hub msg msg = self.comm.receive() #got msg to collect the flags and send them to the caller. assert(msg.type == "COLLECT_STATIC_FLAGS") #collector is the "shared memory" between the webserver and this bot. flags = collector.collect() eggs = collectorEgg.collect() #sending the collected flags self.comm.send(BotMessage("COLLECT_FLAGS_RESULT",flags)) self.comm.send(BotMessage("COLLECT_STATIC_FLAGS_RESULT",eggs)) self.comm.kill() except Exception as e: self.logger("An exception occured in staticflagbot")
class AttackBot(Process): def __init__(self, conf, init=False, auto_restart=True): Process.__init__(self) self.conf = conf self.comm = None self.init = init self.logger = conf.buildLogger("AttackBot") self.attack_manager = AttackManager(conf, self.logger, init, auto_restart) self.auto_restart = auto_restart self.attack_conf = self.conf.getSection("ATTACK_BOT") self.round_time = self.attack_conf.roundInterval() def run(self): self.attack_manager.start() server_info = self.conf.getGameStateServerInfo() self.comm = BotCommClient(server_info.host, server_info.port, server_info.key, server_info.iv, "ATTACK_BOT") self.comm.start() if (self.auto_restart == True): self.logger.info("Starting (AUTO Logic)") self.__mainLoopAuto() else: self.logger.info("Starting (WAIT Logic)") self.__mainLoopWait() def __mainLoopWait(self): while (True): msg = self.comm.receive() self.logger.debug("Wait logic processing msg: %s (%s)" % (msg.type, str(msg.data))) if (msg.type == "EXECUTE_EXPLOITS"): exploits = msg.data for exploit in exploits: self.attack_manager.cmd(AttackManager.LAUNCH_EXPLOIT, exploit) elif (msg.type == "UPDATE_EXPLOITS"): self.attack_manager.cmd(AttackManager.UPDATE_EXPLOITS) elif (msg.type == "PROCESS_OUTPUT"): self.attack_manager.cmd(AttackManager.PROCESS_OUTPUT) elif (msg.type == "GATHER_FLAGS"): self.attack_manager.cmd(AttackManager.GATHER_FLAGS) collected = [] while (True): try: collected.append( self.attack_manager.collected_flags.get(True, 1)) except Queue.Empty: break self.comm.send(BotMessage("COLLECTED_FLAGS", collected)) elif (msg.type == "STOP_EXPLOITS"): self.attack_manager.cmd(AttackManager.STOP_ALL) elif (msg.type == "TERMINATE"): self.comm.kill() break else: assert (False), "Invalid msg type received" def __mainLoopAuto(self): while (True): msg = self.comm.receive(True, 1) if (msg != None): if (msg.type == "TERMINATE"): self.comm.kill() break elif (msg.type == "NEW_EXPLOIT"): self.__newExploit(msg.data[0], msg.data[1]) elif (msg.type == "LIST_EXPLOITS"): exploits = self.__listExploits() self.comm.sendResponse( msg, BotMessage("LIST_EXPLOITS_RESULT", exploits)) elif (msg.type.startswith("GET_LOG:")): payload = msg.type[8:] (exploit, lines) = payload.split("|") lines = int(lines) log_data = self.__getLog(exploit, lines) self.comm.sendResponse( msg, BotMessage("GET_LOG_RESULT:%s" % exploit, log_data)) elif (msg.type.startswith("GET_EXPLOIT:")): exploit = msg.type[12:] data = self.__getExploit(exploit) self.comm.sendResponse( msg, BotMessage("GET_EXPLOIT_RESULT:%s" % exploit, data)) elif (msg.type.startswith("TOGGLE_EXPLOIT:")): exploit = msg.type[15:] self.__toggleExploit(exploit) else: flags = self.attack_manager.getFlags() if (len(flags) != 0): self.comm.send(BotMessage("COLLECTED_FLAGS", flags)) def __newExploit(self, filename, filedata): self.logger.info("New exploit uploaded: %s" % filename) exploit_dir = self.attack_conf.exploitDir() path = os.path.join(exploit_dir, filename) exploit_file = open(path, "w") exploit_file.write(filedata) exploit_file.close() os.chmod(path, stat.S_IRWXU | stat.S_IRWXO | stat.S_IRWXG) def __toggleExploit(self, exploit): exploit_dir = self.attack_conf.exploitDir() exploit_path = os.path.join(exploit_dir, exploit) if (exploit.endswith(".bin") or exploit.endswith(".dat")): self.logger.warn("Tried to toggled data file %s" % exploit) elif (os.path.exists(exploit_path) and not os.path.isdir(exploit_path)): if (os.access(exploit_path, os.X_OK)): self.logger.info("Toggled %s off" % exploit) os.chmod( exploit_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH | stat.S_IWOTH) else: self.logger.info("Toggled %s on" % exploit) os.chmod(exploit_path, stat.S_IRWXU | stat.S_IRWXO | stat.S_IRWXG) else: self.logger.warn("Tried to toggle unknown exploit: %s" % exploit) def __listExploits(self): exploit_dir = self.attack_conf.exploitDir() exploits = [] for file in os.listdir(exploit_dir): path = os.path.join(exploit_dir, file) if (os.path.isdir(path) == True or path.endswith(".bin") or path.endswith(".dat")): continue if (os.access(path, os.X_OK)): exploits.append((file, True)) else: exploits.append((file, False)) return exploits def __getExploit(self, exploit): try: exploit_dir = self.attack_conf.exploitDir() path = os.path.join(exploit_dir, exploit) file = open(path, "r") data = file.read() return data except: return None def __getLog(self, exploit, nLines): try: log = os.path.join(self.conf.log_dir, "Exploit-%s.log" % exploit) file = open(log, "r") file.seek(0, os.SEEK_END) fsize = file.tell() file.seek(max(fsize - 65536, 0), 0) lines = file.readlines() if len(lines) > nLines: lines = lines[-nLines:] return lines except Exception as e: self.logger.error("Error getting exploit log: %s" % e) return []
class ServiceBot(Process): def __init__(self, conf, init=False): Process.__init__(self) self.conf = conf self.servicebot_conf = conf.getSection("SERVICE_BOT") self.comm = None self.init = init self.logger = conf.buildLogger("ServiceBot") self.scheduler = None def run(self): self.scheduler = ServiceTaskScheduler(self.conf, self.init) try: self.logger.info("=== Starting ===") server_info = self.conf.getGameStateServerInfo() self.comm = BotCommClient(server_info.host, server_info.port, server_info.key, server_info.iv, "SERVICE_BOT") self.comm.start() running = True while (running): msg = self.comm.receive() self.logger.debug("recvd msg: %s (%r)" % (msg.type, str(msg.data))) if (msg.type == "EXECUTE_ROUND"): round = msg.data self.logger.info("=== Service Round(%d) Starting ===" % round) results = self.scheduler.execute(round) result_msg = self.__parseResults(round, results) self.comm.send(result_msg) self.logger.debug("Results: %r" % str(result_msg.data)) self.logger.info("=== Service Round(%d) Ending ===" % round) elif (msg.type == "TERMINATE"): self.logger.info("Received TERM message from gameserver") running = False else: self.logger.error("Unknown message: %s %s" % (msg.type, str(msg.data))) assert (False) except KeyboardInterrupt: self.logger.warn("Servicebot caught Keyboard Interrupt!") finally: #cleanup self.logger.info("Terminating...") # FIXME - What is this comment for? print "WTF", self.scheduler self.scheduler.quit() self.comm.kill() self.logger.info("Terminated...") def __parseResults(self, round, task_results): results = [] for teamId in xrange(self.conf.numTeams()): results.append([]) for serviceId in xrange(self.servicebot_conf.numServices()): results[teamId].append(None) for team, service, task in task_results: if (task.gotExpectedFlag()): results[team.id][service.id] = 'g' elif (task.error() == None and task.retcode() == 0): results[team.id][service.id] = 'b' else: results[team.id][service.id] = 'e' for teamId in xrange(self.conf.numTeams()): for serviceId in xrange(self.servicebot_conf.numServices()): assert (results[teamId][serviceId] != None) return BotMessage("SERVICE_RESULTS", (round, results))
class AttackBot(Process): def __init__(self,conf,init=False,auto_restart=True): Process.__init__(self) self.conf = conf self.comm = None self.init = init self.logger = conf.buildLogger("AttackBot") self.attack_manager = AttackManager(conf,self.logger,init,auto_restart) self.auto_restart = auto_restart self.attack_conf = self.conf.getSection("ATTACK_BOT") self.round_time = self.attack_conf.roundInterval() def run(self): self.attack_manager.start() server_info = self.conf.getGameStateServerInfo() self.comm = BotCommClient( server_info.host, server_info.port, server_info.key, server_info.iv, "ATTACK_BOT") self.comm.start() if(self.auto_restart == True): self.logger.info("Starting (AUTO Logic)") self.__mainLoopAuto() else: self.logger.info("Starting (WAIT Logic)") self.__mainLoopWait() def __mainLoopWait(self): while(True): msg = self.comm.receive() self.logger.debug("Wait logic processing msg: %s (%s)" % (msg.type,str(msg.data))) if(msg.type == "EXECUTE_EXPLOITS"): exploits = msg.data for exploit in exploits: self.attack_manager.cmd(AttackManager.LAUNCH_EXPLOIT,exploit) elif(msg.type == "UPDATE_EXPLOITS"): self.attack_manager.cmd(AttackManager.UPDATE_EXPLOITS) elif(msg.type == "PROCESS_OUTPUT"): self.attack_manager.cmd(AttackManager.PROCESS_OUTPUT) elif(msg.type == "GATHER_FLAGS"): self.attack_manager.cmd(AttackManager.GATHER_FLAGS) collected = [] while(True): try: collected.append( self.attack_manager.collected_flags.get(True,1)) except Queue.Empty: break self.comm.send(BotMessage("COLLECTED_FLAGS",collected)) elif(msg.type == "STOP_EXPLOITS"): self.attack_manager.cmd(AttackManager.STOP_ALL) elif(msg.type == "TERMINATE"): self.comm.kill() break else: assert(False),"Invalid msg type received" def __mainLoopAuto(self): while(True): msg = self.comm.receive(True,1) if(msg != None): if(msg.type == "TERMINATE"): self.comm.kill() break elif(msg.type == "NEW_EXPLOIT"): self.__newExploit(msg.data[0],msg.data[1]) elif(msg.type == "LIST_EXPLOITS"): exploits = self.__listExploits() self.comm.sendResponse(msg,BotMessage("LIST_EXPLOITS_RESULT",exploits)) elif(msg.type.startswith("GET_LOG:")): payload = msg.type[8:] (exploit, lines) = payload.split("|") lines = int(lines) log_data = self.__getLog(exploit,lines) self.comm.sendResponse(msg,BotMessage("GET_LOG_RESULT:%s" % exploit, log_data)) elif(msg.type.startswith("GET_EXPLOIT:")): exploit = msg.type[12:] data = self.__getExploit(exploit) self.comm.sendResponse(msg,BotMessage("GET_EXPLOIT_RESULT:%s" % exploit, data)) elif(msg.type.startswith("TOGGLE_EXPLOIT:")): exploit = msg.type[15:] self.__toggleExploit(exploit) else: flags = self.attack_manager.getFlags() if(len(flags) != 0): self.comm.send(BotMessage("COLLECTED_FLAGS",flags)) def __newExploit(self,filename,filedata): self.logger.info("New exploit uploaded: %s" % filename) exploit_dir = self.attack_conf.exploitDir() path = os.path.join(exploit_dir,filename) exploit_file = open(path,"w") exploit_file.write(filedata) exploit_file.close() os.chmod(path,stat.S_IRWXU | stat.S_IRWXO | stat.S_IRWXG) def __toggleExploit(self,exploit): exploit_dir = self.attack_conf.exploitDir() exploit_path = os.path.join(exploit_dir,exploit) if( exploit.endswith(".bin") or exploit.endswith(".dat")): self.logger.warn("Tried to toggled data file %s" % exploit) elif(os.path.exists(exploit_path) and not os.path.isdir(exploit_path)): if(os.access(exploit_path,os.X_OK)): self.logger.info("Toggled %s off" % exploit) os.chmod(exploit_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH | stat.S_IWOTH ) else: self.logger.info("Toggled %s on" % exploit) os.chmod(exploit_path,stat.S_IRWXU | stat.S_IRWXO | stat.S_IRWXG) else: self.logger.warn("Tried to toggle unknown exploit: %s" % exploit) def __listExploits(self): exploit_dir = self.attack_conf.exploitDir() exploits = [] for file in os.listdir(exploit_dir): path = os.path.join(exploit_dir,file) if( os.path.isdir(path) == True or path.endswith(".bin") or path.endswith(".dat")): continue if(os.access(path,os.X_OK)): exploits.append((file,True)) else: exploits.append((file,False)) return exploits def __getExploit(self, exploit): try: exploit_dir = self.attack_conf.exploitDir() path = os.path.join(exploit_dir,exploit) file = open(path,"r") data = file.read() return data except: return None def __getLog(self, exploit, nLines): try: log = os.path.join(self.conf.log_dir,"Exploit-%s.log"%exploit) file = open(log,"r") file.seek(0,os.SEEK_END) fsize = file.tell() file.seek(max(fsize-65536,0),0) lines = file.readlines() if len(lines) > nLines: lines = lines[-nLines:] return lines except Exception as e: self.logger.error("Error getting exploit log: %s" % e) return []
class UsenixReportBot(Process): def __init__(self,conf,port): Process.__init__(self) self.conf = conf self.comm = None self.cmd_q = None self.port = port self.logger = conf.buildLogger("UsenixReportBot") def cmd(self,cmd,q): self.cmd_q.put((cmd,q)) def run(self): self.cmd_q = Queue.Queue() server_info = self.conf.getGameStateServerInfo() self.comm = BotCommClient( server_info.host, server_info.port, server_info.key, server_info.iv, "USENIX_REPORT_BOT") self.comm.start() report_thread = UsenixReportServerThread(self,self.port) report_thread.setDaemon(True) report_thread.start() while(True): msg = self.comm.receive(False) if(msg != None): if(msg.type == "TERMINATE"): break try: cmd,q = self.cmd_q.get(True,1) except Queue.Empty: continue if(cmd == "SLA_REQ"): self.comm.send(BotMessage("REQUEST_SLA",None)) msg = self.comm.receive() if(msg.type == "TERMINATE"): break elif(msg.type == "REQUEST_SLA_RESULT"): q.put(msg.data) elif(cmd == "SRV_REQ"): self.comm.send(BotMessage("REQUEST_REPORT",None)) msg = self.comm.receive() if(msg.type == "TERMINATE"): break elif(msg.type == "REQUEST_REPORT_RESULT"): q.put(msg.data) self.comm.kill()
class UsenixExploitBot(Process): def __init__(self,conf,init=False): Process.__init__(self) self.conf = conf self.comm = None self.logger = conf.buildLogger("UsenixExploitBot") self.usenix_conf = self.conf.getSection("USENIX_CONFIG") self.exploits = {} def run(self): self.__processConfig() server_info = self.conf.getGameStateServerInfo() self.comm = BotCommClient( server_info.host, server_info.port, server_info.key, server_info.iv, "USENIX_EXPLOIT_BOT") self.comm.start() while(True): msg = self.comm.receive() self.logger.debug("recvd msg: %s (%r)" % (msg.type,str(msg.data))) if(msg.type == "TERMINATE"): self.logger.info("Received TERM message from gameserver") break elif(msg.type == "EXECUTE_ROUND"): results = self.__executeExploits(msg.data) self.comm.send(BotMessage("USENIX_EXPLOIT_RESULTS",results)) else: assert(False),"Invalid msg type received" self.comm.kill() def __executeExploits(self,round): self.logger.info("=== Exploit Round(%d) Starting ===" % round) all_tasks = [] #Select exploits for this round for service,exploit_tasks in self.exploits.items(): exploit,exploit_task_list = random.choice(exploit_tasks) self.logger.info("Using %s against service %s" % (exploit.name,service)) all_tasks.append((exploit,exploit_task_list)) #Start selected exploits for exploit,exploit_task_list in all_tasks: for exploit_task in exploit_task_list: exploit_task.launch() #time.sleep(usenix_conf.exploit_round_time_seconds) #Run selected exploits exploit_round_time = int(self.usenix_conf.getExploitRoundTime()) for i in xrange(exploit_round_time): for exploit,exploit_task_list in all_tasks: for exploit_task in exploit_task_list: exploit_task.processOutput() time.sleep(1) #Stop selected exploits self.logger.info("=== Exploit Round(%d) Ending ===" % round) for exploit,exploit_task_list in all_tasks: for exploit_task in exploit_task_list: exploit_task.stop() exploit_task.processOutput() #Generate results results = [] for exploit,exploit_task_list in all_tasks: team_results = [] for exploit_task in exploit_task_list: team = exploit_task.getTeam() teamId = team.id flags = exploit_task.collectFlags() success = exploit_task.exploitSuccess() team_results.append((teamId,success,flags)) exploit_task.clearExploitSuccess() self.logger.debug("Results: Exploit=%s Team=%s Success=%s Num Flags=%d" %( exploit.name,team.name,str(success),len(flags))) results.append((exploit.id,team_results)) return results def __processConfig(self): for exploit in self.usenix_conf.exploits: if(exploit.service not in self.exploits): self.exploits[exploit.service] = [] exploit_tasks = [] task_logger = self.conf.buildLogger("Exploit-%s " %exploit.name) task_path = os.path.join(self.usenix_conf.exploit_dir,exploit.name) for team in self.conf.teams: task = UsenixExploitTask(task_path,team,task_logger) exploit_tasks.append(task) self.exploits[exploit.service].append((exploit,exploit_tasks))
class ServiceBot(Process): def __init__(self,conf,init=False): Process.__init__(self) self.conf = conf self.servicebot_conf = conf.getSection("SERVICE_BOT") self.comm = None self.init = init self.logger = conf.buildLogger("ServiceBot") self.scheduler = None def run(self): self.scheduler = ServiceTaskScheduler(self.conf,self.init) try: self.logger.info("=== Starting ===") server_info = self.conf.getGameStateServerInfo() self.comm = BotCommClient( server_info.host, server_info.port, server_info.key, server_info.iv, "SERVICE_BOT") self.comm.start() running = True while(running): msg = self.comm.receive() self.logger.debug("recvd msg: %s (%r)" % (msg.type,str(msg.data))) if(msg.type == "EXECUTE_ROUND"): round = msg.data self.logger.info("=== Service Round(%d) Starting ===" % round) results = self.scheduler.execute(round) result_msg = self.__parseResults(round,results) self.comm.send(result_msg) self.logger.debug("Results: %r" % str(result_msg.data)) self.logger.info("=== Service Round(%d) Ending ===" % round) elif(msg.type == "TERMINATE"): self.logger.info("Received TERM message from gameserver") running = False else: self.logger.error("Unknown message: %s %s" % (msg.type,str(msg.data))) assert(False) except KeyboardInterrupt: self.logger.warn("Servicebot caught Keyboard Interrupt!") finally: #cleanup self.logger.info("Terminating...") print "WTF",self.scheduler self.scheduler.quit() self.comm.kill() self.logger.info("Terminated...") def __parseResults(self,round,task_results): results = [] for teamId in xrange(self.conf.numTeams()): results.append([]) for serviceId in xrange(self.servicebot_conf.numServices()): results[teamId].append(None) for team,service,task in task_results: if(task.gotExpectedFlag()): results[team.id][service.id] = 'g' elif(task.error() == None and task.retcode() == 0): results[team.id][service.id] = 'b' else: results[team.id][service.id] = 'e' for teamId in xrange(self.conf.numTeams()): for serviceId in xrange(self.servicebot_conf.numServices()): assert(results[teamId][serviceId] != None) return BotMessage("SERVICE_RESULTS",(round,results))