예제 #1
0
    def start(self, path):
        root = os.environ["TEMP"]
        password = self.options.get("password")

        zipinfos = self.get_infos(path)
        self.extract_zip(path, root, password)

        file_name = self.options.get("file")
        # If no file name is provided via option, take the first file.
        if not file_name:
            # No name provided try to find a better name.
            if len(zipinfos):
                # Take the first one.
                file_name = zipinfos[0].filename
                log.debug("Missing file option, auto executing: {0}".format(
                    file_name))
            else:
                raise CuckooPackageError("Empty ZIP archive")

        file_path = os.path.join(root, file_name)
        return self.execute(file_path, self.options.get("arguments"))
예제 #2
0
    def init_regkeys(self, regkeys):
        """Initializes the registry to avoid annoying popups, configure
        settings, etc.
        @param regkeys: the root keys, subkeys, and key/value pairs.
        """
        for rootkey, subkey, values in regkeys:
            key_handle = CreateKey(rootkey, subkey)

            for key, value in values.items():
                if isinstance(value, str):
                    SetValueEx(key_handle, key, 0, REG_SZ, value)
                elif isinstance(value, int):
                    SetValueEx(key_handle, key, 0, REG_DWORD, value)
                elif isinstance(value, dict):
                    self.init_regkeys([
                        [rootkey, "%s\\%s" % (subkey, key), value],
                    ])
                else:
                    raise CuckooPackageError("Invalid value type: %r" % value)

            CloseKey(key_handle)
예제 #3
0
    def execute(self, path, args, interest):
        """Starts an executable for analysis.
        @param path: executable path
        @param args: executable arguments
        @param interest: file of interest, passed to the cuckoomon config
        @return: process pid
        """
        dll = self.options.get("dll")
        dll_64 = self.options.get("dll_64")
        free = self.options.get("free")

        suspended = True
        if free:
            suspended = False
        kernel_analysis = self.options.get("kernel_analysis", False)

        if kernel_analysis is not False:
            kernel_analysis = True
        p = Process(options=self.options, config=self.config)
        if not p.execute(path=path,
                         args=args,
                         suspended=suspended,
                         kernel_analysis=kernel_analysis):
            raise CuckooPackageError("Unable to execute the initial process, "
                                     "analysis aborted.")

        if free:
            return None

        is_64bit = p.is_64bit()

        if not kernel_analysis:
            if is_64bit:
                p.inject(INJECT_QUEUEUSERAPC, interest)
            else:
                p.inject(INJECT_QUEUEUSERAPC, interest)
        p.resume()
        p.close()

        return p.pid
예제 #4
0
파일: zip.py 프로젝트: Cyber2020/nrl-cuckoo
    def start(self, path):
        root = os.environ["TEMP"]
        password = self.options.get("password")
        exe_regex = re.compile('(\.exe|\.scr|\.msi|\.bat|\.lnk|\.js|\.jse|\.vbs|\.vbe|\.wsf)$',flags=re.IGNORECASE)
        zipinfos = self.get_infos(path)
        self.extract_zip(path, root, password, 0)

        file_name = self.options.get("file")
        # If no file name is provided via option, take the first file.
        if not file_name:
            # No name provided try to find a better name.
            if len(zipinfos):
                # Attempt to find a valid exe extension in the archive
                for f in zipinfos:
                    if exe_regex.search(f.filename):
                        file_name = f.filename
                        break
                # Default to the first one if none found
                file_name = file_name if file_name else zipinfos[0].filename
                log.debug("Missing file option, auto executing: {0}".format(file_name))
            else:
                raise CuckooPackageError("Empty ZIP archive")


        file_path = os.path.join(root, file_name)
        log.debug("file_name: \"%s\"" % (file_name))
        if file_name.lower().endswith(".lnk"):
            cmd_path = self.get_path("cmd.exe")
            cmd_args = "/c start /wait \"\" \"{0}\"".format(file_path)
            return self.execute(cmd_path, cmd_args, file_path)
        elif file_name.lower().endswith(".msi"):
            msi_path = self.get_path("msiexec.exe")
            msi_args = "/I \"{0}\"".format(file_path)
            return self.execute(msi_path, msi_args, file_path)
        elif file_name.lower().endswith((".js", ".jse", ".vbs", ".vbe", ".wsf")):
            wscript = self.get_path_app_in_path("wscript.exe")
            wscript_args = "\"{0}\"".format(file_path)
            return self.execute(wscript, wscript_args, file_path)
        else:
            return self.execute(file_path, self.options.get("arguments"), file_path)
