def __init__(self, options={}, config=None): Thread.__init__(self) Auxiliary.__init__(self, options, config) self.config = Config(cfg="analysis.conf") self.enabled = self.config.curtain self.startupinfo = subprocess.STARTUPINFO() self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
def __init__(self, options={}, analyzer=None): threading.Thread.__init__(self) Auxiliary.__init__(self, options, analyzer) self.config = Config(cfg="analysis.conf") self.enabled = self.config.sysmon self.startupinfo = subprocess.STARTUPINFO() self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
def __init__(self, options={}, analyzer=None): Thread.__init__(self) Auxiliary.__init__(self, options, analyzer) #Move Processing Files (For EMP) pathLocation = os.path.join(os.getcwd(), "processing_files") log.debug("Path for processing files: " + pathLocation) if (os.path.isdir(pathLocation)): fileList = os.listdir(pathLocation) for files in fileList: moveFile(files) log.debug("Copying DLLs") #Move DLL Files (For Either) pathLocation = os.path.join(os.getcwd(), "sw_dll") copyPath = os.path.join("C:", os.sep, "dlls") #copyDirEntries(pathLocation,copyPath) log.debug("Copying from " + pathLocation + " To" + copyPath) for item in os.listdir(pathLocation): s = os.path.join(pathLocation, item) d = os.path.join(copyPath, item) if os.path.isdir(s): log.debug("Copying directory " + s) shutil.copytree(s, d) else: log.debug("Copying file " + s) shutil.copy2(s, d) #if (os.path.isdir(pathLocation)): # fileList = os.listdir(pathLocation) # for files in fileList: # moveDLL(files) self.do_run = True
def __init__(self, options=None, config=None): if options is None: options = {} Thread.__init__(self) Auxiliary.__init__(self, options, config) self.enabled = config.evtx self.startupinfo = subprocess.STARTUPINFO() self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
def __init__(self, options={}): Auxiliary.__init__(self, options) threading.Thread.__init__(self) self.package = options.get("apk_entry", ":").split(":")[0] self.do_run = True self.window_dumps = [] self.temp_dumpfile = None
def __init__(self, options={}, analyzer=None): threading.Thread.__init__(self) Auxiliary.__init__(self, options, analyzer) self.do_run = True self.metrics = [] self.filepath = os.path.join(self.analyzer.path, "bin", "metrics.json") log.info("Successfully started MetricsSnapshots.")
def __init__(self, options, config): Auxiliary.__init__(self, options, config) self.enabled = config.filecollector self.do_run = self.enabled and HAVE_PYINOTIFY if self.enabled: self.initComplete = False self.thread = Thread(target=self.run) self.thread.start() while not self.initComplete: self.thread.join(0.5)
def __init__(self, options={}, analyzer=None): self.do_run = True Thread.__init__(self) Auxiliary.__init__(self, options, analyzer) self.initComplete = False self.thread = Thread(target=self.run) self.thread.start() while not self.initComplete: self.thread.join(0.5) log.debug("Human init complete")
def run(self): """Run analysis. """ self.bootstrap() self.log.debug("Starting analyzer from %s", os.getcwd()) self.log.debug("Storing results at: %s", PATHS["root"]) package = self._setup_analysis_package() if self.config.clock: set_wallclock(self.config.clock) # Initialize Auxiliary modules Auxiliary() prefix = 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"], -1) 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 Auxiliary.__subclasses__(): # Try to start the auxiliary module. try: aux = module(options=self.config.options, analyzer=self) aux_avail.append(aux) aux.start() except (NotImplementedError, AttributeError): log.warning("Auxiliary module %s was not implemented", module.__name__) except CuckooDisableModule: continue except Exception as e: log.warning("Cannot execute auxiliary module %s: %s", module.__name__, e) else: log.debug("Started auxiliary module %s", module.__name__) aux_enabled.append(aux) self._analysis(package) return self._complete()
def __init__(self, options, config): Auxiliary.__init__(self, options, config) self.cert_build = list() self.time_build = list() self.json_data = { "sha1": None, "signers": list(), "timestamp": None, "valid": False, "error": None, "error_desc": None } self.enabled = True
def __init__(self, options, config): Auxiliary.__init__(self, options, config) self.config = config self.enabled = self.config.digisig self.cert_build = [] self.time_build = [] self.json_data = { "sha1": None, "signers": [], "timestamp": None, "valid": False, "error": None, "error_desc": None }
def __init__(self, options, config): Auxiliary.__init__(self, options, config) self.config = config self.enabled = self.config.human_linux self.do_run = self.enabled and HAVE_GUI_LIBS Thread.__init__(self) self.initComplete = False self.thread = Thread(target=self.run) self.thread.start() while not self.initComplete: self.thread.join(0.5) log.debug("Human init complete")
def __init__(self, options=None, config=None): if options is None: options = {} Thread.__init__(self) Auxiliary.__init__(self, options, config) self.config = Config(cfg="analysis.conf") self.enabled = self.config # Go to the temp folder to look for pre_script.py tmp_folder = os.environ["TEMP"] matched_files = glob.glob(os.path.join(tmp_folder, "pre_script.*")) # Check if the file exists and if the pre_script is enabled if matched_files and self.enabled.pre_script: self.file_path = matched_files[0] self.file_ext = os.path.splitext(self.file_path)[-1] self.do_run = True log.debug("pre_script matched_files: %s", matched_files) # Try to retrieve timeout for pre_script_timeout (Default 60) try: self.timeout = int(self.options.get("pre_script_timeout", 60)) except ValueError: log.error( "Invalid timeout value specified, defaulting to 60 seconds" ) self.timeout = 60 pre_script_args = self.options.get("pre_script_args", []) if pre_script_args: try: self.pre_script_args_list = pre_script_args.split(" ") except AttributeError: self.pre_script_args_list = pre_script_args else: self.pre_script_args_list = [] # Setting Executable for python if the file ext is py else powershell if self.file_ext == ".py": self.executable = ["python.exe"] elif self.file_ext == ".ps1": self.executable = [ "powershell.exe", "-NoProfile", "-ExecutionPolicy", "bypass", "-File" ] else: self.executable = ["powershell.exe"] else: self.do_run = False
def start_auxiliaries(self): Auxiliary() iter_aux_modules = pkgutil.iter_modules( auxiliary.__path__, "%s." % auxiliary.__name__ ) for loader, name, ispkg in iter_aux_modules: if ispkg: continue try: importlib.import_module(name) except ImportError as e: log.exception( "Failed to import Auxiliary module: '%s'. %s", name, e ) for aux_module in Auxiliary.__subclasses__(): try: aux = aux_module(options=self.config.options, analyzer=self) self.aux_available[aux_module.__name__.lower()] = aux if not aux.enabled(): log.debug( "Auxiliary module '%s' disabled", aux_module.__name__ ) raise CuckooDisableModule aux.init() aux.start() except (NotImplementedError, AttributeError) as e: log.exception( "Auxiliary module '%s' could not be started. Missing " "attributes or functions. %s", aux_module.__name__, e ) except CuckooDisableModule: continue except Exception as e: log.exception( "Error while starting auxiliary module '%s'. %s", aux_module.__name__, e ) else: self.aux_enabled[aux_module.__name__.lower()] = aux log.debug("Started auxiliary module %s", aux_module.__name__)
def run(self): """Run analysis. """ self.bootstrap() self.log.debug("Starting analyzer from %s", os.getcwd()) self.log.debug("Storing results at: %s", PATHS["root"]) package = self._setup_analysis_package() if self.config.clock: set_wallclock(self.config.clock) # Initialize Auxiliary modules Auxiliary() prefix = 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"], -1) 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 Auxiliary.__subclasses__(): # Try to start the auxiliary module. try: aux = module(options=self.config.options, analyzer=self) aux_avail.append(aux) aux.start() except (NotImplementedError, AttributeError): log.warning("Auxiliary module %s was not implemented", module.__name__) except CuckooDisableModule: continue except Exception as e: log.warning("Cannot execute auxiliary module %s: %s", module.__name__, e) else: log.debug("Started auxiliary module %s", module.__name__) aux_enabled.append(aux) self._analysis(package) return self._complete()
def __init__(self, options=None, config=None): if options is None: options = {} Thread.__init__(self) Auxiliary.__init__(self, options, config) self.config = Config(cfg="analysis.conf") self.enabled = self.config # Go to the temp folder to look for during_script.py tmp_folder = os.environ["TEMP"] matched_files = glob.glob(os.path.join(tmp_folder, "during_script.*")) # Check if the file exists and if the during_script is enabled if matched_files and self.enabled.during_script: log.debug("during_script matched_files: %s", matched_files) self.file_path = matched_files[0] self.file_ext = os.path.splitext(self.file_path)[-1] self.do_run = True if self.file_ext == ".py": self.executable = ["python.exe"] elif self.file_ext == ".ps1": self.executable = [ "powershell.exe", "-NoProfile", "-ExecutionPolicy", "bypass", "-File" ] else: self.executable = ["powershell.exe"] during_script_args = self.options.get("during_script_args", []) if during_script_args: try: self.during_script_args_list = during_script_args.split( " ") except AttributeError: self.during_script_args_list = during_script_args else: self.during_script_args_list = [] else: self.do_run = False
def setup_auxiliary_modules(self): # Initialize Auxiliary modules Auxiliary() prefix = 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"], -1) 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 Auxiliary.__subclasses__(): # Try to start the auxiliary module. try: aux = module(self.config.get_options()) 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)
def run(self): """Run analysis. @return: operation status. """ self.prepare() self.path = os.getcwd() log.debug("Starting analyzer from: %s", self.path) log.debug("Pipe server name: %s", self.config.pipe) log.debug("Log pipe server name: %s", self.config.logpipe) # 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.") # If the analysis target is a file, we choose the package according # to the file format. if self.config.category == "file": package = choose_package(self.config.file_type, self.config.file_name, self.config.pe_exports.split(",")) # If it's an URL, we'll just use the default Internet Explorer # package. else: package = "ie" # If we weren't able to automatically determine the proper package, # we need to abort the analysis. if not package: raise CuckooError("No valid package available for file " "type: {0}".format(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 = "modules.packages.%s" % package # Try to import the analysis package. try: __import__(package_name, globals(), locals(), ["dummy"], -1) # If it fails, we need to abort the analysis. except ImportError: raise CuckooError("Unable to import package \"{0}\", does " "not exist.".format(package_name)) # Initialize the package parent abstract. Package() # Enumerate the abstract subclasses. try: package_class = Package.__subclasses__()[0] except IndexError as e: raise CuckooError("Unable to select package class " "(package={0}): {1}".format(package_name, e)) # Initialize the analysis package. self.package = package_class(self.config.options, analyzer=self) # Move the sample to the current working directory as provided by the # task - one is able to override the starting path of the sample. # E.g., for some samples it might be useful to run from %APPDATA% # instead of %TEMP%. if self.config.category == "file": self.target = self.package.move_curdir(self.target) # Initialize Auxiliary modules Auxiliary() prefix = 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"], -1) 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 Auxiliary.__subclasses__(): # Try to start the auxiliary module. try: aux = module(options=self.config.options, analyzer=self) aux_avail.append(aux) aux.start() except (NotImplementedError, AttributeError): log.warning("Auxiliary module %s was not implemented", module.__name__) except CuckooDisableModule: continue except Exception as e: log.warning("Cannot execute auxiliary module %s: %s", module.__name__, e) else: log.debug("Started auxiliary module %s", module.__name__) aux_enabled.append(aux) ########################################################### #new code 2017_05_19 shutil.copyfile(self.target, 'C:\\dbg\\sample.exe') with open('log.txt', 'w') as creation: creation.write('log start') with open(self.target, 'rb') as sample: s = sample.read(2) if s != 'MZ': is32bit = False else: sample.seek(60) s = sample.read(4) header_offset = struct.unpack("<L", s)[0] sample.seek(header_offset + 4) s = sample.read(2) machine = struct.unpack('<H', s)[0] is32bit = (machine == 332) if is32bit: self.target = 'C:\\dbg\\Helper32.exe' else: self.target = 'C:\\dbg\\Helper64.exe' try: proc = Popen(self.target) pids = proc.pid except Exception as e: log.error('custom : fail to open process %s : %s', self.target, e) ########################################################### #origin # Start analysis package. If for any reason, the execution of the # analysis package fails, we have to abort the analysis. # try: # pids = self.package.start(self.target) # except NotImplementedError: # raise CuckooError( # "The package \"%s\" doesn't contain a run function." % # package_name # ) # except CuckooPackageError as e: # raise CuckooError( # "The package \"%s\" start function raised an error: %s" % # (package_name, e) # ) # except Exception as e: # raise CuckooError( # "The package \"%s\" start function encountered an unhandled " # "exception: %s" % (package_name, e) # ) ########################################################### # If the analysis package returned a list of process identifiers, we # add them to the list of monitored processes and enable the process monitor. if pids: self.process_list.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 while self.do_run: self.time_counter += 1 if self.time_counter == int(self.config.timeout): log.info("Analysis timeout hit, terminating analysis.") break # If the process lock is locked, it means that something is # operating on the list of monitored processes. Therefore we # cannot proceed with the checks until the lock is released. if self.process_lock.locked(): KERNEL32.Sleep(1000) continue try: # If the process monitor is enabled we start checking whether # the monitored processes are still alive. if pid_check: for pid in self.process_list.pids: if not Process(pid=pid).is_alive(): log.info("Process with pid %s has terminated", pid) self.process_list.remove_pid(pid) # If none of the monitored processes are still alive, we # can terminate the analysis. if not self.process_list.pids: 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. self.package.set_pids(self.process_list.pids) 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 self.package.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_name, e) finally: # Zzz. KERNEL32.Sleep(1000) if not self.do_run: log.debug("The analyzer has been stopped on request by an " "auxiliary module.") # Create the shutdown mutex. KERNEL32.CreateMutexA(None, False, SHUTDOWN_MUTEX) try: # Before shutting down the analysis, the package can perform some # final operations through the finish() function. self.package.finish() except Exception as e: log.warning( "The package \"%s\" finish function raised an " "exception: %s", package_name, e) try: # Upload files the package created to package_files in the # results folder. for path, name in self.package.package_files() or []: upload_to_host(path, os.path.join("package_files", name)) except Exception as e: log.warning( "The package \"%s\" package_files function raised an " "exception: %s", package_name, e) # Terminate the Auxiliary modules. for aux in aux_enabled: 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. log.info("Terminating remaining processes before shutdown.") for pid in self.process_list.pids: proc = Process(pid=pid) if proc.is_alive(): try: proc.terminate() except: continue ############################################################################### #new code time.sleep(3) with open('C:\\dbg\\log.txt') as f_log: raw = f_log.read() data = ''.join(raw.split('\x00')) log.debug('logged : \n%s', data) ############################################################################### # 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
def run(self): self.prepare() log.info("Starting analyzer from: {0}".format(os.getcwd())) log.info("Storing results at: {0}".format(PATHS["root"])) log.info("Target is: {0}".format(self.target)) # If no analysis package was specified at submission, we try to select # one automatically. if not self.config.package: log.info( "No analysis package specified, trying to detect it automagically" ) # If the analysis target is a file, we choose the package according # to the file format. if self.config.category == "file": package = choose_package(self.config.file_type, self.config.file_name) # If it's an URL, we'll just use the default Internet Explorer # package. else: package = "default_browser" # If we weren't able to automatically determine the proper package, # we need to abort the analysis. if not package: raise CuckooError( "No valid package available for file type: {0}".format( 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 = "modules.packages.%s" % package # Try to import the analysis package. try: __import__(package_name, globals(), locals(), ["dummy"], -1) # If it fails, we need to abort the analysis. except ImportError: raise CuckooError( "Unable to import package \"{0}\", does not exist.".format( package_name)) # Initialize the package parent abstract. Package() # Enumerate the abstract's subclasses. try: package_class = Package.__subclasses__()[0] except IndexError as e: raise CuckooError( "Unable to select package class (package={0}): {1}".format( package_name, e)) # Initialize the analysis package. pack = package_class(self.get_options()) # Initialize Auxiliary modules Auxiliary() prefix = 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"], -1) except ImportError as e: log.warning( "Unable to import the auxiliary module " "\"%s\": %s", name, e) # Walk through the available auxiliary modules. aux_enabled = [] for module in Auxiliary.__subclasses__(): # Try to start the auxiliary module. try: aux = module() 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.info("Started auxiliary module %s", aux.__class__.__name__) 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: pack.start(self.target) except NotImplementedError: raise CuckooError("The package \"{0}\" doesn't contain a run " "function.".format(package_name)) except CuckooPackageError as e: raise CuckooError("The package \"{0}\" start function raised an " "error: {1}".format(package_name, e)) except Exception as e: raise CuckooError("The package \"{0}\" start function encountered " "an unhandled exception: " "{1}".format(package_name, e)) time_counter = 0 while True: time_counter += 1 if time_counter == int(self.config.timeout): log.info("Analysis timeout hit, terminating analysis") break 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_name, 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_name, e) # Terminate the Auxiliary modules. for aux in aux_enabled: try: aux.stop() except (NotImplementedError, AttributeError): continue except Exception as e: log.warning("Cannot terminate auxiliary module %s: %s", aux.__class__.__name__, e) # Let's invoke the completion procedure. self.complete() return True
def run(self): self.prepare() self.check_environment_ready() log.info("Starting analyzer from: {0}".format(os.getcwd())) log.info("Storing results at: {0}".format(PATHS["root"])) log.info("Target is: {0}".format(self.target)) # If no analysis package was specified at submission, we try to select # one automatically. if not self.config.package: log.info("No analysis package specified, trying to detect it automagically") # If the analysis target is a file, we choose the package according # to the file format. if self.config.category == "file": package = choose_package(self.config.file_type, self.config.file_name) # If it's an URL, we'll just use the default Internet Explorer # package. else: package = "default_browser" # If we weren't able to automatically determine the proper package, # we need to abort the analysis. if not package: raise CuckooError("No valid package available for file type: {0}".format(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 = "modules.packages.%s" % package # Try to import the analysis package. try: __import__(package_name, globals(), locals(), ["dummy"], -1) # If it fails, we need to abort the analysis. except ImportError: raise CuckooError("Unable to import package \"{0}\", does not exist.".format(package_name)) # Initialize the package parent abstract. Package() # Enumerate the abstract's subclasses. try: package_class = Package.__subclasses__()[0] except IndexError as e: raise CuckooError("Unable to select package class (package={0}): {1}".format(package_name, e)) # Initialize the analysis package. pack = package_class(self.get_options()) # Initialize Auxiliary modules Auxiliary() prefix = 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"], -1) except ImportError as e: log.warning("Unable to import the auxiliary module " "\"%s\": %s", name, e) # Walk through the available auxiliary modules. aux_enabled = [] for module in Auxiliary.__subclasses__(): # Try to start the auxiliary module. try: aux = module() 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.info("Started auxiliary module %s", aux.__class__.__name__) 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: pack.start(self.target) except NotImplementedError: raise CuckooError("The package \"{0}\" doesn't contain a run " "function.".format(package_name)) except CuckooPackageError as e: raise CuckooError("The package \"{0}\" start function raised an " "error: {1}".format(package_name, e)) except Exception as e: raise CuckooError("The package \"{0}\" start function encountered " "an unhandled exception: " "{1}".format(package_name, e)) time_counter = 0 while True: time_counter += 1 if time_counter == int(self.config.timeout): log.info("Analysis timeout hit, terminating analysis") break 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_name, 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_name, e) # Terminate the Auxiliary modules. for aux in aux_enabled: try: aux.stop() except (NotImplementedError, AttributeError): continue except Exception as e: log.warning("Cannot terminate auxiliary module %s: %s", aux.__class__.__name__, e) # Let's invoke the completion procedure. self.complete() return True
def __init__(self, options={}, config=None): Thread.__init__(self) Auxiliary.__init__(self, options, config) self.do_run = True
def run(self): """Run analysis. @return: operation status. """ self.prepare() self.path = os.getcwd() log.debug("Starting analyzer from: %s", self.path) log.debug("Pipe server name: %s", self.config.pipe) log.debug("Log pipe server name: %s", self.config.logpipe) # 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.") # If the analysis target is a file, we choose the package according # to the file format. if self.config.category == "file": package = choose_package(self.config.file_type, self.config.file_name, self.config.pe_exports.split(",")) # If it's an URL, we'll just use the default Internet Explorer # package. else: package = "ie" # If we weren't able to automatically determine the proper package, # we need to abort the analysis. if not package: raise CuckooError("No valid package available for file " "type: {0}".format(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 = "modules.packages.%s" % package # Try to import the analysis package. try: __import__(package_name, globals(), locals(), ["dummy"], -1) # If it fails, we need to abort the analysis. except ImportError: raise CuckooError("Unable to import package \"{0}\", does " "not exist.".format(package_name)) # Initialize the package parent abstract. Package() # Enumerate the abstract subclasses. try: package_class = Package.__subclasses__()[0] except IndexError as e: raise CuckooError("Unable to select package class " "(package={0}): {1}".format(package_name, e)) # Initialize the analysis package. self.package = package_class(self.config.options, analyzer=self) # Move the sample to the current working directory as provided by the # task - one is able to override the starting path of the sample. # E.g., for some samples it might be useful to run from %APPDATA% # instead of %TEMP%. if self.config.category == "file": self.target = self.package.move_curdir(self.target) # Initialize Auxiliary modules Auxiliary() prefix = 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"], -1) 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 Auxiliary.__subclasses__(): # Try to start the auxiliary module. try: aux = module(options=self.config.options, analyzer=self) aux_avail.append(aux) aux.init() aux.start() except (NotImplementedError, AttributeError): log.exception("Auxiliary module %s was not implemented", module.__name__) except CuckooDisableModule: continue except Exception as e: log.exception("Cannot execute auxiliary module %s: %s", module.__name__, e) else: log.debug("Started auxiliary module %s", module.__name__) aux_enabled.append(aux) # Inform zer0m0n of the ResultServer address. zer0m0n.resultserver(self.config.ip, self.config.port) # Forward the command pipe and logpipe names on to zer0m0n. zer0m0n.cmdpipe(self.config.pipe) zer0m0n.channel(self.config.logpipe) # Hide the Cuckoo Analyzer & Cuckoo Agent. zer0m0n.hidepid(self.pid) zer0m0n.hidepid(self.ppid) # Initialize zer0m0n with our compiled Yara rules. zer0m0n.yarald("bin/rules.yarac") # Propagate the requested dump interval, if set. zer0m0n.dumpint(int(self.config.options.get("dumpint", "0"))) # Start analysis package. If for any reason, the execution of the # analysis package fails, we have to abort the analysis. pids = self.package.start(self.target) # If the analysis package returned a list of process identifiers, we # add them to the list of monitored processes and enable the process monitor. if pids: self.process_list.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 while self.do_run: self.time_counter += 1 if self.time_counter == int(self.config.timeout): log.info("Analysis timeout hit, terminating analysis.") break # If the process lock is locked, it means that something is # operating on the list of monitored processes. Therefore we # cannot proceed with the checks until the lock is released. if self.process_lock.locked(): KERNEL32.Sleep(1000) continue try: # If the process monitor is enabled we start checking whether # the monitored processes are still alive. if pid_check: # We also track the PIDs provided by zer0m0n. self.process_list.add_pids(zer0m0n.getpids()) for pid in self.process_list.pids: if not Process(pid=pid).is_alive(): log.info("Process with pid %s has terminated", pid) self.process_list.remove_pid(pid) # If none of the monitored processes are still alive, we # can terminate the analysis. if not self.process_list.pids: 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. self.package.set_pids(self.process_list.pids) 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 self.package.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_name, e) finally: # Zzz. KERNEL32.Sleep(1000) if not self.do_run: log.debug("The analyzer has been stopped on request by an " "auxiliary module.") # Create the shutdown mutex. KERNEL32.CreateMutexA(None, False, SHUTDOWN_MUTEX) try: # Before shutting down the analysis, the package can perform some # final operations through the finish() function. self.package.finish() except Exception as e: log.warning( "The package \"%s\" finish function raised an " "exception: %s", package_name, e) try: # Upload files the package created to package_files in the # results folder. for path, name in self.package.package_files() or []: upload_to_host(path, os.path.join("package_files", name)) except Exception as e: log.warning( "The package \"%s\" package_files function raised an " "exception: %s", package_name, e) # Terminate the Auxiliary modules. for aux in aux_enabled: 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. log.info("Terminating remaining processes before shutdown.") for pid in self.process_list.pids: proc = Process(pid=pid) if proc.is_alive(): try: proc.terminate() except: 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) # Dump all the notified files. self.files.dump_files() # Hell yeah. log.info("Analysis completed.") return True
def __init__(self, options, config): Auxiliary.__init__(self, options, config) self.enabled = config.disguise
def __init__(self, options, config): Auxiliary.__init__(self, options, config) Thread.__init__(self) self.do_run = True
def __init__(self, options={}, analyzer=None): threading.Thread.__init__(self) Auxiliary.__init__(self, options, analyzer) self.do_run = True
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"]) log.debug("Pipe server name: %s", PIPE) # 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.") # If the analysis target is a file, we choose the package according # to the file format. if self.config.category == "file": package = choose_package(self.config.file_type, self.config.file_name, self.config.exports) # If it's an URL, we'll just use the default Internet Explorer # package. else: package = "ie" # If we weren't able to automatically determine the proper package, # we need to abort the analysis. if not package: raise CuckooError("No valid package available for file " "type: {0}".format(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 = "modules.packages.%s" % package # Try to import the analysis package. try: __import__(package_name, globals(), locals(), ["dummy"], -1) # If it fails, we need to abort the analysis. except ImportError: raise CuckooError("Unable to import package \"{0}\", does " "not exist.".format(package_name)) # Initialize the package parent abstract. Package() # Enumerate the abstract subclasses. try: package_class = Package.__subclasses__()[0] except IndexError as e: raise CuckooError("Unable to select package class " "(package={0}): {1}".format(package_name, e)) # Initialize the analysis package. pack = package_class(self.config.get_options(), self.config) # Initialize Auxiliary modules Auxiliary() prefix = 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"], -1) 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 Auxiliary.__subclasses__(): # Try to start the auxiliary module. try: aux = module(self.config.get_options(), self.config) aux_avail.append(aux) aux.start() except (NotImplementedError, AttributeError): log.warning("Auxiliary module %s was not implemented", module.__name__) except Exception as e: log.warning("Cannot execute auxiliary module %s: %s", module.__name__, e) else: log.debug("Started auxiliary module %s", module.__name__) 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) except NotImplementedError: raise CuckooError("The package \"{0}\" doesn't contain a run " "function.".format(package_name)) except CuckooPackageError as e: raise CuckooError("The package \"{0}\" start function raised an " "error: {1}".format(package_name, e)) except Exception as e: raise CuckooError("The package \"{0}\" start function encountered " "an unhandled exception: " "{1}".format(package_name, 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 kernel_analysis = self.config.get_options().get("kernel_analysis", False) if kernel_analysis != False: kernel_analysis = True emptytime = None while True: time_counter += 1 if time_counter == int(self.config.timeout): log.info("Analysis timeout hit, terminating analysis.") break # If the process lock is locked, it means that something is # operating on the list of monitored processes. Therefore we # cannot proceed with the checks until the lock is released. if PROCESS_LOCK.locked(): KERNEL32.Sleep(1000) continue try: # If the process monitor is enabled we start checking whether # the monitored processes are still alive. if pid_check: if not kernel_analysis: for pid in PROCESS_LIST: if not Process(pid=pid).is_alive(): log.info("Process with pid %s has terminated", pid) PROCESS_LIST.remove(pid) # If none of the monitored processes are still alive, we # can terminate the analysis. if not PROCESS_LIST and (not LASTINJECT_TIME or (datetime.now() >= (LASTINJECT_TIME + timedelta(seconds=15)))): if emptytime and (datetime.now() >= (emptytime + timedelta(seconds=5))): log.info("Process list is empty, " "terminating analysis.") break elif not emptytime: emptytime = datetime.now() else: emptytime = None # 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_name, e) finally: # Zzz. KERNEL32.Sleep(1000) # Create the shutdown mutex. KERNEL32.CreateMutexA(None, False, SHUTDOWN_MUTEX) log.info("Created shutdown mutex.") # since the various processes poll for the existence of the mutex, sleep # for a second to ensure they see it before they're terminated KERNEL32.Sleep(1000) log.info("Shutting down package.") 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_name, e) log.info("Stopping auxiliary modules.") # Terminate the Auxiliary modules. for aux in aux_enabled: try: aux.stop() except (NotImplementedError, AttributeError): continue except Exception as e: log.warning("Cannot terminate auxiliary module %s: %s", aux.__class__.__name__, e) # Tell all processes to flush their logs regardless of terminate_processes setting if not kernel_analysis: for pid in PROCESS_LIST: proc = Process(pid=pid) if proc.is_alive(): try: proc.set_terminate_event() except: continue 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.") if not kernel_analysis: for pid in PROCESS_LIST: proc = Process(pid=pid) if proc.is_alive(): try: if not proc.is_critical(): proc.terminate() else: log.info("Not terminating critical process with pid %d.", proc.pid) except: continue log.info("Finishing auxiliary modules.") # 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. log.info("Shutting down pipe server and dumping dropped files.") self.complete() return True
def __init__(self, options, config): Auxiliary.__init__(self, options, config) self.enabled = config.file_pickup self.do_run = self.enabled
def __init__(self, options, config): Auxiliary.__init__(self, options, config) Thread.__init__(self) self.do_run = True self.seconds_elapsed = 0
def __init__(self, options, config): Auxiliary.__init__(self, options, config) self.enabled = True
def __init__(self, options, config): Auxiliary.__init__(self, options, config) Thread.__init__(self) self.do_run = True self.pidlist = []
def __init__(self, options): Auxiliary.__init__(self, options) Thread.__init__(self) self.do_run = True self.seconds_elapsed = 0
def __init__(self, options={}, config=None): Thread.__init__(self) Auxiliary.__init__(self, options, config) self.config = Config(cfg="analysis.conf") self.enabled = self.config.evtx self.do_run = self.enabled
def run(self): """Run analysis. @return: operation status. """ self.prepare() log.info("Starting analyzer from: %s", os.getcwd()) log.info("Storing results at: %s", PATHS["root"]) log.info("Pipe server name: %s", PIPE) # If no analysis package was specified at submission, we try to select # one automatically. if not self.config.package: log.info("No analysis package specified, trying to detect " "it automagically") # If the analysis target is a file, we choose the package according # to the file format. if self.config.category == "file": package = choose_package(self.config.file_type, self.config.file_name) # If it's an URL, we'll just use the default Internet Explorer # package. else: package = "ie" # If we weren't able to automatically determine the proper package, # we need to abort the analysis. if not package: raise CuckooError("No valid package available for file " "type: {0}".format(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 = "modules.packages.%s" % package # Try to import the analysis package. try: __import__(package_name, globals(), locals(), ["dummy"], -1) # If it fails, we need to abort the analysis. except ImportError: raise CuckooError('Unable to import package "{0}", does ' "not exist.".format(package_name)) # Initialize the package parent abstract. Package() # Enumerate the abstract's subclasses. try: package_class = Package.__subclasses__()[0] except IndexError as e: raise CuckooError("Unable to select package class " "(package={0}): {1}".format(package_name, e)) # Initialize the analysis package. pack = package_class(self.get_options()) # Initialize Auxiliary modules Auxiliary() prefix = 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"], -1) except ImportError as e: log.warning("Unable to import the auxiliary module " '"%s": %s', name, e) # Walk through the available auxiliary modules. aux_enabled = [] for module in Auxiliary.__subclasses__(): # Try to start the auxiliary module. try: aux = module() 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.info("Started auxiliary module %s", aux.__class__.__name__) 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) except NotImplementedError: raise CuckooError('The package "{0}" doesn\'t contain a run ' "function.".format(package_name)) except CuckooPackageError as e: raise CuckooError('The package "{0}" start function raised an ' "error: {1}".format(package_name, e)) except Exception as e: raise CuckooError( 'The package "{0}" start function encountered ' "an unhandled exception: " "{1}".format(package_name, 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 # If the process lock is locked, it means that something is # operating on the list of monitored processes. Therefore we cannot # proceed with the checks until the lock is released. if PROCESS_LOCK.locked(): KERNEL32.Sleep(1000) continue try: # If the process monitor is enabled we start checking whether # the monitored processes are still alive. if pid_check: for pid in PROCESS_LIST: if not Process(pid=pid).is_alive(): log.info("Process with pid %s has terminated", pid) PROCESS_LIST.remove(pid) # If none of the monitored processes are still alive, we # can terminate the analysis. if len(PROCESS_LIST) == 0: 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_name, e) finally: # Zzz. KERNEL32.Sleep(1000) 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_name, e) try: # Upload files the package created to package_files in the results folder package_files = pack.package_files() if package_files != None: for package in package_files: upload_to_host(package[0], os.path.join("package_files", package[1])) except Exception as e: log.warning('The package "%s" package_files function raised an ' "exception: %s", package_name, e) # Terminate the Auxiliary modules. for aux in aux_enabled: try: aux.stop() except (NotImplementedError, AttributeError): continue except Exception as e: log.warning("Cannot terminate auxiliary module %s: %s", aux.__class__.__name__, e) # 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: continue # Let's invoke the completion procedure. self.complete() return True
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
def run(self): """Run analysis. @return: operation status. """ self.prepare() log.info("Starting analyzer from: %s", os.getcwd()) log.info("Storing results at: %s", PATHS["root"]) log.info("Pipe server name: %s", PIPE) # If no analysis package was specified at submission, we try to select # one automatically. if not self.config.package: log.info("No analysis package specified, trying to detect " "it automagically") # If the analysis target is a file, we choose the package according # to the file format. if self.config.category == "file": package = choose_package(self.config.file_type, self.config.file_name) # If it's an URL, we'll just use the default Internet Explorer # package. else: package = "ie" # If we weren't able to automatically determine the proper package, # we need to abort the analysis. if not package: raise CuckooError("No valid package available for file " "type: {0}".format(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 = "modules.packages.%s" % package # Try to import the analysis package. try: __import__(package_name, globals(), locals(), ["dummy"], -1) # If it fails, we need to abort the analysis. except ImportError: raise CuckooError("Unable to import package \"{0}\", does " "not exist.".format(package_name)) # Initialize the package parent abstract. Package() # Enumerate the abstract's subclasses. try: package_class = Package.__subclasses__()[0] except IndexError as e: raise CuckooError("Unable to select package class " "(package={0}): {1}".format(package_name, e)) # Initialize the analysis package. pack = package_class(self.get_options()) # Initialize Auxiliary modules Auxiliary() prefix = 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"], -1) except ImportError as e: log.warning( "Unable to import the auxiliary module " "\"%s\": %s", name, e) # Walk through the available auxiliary modules. aux_enabled = [] for module in Auxiliary.__subclasses__(): # Try to start the auxiliary module. try: aux = module() 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.info("Started auxiliary module %s", aux.__class__.__name__) 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) except NotImplementedError: raise CuckooError("The package \"{0}\" doesn't contain a run " "function.".format(package_name)) except CuckooPackageError as e: raise CuckooError("The package \"{0}\" start function raised an " "error: {1}".format(package_name, e)) except Exception as e: raise CuckooError("The package \"{0}\" start function encountered " "an unhandled exception: " "{1}".format(package_name, 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 # If the process lock is locked, it means that something is # operating on the list of monitored processes. Therefore we cannot # proceed with the checks until the lock is released. if PROCESS_LOCK.locked(): KERNEL32.Sleep(1000) continue try: # If the process monitor is enabled we start checking whether # the monitored processes are still alive. if pid_check: for pid in PROCESS_LIST: if not Process(pid=pid).is_alive(): log.info("Process with pid %s has terminated", pid) PROCESS_LIST.remove(pid) # If none of the monitored processes are still alive, we # can terminate the analysis. if len(PROCESS_LIST) == 0: 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_name, e) finally: # Zzz. KERNEL32.Sleep(1000) 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_name, e) # Terminate the Auxiliary modules. for aux in aux_enabled: try: aux.stop() except (NotImplementedError, AttributeError): continue except Exception as e: log.warning("Cannot terminate auxiliary module %s: %s", aux.__class__.__name__, e) # 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: continue # Let's invoke the completion procedure. self.complete() return True
def __init__(self, options={}): threading.Thread.__init__(self) Auxiliary.__init__(self, options) self.do_run = True
def __init__(self, options): Thread.__init__(self) Auxiliary.__init__(self, options) self.do_run = True
def run(self): """Run analysis. @return: operation status. """ self.prepare() log.debug("Starting analyzer from: %s", os.getcwd()) log.debug("Pipe server name: %s", self.config.pipe) log.debug("Log pipe server name: %s", self.config.logpipe) # 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.") # If the analysis target is a file, we choose the package according # to the file format. if self.config.category == "file": package = choose_package(self.config.file_type, self.config.file_name, self.config.pe_exports.split(",")) # If it's an URL, we'll just use the default Internet Explorer # package. else: package = "ie" # If we weren't able to automatically determine the proper package, # we need to abort the analysis. if not package: raise CuckooError("No valid package available for file " "type: {0}".format(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 = "modules.packages.%s" % package # Try to import the analysis package. try: __import__(package_name, globals(), locals(), ["dummy"], -1) # If it fails, we need to abort the analysis. except ImportError: raise CuckooError("Unable to import package \"{0}\", does " "not exist.".format(package_name)) # Initialize the package parent abstract. Package() # Enumerate the abstract subclasses. try: package_class = Package.__subclasses__()[0] except IndexError as e: raise CuckooError("Unable to select package class " "(package={0}): {1}".format(package_name, e)) # Initialize the analysis package. self.package = package_class(self.config.options) # Move the sample to the current working directory as provided by the # task - one is able to override the starting path of the sample. # E.g., for some samples it might be useful to run from %APPDATA% # instead of %TEMP%. if self.config.category == "file": self.target = self.package.move_curdir(self.target) # Initialize Auxiliary modules Auxiliary() prefix = 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"], -1) 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 Auxiliary.__subclasses__(): # Try to start the auxiliary module. try: aux = module(options=self.config.options, analyzer=self) aux_avail.append(aux) aux.start() except (NotImplementedError, AttributeError): log.warning("Auxiliary module %s was not implemented", aux.__class__.__name__) except Exception as e: log.warning("Cannot execute auxiliary module %s: %s", aux.__class__.__name__, e) else: log.debug("Started auxiliary module %s", aux.__class__.__name__) 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 = self.package.start(self.target) except NotImplementedError: raise CuckooError("The package \"{0}\" doesn't contain a run " "function.".format(package_name)) except CuckooPackageError as e: raise CuckooError("The package \"{0}\" start function raised an " "error: {1}".format(package_name, e)) except Exception as e: raise CuckooError("The package \"{0}\" start function encountered " "an unhandled exception: " "{1}".format(package_name, e)) # If the analysis package returned a list of process identifiers, we # add them to the list of monitored processes and enable the process monitor. if pids: self.process_list.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 while self.do_run: self.time_counter += 1 if self.time_counter == int(self.config.timeout): log.info("Analysis timeout hit, terminating analysis.") break # If the process lock is locked, it means that something is # operating on the list of monitored processes. Therefore we # cannot proceed with the checks until the lock is released. if self.process_lock.locked(): KERNEL32.Sleep(1000) continue try: # If the process monitor is enabled we start checking whether # the monitored processes are still alive. if pid_check: for pid in self.process_list.pids: if not Process(pid=pid).is_alive(): log.info("Process with pid %s has terminated", pid) self.process_list.remove_pid(pid) # If none of the monitored processes are still alive, we # can terminate the analysis. if not self.process_list.pids: 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. self.package.set_pids(self.process_list.pids) 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 self.package.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_name, e) finally: # Zzz. KERNEL32.Sleep(1000) if not self.do_run: log.debug("The analyzer has been stopped on request by an " "auxiliary module.") # Create the shutdown mutex. KERNEL32.CreateMutexA(None, False, SHUTDOWN_MUTEX) try: # Before shutting down the analysis, the package can perform some # final operations through the finish() function. self.package.finish() except Exception as e: log.warning("The package \"%s\" finish function raised an " "exception: %s", package_name, e) try: # Upload files the package created to package_files in the # results folder. for path, name in self.package.package_files() or []: upload_to_host(path, os.path.join("package_files", name)) except Exception as e: log.warning("The package \"%s\" package_files function raised an " "exception: %s", package_name, e) # Terminate the Auxiliary modules. for aux in aux_enabled: 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 self.process_list.pids: proc = Process(pid=pid) if proc.is_alive(): try: proc.terminate() except: 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
def __init__(self, options): Auxiliary.__init__(self, options) Thread.__init__(self) self.do_run = True
def run(self): """Run analysis. @return: operation status. """ self.prepare() log.info("Starting analyzer from: %s" % os.getcwd()) log.info("Storing results at: %s" % PATHS["root"]) log.info("Pipe server name: %s" % PIPE) # If no analysis package was specified at submission, we try to select # one automatically. if not self.config.package: log.info("No analysis package specified, trying to detect it automagically") # If the analysis target is a file, we choose the package according # to the file format. if self.config.category == "file": #package = choose_package(self.config.file_type, self.config.file_name) package = choose_package(self.config.file_type, self.config.filename) # If it's an URL, we'll just use the default Internet Explorer # package. else: package = "ie" # If we weren't able to automatically determine the proper package, # we need to abort the analysis. if not package: log.warning("File type (%s) not recognized, using default exe package", self.config.file_type) package = "exe" else: log.info("Automatically selected analysis package \"%s\"" % package) ### JG: write package back to config self.config.package = package # Otherwise just select the specified package. else: package = self.config.package # Generate the package path. package_name = "modules.packages.%s" % package # Try to import the analysis package. try: __import__(package_name, globals(), locals(), ["dummy"], -1) # If it fails, we need to abort the analysis. except ImportError: raise CuckooError("Unable to import package \"{0}\", does not exist.".format(package_name)) # Initialize the package parent abstract. Package() # Enumerate the abstract's subclasses. try: package_class = Package.__subclasses__()[0] except IndexError as e: raise CuckooError("Unable to select package class (package={0}): {1}".format(package_name, e)) # Initialize the analysis package. pack = package_class(self.get_options()) ### JG: disable timer if interactive command shell if self.config.interaction != 0: log.info("Disabling IE spawn due to interactive command shell") enableIEspawn = False else: enableIEspawn = False start_time = time.time() # Initialize Auxiliary modules Auxiliary() prefix = auxiliaries.__name__ + "." for loader, name, ispkg in pkgutil.iter_modules(auxiliaries.__path__, prefix): if ispkg: continue # Import the auxiliary module. try: __import__(name, globals(), locals(), ["dummy"], -1) except ImportError as e: log.warning("Unable to import the auxiliary module \"%s\": %s", name, e) # Walk through the available auxiliary modules. aux_enabled = [] for auxiliary in Auxiliary.__subclasses__(): # Try to start the auxiliary module. try: aux = auxiliary() if aux.name == 'human' and self.config.interaction != 0: aux.stop() else: 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: 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) except NotImplementedError: raise CuckooError("The package \"{0}\" doesn't contain a run " "function.".format(package_name)) except CuckooPackageError as e: raise CuckooError("The package \"{0}\" start function raised an " "error: {1}".format(package_name, e)) except Exception as e: raise CuckooError("The package \"{0}\" start function encountered " "an unhandled exception: {1}".format(package_name, e)) ### JG: maintain intial pid(s) list in interactive modes and close monitoring if all of them are gone initialPIDs = [] if pids: if type(pids) == list: initialPIDs = initialPIDs + pids else: initialPIDs.append(pids) # 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 ### JG: flag that last minutes are running from reduced timer wait_mode = True wait_active = True while True: time_counter += 1 ### JG: added interaction check if time_counter >= int(self.config.timeout) and self.config.interaction == 0: log.info("Analysis timeout hit, terminating analysis") break # If the process lock is locked, it means that something is # operating on the list of monitored processes. Therefore we cannot # proceed with the checks until the lock is released. if PROCESS_LOCK.locked(): KERNEL32.Sleep(1000) continue try: ### JG: check if IE should be spawned if enableIEspawn: elapsed_time = time.time() - start_time if elapsed_time >= 30.0: log.info("spawning IE") p = Process() p.execute(path=os.path.join(os.getenv("ProgramFiles"), "Internet Explorer", "iexplore.exe"), args="\"http://www.google.de\"", suspended=False) enableIEspawn = False # If the process monitor is enabled we start checking whether # the monitored processes are still alive. if pid_check: for pid in PROCESS_LIST: if not Process(pid=pid).is_alive(): log.info("Process with pid %s has terminated", pid) PROCESS_LIST.remove(pid) log.info("%s" % (PROCESS_LIST)) ### JG: in interactive mode check if an initial pid terminated if self.config.interaction != 0 and pid in initialPIDs: log.info("Interactive Mode: initial PID terminated -> terminating analysis ...") wait_mode = False break # If none of the monitored processes are still alive, we # can terminate the analysis. if len(PROCESS_LIST) == 0: ### JG: set timer to one minute if wait_mode: if wait_active and int(self.config.timeout)>60: wait_active = False time_counter = int(self.config.timeout)-60 log.info("wait another 60 seconds if something happens ...") else: 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_name, e) finally: # Zzz. KERNEL32.Sleep(1000) 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_name, e) # Terminate the Auxiliary modules. for aux in aux_enabled: try: aux.stop() except Exception as e: log.warning("Cannot terminate auxiliary module %s: %s", aux.__class__.__name__, e) # Let's invoke the completion procedure. self.complete() return True
def __init__(self, options={}, analyzer=None): Thread.__init__(self) Auxiliary.__init__(self, options, analyzer) self.do_run = True
def __init__(self, options={}, config=None): Thread.__init__(self) Auxiliary.__init__(self, options, config) self.do_run = options.get("curtain", {}).get("enabled", False) self.enabled = options.get("curtain", {}).get("enabled", False)