Пример #1
0
 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)
Пример #2
0
    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)
Пример #3
0
 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)
Пример #4
0
 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)
Пример #5
0
 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)
Пример #6
0
    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)
Пример #7
0
    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)
Пример #8
0
    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