Exemplo n.º 1
0
    def build_options(self):
        """Generate analysis options.
        @return: options dict.
        """
        options = {}

        if self.task.category == "file":
            options["file_name"] = File(self.task.target).get_name()
            options["file_type"] = File(self.task.target).get_type()
            options["pe_exports"] = \
                ",".join(File(self.task.target).get_exported_functions())

            package, activity = File(self.task.target).get_apk_entry()
            self.task.options["apk_entry"] = "%s:%s" % (package, activity)

        options["id"] = self.task.id
        options["ip"] = self.machine.resultserver_ip
        options["port"] = self.machine.resultserver_port
        options["category"] = self.task.category
        options["target"] = self.task.target
        options["package"] = self.task.package
        options["options"] = emit_options(self.task.options)
        options["enforce_timeout"] = self.task.enforce_timeout
        options["clock"] = self.task.clock
        options["terminate_processes"] = self.cfg.cuckoo.terminate_processes

        if not self.task.timeout:
            options["timeout"] = self.cfg.timeouts.default
        else:
            options["timeout"] = self.task.timeout

        # copy in other analyzer specific options, TEMPORARY (most likely)
        vm_options = getattr(machinery.options, self.machine.name)
        for k in vm_options:
            if k.startswith("analyzer_"):
                options[k] = vm_options[k]

        return options
Exemplo n.º 2
0
    def run(self):
        self.key = "network"
        self.ja3_file = self.options.get(
            "ja3_file",
            os.path.join(CUCKOO_ROOT, "data", "ja3", "ja3fingerprint.json"))
        if not IS_DPKT:
            log.error("Python DPKT is not installed, aborting PCAP analysis.")
            return {}

        if not os.path.exists(self.pcap_path):
            log.warning("The PCAP file does not exist at path \"%s\".",
                        self.pcap_path)
            return {}

        if os.path.getsize(self.pcap_path) == 0:
            log.error("The PCAP file at path \"%s\" is empty." %
                      self.pcap_path)
            return {}

        ja3_fprints = self._import_ja3_fprints()

        sorted_path = self.pcap_path.replace("dump.", "dump_sorted.")
        if cfg.processing.sort_pcap:
            sort_pcap(self.pcap_path, sorted_path)
            buf = Pcap(self.pcap_path, ja3_fprints).run()
            results = Pcap(sorted_path, ja3_fprints).run()
            results["http"] = buf["http"]
            results["dns"] = buf["dns"]
        else:
            results = Pcap(self.pcap_path, ja3_fprints).run()

        # Save PCAP file hash.
        if os.path.exists(self.pcap_path):
            results["pcap_sha256"] = File(self.pcap_path).get_sha256()
        if os.path.exists(sorted_path):
            results["sorted_pcap_sha256"] = File(sorted_path).get_sha256()

        return results
Exemplo n.º 3
0
    def run(self):
        self.key = "network"
        self.ja3_file = self.options.get("ja3_file", os.path.join(CUCKOO_ROOT, "data", "ja3", "ja3fingerprint.json"))
        if not IS_DPKT:
            log.error("Python DPKT is not installed, aborting PCAP analysis")
            return {}

        if not os.path.exists(self.pcap_path):
            log.warning('The PCAP file does not exist at path "%s"', self.pcap_path)
            return {}

        if os.path.getsize(self.pcap_path) == 0:
            log.error('The PCAP file at path "%s" is empty', self.pcap_path)
            return {}

        ja3_fprints = self._import_ja3_fprints()

        results = {"pcap_sha256": File(self.pcap_path).get_sha256()}
        self.options["sorted"] = False
        results.update(Pcap(self.pcap_path, ja3_fprints, self.options).run())

        if proc_cfg.network.sort_pcap:
            sorted_path = self.pcap_path.replace("dump.", "dump_sorted.")
            sort_pcap(self.pcap_path, sorted_path)
            if os.path.exists(sorted_path):
                results["sorted_pcap_sha256"] = File(sorted_path).get_sha256()
                self.options["sorted"] = True
                results.update(Pcap(sorted_path, ja3_fprints, self.options).run())

        if HAVE_HTTPREPLAY:
            try:
                p2 = Pcap2(self.pcap_path, self.get_tlsmaster(), self.network_path).run()
                if p2:
                    results.update(p2)
            except Exception:
                log.exception("Error running httpreplay-based PCAP analysis")

        return results
