Exemplo n.º 1
0
 def calculate(self):
     addr_space = utils.load_as(self._config)
     self.apply_types(addr_space, self._config.VERSION)
     scanner = filescan.DriverScan(self._config)
     for driver in scanner.calculate():    
         drivername = str(driver.DriverName or '')
         if drivername.endswith("truecrypt"):
             for device in driver.devices():
                 code = device.DeviceType.v()
                 type = devicetree.DEVICE_CODES.get(code)
                 if type == 'FILE_DEVICE_DISK':
                     yield device
Exemplo n.º 2
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)
Exemplo n.º 3
0
    def calculate(self):

        space = utils.load_as(self._config)

        # enumerate system threads (0x00000010 = PS_CROSS_THREAD_FLAGS_SYSTEM)
        system_threads = [
            t for t in modscan.ThrdScan(self._config).calculate()
            if t.CrossThreadFlags & 0x00000010
        ]

        # find and dump the malicious kernel driver
        for item in filescan.DriverScan(self._config).calculate():

            # unpack the parameters
            (object, driver, extension, object_name) = item

            # looking for unnamed driver objects
            if driver.DriverName.Length != 0:
                continue

            # the first and only device should be ACPI#PNP[...]
            device = obj.Object("_DEVICE_OBJECT",
                                offset=driver.DeviceObject,
                                vm=space)

            # get the device's object header
            object = obj.Object("_OBJECT_HEADER", \
                offset = device.obj_offset - \
                device.obj_vm.profile.get_obj_offset("_OBJECT_HEADER", "Body"), \
                vm = space)

            object.kas = space
            device_name = object.get_object_name()

            # did we find zeroaccess?
            if not str(device_name).startswith("ACPI#PNP"):
                continue

            sys.stdout.write("DriverObject:  {0:#x}\n".format(
                device.DriverObject))
            sys.stdout.write("  DriverStart: {0:#x}\n".format(
                driver.DriverStart))
            sys.stdout.write("  DriverSize:  {0:#x}\n".format(
                driver.DriverSize))
            sys.stdout.write("DeviceObject:  {0:#x} {1}\n".format(
                device.obj_offset, device_name))

            # dump the driver
            file_name = "Driver.{0:#x}.sys".format(driver.DriverStart)
            self.dump_pe(space, driver.DriverStart, file_name)

            # now what we know the memory range, look for bad threads
            for thread in system_threads:

                if thread.StartAddress > driver.DriverStart and \
                        thread.StartAddress < driver.DriverStart + driver.DriverSize:

                    sys.stdout.write("Bad Thread:    {0:#x} Tid {1}\n".format(\
                        thread.obj_offset,
                        thread.Cid.UniqueThread))

        # now find and dump the fake usermode ADS process
        for proc in tasks.pslist(space):

            for dll in proc.Peb.Ldr.InLoadOrderModuleList.list_of_type(\
                "_LDR_DATA_TABLE_ENTRY", "InLoadOrderLinks"):

                # look for the ADS name
                if str(dll.BaseDllName).find(":") != -1:

                    sys.stdout.write("Fake ADS EXE:  {0} pid {1} base {2:#x}\n".format(\
                        proc.ImageFileName,
                        proc.UniqueProcessId,
                        dll.DllBase))

                    file_name = "Dll.{0:#x}.{1:#x}.dll".format(
                        proc.obj_offset, dll.DllBase)
                    self.dump_pe(proc.get_process_address_space(), dll.DllBase,
                                 file_name)