def run(self): """Run all processing modules and all signatures. @return: processing results. """ # This is the results container. It's what will be used by all the # reporting modules to make it consumable by humans and machines. # It will contain all the results generated by every processing # module available. Its structure can be observed throgh the JSON # dump in the the analysis' reports folder. # We friendly call this "fat dict". results = {} # Order modules using the user-defined sequence number. # If none is specified for the modules, they are selected in # alphabetical order. modules_list = list_plugins(group="processing") # If no modules are loaded, return an empty dictionary. if not modules_list: log.debug("No processing modules loaded") return results modules_list.sort(key=lambda module: module.order) # Run every loaded processing module. for module in modules_list: result = self._run_processing(module) # If it provided some results, append it to the big results # container. if result: results.update(result) # This will contain all the matched signatures. sigs = [] # Run every loaded signature. for signature in list_plugins(group="signatures"): match = self._run_signature(signature, results) # If the signature is matched, add it to the list. if match: sigs.append(match) # Sort the matched signatures by their severity level. sigs.sort(key=lambda key: key["severity"]) # Append the signatures to the fat dict. results["signatures"] = sigs # Return the fat dict. return results
def init_modules(): """Initializes plugins.""" log.debug("Importing modules...") # Import all auxiliary modules. import_package(modules.auxiliary) # Import all processing modules. import_package(modules.processing) # Import all signatures. import_package(modules.signatures) # Import all reporting modules. import_package(modules.reporting) # Import machine manager. import_plugin("modules.machinery." + Config().cuckoo.machinery) for category, entries in list_plugins().items(): log.debug("Imported \"%s\" modules:", category) for entry in entries: if entry == entries[-1]: log.debug("\t `-- %s", entry.__name__) else: log.debug("\t |-- %s", entry.__name__)
def initialize(self): """Initialize the machine manager.""" global mmanager mmanager_name = self.cfg.cuckoo.machine_manager log.info("Using \"%s\" machine manager" % mmanager_name) # Get registered class name. Only one machine manager is imported, # therefore there should be only one class in the list. plugin = list_plugins("machinemanagers")[0] # Initialize the machine manager. mmanager = plugin() # Find its configuration file. conf = os.path.join(CUCKOO_ROOT, "conf", "%s.conf" % mmanager_name) if not os.path.exists(conf): raise CuckooCriticalError("The configuration file for machine " "manager \"%s\" does not exist at path: " "%s" % (mmanager_name, conf)) # Provide a dictionary with the configuration options to the # machine manager instance. mmanager.set_options(Config(conf)) # Initialize the machine manager. mmanager.initialize(mmanager_name) # At this point all the available machines should have been identified # and added to the list. If none were found, Cuckoo needs to abort the # execution. if mmanager.machines().count() == 0: raise CuckooCriticalError("No machines available") else: log.info("Loaded %s machine/s" % mmanager.machines().count())
def init_modules(): """Initializes plugins.""" log.debug("Importing modules...") # Import all auxiliary modules. import_package(modules.auxiliary) # Import all processing modules. import_package(modules.processing) # Import all signatures. import_package(modules.signatures) if len(os.listdir(os.path.join(CUCKOO_ROOT, "modules", "signatures"))) < 5: log.warning( "Suggestion: looks like you didn't install community, execute: python3 utils/community.py -h" ) # Import all reporting modules. import_package(modules.reporting) # Import all feeds modules. import_package(modules.feeds) # Import machine manager. import_plugin("modules.machinery." + cuckoo.cuckoo.machinery) for category, entries in list_plugins().items(): log.debug('Imported "%s" modules:', category) for entry in entries: if entry == entries[-1]: log.debug("\t `-- %s", entry.__name__) else: log.debug("\t |-- %s", entry.__name__)
def init_modules(): """Initializes plugins.""" log.debug("Importing modules...") # Import all auxiliary modules. import_package(modules.auxiliary) # Import all processing modules. import_package(modules.processing) # Import all signatures. import_package(modules.signatures) # Import all reporting modules. import_package(modules.reporting) # Import machine manager. import_plugin("modules.machinery." + Config().cuckoo.machinery) for category, entries in list_plugins().items(): log.debug("Imported \"%s\" modules:", category) for entry in entries: if entry == entries[-1]: log.debug("\t `-- %s", entry.__name__) else: log.debug("\t |-- %s", entry.__name__) # CHANGED: Added this event. e = threading.Event(STOP_EVENT)
def init_modules(): """Initializes plugins.""" log.debug("Importing modules...") # Import all auxiliary modules. import_package(modules.auxiliary) # Import all processing modules. import_package(modules.processing) # Import all signatures. import_package(modules.signatures) # Import all reporting modules. import_package(modules.reporting) # Import all feeds modules. import_package(modules.feeds) # Import machine manager. import_plugin("modules.machinery." + cuckoo.cuckoo.machinery) for category, entries in list_plugins().items(): log.debug("Imported \"%s\" modules:", category) for entry in entries: if entry == entries[-1]: log.debug("\t `-- %s", entry.__name__) else: log.debug("\t |-- %s", entry.__name__)
def initialize(self): """Initialize the machine manager.""" global machinery, machine_lock machinery_name = self.cfg.cuckoo.machinery max_vmstartup_count = self.cfg.cuckoo.max_vmstartup_count if max_vmstartup_count: machine_lock = threading.Semaphore(max_vmstartup_count) else: machine_lock = threading.Lock() log.info("Using \"%s\" as machine manager", machinery_name) # Get registered class name. Only one machine manager is imported, # therefore there should be only one class in the list. plugin = list_plugins("machinery")[0] # Initialize the machine manager. machinery = plugin() # Find its configuration file. conf = os.path.join(CUCKOO_ROOT, "conf", "%s.conf" % machinery_name) if not os.path.exists(conf): raise CuckooCriticalError("The configuration file for machine " "manager \"{0}\" does not exist at path:" " {1}".format(machinery_name, conf)) # Provide a dictionary with the configuration options to the # machine manager instance. machinery.set_options(Config(machinery_name)) # Initialize the machine manager. try: machinery.initialize(machinery_name) except CuckooMachineError as e: raise CuckooCriticalError("Error initializing machines: %s" % e) # At this point all the available machines should have been identified # and added to the list. If none were found, Cuckoo needs to abort the # execution. if not len(machinery.machines()): raise CuckooCriticalError("No machines available.") else: log.info("Loaded %s machine/s", len(machinery.machines())) if len(machinery.machines()) > 1 and self.db.engine.name == "sqlite": log.warning("As you've configured Cuckoo to execute parallel " "analyses, we recommend you to switch to a MySQL or" "a PostgreSQL database as SQLite might cause some " "issues.") if len(machinery.machines()) > 4 and self.cfg.cuckoo.process_results: log.warning("When running many virtual machines it is recommended " "to process the results in a separate process.py to " "increase throughput and stability. Please read the " "documentation about the `Processing Utility`.")
def initialize(self): """Initialize the machine manager.""" global machinery machinery_name = self.cfg.cuckoo.machinery log.info("Using \"%s\" machine manager", machinery_name) # Get registered class name. Only one machine manager is imported, # therefore there should be only one class in the list. plugin = list_plugins("machinery")[0] # Initialize the machine manager. machinery = plugin() # Find its configuration file. conf = os.path.join(CUCKOO_ROOT, "conf", "%s.conf" % machinery_name) if not os.path.exists(conf): raise CuckooCriticalError("The configuration file for machine " "manager \"{0}\" does not exist at path:" " {1}".format(machinery_name, conf)) # Provide a dictionary with the configuration options to the # machine manager instance. machinery.set_options(Config(machinery_name)) # Initialize the machine manager. try: machinery.initialize(machinery_name) except CuckooMachineError as e: raise CuckooCriticalError("Error initializing machines: %s" % e) # At this point all the available machines should have been identified # and added to the list. If none were found, Cuckoo needs to abort the # execution. if not len(machinery.machines()): raise CuckooCriticalError("No machines available.") else: log.info("Loaded %s machine/s", len(machinery.machines())) if len(machinery.machines()) > 1 and self.db.engine.name == "sqlite": log.warning("The SQLite database is not compatible with " "multi-threaded use-cases such as running multiple " "virtual machine in parallel. Please upgrade to " "PostgreSQL or MySQL when running multiple VMs.") if len(machinery.machines()) > 3 and self.cfg.cuckoo.process_results: log.warning("When running many virtual machines it is recommended " "to process the results in a separate process.py to " "increase throughput and stability. Please read the " "documentation about the `Processing Utility`.")
def startDefault(): cuckoo_conf = Config("cuckoo") vmarch = cuckoo_conf.get("cuckoo").get("machinery") import_plugin("modules.machinery." + vmarch) machinery_plugin = list_plugins("machinery")[0] conf = os.path.join(CUCKOO_ROOT, "conf", "%s.conf" % vmarch) machinery = machinery_plugin() machinery.set_options(Config(vmarch)) machinery.initialize(vmarch) return machinery
def run(self, results): """Generates all reports. @param results: analysis results. @raise CuckooReportError: if a report module fails. """ # In every reporting module you can specify a numeric value that # represents at which position that module should be executed among # all the available ones. It can be used in the case where a # module requires another one to be already executed beforehand. modules_list = list_plugins(group="reporting") modules_list.sort(key=lambda module: module.order) # Run every loaded reporting module. for module in modules_list: self._run_report(module, results)
def init_modules(): """Initializes plugins.""" log.debug("Importing modules...") # Import all processing modules. import_package(modules.processing) # Import all signatures. import_package(modules.signatures) # Import only enabled reporting modules. report_cfg = Config(cfg=os.path.join(CUCKOO_ROOT, "conf", "reporting.conf")) prefix = modules.reporting.__name__ + "." for loader, name, ispkg in pkgutil.iter_modules(modules.reporting.__path__): if ispkg: continue try: options = report_cfg.get(name) except AttributeError: log.debug("Reporting module %s not found in " "configuration file" % module_name) if not options.enabled: continue import_plugin("%s.%s" % (modules.reporting.__name__, name)) # Import machine manager. import_plugin("modules.machinemanagers.%s" % Config().cuckoo.machine_manager) for category, mods in list_plugins().items(): log.debug("Imported \"%s\" modules:" % category) for mod in mods: if mod == mods[-1]: log.debug("\t `-- %s" % mod.__name__) else: log.debug("\t |-- %s" % mod.__name__)
def init_modules(): """Initializes plugins.""" log.debug("Importing modules...") # Import all processing modules. import_package(modules.processing) # Import all signatures. import_package(modules.signatures) # Import only enabled reporting modules. report_cfg = Config( cfg=os.path.join(CUCKOO_ROOT, "conf", "reporting.conf")) prefix = modules.reporting.__name__ + "." for loader, name, ispkg in pkgutil.iter_modules( modules.reporting.__path__): if ispkg: continue try: options = report_cfg.get(name) except (AttributeError, CuckooOperationalError): log.debug("Reporting module %s not found in " "configuration file" % name) if not options.enabled: continue import_plugin("%s.%s" % (modules.reporting.__name__, name)) # Import machine manager. import_plugin("modules.machinemanagers.%s" % Config().cuckoo.machine_manager) for category, mods in list_plugins().items(): log.debug("Imported \"%s\" modules:" % category) for mod in mods: if mod == mods[-1]: log.debug("\t `-- %s" % mod.__name__) else: log.debug("\t |-- %s" % mod.__name__)
def run(self, results): """Generates all reports. @param results: analysis results. @raise CuckooReportError: if a report module fails. """ # In every reporting module you can specify a numeric value that # represents at which position that module should be executed among # all the available ones. It can be used in the case where a # module requires another one to be already executed beforehand. modules_list = list_plugins(group="reporting") # Return if no reporting modules are loaded. if not modules_list: log.debug("No reporting modules loaded") return modules_list.sort(key=lambda module: module.order) # Run every loaded reporting module. for module in modules_list: self._run_report(module, results)
def initialize(self): """Initialize the machine manager.""" global machinery machinery_name = self.cfg.cuckoo.machinery log.info("Using \"%s\" machine manager", machinery_name) # Get registered class name. Only one machine manager is imported, # therefore there should be only one class in the list. plugin = list_plugins("machinery")[0] # Initialize the machine manager. machinery = plugin() # Find its configuration file. conf = os.path.join(CUCKOO_ROOT, "conf", "%s.conf" % machinery_name) if not os.path.exists(conf): raise CuckooCriticalError("The configuration file for machine " "manager \"{0}\" does not exist at path:" " {1}".format(machinery_name, conf)) # Provide a dictionary with the configuration options to the # machine manager instance. machinery.set_options(Config(conf)) # Initialize the machine manager. try: machinery.initialize(machinery_name) except CuckooMachineError as e: raise CuckooCriticalError("Error initializing machines: %s" % e) # At this point all the available machines should have been identified # and added to the list. If none were found, Cuckoo needs to abort the # execution. if not len(machinery.machines()): raise CuckooCriticalError("No machines available") else: log.info("Loaded %s machine/s", len(machinery.machines()))
def initialize(self): """Initialize the machine manager.""" global machinery machinery_name = self.cfg.cuckoo.machinery log.info("Using \"%s\" machine manager", machinery_name) # Get registered class name. Only one machine manager is imported, # therefore there should be only one class in the list. plugin = list_plugins("machinery")[0] # Initialize the machine manager. machinery = plugin() # Find its configuration file. conf = os.path.join(CUCKOO_ROOT, "conf", "%s.conf" % machinery_name) if not os.path.exists(conf): raise CuckooCriticalError("The configuration file for machine " "manager \"{0}\" does not exist at path:" " {1}".format(machinery_name, conf)) # Provide a dictionary with the configuration options to the # machine manager instance. machinery.set_options(Config(conf)) # Initialize the machine manager. try: machinery.initialize(machinery_name) except CuckooMachineError as e: raise CuckooCriticalError("Error initializing machines: %s" % e) # At this point all the available machines should have been identified # and added to the list. If none were found, Cuckoo needs to abort the # execution. if not len(machinery.machines()): raise CuckooCriticalError("No machines available.") else: log.info("Loaded %s machine/s", len(machinery.machines()))
def init_modules(machinery=True): """Initializes plugins.""" log.debug("Importing modules...") # Import all auxiliary modules. import modules.auxiliary import_package(modules.auxiliary) # Import all processing modules. import modules.processing import_package(modules.processing) # Import all signatures. import modules.signatures import_package(modules.signatures) delete_file("modules", "reporting", "maec40.pyc") delete_file("modules", "reporting", "maec41.pyc") delete_file("modules", "reporting", "mmdef.pyc") # Import all reporting modules. import modules.reporting import_package(modules.reporting) # Import machine manager. if machinery: import_plugin("modules.machinery." + Config().cuckoo.machinery) for category, entries in list_plugins().items(): log.debug("Imported \"%s\" modules:", category) for entry in entries: if entry == entries[-1]: log.debug("\t `-- %s", entry.__name__) else: log.debug("\t |-- %s", entry.__name__)
def initialize(self): """Initialize the machine manager.""" global machinery, machine_lock machinery_name = self.cfg.cuckoo.machinery max_vmstartup_count = self.cfg.cuckoo.max_vmstartup_count if max_vmstartup_count: machine_lock = threading.Semaphore(max_vmstartup_count) else: machine_lock = threading.Lock() log.info( 'Using "%s" machine manager with max_analysis_count=%d, ' "max_machines_count=%d, and max_vmstartup_count=%d", machinery_name, self.cfg.cuckoo.max_analysis_count, self.cfg.cuckoo.max_machines_count, self.cfg.cuckoo.max_vmstartup_count, ) # Get registered class name. Only one machine manager is imported, # therefore there should be only one class in the list. plugin = list_plugins("machinery")[0] # Initialize the machine manager. machinery = plugin() # Find its configuration file. conf = os.path.join(CUCKOO_ROOT, "conf", "%s.conf" % machinery_name) if not os.path.exists(conf): raise CuckooCriticalError("The configuration file for machine " 'manager "{0}" does not exist at path:' " {1}".format(machinery_name, conf)) # Provide a dictionary with the configuration options to the # machine manager instance. machinery.set_options(Config(machinery_name)) # Initialize the machine manager. try: machinery.initialize(machinery_name) except CuckooMachineError as e: raise CuckooCriticalError("Error initializing machines: %s" % e) # At this point all the available machines should have been identified # and added to the list. If none were found, Cuckoo needs to abort the # execution. if not len(machinery.machines()): raise CuckooCriticalError("No machines available.") else: log.info("Loaded %s machine/s", len(machinery.machines())) if len(machinery.machines()) > 1 and self.db.engine.name == "sqlite": log.warning("As you've configured Cuckoo to execute parallel " "analyses, we recommend you to switch to a MySQL " "a PostgreSQL database as SQLite might cause some " "issues.") # Drop all existing packet forwarding rules for each VM. Just in case # Cuckoo was terminated for some reason and various forwarding rules # have thus not been dropped yet. for machine in machinery.machines(): if not machine.interface: log.info( "Unable to determine the network interface for VM " "with name %s, Cuckoo will not be able to give it " "full internet access or route it through a VPN! " "Please define a default network interface for the " "machinery or define a network interface for each " "VM.", machine.name, ) continue # Drop forwarding rule to each VPN. for vpn in vpns.values(): rooter("forward_disable", machine.interface, vpn.interface, machine.ip) # Drop forwarding rule to the internet / dirty line. if routing.routing.internet != "none": rooter("forward_disable", machine.interface, routing.routing.internet, machine.ip)
def initialize(self): """Initialize the machine manager.""" global machinery, machine_lock machinery_name = self.cfg.cuckoo.machinery max_vmstartup_count = self.cfg.cuckoo.max_vmstartup_count if max_vmstartup_count: machine_lock = threading.Semaphore(max_vmstartup_count) else: machine_lock = threading.Lock() log.info("Using \"%s\" as machine manager", machinery_name) # Get registered class name. Only one machine manager is imported, # therefore there should be only one class in the list. plugin = list_plugins("machinery")[0] # Initialize the machine manager. machinery = plugin() # Find its configuration file. conf = os.path.join(CUCKOO_ROOT, "conf", "%s.conf" % machinery_name) if not os.path.exists(conf): raise CuckooCriticalError("The configuration file for machine " "manager \"{0}\" does not exist at path:" " {1}".format(machinery_name, conf)) # Provide a dictionary with the configuration options to the # machine manager instance. machinery.set_options(Config(machinery_name)) # Initialize the machine manager. try: machinery.initialize(machinery_name) except CuckooMachineError as e: raise CuckooCriticalError("Error initializing machines: %s" % e) # At this point all the available machines should have been identified # and added to the list. If none were found, Cuckoo needs to abort the # execution. if not len(machinery.machines()): raise CuckooCriticalError("No machines available.") else: log.info("Loaded %s machine/s", len(machinery.machines())) if len(machinery.machines()) > 1 and self.db.engine.name == "sqlite": log.warning("As you've configured Cuckoo to execute parallel " "analyses, we recommend you to switch to a MySQL or" "a PostgreSQL database as SQLite might cause some " "issues.") if len(machinery.machines()) > 4 and self.cfg.cuckoo.process_results: log.warning("When running many virtual machines it is recommended " "to process the results in a separate process.py to " "increase throughput and stability. Please read the " "documentation about the `Processing Utility`.") # Drop all existing packet forwarding rules for each VM. Just in case # Cuckoo was terminated for some reason and various forwarding rules # have thus not been dropped yet. for machine in machinery.machines(): if not machine.interface: log.info("Unable to determine the network interface for VM " "with name %s, Cuckoo will not be able to give it " "full internet access or route it through a VPN! " "Please define a default network interface for the " "machinery or define a network interface for each " "VM.", machine.name) continue # Drop forwarding rule to each VPN. for vpn in vpns.values(): rooter("forward_disable", machine.interface, vpn.interface, machine.ip) # Drop forwarding rule to the internet / dirty line. if self.cfg.routing.internet != "none": rooter("forward_disable", machine.interface, self.cfg.routing.internet, machine.ip)
def initialize(self): """Initialize the machine manager.""" global machinery machinery_name = self.cfg.cuckoo.machinery log.info("Using \"%s\" machine manager", machinery_name) # Get registered class name. Only one machine manager is imported, # therefore there should be only one class in the list. plugin = list_plugins("machinery")[0] # Initialize the machine manager. machinery = plugin() # Find its configuration file. conf = os.path.join(CUCKOO_ROOT, "conf", "%s.conf" % machinery_name) if not os.path.exists(conf): raise CuckooCriticalError("The configuration file for machine " "manager \"{0}\" does not exist at path:" " {1}".format(machinery_name, conf)) # Provide a dictionary with the configuration options to the # machine manager instance. machinery.set_options(Config(conf)) # Initialize the machine manager. try: machinery.initialize(machinery_name) except CuckooMachineError as e: raise CuckooCriticalError("Error initializing machines: %s" % e) # At this point all the available machines should have been identified # and added to the list. If none were found, Cuckoo needs to abort the # execution. if len(machinery.machines()) == 0: raise CuckooCriticalError("No machines available") else: log.info("Loaded %s machine/s", len(machinery.machines())) for machine in machinery.machines(): mem_conf_path = os.path.join(CUCKOO_ROOT, "conf", "processing.conf") conf = Config(mem_conf_path) machine.dump_path = "" if conf.memoryanalysis.enabled: log.info("Starting machine %s" % machine.label) machinery.start(machine.label) machine.dump_path = os.path.join(CUCKOO_ROOT, "storage", "analyses", "%s_clean.dmp" % machine.name) # CHANGED: Take initial memory dump if memory analysis option is enabled log.info("Dumping clean dump of machine: %s" % machine.label) machinery.dump_memory(machine.label, machine.dump_path) # Collect volatility info on clean dump machine.clean_volatility = {} try: log.info("Running Volatility for clean dump...") vol = VolatilityManager(machine.dump_path) _, res, _ = vol.run() machinery.db.set_machine_clean_volatility_data( machine.name, json.dumps(res, sort_keys=False, indent=4)) except Exception: log.exception("Generic error executing volatility") else: log.error( "Cannot run volatility module: volatility library not available" )
def initialize(self): """Initialize the machine manager.""" global machinery machinery_name = self.cfg.cuckoo.machinery log.info("Using \"%s\" machine manager", machinery_name) # Get registered class name. Only one machine manager is imported, # therefore there should be only one class in the list. plugin = list_plugins("machinery")[0] # Initialize the machine manager. machinery = plugin() # Find its configuration file. conf = os.path.join(CUCKOO_ROOT, "conf", "%s.conf" % machinery_name) if not os.path.exists(conf): raise CuckooCriticalError("The configuration file for machine " "manager \"{0}\" does not exist at path:" " {1}".format(machinery_name, conf)) # Provide a dictionary with the configuration options to the # machine manager instance. machinery.set_options(Config(conf)) # Initialize the machine manager. try: machinery.initialize(machinery_name) except CuckooMachineError as e: raise CuckooCriticalError("Error initializing machines: %s" % e) # At this point all the available machines should have been identified # and added to the list. If none were found, Cuckoo needs to abort the # execution. if len(machinery.machines()) == 0: raise CuckooCriticalError("No machines available") else: log.info("Loaded %s machine/s", len(machinery.machines())) for machine in machinery.machines(): mem_conf_path = os.path.join(CUCKOO_ROOT, "conf", "processing.conf") conf = Config(mem_conf_path) machine.dump_path = "" if conf.memoryanalysis.enabled: log.info("Starting machine %s" % machine.label) machinery.start(machine.label) machine.dump_path = os.path.join(CUCKOO_ROOT, "storage", "analyses", "%s_clean.dmp" % machine.name) # CHANGED: Take initial memory dump if memory analysis option is enabled log.info("Dumping clean dump of machine: %s" % machine.label) machinery.dump_memory(machine.label, machine.dump_path) # Collect volatility info on clean dump machine.clean_volatility = {} try: log.info("Running Volatility for clean dump...") vol = VolatilityManager(machine.dump_path) _, res, _ = vol.run() machinery.db.set_machine_clean_volatility_data(machine.name, json.dumps(res, sort_keys=False, indent=4)) except Exception: log.exception("Generic error executing volatility") else: log.error("Cannot run volatility module: volatility library not available")