Exemplo n.º 4
0
def demux_sample(filename, package, options):
    """
    If file is a ZIP, extract its included files and return their file paths
    If file is an email, extracts its attachments and return their file paths (later we'll also extract URLs)
    """

    # if a package was specified, then don't do anything special
    if package:
        return [filename]

    # don't try to extract from office docs
    magic = File(filename).get_type()

    # if file is an Office doc and password is supplied, try to decrypt the doc
    if "Microsoft" in magic:
        ignore = ["Outlook", "Message", "Disk Image"]
        if any(x in magic for x in ignore):
            pass
        elif "Composite Document File" in magic or "CDFV2 Encrypted" in magic:
            password = False
            tmp_pass = options2passwd(options)
            if tmp_pass:
                password = tmp_pass
            if password:
                return demux_office(filename, password)
            else:
                return [filename]

    # don't try to extract from Java archives or executables
    if "Java Jar" in magic:
        return [filename]
    if "PE32" in magic or "MS-DOS executable" in magic:
        return [filename]
    if any(x in magic for x in VALID_LINUX_TYPES):
        return [filename]

    retlist = list()
    if HAS_SFLOCK:
        # all in one unarchiver
        retlist = demux_sflock(filename, options)

    # if it wasn't a ZIP or an email or we weren't able to obtain anything interesting from either, then just submit the
    # original file
    if not retlist:
        retlist.append(filename)
    else:
        if len(retlist) > 10:
            retlist = retlist[:10]

    return retlist
Exemplo n.º 5
0
    def run(self, results):
        """Writes report.
        @param results: Cuckoo results dict.
        @raise CuckooReportError: if fails to write report.
        """
        if not HAVE_JINJA2:
            raise CuckooReportError("Failed to generate HTML report: Jinja2 Python library is not installed")

        shots_path = os.path.join(self.analysis_path, "shots")
        if os.path.exists(shots_path):
            shots = []
            counter = 1
            for shot_name in os.listdir(shots_path):
                if not shot_name.endswith(".jpg"):
                    continue

                shot_path = os.path.join(shots_path, shot_name)

                if os.path.getsize(shot_path) == 0:
                    continue

                shot = {}
                shot["id"] = os.path.splitext(File(shot_path).get_name())[0]
                shot["data"] = base64.b64encode(open(shot_path, "rb").read())
                shots.append(shot)

                counter += 1

            shots.sort(key=lambda shot: shot["id"])
            results["screenshots"] = shots
        else:
            results["screenshots"] = []

        env = Environment(autoescape=True)
        env.loader = FileSystemLoader(os.path.join(CUCKOO_ROOT, "data", "html"))

        try:
            tpl = env.get_template("report.html")
            html = tpl.render({"results" : results})
        except Exception as e:
            raise CuckooReportError("Failed to generate HTML report: %s" % e)
        
        try:
            report = open(os.path.join(self.reports_path, "report.html"), "w")
            report.write(html)
            report.close()
        except (TypeError, IOError) as e:
            raise CuckooReportError("Failed to write HTML report: %s" % e)

        return True
Exemplo n.º 6
0
    def run(self):
        self.key = "network"
        self.ja3_file = self.options.get("ja3_file", os.path.join(CUCKOO_ROOT, "data", "ja3", "ja3fingerprint.json"))
        if not IS_DPKT:
            log.error("Python DPKT is not installed, aborting PCAP analysis.")
            return {}

        if not os.path.exists(self.pcap_path):
            log.warning('The PCAP file does not exist at path "%s".', self.pcap_path)
            return {}

        if os.path.getsize(self.pcap_path) == 0:
            log.error('The PCAP file at path "%s" is empty.' % self.pcap_path)
            return {}

        ja3_fprints = self._import_ja3_fprints()

        results = {}
        # Save PCAP file hash.
        if os.path.exists(self.pcap_path):
            results["pcap_sha256"] = File(self.pcap_path).get_sha256()

        """
        if proc_cfg.network.sort_pcap:
            sorted_path = self.pcap_path.replace("dump.", "dump_sorted.")
            sort_pcap(self.pcap_path, sorted_path)
            # Sorted PCAP file hash.
            if os.path.exists(sorted_path):
                results["sorted_pcap_sha256"] = File(sorted_path).get_sha256()
                pcap_path = sorted_path
            else:
                pcap_path = self.pcap_path
        else:
            pcap_path = self.pcap_path
        """
        pcap_path = self.pcap_path
        results.update(Pcap(pcap_path, ja3_fprints, self.options).run())
        # buf = Pcap(self.pcap_path, ja3_fprints).run()
        # results = Pcap(sorted_path, ja3_fprints).run()
        # results["http"] = buf["http"]
        # results["dns"] = buf["dns"]

        if os.path.exists(pcap_path) and HAVE_HTTPREPLAY:
            try:
                p2 = Pcap2(pcap_path, self.get_tlsmaster(), self.network_path)
                results.update(p2.run())
            except:
                log.exception("Error running httpreplay-based PCAP analysis")

        return results
