def _setup_analysis_package(self): # Do we have a suggestion about an analysis package? print self.config.category if self.config.package: suggestion = self.config.package elif self.config.category == 'url': suggestion = 'safari' else: suggestion = None # Try to figure out what analysis package to use with this target kwargs = {"suggestion": suggestion} if suggestion == 'safari': # file_type and file_name are not generate if a url is passed in. self.config.file_type = None self.config.file_name = None package_class = choose_package_class(self.config.file_type, self.config.file_name, **kwargs) if not package_class: raise Exception("Could not find an appropriate analysis package") # Package initialization kwargs = { "options": self.config.get_options(), "timeout": self.config.timeout } return package_class(self.target, self.host, **kwargs)
def prepare(self): password = self.options.get("password") files = self._extract(self.target, password) if not files or len(files) == 0: raise Exception(f"Invalid (or empty) zip archive: {self.target}") # Look for a file to analyse target_name = self.options.get("file") if not target_name: # If no file name is provided via option, take the first file target_name = files[0] log.debug("Missing file option, auto executing: %s", target_name) filepath = path.join(environ.get("TEMP", "/tmp"), target_name) # Remove the trailing slash (if any) self.target = filepath.rstrip("/") # Since we don't know what kind of file we're going to analyse, let's # detect it automatically and create an appropriate analysis package # for this file file_info = _fileinfo(self.target) log.info(file_info) log.info(self.target) pkg_class = choose_package_class(file_info, target_name) if not pkg_class: raise Exception( f"Unable to detect analysis package for the file {target_name}" ) else: log.info('Analysing file "%s" using package "%s"', target_name, pkg_class) kwargs = {"options": self.options, "timeout": self.timeout} # We'll forward start() method invocation to the proper package later self.real_package = pkg_class(self.target, **kwargs)
def prepare(self): # todo use random tempfile # ToDo random name ret = system(f'wget "{self.target}" -O /tmp/file_malwr --no-check-certificate') log.info(ret) # py3 permission chmod("/tmp/file_malwr", 0o755) self.target = "/tmp/file_malwr" # self.args = [self.target] + self.args # self.target = "sh -c" file_info = _fileinfo(self.target) pkg_class = choose_package_class(file_info) kwargs = {"options": self.options, "timeout": self.timeout} self.real_package = pkg_class(self.target, **kwargs)
def _setup_analysis_package(self): # Do we have a suggestion about an analysis package? if self.config.package: suggestion = self.config.package elif self.config.category != "file": suggestion = "url" else: suggestion = None # Try to figure out what analysis package to use with this target kwargs = {"suggestion" : suggestion} package_class = choose_package_class(self.config.file_type, self.config.file_name, **kwargs) if not package_class: raise Exception("Could not find an appropriate analysis package") # Package initialization kwargs = { "options" : self.config.get_options(), "timeout" : self.config.timeout } return package_class(self.target, self.host, **kwargs)
def _setup_analysis_package(self): # Do we have a suggestion about an analysis package? if self.config.package: suggestion = self.config.package elif self.config.category != "file": suggestion = "url" else: suggestion = None # Try to figure out what analysis package to use with this target kwargs = {"suggestion": suggestion} package_class = choose_package_class(self.config.file_type, self.config.file_name, **kwargs) if not package_class: raise Exception("Could not find an appropriate analysis package") # Package initialization kwargs = { "options": self.config.get_options(), "timeout": self.config.timeout } return package_class(self.target, self.host, **kwargs)
def prepare(self): password = self.options.get("password") files = self._extract(self.target, password) if not files or len(files) == 0: raise Exception("Invalid (or empty) DMG %s" % self.target) # Look for a file to analyse target_name = self.options.get("file") if not target_name: # If no file name is provided via option, take the first file target_name = files[0] log.debug("Missing file option, auto executing: %s", target_name) else: for file in files: if target_name in file: target_name = file # Remove the trailing slash (if any) if target_name.endswith("/"): self.target = target_name[:-1] else: self.target = target_name # Since we don't know what kind of file we're going to analyse, let's # detect it automatically and create an appropriate analysis package # for this file file_info = _fileinfo(self.target) pkg_class = choose_package_class(file_info, target_name) if not pkg_class: raise Exception( "Unable to detect analysis package for the file %s" % target_name) else: log.debug("Analysing file \"%s\" using package \"%s\"", target_name, pkg_class.__name__) kwargs = {"options": self.options, "timeout": self.timeout} # We'll forward start() method invocation to the proper package later self.real_package = pkg_class(self.target, self.host, **kwargs)
def prepare(self): password = self.options.get("password") files = self._extract(self.target, password) if not files or len(files) == 0: raise Exception("Invalid (or empty) zip archive: %s" % self.target) # Look for a file to analyse target_name = self.options.get("file") if not target_name: # If no file name is provided via option, take the first file target_name = files[0] log.debug("Missing file option, auto executing: %s", target_name) filepath = path.join(environ.get("TEMP", "/tmp"), target_name) # Remove the trailing slash (if any) if filepath.endswith("/"): self.target = filepath[:-1] else: self.target = filepath # Since we don't know what kind of file we're going to analyse, let's # detect it automatically and create an appropriate analysis package # for this file file_info = _fileinfo(self.target) pkg_class = choose_package_class(file_info, target_name) if not pkg_class: raise Exception("Unable to detect analysis package for the file %s" % target_name) else: log.debug("Analysing file \"%s\" using package \"%s\"", target_name, pkg_class.__name__) kwargs = { "options" : self.options, "timeout" : self.timeout } # We'll forward start() method invocation to the proper package later self.real_package = pkg_class(self.target, self.host, **kwargs)
def run(self): """Run analysis. @return: operation status. """ self.prepare() log.debug("Starting analyzer from: %s", os.getcwd()) log.debug("Storing results at: %s", PATHS["root"]) # If no analysis package was specified at submission, we try to select # one automatically. """ if not self.config.package: log.debug("No analysis package specified, trying to detect it automagically") package = "generic" if self.config.category == "file" else "wget" # If we weren't able to automatically determine the proper package, # we need to abort the analysis. if not package: raise CuckooError(f"No valid package available for file type: {self.config.file_type}") log.info('Automatically selected analysis package "%s"', package) # Otherwise just select the specified package. else: package = self.config.package # Generate the package path. package_name = f"modules.packages.{package}" # Try to import the analysis package. try: __import__(package_name, globals(), locals(), ["dummy"], 0) # If it fails, we need to abort the analysis. except ImportError: raise CuckooError('Unable to import package "{package_name}", does not exist') # Initialize the package parent abstract. Package() # Enumerate the abstract subclasses. try: package_class = Package.__subclasses__()[0] except IndexError as e: raise CuckooError(f"Unable to select package class (package={package_name}): {e}") """ if self.config.package: suggestion = "ff" if self.config.package == "ie" else self.config.package elif self.config.category != "file": suggestion = "url" else: suggestion = None # Try to figure out what analysis package to use with this target kwargs = {"suggestion": suggestion} if self.config.category == "file": package_class = choose_package_class(self.config.file_type, self.config.file_name, **kwargs) else: package_class = choose_package_class(None, None, **kwargs) if not package_class: raise Exception("Could not find an appropriate analysis package") # Package initialization kwargs = { "options": self.config.options, "timeout": self.config.timeout } # Initialize the analysis package. # pack = package_class(self.config.get_options()) pack = package_class(self.target, **kwargs) # Initialize Auxiliary modules Auxiliary() prefix = f"{auxiliary.__name__}." for loader, name, ispkg in pkgutil.iter_modules( auxiliary.__path__, prefix): if ispkg: continue # Import the auxiliary module. try: __import__(name, globals(), locals(), ["dummy"], 0) except ImportError as e: log.warning('Unable to import the auxiliary module "%s": %s', name, e) # Walk through the available auxiliary modules. aux_enabled, aux_avail = [], [] for module in sorted(Auxiliary.__subclasses__(), key=lambda x: x.priority, reverse=True): # Try to start the auxiliary module. try: aux = module() aux_avail.append(aux) aux.start() except (NotImplementedError, AttributeError): log.warning("Auxiliary module %s was not implemented", aux.__class__.__name__) continue except Exception as e: log.warning("Cannot execute auxiliary module %s: %s", aux.__class__.__name__, e) continue finally: log.debug("Started auxiliary module %s", aux.__class__.__name__) # aux_enabled.append(aux) if aux: aux_enabled.append(aux) # Start analysis package. If for any reason, the execution of the # analysis package fails, we have to abort the analysis. try: # pids = pack.start(self.target) pids = pack.start() except NotImplementedError: raise CuckooError( f'The package "{package_class}" doesn\'t contain a run function' ) except CuckooPackageError as e: raise CuckooError( f'The package "{package_class}" start function raised an error: {e}' ) except Exception as e: raise CuckooError( f'The package "{package_class}" start function encountered an unhandled exception: {e}' ) # If the analysis package returned a list of process IDs, we add them # to the list of monitored processes and enable the process monitor. if pids: add_pids(pids) pid_check = True # If the package didn't return any process ID (for example in the case # where the package isn't enabling any behavioral analysis), we don't # enable the process monitor. else: log.info( "No process IDs returned by the package, running for the full timeout" ) pid_check = False # Check in the options if the user toggled the timeout enforce. If so, # we need to override pid_check and disable process monitor. if self.config.enforce_timeout: log.info("Enabled timeout enforce, running for the full timeout") pid_check = False time_counter = 0 while True: time_counter += 1 if time_counter > int(self.config.timeout): log.info("Analysis timeout hit, terminating analysis") break try: # If the process monitor is enabled we start checking whether # the monitored processes are still alive. if pid_check: for pid in list(PROCESS_LIST): if not Process(pid=pid).is_alive(): log.info("Process with pid %s has terminated", pid) PROCESS_LIST.remove(pid) # ToDo # ask the package if it knows any new pids # add_pids(pack.get_pids()) # also ask the auxiliaries for aux in aux_avail: add_pids(aux.get_pids()) # If none of the monitored processes are still alive, we # can terminate the analysis. if not PROCESS_LIST: log.info("Process list is empty, terminating analysis") break # Update the list of monitored processes available to the # analysis package. It could be used for internal # operations within the module. pack.set_pids(PROCESS_LIST) try: # The analysis packages are provided with a function that # is executed at every loop's iteration. If such function # returns False, it means that it requested the analysis # to be terminate. if not pack.check(): log.info( "The analysis package requested the termination of the analysis" ) break # If the check() function of the package raised some exception # we don't care, we can still proceed with the analysis but we # throw a warning. except Exception as e: log.warning( 'The package "%s" check function raised an exception: %s', package_class, e) except Exception as e: log.exception("The PID watching loop raised an exception: %s", e) finally: # Zzz. time.sleep(1) try: # Before shutting down the analysis, the package can perform some # final operations through the finish() function. pack.finish() except Exception as e: log.warning( 'The package "%s" finish function raised an exception: %s', package_class, e) try: # Upload files the package created to files in the results folder package_files = pack.package_files() if package_files is not None: for package in package_files: upload_to_host(package[0], os.path.join("files", package[1])) except Exception as e: log.warning( 'The package "%s" package_files function raised an exception: %s', package_class, e) # Terminate the Auxiliary modules. for aux in sorted(aux_enabled, key=lambda x: x.priority): try: aux.stop() except (NotImplementedError, AttributeError): continue except Exception as e: log.warning("Cannot terminate auxiliary module %s: %s", aux.__class__.__name__, e) if self.config.terminate_processes: # Try to terminate remaining active processes. We do this to make sure # that we clean up remaining open handles (sockets, files, etc.). log.info("Terminating remaining processes before shutdown") for pid in PROCESS_LIST: proc = Process(pid=pid) if proc.is_alive(): try: proc.terminate() except Exception: continue # Run the finish callback of every available Auxiliary module. for aux in aux_avail: try: aux.finish() except (NotImplementedError, AttributeError): continue except Exception as e: log.warning( "Exception running finish callback of auxiliary module %s: %s", aux.__class__.__name__, e) # Let's invoke the completion procedure. self.complete() return True