Source code for plaso.parsers.winreg_plugins.userassist

# -*- coding: utf-8 -*-
"""The UserAssist Windows Registry plugin."""

from __future__ import unicode_literals

import codecs

from dfdatetime import filetime as dfdatetime_filetime
from dfdatetime import semantic_time as dfdatetime_semantic_time

from plaso.containers import events
from plaso.containers import time_events
from plaso.engine import path_helper
from plaso.lib import definitions
from plaso.lib import errors
from plaso.parsers import logger
from plaso.parsers import winreg
from plaso.parsers.winreg_plugins import dtfabric_plugin
from plaso.parsers.winreg_plugins import interface
from plaso.winnt import known_folder_ids


[docs]class UserAssistWindowsRegistryEventData(events.EventData): """UserAssist Windows Registry event data. Attributes: application_focus_count (int): application focus count. application_focus_duration (int): application focus duration. entry_index (int): entry index. key_path (str): Windows Registry key path. number_of_executions (int): nubmer of executions. regvalue (dict[str, str]): UserAssist values. value_name (str): name of the Windows Registry value. """ DATA_TYPE = 'windows:registry:userassist' def __init__(self): """Initializes event data.""" super(UserAssistWindowsRegistryEventData, self).__init__( data_type=self.DATA_TYPE) self.application_focus_count = None self.application_focus_duration = None self.entry_index = None self.key_path = None self.number_of_executions = None
self.value_name = None
[docs]class UserAssistWindowsRegistryKeyPathFilter( interface.WindowsRegistryKeyPathFilter): """UserAssist Windows Registry key path filter.""" _KEY_PATH_FORMAT = ( 'HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\' 'Explorer\\UserAssist\\{{{0:s}}}') def __init__(self, user_assist_guid): """Initializes Windows Registry key filter. Args: user_assist_guid (str): UserAssist GUID. """ key_path = self._KEY_PATH_FORMAT.format(user_assist_guid)
super(UserAssistWindowsRegistryKeyPathFilter, self).__init__(key_path)
[docs]class UserAssistPlugin(dtfabric_plugin.DtFabricBaseWindowsRegistryPlugin): """Plugin that parses an UserAssist key.""" NAME = 'userassist' DESCRIPTION = 'Parser for User Assist Registry data.' FILTERS = frozenset([ UserAssistWindowsRegistryKeyPathFilter( 'FA99DFC7-6AC2-453A-A5E2-5E2AFF4507BD'), UserAssistWindowsRegistryKeyPathFilter( 'F4E57C4B-2036-45F0-A9AB-443BCFE33D9F'), UserAssistWindowsRegistryKeyPathFilter( 'F2A1CB5A-E3CC-4A2E-AF9D-505A7009D442'), UserAssistWindowsRegistryKeyPathFilter( 'CEBFF5CD-ACE2-4F4F-9178-9926F41749EA'), UserAssistWindowsRegistryKeyPathFilter( 'CAA59E3C-4792-41A5-9909-6A6A8D32490E'), UserAssistWindowsRegistryKeyPathFilter( 'B267E3AD-A825-4A09-82B9-EEC22AA3B847'), UserAssistWindowsRegistryKeyPathFilter( 'A3D53349-6E61-4557-8FC7-0028EDCEEBF6'), UserAssistWindowsRegistryKeyPathFilter( '9E04CAB2-CC14-11DF-BB8C-A2F1DED72085'), UserAssistWindowsRegistryKeyPathFilter( '75048700-EF1F-11D0-9888-006097DEACF9'), UserAssistWindowsRegistryKeyPathFilter( '5E6AB780-7743-11CF-A12B-00AA004AE837'), UserAssistWindowsRegistryKeyPathFilter( '0D6D4F41-2994-4BA0-8FEF-620E43CD2812'), UserAssistWindowsRegistryKeyPathFilter( 'BCB48336-4DDD-48FF-BB0B-D3190DACB3E2')]) URLS = [ 'http://blog.didierstevens.com/programs/userassist/', 'https://code.google.com/p/winreg-kb/wiki/UserAssistKeys', 'http://intotheboxes.files.wordpress.com/2010/04' '/intotheboxes_2010_q1.pdf'] _DEFINITION_FILE = 'userassist.yaml' # pylint 1.9.3 wants a docstring for kwargs, but this is not useful to add. # pylint: disable=missing-param-doc
[docs] def ExtractEvents(self, parser_mediator, registry_key, **kwargs): """Extracts events from a Windows Registry key. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. registry_key (dfwinreg.WinRegistryKey): Windows Registry key. """ version_value = registry_key.GetValueByName('Version') count_subkey = registry_key.GetSubkeyByName('Count') if not version_value: parser_mediator.ProduceExtractionError('missing version value') return if not version_value.DataIsInteger(): parser_mediator.ProduceExtractionError( 'unsupported version value data type') return format_version = version_value.GetDataAsObject() if format_version not in (3, 5): parser_mediator.ProduceExtractionError( 'unsupported format version: {0:d}'.format(format_version)) return if not count_subkey: parser_mediator.ProduceExtractionError('missing count subkey') return userassist_entry_index = 0 for registry_value in count_subkey.GetValues(): try: # Note that Python 2 codecs.decode() does not support keyword arguments # such as encodings='rot-13'. value_name = codecs.decode(registry_value.name, 'rot-13') except UnicodeEncodeError as exception: logger.debug(( 'Unable to decode UserAssist string: {0:s} with error: {1!s}.\n' 'Attempting piecewise decoding.').format( registry_value.name, exception)) characters = [] for char in registry_value.name: if ord(char) < 128: try: characters.append(char.decode('rot-13')) except UnicodeEncodeError: characters.append(char) else: characters.append(char) value_name = ''.join(characters) if format_version == 5: path_segments = value_name.split('\\') for segment_index, path_segment in enumerate(path_segments): # Remove the { } from the path segment to get the GUID. guid = path_segments[segment_index][1:-1] path_segments[segment_index] = known_folder_ids.PATHS.get( guid, path_segment) value_name = '\\'.join(path_segments) # Check if we might need to substitute values. if '%' in value_name: # TODO: fix missing self._knowledge_base # pylint: disable=no-member environment_variables = self._knowledge_base.GetEnvironmentVariables() value_name = path_helper.PathHelper.ExpandWindowsPath( value_name, environment_variables) if value_name == 'UEME_CTLSESSION': continue if format_version == 3: entry_map = self._GetDataTypeMap('user_assist_entry_v3') elif format_version == 5: entry_map = self._GetDataTypeMap('user_assist_entry_v5') else: parser_mediator.ProduceExtractionError( 'unsupported format version: {0:d}'.format(format_version)) continue if not registry_value.DataIsBinaryData(): parser_mediator.ProduceExtractionError( 'unsupported value data type: {0:s}'.format( registry_value.data_type_string)) continue entry_data_size = entry_map.GetByteSize() value_data_size = len(registry_value.data) if entry_data_size != value_data_size: parser_mediator.ProduceExtractionError( 'unsupported value data size: {0:d}'.format(value_data_size)) continue try: user_assist_entry = self._ReadStructureFromByteStream( registry_value.data, 0, entry_map) except (ValueError, errors.ParseError) as exception: parser_mediator.ProduceExtractionError( 'unable to parse UserAssist entry value with error: {0!s}'.format( exception)) continue event_data = UserAssistWindowsRegistryEventData() event_data.key_path = count_subkey.path event_data.number_of_executions = user_assist_entry.number_of_executions event_data.value_name = value_name if format_version == 3: if event_data.number_of_executions > 5: event_data.number_of_executions -= 5 elif format_version == 5: userassist_entry_index += 1 event_data.application_focus_count = ( user_assist_entry.application_focus_count) event_data.application_focus_duration = ( user_assist_entry.application_focus_duration) event_data.entry_index = userassist_entry_index timestamp = user_assist_entry.last_execution_time if not timestamp: date_time = dfdatetime_semantic_time.SemanticTime('Not set') else: date_time = dfdatetime_filetime.Filetime(timestamp=timestamp) event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_LAST_RUN)
parser_mediator.ProduceEventWithEventData(event, event_data) winreg.WinRegistryParser.RegisterPlugin(UserAssistPlugin)