Exemplo n.º 7
0
    def run(self):
        """Run analysis.
        @return: list of dropped files with related information.
        """
        self.key = "dropped"
        dropped_files = []

        for dir_name, dir_names, file_names in os.walk(self.dropped_path):
            for file_name in file_names:
                file_path = os.path.join(dir_name, file_name)
                file_info = File(file_path=file_path).get_all()
                dropped_files.append(file_info)

        return dropped_files
Exemplo n.º 8
0
    def run(self):
        """Runs VirusTotal processing
        @return: full VirusTotal report.
        """
        self.key = "virustotal"
        virustotal = []

        key = self.options.get("key", None)
        if not key:
            raise CuckooProcessingError(
                "VirusTotal API key not configured, skip")

        if self.task["category"] == "file":
            if not os.path.exists(self.file_path):
                raise CuckooProcessingError("File {0} not found, skip".format(
                    self.file_path))

            resource = File(self.file_path).get_md5()
            url = VIRUSTOTAL_FILE_URL
        elif self.task["category"] == "url":
            resource = self.task["target"]
            url = VIRUSTOTAL_URL_URL

        data = urllib.urlencode({"resource": resource, "apikey": key})

        try:
            request = urllib2.Request(url, data)
            response = urllib2.urlopen(request)
            response_data = response.read()
        except urllib2.URLError as e:
            raise CuckooProcessingError(
                "Unable to establish connection to VirusTotal: {0}".format(e))
        except urllib2.HTTPError as e:
            raise CuckooProcessingError(
                "Unable to perform HTTP request to VirusTotal (http code={0})".
                format(e.code))

        try:
            virustotal = json.loads(response_data)
        except ValueError as e:
            raise CuckooProcessingError(
                "Unable to convert response to JSON: {0}".format(e))

        if "scans" in virustotal:
            virustotal["scans"] = dict([
                (engine.replace(".", "_"), signature)
                for engine, signature in virustotal["scans"].items()
            ])

        return virustotal
Exemplo n.º 9
0
    def run(self):
        """Run analysis.
        @return: structured results.
        """
        self.key = "procmemory"
        results = []

        if self.options.get("extract_img") and not HAVE_PEFILE:
            log.warning(
                "In order to extract PE files from memory dumps it is "
                "required to have pefile installed (`pip install pefile`).")

        if os.path.exists(self.pmemory_path):
            for dmp in os.listdir(self.pmemory_path):
                if not dmp.endswith(".dmp"):
                    continue

                dump_path = os.path.join(self.pmemory_path, dmp)
                dump_file = File(dump_path)

                pid, num = map(int, re.findall("(\\d+)", dmp))

                proc = dict(
                    file=dump_path,
                    pid=pid,
                    num=num,
                    yara=dump_file.get_yara("memory"),
                    urls=list(dump_file.get_urls()),
                    regions=list(self.read_dump(dump_path)),
                )

                if self.options.get("idapro"):
                    self.create_idapy(proc)

                if self.options.get("extract_img") and HAVE_PEFILE:
                    proc["extracted"] = list(self.dump_images(proc))

                if self.options.get("dump_delete"):
                    try:
                        os.remove(dump_path)
                    except OSError:
                        log.error(
                            "Unable to delete memory dump file at path \"%s\"",
                            dump_path)

                results.append(proc)

        results.sort(key=lambda x: (x["pid"], x["num"]))
        return results
Exemplo n.º 10
0
    def run(self):
        """Run analysis.
        @return: results dict.
        """
        self.key = "static"
        static = {}

        if self.task["category"] == "file" and os.path.exists(self.file_path):
            if HAVE_PEFILE:
                if "PE32" in File(self.file_path).get_type():
                    static.update(PortableExecutable(self.file_path).run())

            static["keys"] = self._get_keys()

        return static
Exemplo n.º 11
0
    def run(self):
        """Run file information gathering.
        @return: information dict.
        """
        self.key = "target"
        if not self.task:
            return {"category": "unknown", "file": {"name": "unknown"}}

        target_info = {"category": self.task["category"]}

        # We have to deal with file or URL targets.
        if self.task["category"] == "file":
            target_info["file"] = {}

            # et's try to get as much information as possible, i.e., the
            # filename if the file is not available anymore.
            if os.path.exists(self.file_path):
                target_info["file"] = File(self.file_path).get_all()

            target_info["file"]["name"] = File(self.task["target"]).get_name()
        elif self.task["category"] == "url":
            target_info["url"] = self.task["target"]

        return target_info
