mirror of
https://github.com/volatilityfoundation/volatility
synced 2026-06-08 18:04:46 +00:00
676 lines
30 KiB
Python
676 lines
30 KiB
Python
# Volatility
|
|
# Copyright (c) 2008-2014 Volatility Foundation
|
|
# Copyright (c) 2013,2014 Michael Ligh (michael.ligh@mnin.org)
|
|
#
|
|
# This file is part of Volatility.
|
|
#
|
|
# Volatility is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License Version 2 as
|
|
# published by the Free Software Foundation. You may not use, modify or
|
|
# distribute this program under any other version of the GNU General
|
|
# Public License.
|
|
#
|
|
# Volatility is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with Volatility. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
import os
|
|
import volatility.obj as obj
|
|
import volatility.debug as debug
|
|
import volatility.utils as utils
|
|
import volatility.plugins.common as common
|
|
import volatility.win32.modules as modules
|
|
|
|
import volatility.win32.tasks as tasks
|
|
import volatility.plugins.filescan as filescan
|
|
import volatility.plugins.malware.devicetree as devicetree
|
|
import volatility.plugins.malware.svcscan as svcscan
|
|
import volatility.plugins.registry.registryapi as registryapi
|
|
|
|
tc_70a_vtypes_x86 = {
|
|
'UINT64_STRUCT' : [ 0x8, {
|
|
'LowPart' : [ 0x0, ['unsigned long']],
|
|
'HighPart' : [ 0x4, ['unsigned long']],
|
|
'Value' : [ 0x0, ['unsigned long long']],
|
|
} ],
|
|
'CRYPTO_INFO_t' : [ 0x4468, {
|
|
'ea' : [ 0x0, ['long']],
|
|
'mode' : [ 0x4, ['long']],
|
|
'ks' : [ 0x8, ['array', 5324, ['unsigned char']]],
|
|
'ks2' : [ 0x14d4, ['array', 5324, ['unsigned char']]],
|
|
'hiddenVolume' : [ 0x29a0, ['long']],
|
|
'HeaderVersion' : [ 0x29a4, ['unsigned short']],
|
|
'gf_ctx' : [ 0x29a8, ['GfCtx']],
|
|
'master_keydata' : [ 0x41a8, ['array', 256, ['unsigned char']]],
|
|
'k2' : [ 0x42a8, ['array', 256, ['unsigned char']]],
|
|
'salt' : [ 0x43a8, ['array', 64, ['unsigned char']]],
|
|
'noIterations' : [ 0x43e8, ['long']],
|
|
'pkcs5' : [ 0x43ec, ['long']],
|
|
'volume_creation_time' : [ 0x43f0, ['unsigned long long']],
|
|
'header_creation_time' : [ 0x43f8, ['unsigned long long']],
|
|
'bProtectHiddenVolume' : [ 0x4400, ['long']],
|
|
'bHiddenVolProtectionAction' : [ 0x4404, ['long']],
|
|
'volDataAreaOffset' : [ 0x4408, ['unsigned long long']],
|
|
'hiddenVolumeSize' : [ 0x4410, ['unsigned long long']],
|
|
'hiddenVolumeOffset' : [ 0x4418, ['unsigned long long']],
|
|
'hiddenVolumeProtectedSize' : [ 0x4420, ['unsigned long long']],
|
|
'bPartitionInInactiveSysEncScope' : [ 0x4428, ['long']],
|
|
'FirstDataUnitNo' : [ 0x4430, ['UINT64_STRUCT']],
|
|
'RequiredProgramVersion' : [ 0x4438, ['unsigned short']],
|
|
'LegacyVolume' : [ 0x443c, ['long']],
|
|
'SectorSize' : [ 0x4440, ['unsigned long']],
|
|
'VolumeSize' : [ 0x4448, ['UINT64_STRUCT']],
|
|
'EncryptedAreaStart' : [ 0x4450, ['UINT64_STRUCT']],
|
|
'EncryptedAreaLength' : [ 0x4458, ['UINT64_STRUCT']],
|
|
'HeaderFlags' : [ 0x4460, ['unsigned long']],
|
|
} ],
|
|
'Password' : [ 0x48, {
|
|
'Length' : [ 0x0, ['unsigned long']],
|
|
'Text' : [ 0x4, ['array', 65, ['unsigned char']]],
|
|
'Pad' : [ 0x45, ['array', 3, ['unsigned char']]],
|
|
} ],
|
|
'EXTENSION' : [ 0x510, {
|
|
'bRootDevice' : [ 0x0, ['long']],
|
|
'IsVolumeDevice' : [ 0x4, ['long']],
|
|
'IsDriveFilterDevice' : [ 0x8, ['long']],
|
|
'IsVolumeFilterDevice' : [ 0xc, ['long']],
|
|
'lMagicNumber' : [ 0x10, ['unsigned long']],
|
|
'UniqueVolumeId' : [ 0x14, ['long']],
|
|
'nDosDriveNo' : [ 0x18, ['long']],
|
|
'bShuttingDown' : [ 0x1c, ['long']],
|
|
'bThreadShouldQuit' : [ 0x20, ['long']],
|
|
'peThread' : [ 0x24, ['pointer', ['_KTHREAD']]],
|
|
'keCreateEvent' : [ 0x28, ['_KEVENT']],
|
|
'ListSpinLock' : [ 0x38, ['unsigned long']],
|
|
'ListEntry' : [ 0x3c, ['_LIST_ENTRY']],
|
|
'RequestSemaphore' : [ 0x44, ['_KSEMAPHORE']],
|
|
'hDeviceFile' : [ 0x58, ['pointer', ['void']]],
|
|
'pfoDeviceFile' : [ 0x5c, ['pointer', ['_FILE_OBJECT']]],
|
|
'pFsdDevice' : [ 0x60, ['pointer', ['_DEVICE_OBJECT']]],
|
|
'cryptoInfo' : [ 0x64, ['pointer', ['CRYPTO_INFO_t']]],
|
|
'HostLength' : [ 0x68, ['long long']],
|
|
'DiskLength' : [ 0x70, ['long long']],
|
|
'NumberOfCylinders' : [ 0x78, ['long long']],
|
|
'TracksPerCylinder' : [ 0x80, ['unsigned long']],
|
|
'SectorsPerTrack' : [ 0x84, ['unsigned long']],
|
|
'BytesPerSector' : [ 0x88, ['unsigned long']],
|
|
'PartitionType' : [ 0x8c, ['unsigned char']],
|
|
'HostBytesPerSector' : [ 0x90, ['unsigned long']],
|
|
'keVolumeEvent' : [ 0x94, ['_KEVENT']],
|
|
'Queue' : [ 0xa8, ['EncryptedIoQueue']],
|
|
'bReadOnly' : [ 0x288, ['long']],
|
|
'bRemovable' : [ 0x28c, ['long']],
|
|
'PartitionInInactiveSysEncScope' : [ 0x290, ['long']],
|
|
'bRawDevice' : [ 0x294, ['long']],
|
|
'bMountManager' : [ 0x298, ['long']],
|
|
'SystemFavorite' : [ 0x29c, ['long']],
|
|
'wszVolume' : [ 0x2a0, ['array', 260, ['wchar']]],
|
|
'fileCreationTime' : [ 0x4a8, ['_LARGE_INTEGER']],
|
|
'fileLastAccessTime' : [ 0x4b0, ['_LARGE_INTEGER']],
|
|
'fileLastWriteTime' : [ 0x4b8, ['_LARGE_INTEGER']],
|
|
'fileLastChangeTime' : [ 0x4c0, ['_LARGE_INTEGER']],
|
|
'bTimeStampValid' : [ 0x4c8, ['long']],
|
|
'UserSid' : [ 0x4cc, ['pointer', ['void']]],
|
|
'SecurityClientContextValid' : [ 0x4d0, ['long']],
|
|
'SecurityClientContext' : [ 0x4d4, ['_SECURITY_CLIENT_CONTEXT']],
|
|
} ],
|
|
}
|
|
|
|
tc_71a_vtypes_x86 = {
|
|
'UINT64_STRUCT' : [ 0x8, {
|
|
'LowPart' : [ 0x0, ['unsigned long']],
|
|
'HighPart' : [ 0x4, ['unsigned long']],
|
|
'Value' : [ 0x0, ['unsigned long long']],
|
|
} ],
|
|
'CRYPTO_INFO_t' : [ 0x4468, {
|
|
'ea' : [ 0x0, ['long']],
|
|
'mode' : [ 0x4, ['long']],
|
|
'ks' : [ 0x8, ['array', 5324, ['unsigned char']]],
|
|
'ks2' : [ 0x14d4, ['array', 5324, ['unsigned char']]],
|
|
'hiddenVolume' : [ 0x29a0, ['long']],
|
|
'HeaderVersion' : [ 0x29a4, ['unsigned short']],
|
|
'gf_ctx' : [ 0x29a8, ['GfCtx']],
|
|
'master_keydata' : [ 0x41a8, ['array', 256, ['unsigned char']]],
|
|
'k2' : [ 0x42a8, ['array', 256, ['unsigned char']]],
|
|
'salt' : [ 0x43a8, ['array', 64, ['unsigned char']]],
|
|
'noIterations' : [ 0x43e8, ['long']],
|
|
'pkcs5' : [ 0x43ec, ['long']],
|
|
'volume_creation_time' : [ 0x43f0, ['unsigned long long']],
|
|
'header_creation_time' : [ 0x43f8, ['unsigned long long']],
|
|
'bProtectHiddenVolume' : [ 0x4400, ['long']],
|
|
'bHiddenVolProtectionAction' : [ 0x4404, ['long']],
|
|
'volDataAreaOffset' : [ 0x4408, ['unsigned long long']],
|
|
'hiddenVolumeSize' : [ 0x4410, ['unsigned long long']],
|
|
'hiddenVolumeOffset' : [ 0x4418, ['unsigned long long']],
|
|
'hiddenVolumeProtectedSize' : [ 0x4420, ['unsigned long long']],
|
|
'bPartitionInInactiveSysEncScope' : [ 0x4428, ['long']],
|
|
'FirstDataUnitNo' : [ 0x4430, ['UINT64_STRUCT']],
|
|
'RequiredProgramVersion' : [ 0x4438, ['unsigned short']],
|
|
'LegacyVolume' : [ 0x443c, ['long']],
|
|
'SectorSize' : [ 0x4440, ['unsigned long']],
|
|
'VolumeSize' : [ 0x4448, ['UINT64_STRUCT']],
|
|
'EncryptedAreaStart' : [ 0x4450, ['UINT64_STRUCT']],
|
|
'EncryptedAreaLength' : [ 0x4458, ['UINT64_STRUCT']],
|
|
'HeaderFlags' : [ 0x4460, ['unsigned long']],
|
|
} ],
|
|
'EXTENSION' : [ 0x4d0, {
|
|
'bRootDevice' : [ 0x0, ['long']],
|
|
'IsVolumeDevice' : [ 0x4, ['long']],
|
|
'IsDriveFilterDevice' : [ 0x8, ['long']],
|
|
'IsVolumeFilterDevice' : [ 0xc, ['long']],
|
|
'UniqueVolumeId' : [ 0x10, ['long']],
|
|
'nDosDriveNo' : [ 0x14, ['long']],
|
|
'bShuttingDown' : [ 0x18, ['long']],
|
|
'bThreadShouldQuit' : [ 0x1c, ['long']],
|
|
'peThread' : [ 0x20, ['pointer', ['_KTHREAD']]],
|
|
'keCreateEvent' : [ 0x24, ['_KEVENT']],
|
|
'ListSpinLock' : [ 0x34, ['unsigned long']],
|
|
'ListEntry' : [ 0x38, ['_LIST_ENTRY']],
|
|
'RequestSemaphore' : [ 0x40, ['_KSEMAPHORE']],
|
|
'hDeviceFile' : [ 0x54, ['pointer', ['void']]],
|
|
'pfoDeviceFile' : [ 0x58, ['pointer', ['_FILE_OBJECT']]],
|
|
'pFsdDevice' : [ 0x5c, ['pointer', ['_DEVICE_OBJECT']]],
|
|
'cryptoInfo' : [ 0x60, ['pointer', ['CRYPTO_INFO_t']]],
|
|
'HostLength' : [ 0x68, ['long long']],
|
|
'DiskLength' : [ 0x70, ['long long']],
|
|
'NumberOfCylinders' : [ 0x78, ['long long']],
|
|
'TracksPerCylinder' : [ 0x80, ['unsigned long']],
|
|
'SectorsPerTrack' : [ 0x84, ['unsigned long']],
|
|
'BytesPerSector' : [ 0x88, ['unsigned long']],
|
|
'PartitionType' : [ 0x8c, ['unsigned char']],
|
|
'HostBytesPerSector' : [ 0x90, ['unsigned long']],
|
|
'keVolumeEvent' : [ 0x94, ['_KEVENT']],
|
|
'Queue' : [ 0xa8, ['EncryptedIoQueue']],
|
|
'bReadOnly' : [ 0x248, ['long']],
|
|
'bRemovable' : [ 0x24c, ['long']],
|
|
'PartitionInInactiveSysEncScope' : [ 0x250, ['long']],
|
|
'bRawDevice' : [ 0x254, ['long']],
|
|
'bMountManager' : [ 0x258, ['long']],
|
|
'SystemFavorite' : [ 0x25c, ['long']],
|
|
'wszVolume' : [ 0x260, ['array', 260, ['wchar']]],
|
|
'fileCreationTime' : [ 0x468, ['_LARGE_INTEGER']],
|
|
'fileLastAccessTime' : [ 0x470, ['_LARGE_INTEGER']],
|
|
'fileLastWriteTime' : [ 0x478, ['_LARGE_INTEGER']],
|
|
'fileLastChangeTime' : [ 0x480, ['_LARGE_INTEGER']],
|
|
'bTimeStampValid' : [ 0x488, ['long']],
|
|
'UserSid' : [ 0x48c, ['pointer', ['void']]],
|
|
'SecurityClientContextValid' : [ 0x490, ['long']],
|
|
'SecurityClientContext' : [ 0x494, ['_SECURITY_CLIENT_CONTEXT']],
|
|
} ],
|
|
'Password' : [ 0x48, {
|
|
'Length' : [ 0x0, ['unsigned long']],
|
|
'Text' : [ 0x4, ['array', 65, ['unsigned char']]],
|
|
'Pad' : [ 0x45, ['array', 3, ['unsigned char']]],
|
|
} ],
|
|
}
|
|
|
|
tc_70a_vtypes_x64 = {
|
|
'UINT64_STRUCT' : [ 0x8, {
|
|
'LowPart' : [ 0x0, ['unsigned long']],
|
|
'HighPart' : [ 0x4, ['unsigned long']],
|
|
'Value' : [ 0x0, ['unsigned long long']],
|
|
} ],
|
|
'CRYPTO_INFO_t' : [ 0x4468, {
|
|
'ea' : [ 0x0, ['long']],
|
|
'mode' : [ 0x4, ['long']],
|
|
'ks' : [ 0x8, ['array', 5324, ['unsigned char']]],
|
|
'ks2' : [ 0x14d4, ['array', 5324, ['unsigned char']]],
|
|
'hiddenVolume' : [ 0x29a0, ['long']],
|
|
'HeaderVersion' : [ 0x29a4, ['unsigned short']],
|
|
'gf_ctx' : [ 0x29a8, ['GfCtx']],
|
|
'master_keydata' : [ 0x41a8, ['array', 256, ['unsigned char']]],
|
|
'k2' : [ 0x42a8, ['array', 256, ['unsigned char']]],
|
|
'salt' : [ 0x43a8, ['array', 64, ['unsigned char']]],
|
|
'noIterations' : [ 0x43e8, ['long']],
|
|
'pkcs5' : [ 0x43ec, ['long']],
|
|
'volume_creation_time' : [ 0x43f0, ['unsigned long long']],
|
|
'header_creation_time' : [ 0x43f8, ['unsigned long long']],
|
|
'bProtectHiddenVolume' : [ 0x4400, ['long']],
|
|
'bHiddenVolProtectionAction' : [ 0x4404, ['long']],
|
|
'volDataAreaOffset' : [ 0x4408, ['unsigned long long']],
|
|
'hiddenVolumeSize' : [ 0x4410, ['unsigned long long']],
|
|
'hiddenVolumeOffset' : [ 0x4418, ['unsigned long long']],
|
|
'hiddenVolumeProtectedSize' : [ 0x4420, ['unsigned long long']],
|
|
'bPartitionInInactiveSysEncScope' : [ 0x4428, ['long']],
|
|
'FirstDataUnitNo' : [ 0x4430, ['UINT64_STRUCT']],
|
|
'RequiredProgramVersion' : [ 0x4438, ['unsigned short']],
|
|
'LegacyVolume' : [ 0x443c, ['long']],
|
|
'SectorSize' : [ 0x4440, ['unsigned long']],
|
|
'VolumeSize' : [ 0x4448, ['UINT64_STRUCT']],
|
|
'EncryptedAreaStart' : [ 0x4450, ['UINT64_STRUCT']],
|
|
'EncryptedAreaLength' : [ 0x4458, ['UINT64_STRUCT']],
|
|
'HeaderFlags' : [ 0x4460, ['unsigned long']],
|
|
} ],
|
|
'EXTENSION' : [ 0x640, {
|
|
'bRootDevice' : [ 0x0, ['long']],
|
|
'IsVolumeDevice' : [ 0x4, ['long']],
|
|
'IsDriveFilterDevice' : [ 0x8, ['long']],
|
|
'IsVolumeFilterDevice' : [ 0xc, ['long']],
|
|
'lMagicNumber' : [ 0x10, ['unsigned long']],
|
|
'UniqueVolumeId' : [ 0x14, ['long']],
|
|
'nDosDriveNo' : [ 0x18, ['long']],
|
|
'bShuttingDown' : [ 0x1c, ['long']],
|
|
'bThreadShouldQuit' : [ 0x20, ['long']],
|
|
'peThread' : [ 0x28, ['pointer64', ['_KTHREAD']]],
|
|
'keCreateEvent' : [ 0x30, ['_KEVENT']],
|
|
'ListSpinLock' : [ 0x48, ['unsigned long long']],
|
|
'ListEntry' : [ 0x50, ['_LIST_ENTRY']],
|
|
'RequestSemaphore' : [ 0x60, ['_KSEMAPHORE']],
|
|
'hDeviceFile' : [ 0x80, ['pointer64', ['void']]],
|
|
'pfoDeviceFile' : [ 0x88, ['pointer64', ['_FILE_OBJECT']]],
|
|
'pFsdDevice' : [ 0x90, ['pointer64', ['_DEVICE_OBJECT']]],
|
|
'cryptoInfo' : [ 0x98, ['pointer64', ['CRYPTO_INFO_t']]],
|
|
'HostLength' : [ 0xa0, ['long long']],
|
|
'DiskLength' : [ 0xa8, ['long long']],
|
|
'NumberOfCylinders' : [ 0xb0, ['long long']],
|
|
'TracksPerCylinder' : [ 0xb8, ['unsigned long']],
|
|
'SectorsPerTrack' : [ 0xbc, ['unsigned long']],
|
|
'BytesPerSector' : [ 0xc0, ['unsigned long']],
|
|
'PartitionType' : [ 0xc4, ['unsigned char']],
|
|
'HostBytesPerSector' : [ 0xc8, ['unsigned long']],
|
|
'keVolumeEvent' : [ 0xd0, ['_KEVENT']],
|
|
'Queue' : [ 0xe8, ['EncryptedIoQueue']],
|
|
'bReadOnly' : [ 0x3a0, ['long']],
|
|
'bRemovable' : [ 0x3a4, ['long']],
|
|
'PartitionInInactiveSysEncScope' : [ 0x3a8, ['long']],
|
|
'bRawDevice' : [ 0x3ac, ['long']],
|
|
'bMountManager' : [ 0x3b0, ['long']],
|
|
'SystemFavorite' : [ 0x3b4, ['long']],
|
|
'wszVolume' : [ 0x3b8, ['array', 260, ['wchar']]],
|
|
'fileCreationTime' : [ 0x5c0, ['_LARGE_INTEGER']],
|
|
'fileLastAccessTime' : [ 0x5c8, ['_LARGE_INTEGER']],
|
|
'fileLastWriteTime' : [ 0x5d0, ['_LARGE_INTEGER']],
|
|
'fileLastChangeTime' : [ 0x5d8, ['_LARGE_INTEGER']],
|
|
'bTimeStampValid' : [ 0x5e0, ['long']],
|
|
'UserSid' : [ 0x5e8, ['pointer64', ['void']]],
|
|
'SecurityClientContextValid' : [ 0x5f0, ['long']],
|
|
'SecurityClientContext' : [ 0x5f8, ['_SECURITY_CLIENT_CONTEXT']],
|
|
} ],
|
|
'Password' : [ 0x48, {
|
|
'Length' : [ 0x0, ['unsigned long']],
|
|
'Text' : [ 0x4, ['array', 65, ['unsigned char']]],
|
|
'Pad' : [ 0x45, ['array', 3, ['unsigned char']]],
|
|
} ],
|
|
}
|
|
|
|
tc_71a_vtypes_x64 = {
|
|
'UINT64_STRUCT' : [ 0x8, {
|
|
'LowPart' : [ 0x0, ['unsigned long']],
|
|
'HighPart' : [ 0x4, ['unsigned long']],
|
|
'Value' : [ 0x0, ['unsigned long long']],
|
|
} ],
|
|
'CRYPTO_INFO_t' : [ 0x4468, {
|
|
'ea' : [ 0x0, ['long']],
|
|
'mode' : [ 0x4, ['long']],
|
|
'ks' : [ 0x8, ['array', 5324, ['unsigned char']]],
|
|
'ks2' : [ 0x14d4, ['array', 5324, ['unsigned char']]],
|
|
'hiddenVolume' : [ 0x29a0, ['long']],
|
|
'HeaderVersion' : [ 0x29a4, ['unsigned short']],
|
|
'gf_ctx' : [ 0x29a8, ['GfCtx']],
|
|
'master_keydata' : [ 0x41a8, ['array', 256, ['unsigned char']]],
|
|
'k2' : [ 0x42a8, ['array', 256, ['unsigned char']]],
|
|
'salt' : [ 0x43a8, ['array', 64, ['unsigned char']]],
|
|
'noIterations' : [ 0x43e8, ['long']],
|
|
'pkcs5' : [ 0x43ec, ['long']],
|
|
'volume_creation_time' : [ 0x43f0, ['unsigned long long']],
|
|
'header_creation_time' : [ 0x43f8, ['unsigned long long']],
|
|
'bProtectHiddenVolume' : [ 0x4400, ['long']],
|
|
'bHiddenVolProtectionAction' : [ 0x4404, ['long']],
|
|
'volDataAreaOffset' : [ 0x4408, ['unsigned long long']],
|
|
'hiddenVolumeSize' : [ 0x4410, ['unsigned long long']],
|
|
'hiddenVolumeOffset' : [ 0x4418, ['unsigned long long']],
|
|
'hiddenVolumeProtectedSize' : [ 0x4420, ['unsigned long long']],
|
|
'bPartitionInInactiveSysEncScope' : [ 0x4428, ['long']],
|
|
'FirstDataUnitNo' : [ 0x4430, ['UINT64_STRUCT']],
|
|
'RequiredProgramVersion' : [ 0x4438, ['unsigned short']],
|
|
'LegacyVolume' : [ 0x443c, ['long']],
|
|
'SectorSize' : [ 0x4440, ['unsigned long']],
|
|
'VolumeSize' : [ 0x4448, ['UINT64_STRUCT']],
|
|
'EncryptedAreaStart' : [ 0x4450, ['UINT64_STRUCT']],
|
|
'EncryptedAreaLength' : [ 0x4458, ['UINT64_STRUCT']],
|
|
'HeaderFlags' : [ 0x4460, ['unsigned long']],
|
|
} ],
|
|
'Password' : [ 0x48, {
|
|
'Length' : [ 0x0, ['unsigned long']],
|
|
'Text' : [ 0x4, ['array', 65, ['unsigned char']]],
|
|
'Pad' : [ 0x45, ['array', 3, ['unsigned char']]],
|
|
} ],
|
|
'EXTENSION' : [ 0x5e0, {
|
|
'bRootDevice' : [ 0x0, ['long']],
|
|
'IsVolumeDevice' : [ 0x4, ['long']],
|
|
'IsDriveFilterDevice' : [ 0x8, ['long']],
|
|
'IsVolumeFilterDevice' : [ 0xc, ['long']],
|
|
'UniqueVolumeId' : [ 0x10, ['long']],
|
|
'nDosDriveNo' : [ 0x14, ['long']],
|
|
'bShuttingDown' : [ 0x18, ['long']],
|
|
'bThreadShouldQuit' : [ 0x1c, ['long']],
|
|
'peThread' : [ 0x20, ['pointer64', ['_KTHREAD']]],
|
|
'keCreateEvent' : [ 0x28, ['_KEVENT']],
|
|
'ListSpinLock' : [ 0x40, ['unsigned long long']],
|
|
'ListEntry' : [ 0x48, ['_LIST_ENTRY']],
|
|
'RequestSemaphore' : [ 0x58, ['_KSEMAPHORE']],
|
|
'hDeviceFile' : [ 0x78, ['pointer64', ['void']]],
|
|
'pfoDeviceFile' : [ 0x80, ['pointer64', ['_FILE_OBJECT']]],
|
|
'pFsdDevice' : [ 0x88, ['pointer64', ['_DEVICE_OBJECT']]],
|
|
'cryptoInfo' : [ 0x90, ['pointer64', ['CRYPTO_INFO_t']]],
|
|
'HostLength' : [ 0x98, ['long long']],
|
|
'DiskLength' : [ 0xa0, ['long long']],
|
|
'NumberOfCylinders' : [ 0xa8, ['long long']],
|
|
'TracksPerCylinder' : [ 0xb0, ['unsigned long']],
|
|
'SectorsPerTrack' : [ 0xb4, ['unsigned long']],
|
|
'BytesPerSector' : [ 0xb8, ['unsigned long']],
|
|
'PartitionType' : [ 0xbc, ['unsigned char']],
|
|
'HostBytesPerSector' : [ 0xc0, ['unsigned long']],
|
|
'keVolumeEvent' : [ 0xc8, ['_KEVENT']],
|
|
'Queue' : [ 0xe0, ['EncryptedIoQueue']],
|
|
'bReadOnly' : [ 0x340, ['long']],
|
|
'bRemovable' : [ 0x344, ['long']],
|
|
'PartitionInInactiveSysEncScope' : [ 0x348, ['long']],
|
|
'bRawDevice' : [ 0x34c, ['long']],
|
|
'bMountManager' : [ 0x350, ['long']],
|
|
'SystemFavorite' : [ 0x354, ['long']],
|
|
'wszVolume' : [ 0x358, ['array', 260, ['wchar']]],
|
|
'fileCreationTime' : [ 0x560, ['_LARGE_INTEGER']],
|
|
'fileLastAccessTime' : [ 0x568, ['_LARGE_INTEGER']],
|
|
'fileLastWriteTime' : [ 0x570, ['_LARGE_INTEGER']],
|
|
'fileLastChangeTime' : [ 0x578, ['_LARGE_INTEGER']],
|
|
'bTimeStampValid' : [ 0x580, ['long']],
|
|
'UserSid' : [ 0x588, ['pointer64', ['void']]],
|
|
'SecurityClientContextValid' : [ 0x590, ['long']],
|
|
'SecurityClientContext' : [ 0x598, ['_SECURITY_CLIENT_CONTEXT']],
|
|
} ],
|
|
}
|
|
|
|
#---------------------------------------------------------------------
|
|
# TrueCryptPassphrase Plugin
|
|
#---------------------------------------------------------------------
|
|
|
|
class TrueCryptPassphrase(common.AbstractWindowsCommand):
|
|
"""TrueCrypt Cached Passphrase Finder"""
|
|
|
|
def __init__(self, config, *args, **kwargs):
|
|
common.AbstractWindowsCommand.__init__(self, config, *args, **kwargs)
|
|
config.add_option('MIN-LENGTH', short_option = 'M', default = 5,
|
|
help = 'Mimumim length of passphrases to identify',
|
|
action = 'store', type = 'int')
|
|
|
|
@staticmethod
|
|
def scan_module(addr_space, module_base, min_length):
|
|
|
|
dos_header = obj.Object("_IMAGE_DOS_HEADER",
|
|
offset = module_base,
|
|
vm = addr_space)
|
|
|
|
nt_header = dos_header.get_nt_header()
|
|
|
|
# Finding the PE data section
|
|
data_section = None
|
|
for sec in nt_header.get_sections():
|
|
if str(sec.Name) == ".data":
|
|
data_section = sec
|
|
break
|
|
|
|
if not data_section:
|
|
raise StopIteration
|
|
|
|
base = sec.VirtualAddress + module_base
|
|
size = sec.Misc.VirtualSize
|
|
|
|
# Looking for the Length member, DWORD-aligned
|
|
ints = obj.Object("Array", targetType = "int",
|
|
offset = base, count = size / 4,
|
|
vm = addr_space)
|
|
|
|
for length in ints:
|
|
# Min and max passphrase lengths
|
|
if length >= min_length and length <= 64:
|
|
offset = length.obj_offset + 4
|
|
passphrase = addr_space.read(offset, length)
|
|
if not passphrase:
|
|
continue
|
|
# All characters in the range must be ASCII
|
|
chars = [c for c in passphrase if ord(c) >= 0x20 and ord(c) <= 0x7F]
|
|
if len(chars) != length:
|
|
continue
|
|
# At least three zero-bad bytes must follow
|
|
if addr_space.read(offset + length, 3) != "\x00" * 3:
|
|
continue
|
|
yield offset, passphrase
|
|
|
|
def calculate(self):
|
|
addr_space = utils.load_as(self._config)
|
|
|
|
for mod in modules.lsmod(addr_space):
|
|
|
|
# Finding the TC kernel module
|
|
if str(mod.BaseDllName).lower() != "truecrypt.sys":
|
|
continue
|
|
|
|
for offset, password in self.scan_module(addr_space, mod.DllBase, self._config.MIN_LENGTH):
|
|
yield offset, password
|
|
|
|
def render_text(self, outfd, data):
|
|
for offset, passphrase in data:
|
|
outfd.write("Found at {0:#x} length {1}: {2}\n".format(
|
|
offset, len(passphrase), passphrase))
|
|
|
|
#---------------------------------------------------------------------
|
|
# TrueCryptSummary Plugin
|
|
#---------------------------------------------------------------------
|
|
|
|
class TrueCryptSummary(common.AbstractWindowsCommand):
|
|
"""TrueCrypt Summary"""
|
|
|
|
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)
|
|
|
|
def render_text(self, outfd, data):
|
|
for field, info in data:
|
|
outfd.write("{0:20} {1}\n".format(field, info))
|
|
|
|
#---------------------------------------------------------------------
|
|
# TrueCryptMaster Plugin
|
|
#---------------------------------------------------------------------
|
|
|
|
class TrueCryptMaster(common.AbstractWindowsCommand):
|
|
"""Recover TrueCrypt 7.1a Master Keys"""
|
|
|
|
version_map = {
|
|
# the most recent - released feb 2012
|
|
'7.1a' : {'32bit': tc_71a_vtypes_x86, '64bit': tc_71a_vtypes_x64},
|
|
# released july 2010. also supports 6.3a from
|
|
# november 2009, so its likely all versions between
|
|
# 6.3a and 7.0a are supported by these vtypes
|
|
'7.0a' : {'32bit': tc_70a_vtypes_x86, '64bit': tc_70a_vtypes_x64},
|
|
}
|
|
|
|
def __init__(self, config, *args, **kwargs):
|
|
common.AbstractWindowsCommand.__init__(self, config, *args, **kwargs)
|
|
config.add_option('DUMP-DIR', short_option = 'D', default = None,
|
|
help = 'Directory in which to dump the keys')
|
|
config.add_option('VERSION', short_option = 'T', default = '7.1a',
|
|
help = 'Truecrypt version string (default: 7.1a)')
|
|
|
|
@staticmethod
|
|
def apply_types(addr_space, ver):
|
|
"""Apply the TrueCrypt types for a specific version of TC.
|
|
|
|
@param addr_space: <volatility.BaseAddressSpace>
|
|
@param ver: <string> version
|
|
"""
|
|
|
|
mm_model = addr_space.profile.metadata.get('memory_model', '32bit')
|
|
try:
|
|
vtypes = TrueCryptMaster.version_map[ver][mm_model]
|
|
addr_space.profile.vtypes.update(vtypes)
|
|
addr_space.profile.merge_overlay({
|
|
'EXTENSION' : [ None, {
|
|
'wszVolume' : [ None, ['String', dict(length = 260, encoding = "utf16")]],
|
|
}],
|
|
'CRYPTO_INFO_t' : [ None, {
|
|
'mode' : [ None, ['Enumeration', dict(target = "long",
|
|
choices = {1: 'XTS',
|
|
2: 'LWR',
|
|
3: 'CBC',
|
|
4: 'OUTER_CBC',
|
|
5: 'INNER_CBC'})]],
|
|
'ea' : [ None, ['Enumeration', dict(target = "long",
|
|
choices = {1: 'AES',
|
|
2: 'SERPENT',
|
|
3: 'TWOFISH',
|
|
4: 'BLOWFISH',
|
|
5: 'CAST',
|
|
6: 'TRIPLEDES'})]],
|
|
}]})
|
|
addr_space.profile.compile()
|
|
except KeyError:
|
|
debug.error("Truecrypt version {0} is not supported".format(ver))
|
|
|
|
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
|
|
|
|
def render_text(self, outfd, data):
|
|
for device in data:
|
|
ext = device.DeviceExtension.dereference_as("EXTENSION")
|
|
outfd.write("Container: {0}\n".format(ext.wszVolume))
|
|
outfd.write("Hidden Volume: {0}\n".format("Yes" if ext.cryptoInfo.hiddenVolume == 1 else "No"))
|
|
outfd.write("Removable: {0}\n".format("Yes" if ext.bRemovable == 1 else "No"))
|
|
outfd.write("Read Only: {0}\n".format("Yes" if ext.bReadOnly == 1 else "No"))
|
|
outfd.write("Disk Length: {0} (bytes)\n".format(ext.DiskLength))
|
|
outfd.write("Host Length: {0} (bytes)\n".format(ext.HostLength))
|
|
outfd.write("Encryption Algorithm: {0}\n".format(ext.cryptoInfo.ea))
|
|
outfd.write("Mode: {0}\n".format(ext.cryptoInfo.mode))
|
|
outfd.write("Master Key\n")
|
|
key = device.obj_vm.read(ext.cryptoInfo.master_keydata.obj_offset, 64)
|
|
addr = ext.cryptoInfo.master_keydata.obj_offset
|
|
outfd.write("{0}\n".format("\n".join(
|
|
["{0:#010x} {1:<48} {2}".format(addr + o, h, ''.join(c))
|
|
for o, h, c in utils.Hexdump(key)
|
|
])))
|
|
if self._config.DUMP_DIR:
|
|
if not os.path.isdir(self._config.DUMP_DIR):
|
|
debug.error("The path {0} is not a valid directory".format(self._config.DUMP_DIR))
|
|
name = "{0:#x}_master.key".format(addr)
|
|
keyfile = os.path.join(self._config.DUMP_DIR, name)
|
|
with open(keyfile, "wb") as handle:
|
|
handle.write(key)
|
|
outfd.write("Dumped {0} bytes to {1}\n".format(len(key), keyfile))
|
|
outfd.write("\n") |