Esempio n. 1
0
    def detect_guid_from_mapped_file(self):
        """Guess the guid for the PE file."""
        # Try to load the file from the physical address space.
        if self.session.physical_address_space.metadata("can_map_files"):
            phys_as = self.session.physical_address_space
            if self.filename:
                image_offset = phys_as.get_mapped_offset(self.filename, 0)
                if image_offset:
                    try:
                        file_as = addrspace.RunBasedAddressSpace(
                            base=phys_as, session=self.session)

                        file_as.add_run(0, image_offset, 2**63)

                        pe_file_as = pe_vtypes.PEFileAddressSpace(
                            base=file_as, session=self.session)

                        pe_helper = pe_vtypes.PE(
                            address_space=pe_file_as,
                            image_base=pe_file_as.image_base,
                            session=self.session)

                        return pe_helper.RSDS.GUID_AGE
                    except IOError:
                        pass
    def DetectFromHit(self, hit, _, address_space):
        for potential_path in self.KERNEL_PATHS:
            # Try to make the kernel image into the address_space.
            image_offset = address_space.get_mapped_offset(potential_path, 0)

            if image_offset is not None:
                file_as = addrspace.RunBasedAddressSpace(
                    base=address_space, session=self.session)
                file_as.add_run(0, image_offset, 2**63)

                pe_file_as = pe_vtypes.PEFileAddressSpace(
                    base=file_as, session=self.session)

                pe_helper = pe_vtypes.PE(
                    session=self.session,
                    address_space=pe_file_as,
                    image_base=pe_file_as.image_base)

                rsds = pe_helper.RSDS
                self.session.logging.info(
                    "Found RSDS in kernel image: %s (%s)",
                    rsds.GUID_AGE, rsds.Filename)
                result = self._test_rsds(rsds)
                if result:
                    return result
    def DetectFromHit(self, hit, _, address_space):
        # If the file is a PE file, we simply return the PE address space.
        if self.pe_profile._IMAGE_DOS_HEADER(vm=address_space).NTHeader:
            pe_as = pe_vtypes.PEFileAddressSpace(
                base=address_space, profile=self.pe_profile)

            self.session.kernel_address_space = pe_as
            self.session.SetCache("default_image_base", pe_as.image_base)

            machine_type = pe_as.nt_header.FileHeader.Machine
            if machine_type == "IMAGE_FILE_MACHINE_AMD64":
                self.pe_profile.set_metadata("arch", "AMD64")
            else:
                self.pe_profile.set_metadata("arch", "I386")

            return self.pe_profile
Esempio n. 4
0
    def DetectFromHit(self, hit, _, address_space):
        # Try to make the kernel image into the address_space.
        image_offset = address_space.get_mapped_offset(self.KERNEL_PATH, 0)

        if image_offset is not None:
            file_as = addrspace.RunBasedAddressSpace(base=address_space,
                                                     session=self.session)
            file_as.add_run(0, image_offset, 2**63)

            pe_file_as = pe_vtypes.PEFileAddressSpace(base=file_as,
                                                      session=self.session)

            pe_helper = pe_vtypes.PE(session=self.session,
                                     address_space=pe_file_as,
                                     image_base=pe_file_as.image_base)

            return self._test_rsds(pe_helper.RSDS)
Esempio n. 5
0
    def ScanProfiles(self):
        pe_profile = self.session.LoadProfile("pe")
        address_space = self.session.physical_address_space
        best_profile = None
        best_match = 0

        # If the file is a PE file, we simply return the PE address space.
        if pe_profile._IMAGE_DOS_HEADER(vm=address_space).NTHeader:
            self.session.kernel_address_space = pe_vtypes.PEFileAddressSpace(
                base=address_space, profile=pe_profile)

            return pe_profile

        for hit in ProfileScanner(address_space=address_space,
                                  session=self.session).scan():

            # Try Windows by GUID:
            rsds = pe_profile.CV_RSDS_HEADER(offset=hit, vm=address_space)
            if (rsds.Signature.is_valid()
                    and str(rsds.Filename) in self.KERNEL_NAMES):
                profile = self.VerifyWinProfile("nt/GUID/%s" % rsds.GUID_AGE)

                if profile:
                    logging.info("Detected %s with GUID %s", rsds.Filename,
                                 rsds.GUID_AGE)

                    best_profile = profile
                    best_match = 1

            # Try OS X by profile similarity:
            elif address_space.read(hit, len(OSX_NEEDLE)) == OSX_NEEDLE:
                # To work around KASLR, we have an index of known symbols'
                # offsets relative to the Catfish string, along with the data we
                # expect to find at those offsets. Profile similarity is the
                # percentage of these symbols that match as expected.
                #
                # Ideally, we'd like a 100% match, but in case we don't have the
                # exact profile, we'll make do with anything higher than 0% that
                # can resolve the DTB.
                logging.debug("Hit for Darwin at 0x%x", hit)
                index = self.session.LoadProfile("OSX/index")
                for profile_name, match in index.LookupIndex(
                        image_base=hit,
                        address_space=self.session.physical_address_space):
                    profile = self.VerifyDarwinProfile(profile_name)
                    if profile:
                        if match > best_match:
                            logging.info("New best match: %s (%.0f%% match)",
                                         profile_name, match * 100)
                            best_profile, best_match = profile, match
                            self.session.SetParameter("catfish_offset", hit)

                            if match == 1.0:
                                break

            # Try Linux by version string:
            else:
                guess = address_space.read(hit - 100, 300)

                m = self.LINUX_TEMPLATE.search(guess)
                if m:
                    # Try to guess the distribution.
                    distribution = "LinuxGeneric"
                    if "Ubuntu" in guess:
                        distribution = "Ubuntu"

                    if "Debian" in guess:
                        distribution = "Debian"

                    profile_name = "%s/%s" % (distribution, m.group(1))
                    profile = self.VerifyLinuxProfile(profile_name)
                    if profile:
                        logging.info("Detected %s: %s", profile_name,
                                     m.group(0))

                        best_profile = profile
                        best_match = 1

            if best_match == 1.0:
                # If we have an exact match we can stop scanning.
                break

        threshold = self.session.GetParameter("autodetect_threshold")
        if best_match == 0:
            logging.error(
                "No profiles match this image. Try specifying manually.")

        elif best_match < threshold:
            logging.error(
                "Best match for profile is %s with %.0f%%, which is too low " +
                "for given threshold of %.0f%%. Try lowering " +
                "--autodetect-threshold.", best_profile.name, best_match * 100,
                threshold * 100)

        else:
            logging.info("Profile %s matched with %.0f%% confidence.",
                         best_profile.name, best_match * 100)

            return best_profile