Exemplo n.º 12
0
def demux_sample(filename, package, options):
    """
    If file is a ZIP, extract its included files and return their file paths
    If file is an email, extracts its attachments and return their file paths (later we'll also extract URLs)
    """

    # if a package was specified, then don't do anything special
    # this will allow for the ZIP package to be used to analyze binaries with included DLL dependencies
    # do the same if file= is specified in the options
    if package or "file=" in options:
        return [filename]

    # don't try to extract from office docs
    magic = File(filename).get_type()
    if "Microsoft" in magic or "Java Jar" in magic or "Composite Document File" in magic:
        return [filename]
    if "PE32" in magic or "MS-DOS executable" in magic:
        return [filename]

    retlist = demux_zip(filename, options)
    if not retlist:
        retlist = demux_rar(filename, options)
    if not retlist:
        retlist = demux_email(filename, options)
    if not retlist:
        retlist = demux_msg(filename, options)
    # handle ZIPs/RARs inside extracted files
    if retlist:
        newretlist = []
        for item in retlist:
            zipext = demux_zip(item, options)
            if zipext:
                newretlist.extend(zipext)
            else:
                rarext = demux_rar(item, options)
                if rarext:
                    newretlist.extend(rarext)
                else:
                    newretlist.append(item)
        retlist = newretlist

    # if it wasn't a ZIP or an email or we weren't able to obtain anything interesting from either, then just submit the
    # original file

    if not retlist:
        retlist.append(filename)

    return retlist
Exemplo n.º 13
0
    def add_path(self,
                 file_path,
                 timeout=0,
                 package="",
                 options="",
                 priority=1,
                 custom="",
                 machine="",
                 platform="",
                 tags=None,
                 memory=False,
                 enforce_timeout=False,
                 clock=None):
        """Add a task to database from file path.
        @param file_path: sample path.
        @param timeout: selected timeout.
        @param options: analysis options.
        @param priority: analysis priority.
        @param custom: custom options.
        @param machine: selected machine.
        @param platform: platform.
        @param tags: Tags required in machine selection
        @param memory: toggle full memory dump.
        @param enforce_timeout: toggle full timeout execution.
        @param clock: virtual machine clock time
        @return: cursor or None.
        """
        if not file_path or not os.path.exists(file_path):
            return None
        
        # Convert empty strings and None values to a valid int
        if not timeout:
            timeout = 0
        if not priority:
            priority = 1

        return self.add(File(file_path),
                        timeout,
                        package,
                        options,
                        priority,
                        custom,
                        machine,
                        platform,
                        tags,
                        memory,
                        enforce_timeout,
                        clock)
Exemplo n.º 14
0
    def run(self):
        """Run analysis.
        @return: list of dropped files with related information.
        """
        self.key = "dropped"
        dropped_files = []
        buf = self.options.get("buffer", 8192)

        if self.task["category"] == "pcap":
            return dropped_files

        file_names = os.listdir(self.dropped_path)
        for file_name in file_names:
            file_path = os.path.join(self.dropped_path, file_name)
            if not os.path.isfile(file_path):
                continue
            if file_name.endswith("_info.txt"):
                continue
            guest_paths = [
                line.strip() for line in open(file_path + "_info.txt")
            ]
            guest_name = guest_paths[0].split("\\")[-1]
            file_info = File(file_path=file_path,
                             guest_paths=guest_paths,
                             file_name=guest_name).get_all()
            texttypes = [
                "ASCII",
                "Windows Registry text",
                "XML document text",
                "Unicode text",
            ]
            readit = False
            for texttype in texttypes:
                if texttype in file_info["type"]:
                    readit = True
                    break
            if readit:
                with open(file_info["path"], "r") as drop_open:
                    filedata = drop_open.read(buf + 1)
                if len(filedata) > buf:
                    file_info["data"] = convert_to_printable(filedata[:buf] +
                                                             " <truncated>")
                else:
                    file_info["data"] = convert_to_printable(filedata)

            dropped_files.append(file_info)

        return dropped_files