예제 #5
0
    def execute(self, path, args, interest):
        """Starts an executable for analysis.
        @param path: executable path
        @param args: executable arguments
        @param interest: file of interest, passed to the cuckoomon config
        @return: process pid
        """
        dll = self.options.get("dll")
        free = self.options.get("free")
        gw = self.options.get("setgw", None)

        u = Utils()
        if gw:
            u.set_default_gw(gw)

        suspended = True
        if free:
            suspended = False
        kernel_analysis = self.options.get("kernel_analysis", False)

        if kernel_analysis != False:
            kernel_analysis = True

        p = Process()
        if not p.execute(path=path,
                         args=args,
                         suspended=suspended,
                         kernel_analysis=kernel_analysis):
            raise CuckooPackageError("Unable to execute the initial process, "
                                     "analysis aborted.")

        if free:
            return None

        if not kernel_analysis:
            p.inject(dll, interest)
        p.resume()
        p.close()

        return p.pid
예제 #6
0
    def run(self):
        if not self.enabled:
            return False

        bin_path = os.path.join(ROOT, "bin")
        self.procmon_exe = os.path.join(bin_path, "procmon.exe")
        self.procmon_pmc = os.path.join(bin_path, "procmon.pmc")
        self.procmon_pml = os.path.join(bin_path, "procmon")
        self.procmon_xml = os.path.join(bin_path, "procmon.xml")

        if not os.path.exists(self.procmon_exe) or not os.path.exists(
                self.procmon_pmc):
            raise CuckooPackageError(
                "In order to use the Process Monitor functionality it is "
                "required to have Procmon setup with CAPE. Please run the "
                "CAPE Community script which will automatically fetch all "
                "related files to get you up-and-running.")

        # Start process monitor in the background.
        subprocess.Popen([
            self.procmon_exe,
            "/AcceptEula",
            "/Quiet",
            "/Minimized",
            "/BackingFile",
            self.procmon_pml,
        ],
                         startupinfo=self.startupinfo,
                         shell=True)

        # Try to avoid race conditions by waiting until at least something
        # has been written to the log file.
        while not os.path.exists(self.procmon_pml) or not os.path.getsize(
                self.procmon_pml):
            time.sleep(0.1)

        if self.enabled:
            return True
        return False
