def get_fileobj_offset(self, regex, cache=filescan_cache):
     file_re = re.compile(regex, re.IGNORECASE)
     if not cache:
         cache = dict()
         data = filescan.FileScan(self._config).calculate()
         for fileobj in data:
             if fileobj.file_name_with_device():
                 cache[fileobj.file_name_with_device()] = fileobj.obj_offset
     for fname, offset in cache.items():
         if file_re.search(fname):
             yield fname, offset
    def scan(self):
        # Enumerate all available file paths
        directories = []
        scanner = filescan.FileScan(self._config)
        for fobj in scanner.calculate():
            fpath = "{0}".format(fobj.file_name_with_device() or '')
            if fpath:
                path = fpath.upper().rsplit('\\', 1)[0]
                if not path in directories:
                    directories.append(path)

        return directories
    def get_tasks(self):
        addr_space = utils.load_as(self._config)
        f = filescan.FileScan(self._config)
        tasks = []
        parsed_tasks = []
        for file in f.calculate():
            filename = str(file.file_name_with_device() or '')
            if "system32\\tasks\\" in filename.lower() and (
                    'system32\\tasks\\microsoft' not in filename.lower()
                    or self._config.VERBOSE):
                header = file.get_object_header()
                tasks.append((file.obj_offset, filename))
                debug.debug("Found task: 0x{0:x} {1}".format(
                    file.obj_offset, filename))

        for offset, name in tasks:

            self._config.PHYSOFFSET = '0x{:x}'.format(offset)
            df = dumpfiles.DumpFiles(self._config)
            self._config.DUMP_DIR = '.'
            for data in df.calculate():
                # Doing this with mmap would probably be cleaner
                # Create a sufficiently large (dynamically resizable?)
                # memory map so that we can seek and write the file accordingly
                #
                # SystemError: mmap: resizing not available--no mremap()

                chopped_file = {}

                for mdata in data['present']:
                    rdata = addr_space.base.read(mdata[0], mdata[2])
                    chopped_file[mdata[1]] = rdata

                task_xml = "".join(part[1]
                                   for part in sorted(chopped_file.items(),
                                                      key=lambda x: x[0]))

                parsed = self.parse_task_xml(task_xml)

                if parsed:
                    args = parsed['Actions']['Exec'].get("Arguments", None)
                    if args:
                        parsed['Actions']['Exec']['Command'] += " {}".format(
                            args)
                    pids = self.find_pids_for_imagepath(
                        parsed['Actions']['Exec']['Command'])
                    parsed_tasks.append(
                        (name.split('\\')[-1], parsed, task_xml, pids))

        return parsed_tasks
Example #4
0
    def find_tasks(self):
        addr_space = utils.load_as(self._config)
        file_list = []
        file_scan = filescan.FileScan(self._config)
        file_results = file_scan.calculate()

        for file in file_results:
            filename = str(file.file_name_with_device()).lower()
            address = Address(file.obj_offset)
            access_string = str(file.access_string())

            for task_location in TASK_LOCATIONS:
                if task_location in filename:
                    if not "system32\\tasks\\microsoft" in filename:
                        print address, filename, access_string
                        offset = "0x{:x}".format(address)
                        self.task_files(offset)
Example #5
0
    def calculate(self):
        addr_space = utils.load_as(self._config)

        # we currently don't use this on x64 because for some reason the 
        # x64 version actually doesn't create a DisplayVersion value 
        memory_model = addr_space.profile.metadata.get('memory_model')
        if memory_model == '32bit':
            regapi = registryapi.RegistryApi(self._config)
            regapi.reset_current()
            regapi.set_current(hive_name = "software")
            x86key = "Microsoft\\Windows\\CurrentVersion\\Uninstall"
            x64key = "Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
            for subkey in regapi.reg_get_all_subkeys(None, key = x86key):
                if str(subkey.Name) == "TrueCrypt":
                    subpath = x86key + "\\" + subkey.Name
                    version = regapi.reg_get_value("software", 
                                            key = subpath, 
                                            value = "DisplayVersion")
                    if version:
                        yield "Registry Version", "{0} Version {1}".format(
                            str(subkey.Name),
                            version)

        scanner = TrueCryptPassphrase(self._config)
        for offset, passphrase in scanner.calculate():
            yield "Password", "{0} at offset {1:#x}".format(
                        passphrase, offset)

        for proc in tasks.pslist(addr_space):
            if str(proc.ImageFileName).lower() == "truecrypt.exe":     
                yield "Process", "{0} at {1:#x} pid {2}".format(
                        proc.ImageFileName,
                        proc.obj_offset, 
                        proc.UniqueProcessId)   

        scanner = svcscan.SvcScan(self._config)
        for service in scanner.calculate():
            name = str(service.ServiceName.dereference())
            if name == "truecrypt":
                yield "Service", "{0} state {1}".format(
                        name, 
                        service.State)

        for mod in modules.lsmod(addr_space):
            basename = str(mod.BaseDllName or '').lower()
            fullname = str(mod.FullDllName or '').lower()
            if (basename.endswith("truecrypt.sys") or 
                        fullname.endswith("truecrypt.sys")):
                yield "Kernel Module",  "{0} at {1:#x} - {2:#x}".format(
                        mod.BaseDllName, 
                        mod.DllBase, 
                        mod.DllBase + mod.SizeOfImage)

        scanner = filescan.SymLinkScan(self._config)
        for symlink in scanner.calculate():
            object_header = symlink.get_object_header()
            if "TrueCryptVolume" in str(symlink.LinkTarget or ''):
                yield "Symbolic Link", "{0} -> {1} mounted {2}".format(
                        str(object_header.NameInfo.Name or ''), 
                        str(symlink.LinkTarget or ''), 
                        str(symlink.CreationTime or ''))

        scanner = filescan.FileScan(self._config)
        for fileobj in scanner.calculate():
            filename = str(fileobj.file_name_with_device() or '')
            if "TrueCryptVolume" in filename:
                yield "File Object", "{0} at {1:#x}".format(
                        filename,
                        fileobj.obj_offset)
        
        scanner = filescan.DriverScan(self._config)
        for driver in scanner.calculate():
            object_header = driver.get_object_header() 
            driverext = driver.DriverExtension
            drivername = str(driver.DriverName or '')
            servicekey = str(driverext.ServiceKeyName or '')
            if (drivername.endswith("truecrypt") or 
                        servicekey.endswith("truecrypt")):
                yield "Driver", "{0} at {1:#x} range {2:#x} - {3:#x}".format(
                        drivername, 
                        driver.obj_offset, 
                        driver.DriverStart, 
                        driver.DriverStart + driver.DriverSize)
                for device in driver.devices():
                    header = device.get_object_header()
                    devname = str(header.NameInfo.Name or '')
                    type = devicetree.DEVICE_CODES.get(device.DeviceType.v())
                    yield "Device", "{0} at {1:#x} type {2}".format(
                        devname or "<HIDDEN>", 
                        device.obj_offset, 
                        type or "UNKNOWN")
                    if type == "FILE_DEVICE_DISK":
                        data = addr_space.read(device.DeviceExtension, 2000)
                        ## the file-hosted container path. no other fields in
                        ## the struct are character based, so we should not 
                        ## hit false positives on this scan. 
                        offset = data.find("\\\x00?\x00?\x00\\\x00")
                        if offset == -1:
                            container = "<HIDDEN>"
                        else:
                            container = obj.Object("String", length = 255, 
                                        offset = device.DeviceExtension + offset, 
                                        encoding = "utf16",
                                        vm = addr_space)
                        yield "Container", "Path: {0}".format(container)