Exemplo n.º 15
0
def get_json_document(results, analysis_path):
    # Create a copy of the dictionary. This is done in order to not modify
    # the original dictionary and possibly
    # compromise the following reporting modules.
    report = dict(results)

    if "network" not in report:
        report["network"] = {}

    # Add screenshot paths
    report["shots"] = []
    shots_path = os.path.join(analysis_path, "shots")
    if os.path.exists(shots_path):
        shots = [
            shot for shot in os.listdir(shots_path) if shot.endswith(".jpg")
        ]
        for shot_file in sorted(shots):
            shot_path = os.path.join(analysis_path, "shots", shot_file)
            screenshot = File(shot_path)
            if screenshot.valid():
                # Strip the extension as it's added later
                # in the Django view
                report["shots"].append(shot_file.replace(".jpg", ""))

    # Calculate the mlist_cnt for display if present to reduce db load
    if "signatures" in results:
        for entry in results["signatures"]:
            if entry["name"] == "ie_martian_children":
                report["mlist_cnt"] = len(entry["data"])
            if entry["name"] == "office_martian_children":
                report["f_mlist_cnt"] = len(entry["data"])

    # Other info we want quick access to from the web UI
    if results.get("virustotal", {}).get("positive") and results.get(
            "virustotal", {}).get("total"):
        report["virustotal_summary"] = "%s/%s" % (
            results["virustotal"]["positive"], results["virustotal"]["total"])
    if results.get("suricata", False):

        keywords = ("tls", "alerts", "files", "http", "ssh", "dns")
        keywords_dict = ("suri_tls_cnt", "suri_alert_cnt", "suri_file_cnt",
                         "suri_http_cnt", "suri_ssh_cnt", "suri_dns_cnt")
        for keyword, keyword_value in zip(keywords, keywords_dict):
            if results["suricata"].get(keyword, 0):
                report[keyword_value] = len(results["suricata"][keyword])

    return report
Exemplo n.º 16
0
def process_new_task_files(request, samples, details, opt_filename, unique):
    list_of_files = []
    for sample in samples:
        # Error if there was only one submitted sample and it's empty.
        # But if there are multiple and one was empty, just ignore it.
        if not sample.size:
            details["errors"].append(
                {sample.name: "You uploaded an empty file."})
            continue
        elif sample.size > web_cfg.general.max_sample_size:
            details["errors"].append({
                sample.name:
                "You uploaded a file that exceeds the maximum allowed upload size specified in conf/web.conf."
            })
            continue

        if opt_filename:
            filename = opt_filename
        else:
            filename = sanitize_filename(sample.name)

        # Moving sample from django temporary file to CAPE temporary storage to let it persist between reboot (if user like to configure it in that way).
        try:
            path = store_temp_file(sample.read(), filename)
        except OSError:
            details["errors"].append({
                filename:
                "Your specified temp folder, disk is out of space. Clean some space before continue."
            })
            continue

        sha256 = File(path).get_sha256()

        if (not request.user.is_staff
                and (web_cfg.uniq_submission.enabled or unique)
                and db.check_file_uniq(sha256,
                                       hours=web_cfg.uniq_submission.hours)):
            details["errors"].append({
                filename:
                "Duplicated file, disable unique option on submit or in conf/web.conf to force submission"
            })
            continue

        content = get_file_content(path)
        list_of_files.append((content, path, sha256))

    return list_of_files, details
Exemplo n.º 17
0
def demux_sample(filename: bytes,
                 package: str,
                 options: str,
                 use_sflock: bool = True) -> List[bytes]:
    """
    If file is a ZIP, extract its included files and return their file paths
    If file is an email, extracts its attachments and return their file paths (later we'll also extract URLs)
    """
    # sflock requires filename to be bytes object for Py3
    # TODO: Remove after checking all uses of demux_sample use bytes ~TheMythologist
    if isinstance(filename, str) and use_sflock:
        filename = filename.encode()
    # if a package was specified, then don't do anything special
    if package:
        return [filename]

    # don't try to extract from office docs
    magic = File(filename).get_type()

    # if file is an Office doc and password is supplied, try to decrypt the doc
    if "Microsoft" in magic:
        pass
        # ignore = {"Outlook", "Message", "Disk Image"}
    elif "Composite Document File" in magic or "CDFV2 Encrypted" in magic:
        password = options2passwd(options) or None
        if use_sflock:
            if HAS_SFLOCK:
                return demux_office(filename, password)
            else:
                log.error(
                    "Detected password protected office file, but no sflock is installed: pip3 install -U sflock2"
                )

    # don't try to extract from Java archives or executables
    if "Java Jar" in magic or "PE32" in magic or "MS-DOS executable" in magic or any(
            x in magic for x in VALID_LINUX_TYPES):
        return [filename]

    # all in one unarchiver
    retlist = demux_sflock(filename,
                           options) if HAS_SFLOCK and use_sflock else []
    # if it wasn't a ZIP or an email or we weren't able to obtain anything interesting from either, then just submit the
    # original file
    if not retlist:
        retlist.append(filename)

    return retlist[:10]
