def check_loaded(self): """Check all loaded commands and methods, reporting on any clashes""" try: ##print("Checking loaded") loaded_methods = {} help = {} for agent in self.active_agents: for mod in agent.modules.keys(): #print("DEBUG _ TRying to add to loaded methods: {}\n adding help for {}\n from {}".format(loaded_methods, mod, agent.modules)) loaded_methods[mod] = agent.modules[mod]['help'] help[mod] = agent.modules[mod]['commands'] #print("Check loaded retunred: {}".format(loaded_methods)) #Finally, set the global loaded methods variable self.loaded_methods = loaded_methods for h in help.values(): for cmd, hlp in h.items(): self.method_help[cmd] = hlp #Now check if any agents are missing a methods for agent in self.active_agents: for mod, meths in self.loaded_methods.items(): #print("DEBUG - Agent: {} module: {}, methods: {}".format(agent.name, mod, meths)) if mod not in agent.modules: bc.warn_print( "\n[!] ", "- Agent: {} missing module: {}.\n".format( agent.name, mod)) return False #print("DEBUG - loaded_methods: {}".format(self.loaded_methods)) except: bc.err_print( "[!] ", "Error checking loaded modules, are some agents missing modules?" )
def check_root(no_confirm): """Check user privs and prompt user that they may want to elevate to enable certain networking stuff""" decision = '' if sys.platform == 'win32': if not ctypes.windll.shell32.IsUserAnAdmin() != 0 and not no_confirm: bc.warn_print( "[!] ", "- You are not running as Admin, you may not be able to do certain actions, e.g. bind to low ports." ) while decision != 'y' and decision != 'n': decision = input( "Do you want to continue anyway? [y/n]:").lower() if decision == 'n': sys.exit(0) else: pass else: if os.getuid() != 0 and not no_confirm: bc.warn_print( "[!] ", "- You are not running as root, you may not be able to do certain actions, e.g. bind to low ports." ) while decision != 'y' and decision != 'n': decision = input( "Do you want to continue anyway? [y/n]:").lower() if decision == 'n': sys.exit(0) else: pass
def do_load(self, line): """Load a module into agent, implant or menu, based off module spec files, which are found and loaded into the menu, agent and implant as needed.""" if not line: bc.warn_print("[!] ", "No module specified.") return try: #Load module functionality into agent(s) module_spec = self.load_path + line + '.yml' bc.blue_print("[+] ", "- Loading module: {}".format(line)) with open(module_spec) as f: ms = yaml.load(f, Loader=yaml.FullLoader) #Menu modules not often loaded, so check before you load. for m in ms['methods']: if m['menu']: self.load_methods(ms) for agent in self.active_agents: #agent.load_agent_methods(ms) agent.send_q.put('load_agent_methods ') agent.send_q.put(ms) time.sleep(1) #Let agent catch up, smooths experience for user self.check_loaded() bc.blue_print("[+] ", "Load command sent.") ms = '' #reset variable #Now load agent and implant modules except Exception as e: bc.err_print("[!] ", "- Exception loading menu module:\n{}".format(e)) finally: self.check_loaded()
def set_option(self, opt, val): """Apply a value to a given setting """ #Don't allow us to add options! if not opt in self.options: bc.warn_print("[!] ", "- {} not a valid option!".format(opt)) return False self.options[opt]['value'] = val return True
def do_set(self, line): """Setting of a global option associated with the root menu.""" option, value, line = self.parseline(line) if not option in self.global_options: bc.warn_print("[!] ", "- {} not a valid option!".format(option)) else: self.global_options[option] = value bc.blue_print("[-] ", "{} set to: {}".format(option, value))
def do_sleep(self, line): """Sleep the Blackfell Shell, for a number of seconds. Occasionally useful in scripting and resource files.""" try: time.sleep(float(line)) except Exception as e: bc.warn_print( "[!] ", "Could not sleep for {} seconds. Exception:\n{}".format( iline, e))
def get_network(self): """Get network interface information to auto-populate listener settings""" test_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: test_sock.connect(("1.1.1.1", 1)) self.global_options['LHOST'] = test_sock.getsockname()[0] except: bc.warn_print( "[!] ", "- Error setting global LHOST, check network settings") self.global_options['LHOST'] = "" finally: test_sock.close()
def do_list(self, line): """list all listener and agent threads, both running and dead""" if line == 'listeners': self.list_listeners() elif line == 'agents': self.list_agents() elif line == 'payloads': bc.warn_print("[-] ", "- TODO - Impelement payload listing.") elif line == 'loot': bc.warn_print("[-] ", "- TODO - Impelement payload listing.") else: self.list_listeners() self.list_agents()
def do_set(self, line): """Set a module option, using the set_option method in the module itself""" cmd, args, line = self.parseline(line) try: if self.module_instance.set_option(cmd, args) and args: #TODO - do menu - side verification of this #Like - if self.module_instance.set_attr(cmd, args) and getattr(self.module_instance.options, cmd)['value'] == args: bc.green_print( "[-] ", "- {} set successfully to {}.".format(cmd, args)) elif not args: bc.warn_print("[!] ", "- No value provided.") else: bc.err_print( "[!] ", "- Error, {} could not be set to {}".format(cmd, args)) except Exception as e: bc.err_print("\n[!] ", "- Exception whilst setting {}:\n{}\n".format(cmd, e))
def run(self): col = self.color['value'] msg = self.message['value'] bc.green_print("[!] ", "- Print incoming!") #Override with what to do with this class when it runs for time in range(self.num_prints['value']): if col == 'red': bc.err_print(msg, "") elif col == 'orange': bc.warn_print(msg, "") elif self.color['value'] == 'blue': bc.blue_print(msg, "") elif self.color['value'] == 'green': bc.green_print(msg, "") else: print(msg) if bool(self.exit_on_exec['value']) == True: bc.green_print("[!] ", "- Module executed, exiting.") return True
def run(self): """Main function run when Agent thread is started""" #Initial setup if not self.CRYPTSETUP(): bc.err("Encryption setup failed. Exiting.") self.terminate() return bc.success("Established encrypted session : {}".format(self.name), True) self.REGISTER() #Main loop while True: if self.kill_flag.is_set(): try: self.send('terminate') self.s.shutdown(socket.SHUT_RDWR) except Exception as e: pass #bc.warn("Exception in {} after kill flag set {}.".format(self.name, e)) finally: self.s.close() return if self.active: if not self.send_q.empty(): self.command = self.send_q.get_nowait() #False non blocking #It's hogging CPU, is the queue maybe full of blank strings? if not self.command: time.sleep(0.5) continue self.do_command() #print("DEBUG - Putting {} in the recv q".format(self.response)) #self.recv_q.put(self.response) #actually recieve needs to be managed e.g. file transfers time.sleep(0.5) bc.warn_print("\n[!] ", "- Agent {} terminated.".format(self.name)) return
def run(self): """Main module code, called when the module is executed This module prints user provided messages to the console""" bc.success("Print incoming!") #Override with what to do with this class when it runs for time in range(self.options['num_prints']['value']): if self.get_option('color') == 'red': bc.err_print(self.options['message']['value'], '') elif self.get_option('color') == 'orange': bc.warn_print(self.options['message']['value'], '') elif self.get_option('color') == 'blue': bc.blue_print(self.options['message']['value'], '') elif self.get_option('color') == 'green': bc.green_print(self.options['message']['value'], '') else: print(self.get_option('message')) #Success variable can be used to check if sub-modules ran successfully #Unused in this case, but important if we don't want to exit failed modules. success = True if bool(self.get_option('exit_on_exec')) == True and success: bc.success("Module executed, exiting.") return True
def run(self): """Main function called when listere thread starts""" try: #Check RSA key again, never too careful if not self.check_RSA_KEY(): bc.err("RSA Key not valid. If you're stuck reset in home menu.") success == False raise ValueError("RSA Key invalid") bc.info('Starting listener on {}:{}'.format(self.LHOST, self.LPORT), True) #Strong info self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: self.s.bind((self.LHOST, self.LPORT)) self.s.listen(self.max_conns) #Listen for max of N connectionsa self.success = True except Exception as e: bc.err_print('[!] ', '- Failed to bind socket : \n {}'.format( str(e))) self.s.shutdown(socket.SHUT_RDWR) self.s.close() return while True: #'print("DEBUG - Listener looping again!") self.s.settimeout(0.5) #Socket must timeout to enable loop if not self.kill_flag.is_set(): #Run general COMMANDS if not self.send_q.empty(): self.command = self.send_q.get_nowait() #False non blocking #It's hogging CPU, is the queue maybe full of blank strings? if self.command == '': continue self.do_method() #Handle TCP connection try: c = self.s.accept() #Timeout on accept so we can read the queue (conn, client_address) = c agt = Agent(self, conn, client_address) agt.name = "agt-"+ self.name + "-" + str(len(self.agent_list) +1) self.agent_list.append(agt) agt.start() bc.blue_print("\n[!] ", "- Agent connected : {}.".format(agt.name)) c = None #So the loop behaves #If no agent in the timeout, let's get q stuff except socket.timeout: pass #Now print anything in the queue: if not self.recv_q.empty(): #print("reading q2") resp = self.recv_q.get() #print("reading q3") bc.blue_print("[-] ", "- Received :".format(resp)) time.sleep(5) # TODO - remove else: self.s.shutdown(socket.SHUT_RDWR) self.s.close() break #Kill thread except Exception as e: bc.warn_print("[!] ", "- Listener stopped: {}".format(e)) self.s.shutdown(socket.SHUT_RDWR) self.s.close() self.success == False finally: bc.blue_print("[-] ", "- Listener {} terminated.".format(self.name))