# -*- coding: utf-8 -*-
""""Windows Registry plugin for SAM Users Account information."""
import os
from dfdatetime import filetime as dfdatetime_filetime
from plaso.containers import events
from plaso.lib import dtfabric_helper
from plaso.lib import errors
from plaso.parsers import winreg_parser
from plaso.parsers.winreg_plugins import interface
[docs]
class SAMUsersWindowsRegistryEventData(events.EventData):
"""Class that defines SAM users Windows Registry event data.
Attributes:
account_rid (int): account relative identifier (RID).
comments (str): comments.
fullname (str): full name.
key_path (str): Windows Registry key path.
last_login_time (dfdatetime.DateTimeValues): date and time of the last
login.
last_password_set_time (dfdatetime.DateTimeValues): date and time of the
last password set.
last_written_time (dfdatetime.DateTimeValues): entry last written date and
time.
login_count (int): login count.
username (str): a string containing the username.
"""
DATA_TYPE = 'windows:registry:sam_users'
[docs]
def __init__(self):
"""Initializes event data."""
super(SAMUsersWindowsRegistryEventData, self).__init__(
data_type=self.DATA_TYPE)
self.account_rid = None
self.comments = None
self.fullname = None
self.key_path = None
self.last_login_time = None
self.last_password_set_time = None
self.last_written_time = None
self.login_count = None
self.username = None
[docs]
class SAMUsersWindowsRegistryPlugin(
interface.WindowsRegistryPlugin, dtfabric_helper.DtFabricHelper):
"""Windows Registry plugin for SAM Users Account information."""
NAME = 'windows_sam_users'
DATA_FORMAT = 'Security Accounts Manager (SAM) users Registry data'
FILTERS = frozenset([
interface.WindowsRegistryKeyPathFilter(
'HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\Users')])
_DEFINITION_FILE = os.path.join(
os.path.dirname(__file__), 'sam_users.yaml')
_V_VALUE_STRINGS_OFFSET = 0xcc
def _ParseFValue(self, registry_key):
"""Parses an F value.
Args:
registry_key (dfwinreg.WinRegistryKey): Windows Registry key.
Returns:
f_value: F value stored in the Windows Registry key.
Raises:
ParseError: if the Windows Registry key does not contain an F value or
F value cannot be parsed.
"""
registry_value = registry_key.GetValueByName('F')
if not registry_value:
raise errors.ParseError(
f'missing value: "F" in Windows Registry key: {registry_key.name:s}.')
f_value_map = self._GetDataTypeMap('f_value')
try:
return self._ReadStructureFromByteStream(
registry_value.data, 0, f_value_map)
except (ValueError, errors.ParseError) as exception:
raise errors.ParseError(exception)
def _ParseVValueString(
self, parser_mediator, data, user_information_descriptor):
"""Parses a V value string.
Args:
parser_mediator (ParserMediator): mediates interactions between parsers
and other components, such as storage and dfVFS.
data (bytes): Windows Registry V value data.
user_information_descriptor (user_information_descriptor): V value
user information descriptor.
Returns:
str: string value stored in the Windows Registry V value data.
"""
data_start_offset = (
user_information_descriptor.offset + self._V_VALUE_STRINGS_OFFSET)
data_end_offset = data_start_offset + user_information_descriptor.size
descriptor_data = data[data_start_offset:data_end_offset]
try:
username = descriptor_data.decode('utf-16-le')
except (UnicodeDecodeError, UnicodeEncodeError) as exception:
username = descriptor_data.decode('utf-16-le', errors='replace')
parser_mediator.ProduceExtractionWarning((
f'unable to decode "V" value string with error: {exception!s}. '
f'Characters that cannot be decoded will be replaced with "?" or '
f'"\\ufffd".'))
return username
winreg_parser.WinRegistryParser.RegisterPlugin(SAMUsersWindowsRegistryPlugin)