예제 #7
0
파일: apk.py 프로젝트: muhzii/cuckoo
    def _execute_app(self):
        """Execute sample via activity manager.
        @raise CuckooError: failed to execute sample.
        """
        log.info("Executing sample on the device via the activity manager.")

        try:
            args = [
                "/system/bin/sh", "/system/bin/am", "start", "-n",
                "%s/%s" % (self.package, self.activity)
            ]
            p = subprocess.Popen(args,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            out, err = p.communicate()

            if p.returncode:
                raise OSError(err.decode())
            log.info("Executed package activity: %s", out.decode())
        except OSError as e:
            raise CuckooPackageError("Error executing package activity: %s" %
                                     e)
예제 #8
0
    def start(self, path):
        free = self.options.get("free", False)
        dll = self.options.get("dll", None)
        suspended = True
        if free:
            suspended = False

        cmd_path = os.path.join(os.getenv("SystemRoot"), "system32", "cmd.exe")
        cmd_args = "/c start \"{0}\"".format(path)

        p = Process()
        if not p.execute(path=cmd_path, args=cmd_args, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial process, "
                                     "analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            p.close()
            return p.pid
        else:
            return None
예제 #9
0
    def debug(self, path, args, interest):
        """Starts an executable for analysis.
        @param path: executable path
        @param args: executable arguments
        @param interest: file of interest, passed to the cuckoomon config
        @return: process pid
        """

        suspended = True

        p = Process(options=self.options, config=self.config)
        if not p.execute(
                path=path, args=args, suspended=suspended,
                kernel_analysis=False):
            raise CuckooPackageError(
                "Unable to execute the initial process, analysis aborted")

        p.debug_inject(interest, childprocess=False)
        p.resume()
        p.close()

        return p.pid
예제 #10
0
파일: ie.py 프로젝트: zozo123/cuckoo
    def start(self, url):
        free = self.options.get("free", False)
        dll = self.options.get("dll", None)
        suspended = True
        if free:
            suspended = False

        iexplore = os.path.join(os.getenv("ProgramFiles"), "Internet Explorer",
                                "iexplore.exe")

        p = Process()
        if not p.execute(
                path=iexplore, args="\"%s\"" % url, suspended=suspended):
            raise CuckooPackageError("Unable to execute initial Internet "
                                     "Explorer process, analysis aborted")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            return p.pid
        else:
            return None
예제 #11
0
파일: dll.py 프로젝트: xarly/cuckoo
    def start(self, path):
        free = self.options.get("free", False)
        function = self.options.get("function", "DllMain")
        arguments = self.options.get("arguments", None)
        suspended = True
        if free:
            suspended = False

        args = "{0},{1}".format(path, function)
        if arguments:
            args += " {0}".format(arguments)

        p = Process()
        if not p.execute(path="C:\\WINDOWS\\system32\\rundll32.exe", args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute rundll32, analysis aborted")

        if not free and suspended:
            p.inject()
            p.resume()
            return p.pid
        else:
            return None
예제 #12
0
    def execute(self, path, args):
        """Starts an executable for analysis.
        @param path: executable path
        @param args: executable arguments
        @return: process pid
        """
        dll = self.options.get("dll")
        free = self.options.get("free")
        suspended = True
        if free:
            suspended = False

        p = Process()
        if not p.execute(path=path, args=args, suspended=suspended):
            raise CuckooPackageError("Unable to execute the initial process, "
                                     "analysis aborted.")

        if not free and suspended:
            p.inject(dll)
            p.resume()
            p.close()
            return p.pid
예제 #13
0
def get_package_activity_name_old(path):
    """Using the Android Asset Packaging Tool to extract from apk the package name and main activity"""
    log.info("getting package and main activity from sample : aapt dump badging "+path)
    str=""
    proc = subprocess.Popen(["aapt", "dump","badging", path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    for s in proc.stdout.xreadlines():
        str=str+s

    lines = str.split("\n")
    myDic = {}
    for line in lines:
        splitedline=line.split(":")
        if len(splitedline)==2:
            myKey,myValue=line.split(":")
            myDic[myKey]=myValue

    if not "package" in myDic or not 'launchable-activity' in myDic:
        #log.warning(str)
        raise CuckooPackageError("failed to get package and main activity from sample!")

    package = myDic['package'].split("'")[1]
    activity = myDic['launchable-activity'].split("'")[1]
    return package, activity
예제 #14
0
    def execute(self, path, args, mode=None, maximize=False):
        """Starts an executable for analysis.
        @param path: executable path
        @param args: executable arguments
        @param mode: monitor mode - which functions to instrument
        @param maximize: whether the GUI should start maximized
        @return: process pid
        """
        dll = self.options.get("dll")
        free = self.options.get("free")
        source = self.options.get("from")

        # Setup pre-defined registry keys.
        self.init_regkeys(self.REGKEYS)

        p = Process()
        if not p.execute(path=path, args=args, dll=dll, free=free,
                         curdir=self.curdir, source=source, mode=mode,
                         maximize=maximize):
            raise CuckooPackageError("Unable to execute the initial process, "
                                     "analysis aborted.")

        return p.pid
예제 #15
0
    def extract_zip(self,
                    zip_path,
                    extract_path,
                    password=b"infected",
                    recursion_depth=1):
        """Extracts a nested ZIP file.
        @param zip_path: ZIP path
        @param extract_path: where to extract
        @param password: ZIP password
        @param recursion_depth: how deep we are in a nested archive
        """
        # Test if zip file contains a file named as itself.
        if self.is_overwritten(zip_path):
            log.debug(
                "ZIP file contains a file with the same name, original is going to be overwrite"
            )
            # TODO: add random string.
            new_zip_path = zip_path + ".old"
            shutil.move(zip_path, new_zip_path)
            zip_path = new_zip_path

        #requires bytes not str
        if not isinstance(password, bytes):
            password = password.encode("utf-8")

        # Extraction.
        with ZipFile(zip_path, "r") as archive:

            # Check if the archive is encrypted
            for zip_info in archive.infolist():
                is_encrypted = zip_info.flag_bits & 0x1
                # If encrypted and the user didn't provide a password
                # set to default value
                if is_encrypted and password == b"":
                    log.debug(
                        "Achive is encrypted and user did not provide a password, using default value: infected"
                    )
                    password = b"infected"
                # Else, either password stays as user specified or archive is not encrypted

            try:
                archive.extractall(path=extract_path, pwd=password)
            except BadZipfile:
                raise CuckooPackageError("Invalid Zip file")
            except RuntimeError:
                try:
                    archive.extractall(path=extract_path, pwd=password)
                except RuntimeError as e:
                    raise CuckooPackageError("Unable to extract Zip file: "
                                             "{0}".format(e))
            finally:
                if recursion_depth < 4:
                    # Extract nested archives.
                    for name in archive.namelist():
                        if name.endswith(".zip"):
                            # Recurse.
                            try:
                                self.extract_zip(
                                    os.path.join(extract_path, name),
                                    extract_path,
                                    password=password,
                                    recursion_depth=recursion_depth + 1)
                            except BadZipfile:
                                log.warning(
                                    "Nested zip file '%s' name end with 'zip' extension is not a valid zip. Skip extracting"
                                    % name)
                            except RuntimeError as run_err:
                                log.error(
                                    "Error to extract nested zip file %s with details: %s"
                                    % name, run_err)
예제 #16
0
    def start(self, path):
        password = self.options.get("password")
        if password is None:
            password = b""
        appdata = self.options.get("appdata")
        if appdata:
            root = os.environ["APPDATA"]
        else:
            root = os.environ["TEMP"]
        exe_regex = re.compile(
            '(\.exe|\.dll|\.scr|\.msi|\.bat|\.lnk|\.js|\.jse|\.vbs|\.vbe|\.wsf)$',
            flags=re.IGNORECASE)
        zipinfos = self.get_infos(path)
        self.extract_zip(path, root, password, 0)

        file_name = self.options.get("file")
        # If no file name is provided via option, take the first file.
        if not file_name:
            # No name provided try to find a better name.
            if len(zipinfos):
                # Attempt to find a valid exe extension in the archive
                for f in zipinfos:
                    if exe_regex.search(f.filename):
                        file_name = f.filename
                        break
                # Default to the first one if none found
                file_name = file_name if file_name else zipinfos[0].filename
                log.debug("Missing file option, auto executing: {0}".format(
                    file_name))
            else:
                raise CuckooPackageError("Empty ZIP archive")

        file_path = os.path.join(root, file_name)
        log.debug("file_name: \"%s\"" % (file_name))
        if file_name.lower().endswith(".lnk"):
            cmd_path = self.get_path("cmd.exe")
            cmd_args = "/c start /wait \"\" \"{0}\"".format(file_path)
            return self.execute(cmd_path, cmd_args, file_path)
        elif file_name.lower().endswith(".msi"):
            msi_path = self.get_path("msiexec.exe")
            msi_args = "/I \"{0}\"".format(file_path)
            return self.execute(msi_path, msi_args, file_path)
        elif file_name.lower().endswith(
            (".js", ".jse", ".vbs", ".vbe", ".wsf")):
            wscript = self.get_path_app_in_path("wscript.exe")
            wscript_args = "\"{0}\"".format(file_path)
            return self.execute(wscript, wscript_args, file_path)
        elif file_name.lower().endswith(".dll"):
            rundll32 = self.get_path_app_in_path("rundll32.exe")
            function = self.options.get("function", "#1")
            arguments = self.options.get("arguments")
            dllloader = self.options.get("dllloader")
            dll_args = "\"{0}\",{1}".format(file_path, function)
            if arguments:
                dll_args += " {0}".format(arguments)
            if dllloader:
                newname = os.path.join(os.path.dirname(rundll32), dllloader)
                shutil.copy(rundll32, newname)
                rundll32 = newname
            return self.execute(rundll32, dll_args, file_path)
        elif file_name.lower().endswith(".ps1"):
            powershell = self.get_path_app_in_path("powershell.exe")
            args = "-NoProfile -ExecutionPolicy bypass -File \"{0}\"".format(
                path)
            return self.execute(powershell, args, file_path)
        else:
            if "." not in os.path.basename(file_path):
                new_path = file_path + ".exe"
                os.rename(file_path, new_path)
                file_path = new_path
            return self.execute(file_path, self.options.get("arguments"),
                                file_path)
예제 #17
0
    def process_unzipped_contents(self, unzipped_directory: str,
                                  json_filename: str) -> Tuple[str, str]:
        """Checks JSON to move the various files to."""
        raw_json = extract_json_data(unzipped_directory, json_filename)

        json_dst_flds = raw_json.get("path_to_extract", {})
        target_file = raw_json.get("target_file", "")

        # Enforce the requirement of having a specified file. No guessing.
        target_file = target_file or self.options.get("file")
        if not target_file:
            raise CuckooPackageError(
                "File must be specified in the JSON or the web submission UI!")
        elif not self.is_valid_extension(target_file):
            raise CuckooPackageError(
                "Invalid, unsupported or no extension recognised by zip_compound package"
            )

        # In case the "file" submittion option is relative, we split here
        target_srcdir, target_name = os.path.split(target_file)

        # Note for 32bit samples: Even if JSON configutation specifies "System32",
        # wow64 redirection will still happen
        # Commented out since redirection-related issues should be uncommon.
        # if is_os_64bit():
        #     wow64 = c_ulong(0)
        #     KERNEL32.Wow64DisableWow64FsRedirection(byref(wow64))

        fin_target_path = os.path.join(unzipped_directory, target_file)

        # Move files that are specified in JSON file
        if json_dst_flds:
            for f, dst_fld in json_dst_flds.items():
                oldpath = os.path.join(unzipped_directory, f)
                dst_fld = os.path.expandvars(dst_fld)
                create_custom_folders(dst_fld)
                # If a relative path is provided, take only the basename
                fname = os.path.split(f)[1]
                newpath = os.path.join(dst_fld, fname)

                # We cannot just shutil.move src dirs if src name == dst name.
                if os.path.isdir(oldpath):
                    log.debug("Resolved Dir: %s for folder '%s'", dst_fld,
                              fname)
                    shutil.copytree(oldpath, newpath, dirs_exist_ok=True)
                    shutil.rmtree(oldpath)
                else:
                    log.debug("Resolved Dir: %s for file '%s'", dst_fld, fname)
                    shutil.move(oldpath, newpath)

                if target_file.lower() == f.lower():
                    fin_target_path = newpath
                    self.options["curdir"] = dst_fld
                    log.debug("New curdir value: %s", self.options["curdir"])

        # Only runs if a relative path is given for target file
        # Errors out if the file's containing folder is shifted
        # before shifting the target file first.
        if target_srcdir and not os.path.exists(fin_target_path):
            raise CuckooPackageError(
                "Error getting the correct path for the target file! \
                Target file should be moved before moving its containing\
                source folder")

        log.debug("Final target name: %s", target_name)
        log.info("Final target path: %s", fin_target_path)
        return target_name, fin_target_path
예제 #18
0
    def start(self, path):
        """
        @param path: 변환(분석)할 문서 파일의 경로
        @return: 프로세스 ID
        """
        # 확장자에 맞는 인쇄 명령을 찾음.
        # (ShellExecute에서 print 동사(verb) 사용 시 실행되는 명령어)
        file_path, file_ext = os.path.splitext(path)

        print_cmd = self.get_print_command(file_ext)
        if not print_cmd:
            raise CuckooPackageError('Not supported extension: ' + file_ext)

        # 인쇄 명령어에서 실행 프로그램의 경로와 각 파라미터를 분리 시킴.
        regex = re.compile(r'((?:(?:[^\s"]+)|"(?:""|[^"])*")+)(?:\s|$)')
        found = regex.findall(print_cmd['command'])
        if len(found) < 2:
            raise CuckooPackageError('Wrong print command: ' +
                                     print_cmd['command'])

        # 프로그램 실행 경로
        execute_path = found[0]
        if execute_path.startswith('"'):
            execute_path = execute_path[1:-1]  # 양 끝의 "(큰따옴표)를 제거함.

        # 프로그램 파라미터
        execute_param = []
        for param in found[1:]:
            if param.startswith('"') and param.endswith('"'):
                param = param[1:-1]  # 양 끝의 "(큰따옴표)를 제거함.
            execute_param.append(param.replace('%1', '{}'.format(path)))

        pid = self.execute(execute_path, args=execute_param)

        # 일부 프로그램(특히 MS 오피스)의 경우
        # 인쇄를 위해서는 DDE 통신이 필요함.
        if print_cmd['ddeexec']:
            log.debug('Need dde!!')
            if not print_cmd['application']:
                raise CuckooPackageError('No dde server name. dde info: ' +
                                         str(print_cmd))
            if not print_cmd['topic']:
                raise CuckooPackageError('No dde topic. dde info: ' +
                                         str(print_cmd))

            time.sleep(5)  # dde 서버가 실행되는 동안 기다림

            try:
                log.debug('dde start')
                server = dde.CreateServer()
                log.debug('dde server create1')
                server.Create('PrintClient')
                log.debug('dde server create2')
                conversation = dde.CreateConversation(server)
                log.debug('dde conversation created')
                conversation.ConnectTo(print_cmd['application'],
                                       print_cmd['topic'])
                log.debug('dde connected')
                conversation.Exec(print_cmd['ddeexec'].replace('%1', path))
                log.debug('dde exec.')
            except Exception as e:
                log.error(str(e))

        return pid
예제 #19
0
    def start_package(self, config):
        """Start an analysis package.

        @param config: a dictionary containing at least a target category,
        options dictionary, and target string or list of targets

        returns a package id
        """
        pkgname = config.get("package")
        if not pkgname:
            log.info(
                "No analysis package provided, trying to automatically find a "
                "matching package"
            )
            pkg = choose_package(config)
        else:
            pkg = get_package_class(pkgname)

        if pkgname and not pkg:
            raise CuckooPackageError(
                "Could not find analysis package '%r'" % pkgname
            )

        if not pkg:
            category = config.get("category")
            raise CuckooPackageError(
                "No valid analysis package available for target category '%s'."
                "%s" % (
                    category,
                    config.get("file_name") if category == "file" else ""
                )
            )

        log.info("Using analysis package '%s'", pkg.__name__)
        options = config.get("options", {}) or {}
        pkg_instance = pkg(options=options, analyzer=self)

        category = config.get("category")
        if category == "file":
            target = os.path.join(os.environ["TEMP"], config.get("file_name"))
            pkg_instance.move_curdir(target)

        elif category == "archive":
            zippath = os.path.join(os.environ["TEMP"], config.get("file_name"))
            zipfile.ZipFile(zippath).extractall(os.environ["TEMP"])
            if not options.get("filename"):
                raise CuckooPackageError(
                    "No filename specified to open after unpacking archive"
                )

            target = os.path.join(os.environ["TEMP"], options.get("filename"))
        elif category == "url":
            target = config.get("target")
        else:
            raise CuckooPackageError(
                "Unknown category '%s' specified" % category
            )

        pids = pkg_instance.start(target)
        if pids:
            self.plist.add_pids(pids)

        self.pkg_counter += 1
        pkg_id = str(config.get("pkg_id") or self.pkg_counter)
        self.packages[pkg_id] = pkg_instance
        return {
            "pkg_id": pkg_id,
            "name": pkg_instance.__class__.__name__,
            "pids": pkg_instance.pids_targets
        }
예제 #20
0
    def execute(self,
                path,
                args,
                mode=None,
                maximize=False,
                env=None,
                source=None,
                trigger=None):
        """Starts an executable for analysis.
        @param path: executable path
        @param args: executable arguments
        @param mode: monitor mode - which functions to instrument
        @param maximize: whether the GUI should start maximized
        @param env: additional environment variables
        @param source: parent process of our process
        @param trigger: trigger to indicate analysis start
        @return: process pid
        """
        dll = self.options.get("dll")
        free = self.options.get("free")
        analysis = self.options.get("analysis")
        kernel_mode = self.options.get("kernelmode")
        kernel_pipe = self.options.get("kernel_logpipe",
                                       "\\\\.\\ThunderDefPipe")
        log_pipe = self.options.get("forwarderpipe")
        dispatcher_pipe = self.options.get("dispatcherpipe")
        driver_options = self.options.get("driver_options")
        package = type(self).__name__

        # Kernel analysis overrides the free argument.
        if analysis == "kernel":
            free = True

        source = source or self.options.get("from")
        mode = mode or self.options.get("mode")

        if not trigger and self.options.get("trigger"):
            if self.options["trigger"] == "exefile":
                trigger = "file:%s" % path

        # Setup pre-defined registry keys.
        self.init_regkeys(self.REGKEYS)

        # check preloaded apps
        self._check_preloaded_apps()

        p = Process()
        if not p.execute(path=path,
                         args=args,
                         dll=dll,
                         free=free,
                         kernel_mode=kernel_mode,
                         kernel_pipe=kernel_pipe,
                         forwarder_pipe=log_pipe,
                         dispatcher_pipe=dispatcher_pipe,
                         destination=self.options.get("destination",
                                                      ("localhost", 1)),
                         curdir=self.curdir,
                         source=source,
                         mode=mode,
                         maximize=maximize,
                         env=env,
                         trigger=trigger,
                         driver_options=driver_options,
                         package=package):
            raise CuckooPackageError(
                "Unable to execute the initial process, analysis aborted.")

        return p.pid
예제 #21
0
    def start(self, path):
        root = os.environ["TEMP"]
        password = self.options.get("password")
        exe_regex = re.compile(
            r"(\.exe|\.scr|\.msi|\.bat|\.lnk|\.js|\.jse|\.vbs|\.vbe|\.wsf)$",
            flags=re.IGNORECASE)
        dll_regex = re.compile(r"(\.dll|\.ocx)$", flags=re.IGNORECASE)
        zipinfos = self.get_infos(path)
        self.extract_zip(path, root, password, 0)

        file_name = self.options.get("file")
        # If no file name is provided via option, take the first file.
        if file_name is None:
            # No name provided try to find a better name.
            if len(zipinfos):
                # Attempt to find a valid exe extension in the archive
                for f in zipinfos:
                    if exe_regex.search(f.filename):
                        file_name = f.filename
                        break
                if file_name is None:
                    for f in zipinfos:
                        if dll_regex.search(f.filename):
                            file_name = f.filename
                            break
                # Default to the first one if none found
                file_name = file_name if file_name else zipinfos[0].filename
                log.debug("Missing file option, auto executing: %s", file_name)
            else:
                raise CuckooPackageError("Empty ZIP archive")

        file_path = os.path.join(root, file_name)
        log.debug('file_name: "%s"', file_name)
        if file_name.lower().endswith(".lnk"):
            cmd_path = self.get_path("cmd.exe")
            cmd_args = f'/c start /wait "" "{file_path}"'
            return self.execute(cmd_path, cmd_args, file_path)
        elif file_name.lower().endswith(".msi"):
            msi_path = self.get_path("msiexec.exe")
            msi_args = f'/I "{file_path}"'
            return self.execute(msi_path, msi_args, file_path)
        elif file_name.lower().endswith(
            (".js", ".jse", ".vbs", ".vbe", ".wsf")):
            wscript = self.get_path_app_in_path("wscript.exe")
            wscript_args = f'"{file_path}"'
            return self.execute(wscript, wscript_args, file_path)
        elif file_name.lower().endswith((".dll", ".ocx")):
            rundll32 = self.get_path_app_in_path("rundll32.exe")
            function = self.options.get("function", "#1")
            arguments = self.options.get("arguments")
            dllloader = self.options.get("dllloader")
            dll_args = f'"{file_path}",{function}'
            if arguments:
                dll_args += f" {arguments}"
            if dllloader:
                newname = os.path.join(os.path.dirname(rundll32), dllloader)
                shutil.copy(rundll32, newname)
                rundll32 = newname
            return self.execute(rundll32, dll_args, file_path)
        elif file_name.lower().endswith(".ps1"):
            powershell = self.get_path_app_in_path("powershell.exe")
            args = f'-NoProfile -ExecutionPolicy bypass -File "{path}"'
            return self.execute(powershell, args, file_path)
        else:
            return self.execute(file_path, self.options.get("arguments"),
                                file_path)