def calculate(self): ## Just grab the AS and scan it using our scanner address_space = utils.load_as(self._config, astype='physical') ## Will need the kernel AS for later: kernel_as = utils.load_as(self._config) for offset in PoolScanDriver().scan(address_space): pool_obj = obj.Object("_POOL_HEADER", vm=address_space, offset=offset) ## We work out the _DRIVER_OBJECT from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(address_space).PoolAlignment.v() extension_obj = obj.Object( "_DRIVER_EXTENSION", vm=address_space, offset=(offset + pool_obj.BlockSize * pool_alignment - common.pool_align(kernel_as, "_DRIVER_EXTENSION", pool_alignment)), native_vm=kernel_as) ## The _DRIVER_OBJECT is immediately below the _DRIVER_EXTENSION driver_obj = obj.Object( "_DRIVER_OBJECT", vm=address_space, offset=extension_obj.obj_offset - common.pool_align(kernel_as, "_DRIVER_OBJECT", pool_alignment), native_vm=kernel_as) ## The _OBJECT_HEADER is immediately below the _DRIVER_OBJECT object_obj = obj.Object( "_OBJECT_HEADER", vm=address_space, offset=driver_obj.obj_offset - address_space.profile.get_obj_offset('_OBJECT_HEADER', 'Body'), native_vm=kernel_as) ## Skip unallocated objects #if object_obj.Type == 0xbad0b0b0: # continue if object_obj.get_object_type() != "Driver": continue yield (object_obj, driver_obj, extension_obj)
def check(self, found): pool_base = found - self.address_space.profile.get_obj_offset( '_POOL_HEADER', 'PoolTag') pool_obj = obj.Object("_POOL_HEADER", vm = self.address_space, offset = pool_base) ## We work out the _ETHREAD from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(self.address_space).PoolAlignment.v() thread = obj.Object("_ETHREAD", vm = self.address_space, offset = pool_base + pool_obj.BlockSize * pool_alignment - common.pool_align(self.address_space, '_ETHREAD', pool_alignment)) #if (thread.Cid.UniqueProcess.v() != 0 and # thread.ThreadsProcess.v() <= self.kernel): # return False ## check the start address if thread.Cid.UniqueProcess.v() != 0 and thread.StartAddress == 0: return False ## Check the Semaphores if (thread.Tcb.SuspendSemaphore.Header.Size != 0x05 and thread.Tcb.SuspendSemaphore.Header.Type != 0x05): return False if (thread.KeyedWaitSemaphore.Header.Size != 0x05 and thread.KeyedWaitSemaphore.Header.Type != 0x05): return False return True
def check(self, found): ## The offset of the object is determined by subtracting the offset ## of the PoolTag member to get the start of Pool Object. This done ## because PoolScanners search for the PoolTag. pool_base = found - self.address_space.profile.get_obj_offset( '_POOL_HEADER', 'PoolTag') pool_obj = obj.Object("_POOL_HEADER", vm=self.address_space, offset=pool_base) ## We work out the _EPROCESS from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(self.address_space).PoolAlignment.v() eprocess = obj.Object( "_EPROCESS", vm=self.address_space, offset=pool_base + pool_obj.BlockSize * pool_alignment - common.pool_align(self.address_space, '_EPROCESS', pool_alignment)) if (eprocess.Pcb.DirectoryTableBase == 0): return False if (eprocess.Pcb.DirectoryTableBase % 0x20 != 0): return False list_head = eprocess.ThreadListHead if (list_head.Flink < self.kernel) or (list_head.Blink < self.kernel): return False return True
def check(self, found): ## The offset of the object is determined by subtracting the offset ## of the PoolTag member to get the start of Pool Object. This done ## because PoolScanners search for the PoolTag. pool_base = found - self.address_space.profile.get_obj_offset( '_POOL_HEADER', 'PoolTag') pool_obj = obj.Object("_POOL_HEADER", vm = self.address_space, offset = pool_base) ## We work out the _EPROCESS from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(self.address_space).PoolAlignment.v() eprocess = obj.Object("_EPROCESS", vm = self.address_space, offset = pool_base + pool_obj.BlockSize * pool_alignment - common.pool_align(self.address_space, '_EPROCESS', pool_alignment)) if (eprocess.Pcb.DirectoryTableBase == 0): return False if (eprocess.Pcb.DirectoryTableBase % 0x20 != 0): return False list_head = eprocess.ThreadListHead if (list_head.Flink < self.kernel) or (list_head.Blink < self.kernel): return False return True
def calculate(self): ## Just grab the AS and scan it using our scanner address_space = utils.load_as(self._config, astype = 'physical') ## Will need the kernel AS for later: kernel_as = utils.load_as(self._config) for offset in PoolScanSymlink().scan(address_space): pool_obj = obj.Object("_POOL_HEADER", vm = address_space, offset = offset) ## We work out the object from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(address_space).PoolAlignment.v() link_obj = obj.Object("_OBJECT_SYMBOLIC_LINK", vm = address_space, offset = (offset + pool_obj.BlockSize * pool_alignment - common.pool_align(kernel_as, "_OBJECT_SYMBOLIC_LINK", pool_alignment)), native_vm = kernel_as) ## The _OBJECT_HEADER is immediately below the _OBJECT_SYMBOLIC_LINK object_obj = obj.Object( "_OBJECT_HEADER", vm = address_space, offset = link_obj.obj_offset - address_space.profile.get_obj_offset('_OBJECT_HEADER', 'Body'), native_vm = kernel_as ) if object_obj.get_object_type() != "SymbolicLink": continue yield object_obj, link_obj
def calculate(self): ## Just grab the AS and scan it using our scanner address_space = utils.load_as(self._config, astype = 'physical') ## Will need the kernel AS for later: kernel_as = utils.load_as(self._config) for offset in PoolScanDriver().scan(address_space): pool_obj = obj.Object("_POOL_HEADER", vm = address_space, offset = offset) ## We work out the _DRIVER_OBJECT from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(address_space).PoolAlignment.v() extension_obj = obj.Object( "_DRIVER_EXTENSION", vm = address_space, offset = (offset + pool_obj.BlockSize * pool_alignment - common.pool_align(kernel_as, "_DRIVER_EXTENSION", pool_alignment)), native_vm = kernel_as) ## The _DRIVER_OBJECT is immediately below the _DRIVER_EXTENSION driver_obj = obj.Object( "_DRIVER_OBJECT", vm = address_space, offset = extension_obj.obj_offset - common.pool_align(kernel_as, "_DRIVER_OBJECT", pool_alignment), native_vm = kernel_as ) ## The _OBJECT_HEADER is immediately below the _DRIVER_OBJECT object_obj = obj.Object( "_OBJECT_HEADER", vm = address_space, offset = driver_obj.obj_offset - address_space.profile.get_obj_offset('_OBJECT_HEADER', 'Body'), native_vm = kernel_as ) ## Skip unallocated objects #if object_obj.Type == 0xbad0b0b0: # continue if object_obj.get_object_type() != "Driver": continue yield (object_obj, driver_obj, extension_obj)
def calculate(self): ## Just grab the AS and scan it using our scanner address_space = utils.load_as(self._config, astype='physical') ## Will need the kernel AS for later: kernel_as = utils.load_as(self._config) for offset in PoolScanMutant().scan(address_space): pool_obj = obj.Object("_POOL_HEADER", vm=address_space, offset=offset) ## We work out the _DRIVER_OBJECT from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(address_space).PoolAlignment.v() mutant = obj.Object( "_KMUTANT", vm=address_space, offset=( offset + pool_obj.BlockSize * pool_alignment - common.pool_align(kernel_as, "_KMUTANT", pool_alignment)), native_vm=kernel_as) ## The _OBJECT_HEADER is immediately below the _KMUTANT object_obj = obj.Object( "_OBJECT_HEADER", vm=address_space, offset=mutant.obj_offset - address_space.profile.get_obj_offset('_OBJECT_HEADER', 'Body'), native_vm=kernel_as) if object_obj.get_object_type() != "Mutant": continue ## Skip unallocated objects ##if object_obj.Type == 0xbad0b0b0: ## continue if self._config.SILENT: if len(object_obj.NameInfo.Name) == 0: continue yield (object_obj, mutant)
def calculate(self): ## Just grab the AS and scan it using our scanner address_space = utils.load_as(self._config, astype='physical') ## Will need the kernel AS for later: kernel_as = utils.load_as(self._config) for offset in PoolScanFile().scan(address_space): pool_obj = obj.Object("_POOL_HEADER", vm=address_space, offset=offset) ## We work out the _FILE_OBJECT from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(address_space).PoolAlignment.v() file_obj = obj.Object( "_FILE_OBJECT", vm=address_space, offset=(offset + pool_obj.BlockSize * pool_alignment - common.pool_align(kernel_as, "_FILE_OBJECT", pool_alignment)), native_vm=kernel_as) ## The _OBJECT_HEADER is immediately below the _FILE_OBJECT object_obj = obj.Object( "_OBJECT_HEADER", vm=address_space, offset=file_obj.obj_offset - address_space.profile.get_obj_offset('_OBJECT_HEADER', 'Body'), native_vm=kernel_as) if object_obj.get_object_type() != "File": continue ## If the string is not reachable we skip it if not file_obj.FileName.v(): continue yield (object_obj, file_obj)
def calculate(self): ## Just grab the AS and scan it using our scanner address_space = utils.load_as(self._config, astype = 'physical') ## Will need the kernel AS for later: kernel_as = utils.load_as(self._config) for offset in PoolScanMutant().scan(address_space): pool_obj = obj.Object("_POOL_HEADER", vm = address_space, offset = offset) ## We work out the _DRIVER_OBJECT from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(address_space).PoolAlignment.v() mutant = obj.Object( "_KMUTANT", vm = address_space, offset = (offset + pool_obj.BlockSize * pool_alignment - common.pool_align(kernel_as, "_KMUTANT", pool_alignment)), native_vm = kernel_as) ## The _OBJECT_HEADER is immediately below the _KMUTANT object_obj = obj.Object( "_OBJECT_HEADER", vm = address_space, offset = mutant.obj_offset - address_space.profile.get_obj_offset('_OBJECT_HEADER', 'Body'), native_vm = kernel_as ) if object_obj.get_object_type() != "Mutant": continue ## Skip unallocated objects ##if object_obj.Type == 0xbad0b0b0: ## continue if self._config.SILENT: if len(object_obj.NameInfo.Name) == 0: continue yield (object_obj, mutant)
def object_offset(self, found, address_space): """ This returns the offset of the object contained within this pool allocation. """ ## The offset of the object is determined by subtracting the offset ## of the PoolTag member to get the start of Pool Object pool_base = found - self.buffer.profile.get_obj_offset('_POOL_HEADER', 'PoolTag') pool_obj = obj.Object("_POOL_HEADER", vm = address_space, offset = pool_base) ## We work out the _ETHREAD from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(address_space).PoolAlignment.v() object_base = (pool_base + pool_obj.BlockSize * pool_alignment - common.pool_align(address_space, '_ETHREAD', pool_alignment)) return object_base
def calculate(self): ## Just grab the AS and scan it using our scanner address_space = utils.load_as(self._config, astype = 'physical') ## Will need the kernel AS for later: kernel_as = utils.load_as(self._config) for offset in PoolScanFile().scan(address_space): pool_obj = obj.Object("_POOL_HEADER", vm = address_space, offset = offset) ## We work out the _FILE_OBJECT from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(address_space).PoolAlignment.v() file_obj = obj.Object("_FILE_OBJECT", vm = address_space, offset = (offset + pool_obj.BlockSize * pool_alignment - common.pool_align(kernel_as, "_FILE_OBJECT", pool_alignment)), native_vm = kernel_as ) ## The _OBJECT_HEADER is immediately below the _FILE_OBJECT object_obj = obj.Object("_OBJECT_HEADER", vm = address_space, offset = file_obj.obj_offset - address_space.profile.get_obj_offset('_OBJECT_HEADER', 'Body'), native_vm = kernel_as ) if object_obj.get_object_type() != "File": continue ## If the string is not reachable we skip it if not file_obj.FileName.v(): continue yield (object_obj, file_obj)
def object_offset(self, found, address_space): """ This returns the offset of the object contained within this pool allocation. """ ## The offset of the object is determined by subtracting the offset ## of the PoolTag member to get the start of Pool Object and then ## walking backwards based on pool alignment and pool size. pool_base = found - self.buffer.profile.get_obj_offset( '_POOL_HEADER', 'PoolTag') pool_obj = obj.Object("_POOL_HEADER", vm=address_space, offset=pool_base) ## We work out the _EPROCESS from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(address_space).PoolAlignment.v() object_base = ( pool_base + pool_obj.BlockSize * pool_alignment - common.pool_align(address_space, '_EPROCESS', pool_alignment)) return object_base
def calculate(self): ## Just grab the AS and scan it using our scanner address_space = utils.load_as(self._config, astype='physical') ## Will need the kernel AS for later: kernel_as = utils.load_as(self._config) for offset in PoolScanSymlink().scan(address_space): pool_obj = obj.Object("_POOL_HEADER", vm=address_space, offset=offset) ## We work out the object from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(address_space).PoolAlignment.v() link_obj = obj.Object( "_OBJECT_SYMBOLIC_LINK", vm=address_space, offset=(offset + pool_obj.BlockSize * pool_alignment - common.pool_align(kernel_as, "_OBJECT_SYMBOLIC_LINK", pool_alignment)), native_vm=kernel_as) ## The _OBJECT_HEADER is immediately below the _OBJECT_SYMBOLIC_LINK object_obj = obj.Object( "_OBJECT_HEADER", vm=address_space, offset=link_obj.obj_offset - address_space.profile.get_obj_offset('_OBJECT_HEADER', 'Body'), native_vm=kernel_as) if object_obj.get_object_type() != "SymbolicLink": continue yield object_obj, link_obj
def check(self, found): pool_base = found - self.address_space.profile.get_obj_offset( '_POOL_HEADER', 'PoolTag') pool_obj = obj.Object("_POOL_HEADER", vm=self.address_space, offset=pool_base) ## We work out the _ETHREAD from the end of the ## allocation (bottom up). pool_alignment = obj.VolMagic(self.address_space).PoolAlignment.v() thread = obj.Object( "_ETHREAD", vm=self.address_space, offset=pool_base + pool_obj.BlockSize * pool_alignment - common.pool_align(self.address_space, '_ETHREAD', pool_alignment)) #if (thread.Cid.UniqueProcess.v() != 0 and # thread.ThreadsProcess.v() <= self.kernel): # return False ## check the start address if thread.Cid.UniqueProcess.v() != 0 and thread.StartAddress == 0: return False ## Check the Semaphores if (thread.Tcb.SuspendSemaphore.Header.Size != 0x05 and thread.Tcb.SuspendSemaphore.Header.Type != 0x05): return False if (thread.KeyedWaitSemaphore.Header.Size != 0x05 and thread.KeyedWaitSemaphore.Header.Type != 0x05): return False return True