Пример #1
0
    def run(self):
        """Run analysis.
        @return: structured results.
        """
        self.key = "procmemory"
        results = []
        do_strings = self.options.get("strings", False)
        nulltermonly = self.options.get("nullterminated_only", True)
        minchars = str(self.options.get("minchars", 5)).encode("utf-8")

        if os.path.exists(self.pmemory_path):
            for dmp in os.listdir(self.pmemory_path):
                # if we're re-processing this task, this means if zips are enabled, we won't do any reprocessing on the
                # process dumps (only matters for now for Yara)
                if not dmp.endswith(".dmp"):
                    continue

                dmp_path = os.path.join(self.pmemory_path, dmp)
                if os.path.getsize(dmp_path) == 0:
                    continue

                dmp_file = File(dmp_path)
                process_name = ""
                process_path = ""
                process_id = int(
                    os.path.splitext(os.path.basename(dmp_path))[0])
                for process in self.results.get("behavior", {}).get(
                        "processes", []) or []:
                    if process_id == process["process_id"]:
                        process_name = process["process_name"]
                        process_path = process["module_path"]

                procdump = ProcDump(dmp_path, pretty=True)

                proc = dict(
                    file=dmp_path,
                    pid=process_id,
                    name=process_name,
                    path=process_path,
                    yara=dmp_file.get_yara(category="memory"),
                    cape_yara=dmp_file.get_yara(category="CAPE"),
                    address_space=procdump.pretty_print(),
                )

                for hit in proc["cape_yara"]:
                    hit["memblocks"] = dict()
                    for item in hit["addresses"]:
                        memblock = self.get_yara_memblock(
                            proc["address_space"], hit["addresses"][item])
                        if memblock:
                            hit["memblocks"][item] = memblock

                # if self.options.get("extract_pe", False)
                extracted_pes = self.get_procmemory_pe(proc)

                endlimit = b""
                if not HAVE_RE2:
                    endlimit = b"8192"

                if do_strings:
                    if nulltermonly:
                        apat = b"([\x20-\x7e]{" + minchars + b"," + endlimit + b"})\x00"
                        upat = b"((?:[\x20-\x7e][\x00]){" + minchars + b"," + endlimit + b"})\x00\x00"
                    else:
                        apat = b"[\x20-\x7e]{" + minchars + b"," + endlimit + b"}"
                        upat = b"(?:[\x20-\x7e][\x00]){" + minchars + b"," + endlimit + b"}"

                    matchdict = procdump.search(apat, all=True)
                    strings = matchdict["matches"]
                    matchdict = procdump.search(upat, all=True)
                    ustrings = matchdict["matches"]
                    for ws in ustrings:
                        strings.append(ws.decode("utf-16le").encode("utf-8"))

                    proc["strings_path"] = dmp_path + ".strings"
                    proc["extracted_pe"] = extracted_pes
                    f = open(proc["strings_path"], "wb")
                    f.write(b"\n".join(strings))
                    f.close()

                procdump.close()
                results.append(proc)

                cape_name = cape_name_from_yara(proc, process_id, self.results)
                if cape_name and "detections" not in self.results:
                    self.results["detections"] = cape_name
        return results
Пример #2
0
    def run(self):
        """Run analysis.
        @return: list of process dumps with related information.
        """
        self.key = "procdump"
        procdump_files = []
        buf = self.options.get("buffer", 8192)
        if not os.path.exists(self.procdump_path):
            return None

        meta = {}
        if os.path.exists(self.files_metadata):
            for line in open(self.files_metadata, "rb"):
                entry = json.loads(line)
                filepath = os.path.join(self.analysis_path, entry["path"])
                meta[filepath] = {
                    "pids": entry["pids"],
                    "filepath": entry["filepath"],
                    "metadata": entry["metadata"],
                }

        file_names = os.listdir(self.procdump_path)
        for file_name in file_names:
            file_path = os.path.join(self.procdump_path, file_name)
            if not meta.get(file_path):
                continue
            file_info, pefile_object = File(
                file_path=file_path,
                guest_paths=meta[file_path]["metadata"],
                file_name=file_name).get_all()
            if pefile_object:
                self.results.setdefault("pefiles", {})
                self.results["pefiles"].setdefault(file_info["sha256"],
                                                   pefile_object)
            metastrings = meta[file_path].get("metadata", "").split(";?")
            if len(metastrings) < 3:
                continue
            file_info["process_path"] = metastrings[1]
            file_info["module_path"] = metastrings[2]
            file_info["process_name"] = file_info["process_path"].rsplit(
                "\\", 1)[-1]
            file_info["pid"] = meta[file_path]["pids"][0]
            type_strings = file_info["type"].split()
            if len(type_strings) < 3:
                continue
            if type_strings[0] == "MS-DOS":
                file_info["cape_type"] = "DOS MZ image: executable"
            else:
                file_info["cape_type"] = "PE image"
                if type_strings[0] == ("PE32+"):
                    file_info["cape_type"] += ": 64-bit "
                elif type_strings[0] == ("PE32"):
                    file_info["cape_type"] += ": 32-bit "
                file_info["cape_type"] += "DLL" if type_strings[2] == (
                    "(DLL)") else "executable"

            texttypes = [
                "ASCII",
                "Windows Registry text",
                "XML document text",
                "Unicode text",
            ]
            if any(texttype in file_info["type"] for texttype in texttypes):
                with open(file_info["path"], "r") as drop_open:
                    filedata = drop_open.read(buf + 1)
                file_info["data"] = convert_to_printable_and_truncate(
                    filedata, buf)

            if file_info["pid"]:
                _ = cape_name_from_yara(file_info, file_info["pid"],
                                        self.results)

            if HAVE_FLARE_CAPA:
                pretime = timeit.default_timer()
                capa_details = flare_capa_details(file_path, "procdump")
                if capa_details:
                    file_info["flare_capa"] = capa_details
                self.add_statistic_tmp("flare_capa", "time", pretime)

            # should we use dropped path here?
            static_file_info(
                file_info,
                file_path,
                str(self.task["id"]),
                self.task.get("package", ""),
                self.task.get("options", ""),
                self.self_extracted,
                self.results,
            )

            procdump_files.append(file_info)

        return procdump_files