Exemplo n.º 18
0
    def run(self):
        """Run analysis.
        @return: list of dropped files with related information.
        """
        self.key = "dropped"
        dropped_files = []
        buf = self.options.get("buffer", 8192)

        for dir_name, dir_names, file_names in os.walk(self.dropped_path):
            for file_name in file_names:
                file_path = os.path.join(dir_name, file_name)
                if file_name.endswith("_info.txt") and not os.path.exists(
                        file_path + "_info.txt"):
                    continue
                guest_paths = [
                    line.strip() for line in open(file_path + "_info.txt")
                ]

                file_info = File(file_path=file_path,
                                 guest_paths=guest_paths).get_all()
                # Used by ElasticSearch to find the file on disk
                # since they are in random generated directories
                if Config("reporting").get("elasticsearchdb").get("enabled"):
                    file_info["dropdir"] = file_path.split("/")[-2]
                texttypes = [
                    "ASCII",
                    "Windows Registry text",
                    "XML document text",
                    "Unicode text",
                ]
                readit = False
                for texttype in texttypes:
                    if texttype in file_info["type"]:
                        readit = True
                        break
                if readit:
                    with open(file_info["path"], "r") as drop_open:
                        filedata = drop_open.read(buf + 1)
                    if len(filedata) > buf:
                        file_info["data"] = convert_to_printable(
                            filedata[:buf] + " <truncated>")
                    else:
                        file_info["data"] = convert_to_printable(filedata)

                dropped_files.append(file_info)

        return dropped_files
Exemplo n.º 19
0
    def run(self):
        """Run analysis.
        @return: list of dropped files with related information.
        """
        self.key = "dropped"
        dropped_files = []
        buf = self.options.get("buffer", 8192)

        if self.task["category"] == "pcap":
            return dropped_files

        if not os.path.exists(self.dropped_path):
            return dropped_files

        textchars = bytearray({7, 8, 9, 10, 12, 13, 27}
                              | set(range(0x20, 0x100)) - {0x7f})
        is_binary_file = lambda bytes: bool(bytes.translate(None, textchars))
        file_names = os.listdir(self.dropped_path)
        for file_name in file_names:
            file_path = os.path.join(self.dropped_path, file_name)
            if not os.path.isfile(file_path):
                continue
            if file_name.endswith("_info.txt"):
                continue
            guest_paths = [
                line.strip() for line in open(file_path + "_info.txt")
            ]
            guest_name = guest_paths[0].split("\\")[-1]
            file_info = File(file_path=file_path,
                             guest_paths=guest_paths,
                             file_name=guest_name).get_all()

            if is_binary_file(open(file_info["path"], 'rb').read(8192)):
                pass
            else:
                with open(file_info["path"], "r") as drop_open:
                    filedata = drop_open.read(buf + 1)
                if len(filedata) > buf:
                    file_info["data"] = convert_to_printable(filedata[:buf] +
                                                             " <truncated>")
                else:
                    file_info["data"] = convert_to_printable(filedata)

            dropped_files.append(file_info)

        return dropped_files
Exemplo n.º 20
0
def static_extraction(path):
    try:
        hits = File(path).get_yara(category="CAPE")
        if not hits:
            return False
        # Get the file data
        with open(path, "rb") as file_open:
            file_data = file_open.read()
        for hit in hits:
            config = static_config_parsers(hit["name"], file_data)
            if config:
                return config
        return False
    except Exception as e:
        log.error(e)

    return False
Exemplo n.º 21
0
    def run(self):
        """Run analysis.
        @return: structured results.
        """
        self.key = "procmemory"
        results = []

        for dmp in os.listdir(self.pmemory_path):
            dmp_path = os.path.join(self.pmemory_path, dmp)
            dmp_file = File(dmp_path)

            proc = dict(yara=dmp_file.get_yara(
                os.path.join(CUCKOO_ROOT, "data", "yara", "index_memory.yar")))

            results.append(proc)

        return results
Exemplo n.º 22
0
def static_extraction(path):
    cape_config = dict()
    try:
        hits = File(path).get_yara(CAPE_YARA_RULEPATH)
        if not hits:
            return False
        # Get the file data
        with open(path, "r") as file_open:
            file_data = file_open.read()
        for hit in hits:
            config = static_config_parsers(hit["name"], file_data, cape_config)
            if config:
                return config
        return False
    except Exception as e:
        log.error(e)

    return False
