-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #275 from ZarKyo/master
Added tests for PR plugins #254
- Loading branch information
Showing
16 changed files
with
1,047 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import logging | ||
|
||
from regipy.hive_types import SOFTWARE_HIVE_TYPE | ||
from regipy.plugins.plugin import Plugin | ||
from regipy.utils import convert_wintime | ||
from regipy.exceptions import RegistryKeyNotFoundException | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
SYS_RESTORE_PATH = r"\Microsoft\Windows NT\CurrentVersion\SystemRestore" | ||
value_list = ("DisableSR") | ||
|
||
|
||
class DisableSRPlugin(Plugin): | ||
NAME = 'disablesr_plugin' | ||
DESCRIPTION = 'Gets the value that turns System Restore either on or off' | ||
COMPATIBLE_HIVE = SOFTWARE_HIVE_TYPE | ||
|
||
def can_run(self): | ||
# TODO: Choose the relevant condition - to determine if the plugin is relevant for the given hive | ||
return self.registry_hive.hive_type == SOFTWARE_HIVE_TYPE | ||
|
||
def run(self): | ||
logger.info("Started disablesr Plugin...") | ||
|
||
try: | ||
key = self.registry_hive.get_key(SYS_RESTORE_PATH) | ||
except RegistryKeyNotFoundException as ex: | ||
logger.error(f'Could not find {self.NAME} subkey at {SYS_RESTORE_PATH}: {ex}') | ||
return None | ||
|
||
self.entries = {SYS_RESTORE_PATH: {'last_write': convert_wintime(key.header.last_modified).isoformat()}} | ||
|
||
for val in key.iter_values(): | ||
if val.name in value_list: | ||
self.entries[SYS_RESTORE_PATH][val.name] = val.value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import logging | ||
|
||
from regipy.hive_types import SOFTWARE_HIVE_TYPE | ||
from regipy.plugins.plugin import Plugin | ||
from regipy.utils import convert_wintime | ||
from regipy.exceptions import RegistryKeyNotFoundException | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
SPP_CLIENT_PATH = r"\Microsoft\Windows NT\CurrentVersion\SPP\Clients" | ||
value_list = ("{09F7EDC5-294E-4180-AF6A-FB0E6A0E9513}") | ||
|
||
|
||
class SppClientsPlugin(Plugin): | ||
NAME = 'spp_clients_plugin' | ||
DESCRIPTION = 'Determines volumes monitored by VSS' | ||
COMPATIBLE_HIVE = SOFTWARE_HIVE_TYPE | ||
|
||
def can_run(self): | ||
# TODO: Choose the relevant condition - to determine if the plugin is relevant for the given hive | ||
return self.registry_hive.hive_type == SOFTWARE_HIVE_TYPE | ||
|
||
def run(self): | ||
logger.info("Started spp_clients Plugin...") | ||
|
||
try: | ||
key = self.registry_hive.get_key(SPP_CLIENT_PATH) | ||
except RegistryKeyNotFoundException as ex: | ||
logger.error(f'Could not find {self.NAME} subkey at {SPP_CLIENT_PATH}: {ex}') | ||
return None | ||
|
||
self.entries = {SPP_CLIENT_PATH: {'last_write': convert_wintime(key.header.last_modified).isoformat()}} | ||
|
||
for val in key.iter_values(): | ||
if val.name in value_list: | ||
aux_list = [] | ||
for value in val.value: | ||
aux_list.append(value.replace("%3A", ":")) | ||
self.entries[SPP_CLIENT_PATH][val.name] = aux_list |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import logging | ||
|
||
from regipy.hive_types import SOFTWARE_HIVE_TYPE | ||
from regipy.plugins.plugin import Plugin | ||
from regipy.utils import convert_wintime | ||
from regipy.exceptions import RegistryKeyNotFoundException | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
WIN_VER_PATH = r"\Microsoft\Windows\CurrentVersion\WindowsUpdate" | ||
value_list = ("LastRestorePointSetTime", "SusClientId") | ||
|
||
|
||
class SusclientPlugin(Plugin): | ||
NAME = 'susclient_plugin' | ||
DESCRIPTION = 'Extracts SusClient* info, including HDD SN' | ||
COMPATIBLE_HIVE = SOFTWARE_HIVE_TYPE | ||
|
||
def can_run(self): | ||
# TODO: Choose the relevant condition - to determine if the plugin is relevant for the given hive | ||
return self.registry_hive.hive_type == SOFTWARE_HIVE_TYPE | ||
|
||
def run(self): | ||
logger.info("Started susclient Plugin...") | ||
|
||
try: | ||
key = self.registry_hive.get_key(WIN_VER_PATH) | ||
except RegistryKeyNotFoundException as ex: | ||
logger.error(f'Could not find {self.NAME} subkey at {WIN_VER_PATH}: {ex}') | ||
return None | ||
|
||
self.entries = {WIN_VER_PATH: {'last_write': convert_wintime(key.header.last_modified).isoformat()}} | ||
|
||
for val in key.iter_values(): | ||
if val.name == "SusClientIdValidation": | ||
self.entries[WIN_VER_PATH][val.name] = get_SN(val.value) | ||
elif val.name in value_list: | ||
self.entries[WIN_VER_PATH][val.name] = val.value | ||
|
||
|
||
def get_SN(data): | ||
offset = int(data[:2], 16) | ||
length = int(data[4:6], 16) | ||
return bytes.fromhex(data[2 * offset:2 * (length + offset)]).decode('utf-16le') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import logging | ||
|
||
from regipy.hive_types import SOFTWARE_HIVE_TYPE | ||
from regipy.plugins.plugin import Plugin | ||
from regipy.utils import convert_wintime | ||
from regipy.exceptions import RegistryKeyNotFoundException | ||
import datetime | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
WIN_VER_PATH = r"\Microsoft\Windows NT\CurrentVersion" | ||
os_list = ("ProductName", "ReleaseID", "CSDVersion", "CurrentVersion", "CurrentBuild", "CurrentBuildNumber", "InstallationType", "EditionID", | ||
"ProductName", "ProductId", "BuildLab", "BuildLabEx", "CompositionEditionID", "RegisteredOrganization", "RegisteredOwner", "InstallDate") | ||
|
||
|
||
class WinVersionPlugin(Plugin): | ||
NAME = 'winver_plugin' | ||
DESCRIPTION = 'Get relevant OS information' | ||
COMPATIBLE_HIVE = SOFTWARE_HIVE_TYPE | ||
|
||
def can_run(self): | ||
# TODO: Choose the relevant condition - to determine if the plugin is relevant for the given hive | ||
return self.registry_hive.hive_type == SOFTWARE_HIVE_TYPE | ||
|
||
def run(self): | ||
logger.info("Started winver Plugin...") | ||
|
||
try: | ||
key = self.registry_hive.get_key(WIN_VER_PATH) | ||
except RegistryKeyNotFoundException as ex: | ||
logger.error(f'Could not find {self.NAME} subkey at {WIN_VER_PATH}: {ex}') | ||
return None | ||
|
||
self.entries = {WIN_VER_PATH: {'last_write': convert_wintime(key.header.last_modified).isoformat()}} | ||
|
||
for val in key.iter_values(): | ||
if val.name in os_list: | ||
if val.name == "InstallDate": | ||
self.entries[WIN_VER_PATH][val.name] = datetime.datetime.utcfromtimestamp(val.value).strftime("%Y-%m-%d %H:%M:%S") | ||
else: | ||
self.entries[WIN_VER_PATH][val.name] = val.value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import logging | ||
|
||
from regipy.hive_types import SYSTEM_HIVE_TYPE | ||
from regipy.plugins.plugin import Plugin | ||
from regipy.utils import convert_wintime | ||
from regipy.exceptions import RegistryKeyNotFoundException | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
BACKUPRESTORE_PATH = [r"Control\BackupRestore\FilesNotToSnapshot", r"Control\BackupRestore\FilesNotToBackup", r"Control\BackupRestore\KeysNotToRestore"] | ||
|
||
|
||
class BackupRestorePlugin(Plugin): | ||
NAME = 'backuprestore_plugin' | ||
DESCRIPTION = "Gets the contents of the FilesNotToSnapshot, KeysNotToRestore, and FilesNotToBackup keys" | ||
COMPATIBLE_HIVE = SYSTEM_HIVE_TYPE | ||
|
||
def can_run(self): | ||
# TODO: Choose the relevant condition - to determine if the plugin is relevant for the given hive | ||
return self.registry_hive.hive_type == SYSTEM_HIVE_TYPE | ||
|
||
def run(self): | ||
self.entries = {} | ||
for br_path in BACKUPRESTORE_PATH: | ||
br_subkeys = self.registry_hive.get_control_sets(br_path) | ||
for br_subkey in br_subkeys: | ||
try: | ||
backuprestore = self.registry_hive.get_key(br_subkey) | ||
except RegistryKeyNotFoundException as ex: | ||
logger.error(f'Could not find {self.NAME} subkey at {br_subkey}: {ex}') | ||
continue | ||
self.entries[br_subkey] = {'last_write': convert_wintime(backuprestore.header.last_modified).isoformat()} | ||
for val in backuprestore.iter_values(): | ||
self.entries[br_subkey][val.name] = val.value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import logging | ||
|
||
from regipy.hive_types import SYSTEM_HIVE_TYPE | ||
from regipy.plugins.plugin import Plugin | ||
from regipy.utils import convert_wintime | ||
from regipy.exceptions import RegistryKeyNotFoundException | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
PROCESSOR_PATH = r"Control\Nls\CodePage" | ||
crash_items = ("ACP") | ||
|
||
|
||
class CodepagePlugin(Plugin): | ||
NAME = 'codepage' | ||
DESCRIPTION = "Get codepage value" | ||
COMPATIBLE_HIVE = SYSTEM_HIVE_TYPE | ||
|
||
def can_run(self): | ||
# TODO: Choose the relevant condition - to determine if the plugin is relevant for the given hive | ||
return self.registry_hive.hive_type == SYSTEM_HIVE_TYPE | ||
|
||
def run(self): | ||
self.entries = {} | ||
codepage_subkeys = self.registry_hive.get_control_sets(PROCESSOR_PATH) | ||
for codepage_subkey in codepage_subkeys: | ||
try: | ||
codepage = self.registry_hive.get_key(codepage_subkey) | ||
except RegistryKeyNotFoundException as ex: | ||
logger.error(f'Could not find {self.NAME} subkey at {codepage_subkey}: {ex}') | ||
continue | ||
self.entries[codepage_subkey] = {'last_write': convert_wintime(codepage.header.last_modified).isoformat()} | ||
for val in codepage.iter_values(): | ||
if val.name in crash_items: | ||
self.entries[codepage_subkey][val.name] = val.value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import logging | ||
|
||
from regipy.hive_types import SYSTEM_HIVE_TYPE | ||
from regipy.plugins.plugin import Plugin | ||
from regipy.utils import convert_wintime | ||
from regipy.exceptions import RegistryKeyNotFoundException | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
PROCESSOR_PATH = r"Control\CrashControl" | ||
crash_items = ("CrashDumpEnabled", "DumpFile", "MinidumpDir", "LogEvent") | ||
dump_enabled = {"0": "None", | ||
"1": "Complete memory dump", | ||
"2": "Kernel memory dump", | ||
"3": "Small memory dump (64 KB)", | ||
"7": "Automatic memory dump"} | ||
|
||
|
||
class CrashDumpPlugin(Plugin): | ||
NAME = 'crash_dump' | ||
DESCRIPTION = "Get crash control information" | ||
COMPATIBLE_HIVE = SYSTEM_HIVE_TYPE | ||
|
||
def can_run(self): | ||
# TODO: Choose the relevant condition - to determine if the plugin is relevant for the given hive | ||
return self.registry_hive.hive_type == SYSTEM_HIVE_TYPE | ||
|
||
def run(self): | ||
self.entries = {} | ||
architecture_subkeys = self.registry_hive.get_control_sets(PROCESSOR_PATH) | ||
for architecture_subkey in architecture_subkeys: | ||
try: | ||
architecture = self.registry_hive.get_key(architecture_subkey) | ||
except RegistryKeyNotFoundException as ex: | ||
logger.error(f'Could not find {self.NAME} subkey at {architecture_subkey}: {ex}') | ||
continue | ||
self.entries[architecture_subkey] = {'last_write': convert_wintime(architecture.header.last_modified).isoformat()} | ||
for val in architecture.iter_values(): | ||
if val.name in crash_items: | ||
self.entries[architecture_subkey][val.name] = val.value | ||
if val.name == "CrashDumpEnabled": | ||
self.entries[architecture_subkey]["CrashDumpEnabledStr"] = dump_enabled.get(str(val.value), "") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import logging | ||
import struct | ||
|
||
from regipy.hive_types import SYSTEM_HIVE_TYPE | ||
from regipy.plugins.plugin import Plugin | ||
from regipy.utils import convert_wintime | ||
from regipy.utils import convert_filetime2 | ||
from regipy.exceptions import RegistryKeyNotFoundException | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
DIAGSR_PATH = r"Services\VSS\Diag\SystemRestore" | ||
crash_items = ("CrashDumpEnabled", "DumpFile", "MinidumpDir", "LogEvent") | ||
|
||
|
||
class DiagSRPlugin(Plugin): | ||
NAME = 'diag_sr' | ||
DESCRIPTION = "Get Diag\\SystemRestore values and data" | ||
COMPATIBLE_HIVE = SYSTEM_HIVE_TYPE | ||
|
||
def can_run(self): | ||
# TODO: Choose the relevant condition - to determine if the plugin is relevant for the given hive | ||
return self.registry_hive.hive_type == SYSTEM_HIVE_TYPE | ||
|
||
def run(self): | ||
self.entries = {} | ||
diagsr_subkeys = self.registry_hive.get_control_sets(DIAGSR_PATH) | ||
for diagsr_subkey in diagsr_subkeys: | ||
try: | ||
diagsr = self.registry_hive.get_key(diagsr_subkey) | ||
except RegistryKeyNotFoundException as ex: | ||
logger.error(f'Could not find {self.NAME} subkey at {diagsr_subkey}: {ex}') | ||
continue | ||
self.entries[diagsr_subkey] = {'last_write': convert_wintime(diagsr.header.last_modified).isoformat()} | ||
for val in diagsr.iter_values(): | ||
self.entries[diagsr_subkey][val.name] = convert_filetime2(val.value[16:32]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import logging | ||
|
||
from regipy.hive_types import SYSTEM_HIVE_TYPE | ||
from regipy.plugins.plugin import Plugin | ||
from regipy.utils import convert_wintime | ||
from regipy.exceptions import RegistryKeyNotFoundException | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
LAST_ACCESS_PATH = r"Control\FileSystem" | ||
crash_items = ("NtfsDisableLastAccessUpdate", "NtfsDisableLastAccessUpdate") | ||
last_acc = {"80000000": "(User Managed, Updates Enabled)", | ||
"80000001": "(User Managed, Updates Disabled)", | ||
"80000002": "(System Managed, Updates Enabled)", | ||
"80000003": "(System Managed, Updates Disabled)"} | ||
|
||
|
||
class DisableLastAccessPlugin(Plugin): | ||
NAME = 'disable_last_access' | ||
DESCRIPTION = "Get NTFSDisableLastAccessUpdate value" | ||
COMPATIBLE_HIVE = SYSTEM_HIVE_TYPE | ||
|
||
def can_run(self): | ||
# TODO: Choose the relevant condition - to determine if the plugin is relevant for the given hive | ||
return self.registry_hive.hive_type == SYSTEM_HIVE_TYPE | ||
|
||
def run(self): | ||
self.entries = {} | ||
access_subkeys = self.registry_hive.get_control_sets(LAST_ACCESS_PATH) | ||
for access_subkey in access_subkeys: | ||
try: | ||
access = self.registry_hive.get_key(access_subkey) | ||
except RegistryKeyNotFoundException as ex: | ||
logger.error(f'Could not find {self.NAME} subkey at {access_subkey}: {ex}') | ||
continue | ||
self.entries[access_subkey] = {'last_write': convert_wintime(access.header.last_modified).isoformat()} | ||
for val in access.iter_values(): | ||
if val.name in crash_items: | ||
self.entries[access_subkey][val.name] = f'{val.value:0x}' | ||
self.entries[access_subkey][f'{val.name}Str'] = last_acc.get(f'{val.value:0x}', '') |
Oops, something went wrong.