def GetEntries(self, parser_mediator, key=None, registry_type=None, codepage='cp1252', **kwargs): """Parses a UserAssist Registry key. Args: parser_mediator: A parser mediator object (instance of ParserMediator). key: Optional Registry key (instance of winreg.WinRegKey). The default is None. registry_type: Optional Registry type string. The default is None. """ version_value = key.GetValue('Version') count_subkey = key.GetSubkey('Count') if not version_value: parser_mediator.ProduceParseError(u'Missing version value') elif not version_value.DataIsInteger(): parser_mediator.ProduceParseError( u'Unsupported version value data type') elif version_value.data not in [3, 5]: parser_mediator.ProduceParseError( u'Unsupported version: {0:d}'.format(version_value.data)) elif not count_subkey: parser_mediator.ProduceParseError(u'Missing count subkey') else: userassist_entry_index = 0 for value in count_subkey.GetValues(): try: value_name = value.name.decode('rot-13') except UnicodeEncodeError as exception: logging.debug(( u'Unable to decode UserAssist string: {0:s} with error: {1:s}.\n' u'Attempting piecewise decoding.').format( value.name, exception)) characters = [] for char in value.name: if ord(char) < 128: try: characters.append(char.decode('rot-13')) except UnicodeEncodeError: characters.append(char) else: characters.append(char) value_name = u''.join(characters) if version_value.data == 5: path_segments = value_name.split(u'\\') for segment_index in range(0, len(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_segments[segment_index]) value_name = u'\\'.join(path_segments) # Check if we might need to substitute values. if '%' in value_name: # TODO: deprecate direct use of pre_obj. value_name = environ_expand.ExpandWindowsEnvironmentVariables( value_name, parser_mediator.knowledge_base.pre_obj) if not value.DataIsBinaryData(): parser_mediator.ProduceParseError( u'Unsupported value data type: {0:s}'.format( value.data_type_string)) elif version_value.data == 3: if len(value.data) != self.USERASSIST_V3_STRUCT.sizeof(): parser_mediator.ProduceParseError( u'Unsupported value data size: {0:d}'.format( len(value.data))) else: parsed_data = self.USERASSIST_V3_STRUCT.parse( value.data) filetime = parsed_data.get('timestamp', 0) count = parsed_data.get('count', 0) if count > 5: count -= 5 text_dict = {} text_dict[value_name] = u'[Count: {0:d}]'.format(count) event_object = windows_events.WindowsRegistryEvent( timelib.Timestamp.FromFiletime(filetime), count_subkey.path, text_dict, offset=value.offset, registry_type=registry_type) parser_mediator.ProduceEvent(event_object) elif version_value.data == 5: if len(value.data) != self.USERASSIST_V5_STRUCT.sizeof(): parser_mediator.ProduceParseError( u'Unsupported value data size: {0:d}'.format( len(value.data))) parsed_data = self.USERASSIST_V5_STRUCT.parse(value.data) userassist_entry_index += 1 count = parsed_data.get('count', None) app_focus_count = parsed_data.get('app_focus_count', None) focus_duration = parsed_data.get('focus_duration', None) timestamp = parsed_data.get('timestamp', 0) text_dict = {} text_dict[value_name] = ( u'[UserAssist entry: {0:d}, Count: {1:d}, ' u'Application focus count: {2:d}, Focus duration: {3:d}]' ).format(userassist_entry_index, count, app_focus_count, focus_duration) event_object = windows_events.WindowsRegistryEvent( timelib.Timestamp.FromFiletime(timestamp), count_subkey.path, text_dict, offset=count_subkey.offset, registry_type=registry_type) parser_mediator.ProduceEvent(event_object)
def GetEntries(self, parser_mediator, registry_key, **kwargs): """Parses a UserAssist Registry key. Args: parser_mediator: A parser mediator object (instance of ParserMediator). registry_key: A Windows Registry key (instance of dfwinreg.WinRegistryKey). """ version_value = registry_key.GetValueByName(u'Version') count_subkey = registry_key.GetSubkeyByName(u'Count') if not version_value: parser_mediator.ProduceExtractionError(u'Missing version value') return if not version_value.DataIsInteger(): parser_mediator.ProduceExtractionError( u'Unsupported version value data type') return format_version = version_value.GetDataAsObject() if format_version not in (3, 5): parser_mediator.ProduceExtractionError( u'Unsupported format version: {0:d}'.format(format_version)) return if not count_subkey: parser_mediator.ProduceExtractionError(u'Missing count subkey') return userassist_entry_index = 0 for registry_value in count_subkey.GetValues(): try: value_name = registry_value.name.decode(u'rot-13') except UnicodeEncodeError as exception: logging.debug(( u'Unable to decode UserAssist string: {0:s} with error: {1:s}.\n' u'Attempting piecewise decoding.').format( registry_value.name, exception)) characters = [] for char in registry_value.name: if ord(char) < 128: try: characters.append(char.decode(u'rot-13')) except UnicodeEncodeError: characters.append(char) else: characters.append(char) value_name = u''.join(characters) if format_version == 5: path_segments = value_name.split(u'\\') for segment_index in range(0, len(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_segments[segment_index]) value_name = u'\\'.join(path_segments) # Check if we might need to substitute values. if u'%' in value_name: path_attributes = parser_mediator.knowledge_base.GetPathAttributes() value_name = environ_expand.ExpandWindowsEnvironmentVariables( value_name, path_attributes) value_data_size = len(registry_value.data) if not registry_value.DataIsBinaryData(): parser_mediator.ProduceExtractionError( u'Unsupported value data type: {0:s}'.format( registry_value.data_type_string)) elif value_name == u'UEME_CTLSESSION': pass elif format_version == 3: if value_data_size != self._USERASSIST_V3_STRUCT.sizeof(): parser_mediator.ProduceExtractionError( u'Unsupported value data size: {0:d}'.format(value_data_size)) else: parsed_data = self._USERASSIST_V3_STRUCT.parse(registry_value.data) filetime = parsed_data.get(u'timestamp', 0) count = parsed_data.get(u'count', 0) if count > 5: count -= 5 values_dict = {} values_dict[value_name] = u'[Count: {0:d}]'.format(count) event_object = UserAssistWindowsRegistryEvent( filetime, count_subkey.path, registry_value.offset, values_dict) parser_mediator.ProduceEvent(event_object) elif format_version == 5: if value_data_size != self._USERASSIST_V5_STRUCT.sizeof(): parser_mediator.ProduceExtractionError( u'Unsupported value data size: {0:d}'.format(value_data_size)) parsed_data = self._USERASSIST_V5_STRUCT.parse(registry_value.data) userassist_entry_index += 1 count = parsed_data.get(u'count', None) app_focus_count = parsed_data.get(u'app_focus_count', None) focus_duration = parsed_data.get(u'focus_duration', None) filetime = parsed_data.get(u'timestamp', 0) values_dict = {} values_dict[value_name] = ( u'[UserAssist entry: {0:d}, Count: {1:d}, ' u'Application focus count: {2:d}, Focus duration: {3:d}]').format( userassist_entry_index, count, app_focus_count, focus_duration) event_object = UserAssistWindowsRegistryEvent( filetime, count_subkey.path, count_subkey.offset, values_dict) parser_mediator.ProduceEvent(event_object)
def GetEntries(self, key, **unused_kwargs): """Parses a UserAssist Registry key. Args: key: A Windows Registry key (instance of WinRegKey). Yields: An event object (instance of EventObject) that contains an user assist entry. """ version_value = key.GetValue('Version') count_subkey = key.GetSubkey('Count') regalert_string = '' if not version_value: regalert_string = 'missing version value' elif not version_value.DataIsInteger(): regalert_string = 'unsupported version value data type' elif version_value.data not in [3, 5]: regalert_string = 'unsupported version: {0:d}'.format( version_value.data) elif not count_subkey: regalert_string = 'missing count subkey' if regalert_string: text_dict = {} text_dict['Version'] = 'REGALERT {0:s}.'.format(regalert_string) regalert_string = '' yield event.WinRegistryEvent(key.path, text_dict, timestamp=key.last_written_timestamp) else: for value in count_subkey.GetValues(): try: value_name = value.name.decode('rot-13') except UnicodeEncodeError as exception: logging.debug(( u'Unable to decode UserAssist string: {0:s} with error: {1:s}.\n' u'Attempting piecewise decoding.').format( value.name, exception)) characters = [] for char in value.name: if ord(char) < 128: try: characters.append(char.decode('rot-13')) except UnicodeEncodeError: characters.append(char) else: characters.append(char) value_name = u''.join(characters) if version_value.data == 5: path_segments = value_name.split('\\') for segment_index in range(0, len(path_segments)): path_segments[ segment_index] = knownfolderid.IDENTIFIERS.get( path_segments[segment_index], path_segments[segment_index]) value_name = u'\\'.join(path_segments) # Check if we might need to substitute values. if '%' in value_name: value_name = environ_expand.ExpandWindowsEnvironmentVariables( value_name, self._config) if not value.DataIsBinaryData(): regalert_string = 'unsupported value data type: {0:s}'.format( value.data_type_string) elif version_value.data == 3: if len(value.data) != self.USERASSIST_V3_STRUCT.sizeof(): regalert_string = 'unsupported value data size: {0:d}'.format( len(value.data)) else: parsed_data = self.USERASSIST_V3_STRUCT.parse( value.data) filetime = parsed_data.get('timestamp', 0) count = parsed_data.get('count', 0) if count > 5: count -= 5 text_dict = {} text_dict[value_name] = u'[Count: {0}]'.format(count) yield event.WinRegistryEvent( count_subkey.path, text_dict, timestamp=timelib.Timestamp.FromFiletime(filetime), offset=value.offset) elif version_value.data == 5: if len(value.data) != self.USERASSIST_V5_STRUCT.sizeof(): regalert_string = 'unsupported value data size: {0:d}'.format( len(value.data)) parsed_data = self.USERASSIST_V5_STRUCT.parse(value.data) userassist_entry = parsed_data.get('userassist_entry', None) count = parsed_data.get('count', None) app_focus_count = parsed_data.get('app_focus_count', None) focus_duration = parsed_data.get('focus_duration', None) timestamp = parsed_data.get('timestamp', 0) text_dict = {} text_dict[value_name] = ( u'[userassist_entry: {0}, Count: {1}, app_focus_count: {2}, ' u'focus_duration: {3}]').format( userassist_entry, count, app_focus_count, focus_duration) yield event.WinRegistryEvent( count_subkey.path, text_dict, timestamp=timelib.Timestamp.FromFiletime(timestamp)) if regalert_string: text_dict = {} text_dict[value_name] = 'REGALERT {0:s}.'.format(regalert_string) regalert_string = '' yield event.WinRegistryEvent(key.path, text_dict, timestamp=key.last_written_timestamp)