Exemplo n.º 23
0
def _extracted_files_metadata(folder: str, destination_folder: str, files: list = None) -> List[dict]:
    """
    args:
        folder - where files extracted
        destination_folder - where to move extracted files
        files - file names
    """
    metadata = []
    filelog = os.path.join(os.path.dirname(destination_folder), "files.json")
    if not files:
        files = os.listdir(folder)
    with open(filelog, "a") as f:
        for file in files:
            full_path = os.path.join(folder, file)
            file_details, _pe = File(full_path).get_all()

            if processing_conf.trid.enabled:
                trid_info(full_path, file_details)

            if processing_conf.die.enabled:
                detect_it_easy_info(full_path, file_details)

            metadata.append(file_details)
            dest_path = os.path.join(destination_folder, file_details["sha256"])
            file_details["path"] = dest_path
            file_details["name"] = os.path.basename(dest_path)
            if not os.path.exists(dest_path):
                shutil.move(full_path, dest_path)
                print(
                    json.dumps(
                        {
                            "path": os.path.join("files", file_details["sha256"]),
                            "filepath": file_details["name"],
                            "pids": [],
                            "ppids": [],
                            "metadata": "",
                            "category": "files",
                        },
                        ensure_ascii=False,
                    ),
                    file=f,
                )

    return metadata
Exemplo n.º 24
0
    def run(self):
        """Run analysis.
        @return: structured results.
        """
        self.key = "procmemory"
        results = []

        if os.path.exists(self.pmemory_path):
            for dmp in os.listdir(self.pmemory_path):
                if not dmp.endswith(".dmp"):
                    continue

                dump_path = os.path.join(self.pmemory_path, dmp)
                dump_file = File(dump_path)

                if "-" in os.path.basename(dump_path):
                    pid = int(os.path.basename(dump_path).split("-")[0])
                else:
                    pid = int(os.path.basename(dump_path).split(".")[0])

                proc = dict(
                    file=dump_path,
                    pid=pid,
                    yara=dump_file.get_yara("memory"),
                    urls=list(dump_file.get_urls()),
                    regions=list(self.read_dump(dump_path)),
                )

                if self.options.get("idapro"):
                    self.create_idapy(proc)

                if self.options.get("dump_delete"):
                    try:
                        os.remove(dump_path)
                    except OSError:
                        log.error(
                            "Unable to delete memory dump file at path \"%s\" ",
                            dump_path)

                results.append(proc)

        return results
Exemplo n.º 25
0
def static_extraction(path):
    try:
        if not File.yara_initialized:
            init_yara()
        hits = File(path).get_yara(category="CAPE")
        if not hits:
            return False
        # Get the file data
        with open(path, "rb") as file_open:
            file_data = file_open.read()
        for hit in hits:
            cape_name = File.get_cape_name_from_yara_hit(hit)
            config = static_config_parsers(cape_name, path, file_data)
            if config:
                return config
        return False
    except Exception as e:
        log.error(e)

    return False
Exemplo n.º 26
0
    def get_procmemory_pe(self, mem_pe):
        res = list()
        file_item = open(mem_pe.get("file"), "rb")

        for memmap in mem_pe.get("address_space") or []:
            if not memmap.get("PE"):
                continue
            data = b""
            for chunk in memmap["chunks"]:
                if int(chunk["start"], 16) >= int(memmap["start"], 16) and int(chunk["end"], 16) <= int(memmap["end"], 16):
                    file_item.seek(chunk["offset"])
                    data += file_item.read(int(chunk["size"], 16))

            # save pe to disk
            path = os.path.join(self.pmemory_path, "{}_{}".format(mem_pe["pid"], memmap["start"]))
            with open(path, "wb") as f:
                f.write(data)

            res.append(File(path).get_all())
        return res
Exemplo n.º 27
0
    def store_file(self):
        """Store a copy of the file being analyzed."""
        if not os.path.exists(self.task.target):
            log.error(
                "Task #{0}: The file to analyze does not exist at path '{1}', "
                "analysis aborted".format(
                    self.task.id, convert_to_printable(self.task.target)))
            return False

        sha256 = File(self.task.target).get_sha256()
        self.binary = os.path.join(CUCKOO_ROOT, "storage", "binaries", sha256)

        if os.path.exists(self.binary):
            log.info("Task #{0}: File already exists at '{1}'".format(
                self.task.id, self.binary))
        else:
            # TODO: do we really need to abort the analysis in case we are not
            # able to store a copy of the file?
            try:
                shutil.copy(self.task.target, self.binary)
            except (IOError, shutil.Error) as e:
                log.error(
                    "Task #{0}: Unable to store file from '{1}' to '{2}', "
                    "analysis aborted".format(
                        self.task.id, convert_to_printable(self.task.target),
                        self.binary))
                return False

        try:
            new_binary_path = os.path.join(self.storage, "binary")

            if hasattr(os, "symlink"):
                os.symlink(self.binary, new_binary_path)
            else:
                shutil.copy(self.binary, new_binary_path)
        except (AttributeError, OSError) as e:
            log.error("Task #{0}: Unable to create symlink/copy from '{1}' to "
                      "'{2}': {3}".format(self.task.id, self.binary,
                                          self.storage, e))

        return True
Exemplo n.º 28
0
    def add_reboot(self, task_id, timeout=0, options="", priority=1,
                   owner="", machine="", platform="", tags=None, memory=False,
                   enforce_timeout=False, clock=None):
        """Add a reboot task to database from an existing analysis.
        @param task_id: task id of existing analysis.
        @param timeout: selected timeout.
        @param options: analysis options.
        @param priority: analysis priority.
        @param owner: task owner.
        @param machine: selected machine.
        @param platform: platform.
        @param tags: tags for machine selection
        @param memory: toggle full memory dump.
        @param enforce_timeout: toggle full timeout execution.
        @param clock: virtual machine clock time
        @return: cursor or None.
        """

        # Convert empty strings and None values to a valid int
        if not timeout:
            timeout = 0
        if not priority:
            priority = 1

        task = self.view_task(task_id)
        if not task or not os.path.exists(task.target):
            log.error(
                "Unable to add reboot analysis as the original task or its "
                "sample has already been deleted."
            )
            return

        # TODO Integrate the Reboot screen with the submission portal and
        # pass the parent task ID through as part of the "options".
        custom = "%s" % task_id

        return self.add(File(task.target), timeout, "reboot", options,
                        priority, custom, owner, machine, platform, tags,
                        memory, enforce_timeout, clock, "file")
Exemplo n.º 29
0
    def run(self):
        """Run analysis.
        @return: results dict.
        """
        self.key = "static"
        static = {}

        # Does the target file still exist?
        if self.task["category"] != "file" or \
                not os.path.exists(self.file_path):
            return

        package = self.task.get("package")

        if self.task["category"] == "file":
            ext = os.path.splitext(self.task["target"])[1].lstrip(".").lower()
        else:
            ext = None

        if ext == "exe" or "PE32" in File(self.file_path).get_type():
            if HAVE_PEFILE:
                static.update(PortableExecutable(self.file_path).run())
            static["keys"] = self._get_keys()

        if package == "wsf" or ext == "wsf":
            static["wsf"] = WindowsScriptFile(self.file_path).run()

        if package in ("doc", "ppt", "xls") or ext in self.office_ext:
            static["office"] = OfficeDocument(self.file_path).run()

        def pdf_worker(filepath):
            return PdfDocument(filepath).run()

        if package == "pdf" or ext == "pdf":
            timeout = int(self.options.get("pdf_timeout", 60))
            static["pdf"] = dispatch(pdf_worker, (self.file_path, ),
                                     timeout=timeout)

        return static
Exemplo n.º 30
0
    def store_file(self):
        """Store a copy of the file being analyzed."""
        if not os.path.exists(self.task.target):
            log.error(
                "The file to analyze does not exist at path \"%s\", "
                "analysis aborted", self.task.target)
            return False

        sha256 = File(self.task.target).get_sha256()
        self.binary = os.path.join(CUCKOO_ROOT, "storage", "binaries", sha256)

        if os.path.exists(self.binary):
            pass

#log.info("File already exists at \"%s\"", self.binary)
        else:
            # TODO: do we really need to abort the analysis in case we are not
            # able to store a copy of the file?
            try:
                shutil.copy(self.task.target, self.binary)
            except (IOError, shutil.Error) as e:
                log.error(
                    "Unable to store file from \"%s\" to \"%s\", "
                    "analysis aborted", self.task.target, self.binary)
                return False

        try:
            self.storage_binary = os.path.join(self.storage, "binary")

            if hasattr(os, "symlink"):
                os.symlink(self.binary, self.storage_binary)
            else:
                shutil.copy(self.binary, self.storage_binary)
        except (AttributeError, OSError) as e:
            log.error(
                "Unable to create symlink/copy from \"%s\" to "
                "\"%s\": %s", self.binary, self.storage, e)

        return True