class BaseMRUListExPlugin(interface.WindowsRegistryPlugin): """Class for common MRUListEx Windows Registry plugin functionality.""" _MRULISTEX_STRUCT = construct.Range( 1, 500, construct.ULInt32('entry_number')) _SOURCE_APPEND = ': MRUListEx' @abc.abstractmethod def _ParseMRUListExEntryValue( self, parser_mediator, registry_key, entry_index, entry_number, **kwargs): """Parses the MRUListEx entry value. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. registry_key (dfwinreg.WinRegistryKey): Windows Registry key that contains the MRUListEx value. entry_index (int): MRUListEx entry index. entry_number (int): entry number. Returns: str: MRUList entry value. """ def _ParseMRUListExValue(self, registry_key): """Parses the MRUListEx value in a given Registry key. Args: registry_key (dfwinreg.WinRegistryKey): Windows Registry key that contains the MRUListEx value. Returns: generator: MRUListEx value generator, which returns the MRU index number and entry value. """ mru_list_value = registry_key.GetValueByName('MRUListEx') # The key exists but does not contain a value named "MRUListEx". if not mru_list_value: return enumerate([]) try: mru_list = self._MRULISTEX_STRUCT.parse(mru_list_value.data) except construct.FieldError: logging.warning('[{0:s}] Unable to parse the MRU key: {1:s}'.format( self.NAME, registry_key.path)) return enumerate([]) return enumerate(mru_list) def _ParseMRUListExKey( self, parser_mediator, registry_key, codepage='cp1252'): """Extract event objects from a MRUListEx 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. codepage (Optional[str]): extended ASCII string codepage. """ values_dict = {} for entry_index, entry_number in self._ParseMRUListExValue(registry_key): # TODO: detect if list ends prematurely. # MRU lists are terminated with 0xffffffff (-1). if entry_number == 0xffffffff: break value_string = self._ParseMRUListExEntryValue( parser_mediator, registry_key, entry_index, entry_number, codepage=codepage) value_text = 'Index: {0:d} [MRU Value {1:d}]'.format( entry_index + 1, entry_number) values_dict[value_text] = value_string event_data = windows_events.WindowsRegistryEventData() event_data.key_path = registry_key.path event_data.offset = registry_key.offset event_data.regvalue = values_dict event_data.source_append = self._SOURCE_APPEND event = time_events.DateTimeValuesEvent( registry_key.last_written_time, definitions.TIME_DESCRIPTION_WRITTEN) parser_mediator.ProduceEventWithEventData(event, event_data)
class MRUListExPluginMixin(object): """Class for common MRUListEx Windows Registry plugin functionality.""" _MRULISTEX_STRUCT = construct.Range(1, 500, construct.ULInt32('entry_number')) @abc.abstractmethod def _ParseMRUListExEntryValue(self, parser_mediator, key, entry_index, entry_number, **kwargs): """Parses the MRUListEx entry value. Args: parser_mediator: A parser mediator object (instance of ParserMediator). key: the Registry key (instance of winreg.WinRegKey) that contains the MRUListEx value. entry_index: integer value representing the MRUListEx entry index. entry_number: integer value representing the entry number. Returns: A string containing the value. """ def _ParseMRUListExValue(self, key): """Parses the MRUListEx value in a given Registry key. Args: key: the Registry key (instance of winreg.WinRegKey) that contains the MRUListEx value. Returns: A MRUListEx value generator, which returns the MRU index number and entry value. """ mru_list_value = key.GetValue('MRUListEx') # The key exists but does not contain a value named "MRUListEx". if not mru_list_value: return enumerate([]) try: mru_list = self._MRULISTEX_STRUCT.parse(mru_list_value.data) except construct.FieldError: logging.warning( u'[{0:s}] Unable to parse the MRU key: {1:s}'.format( self.NAME, key.path)) return enumerate([]) return enumerate(mru_list) def _ParseMRUListExKey(self, parser_mediator, key, registry_type=None, codepage='cp1252'): """Extract event objects from a MRUListEx Registry key. Args: parser_mediator: A parser mediator object (instance of ParserMediator). key: the Registry key (instance of winreg.WinRegKey). registry_type: Optional Registry type string. The default is None. codepage: Optional extended ASCII string codepage. The default is cp1252. """ text_dict = {} for entry_index, entry_number in self._ParseMRUListExValue(key): # TODO: detect if list ends prematurely. # MRU lists are terminated with 0xffffffff (-1). if entry_number == 0xffffffff: break value_string = self._ParseMRUListExEntryValue(parser_mediator, key, entry_index, entry_number, codepage=codepage) value_text = u'Index: {0:d} [MRU Value {1:d}]'.format( entry_index + 1, entry_number) text_dict[value_text] = value_string event_object = windows_events.WindowsRegistryEvent( key.last_written_timestamp, key.path, text_dict, offset=key.offset, registry_type=registry_type, source_append=': MRUListEx') parser_mediator.ProduceEvent(event_object)
class MRUListExPlugin(interface.ValuePlugin): """Class that defines a MRUListEx Windows Registry plugin.""" NAME = 'winreg_mrulistex' REG_TYPE = 'any' REG_VALUES = frozenset(['MRUListEx', '0']) URLS = [u'http://forensicartifacts.com/2011/02/recentdocs/'] LIST_STRUCT = construct.Range(1, 500, construct.ULInt32('entry_number')) def GetText(self, key, mru_entry): """Return a string from a MRU value.""" value = key.GetValue(mru_entry) if not value: return u'' # TODO: refactor this into a function of value? if value.DataIsString(): return value.data if value.data_type == value.REG_BINARY: # TODO: refactor this into an extract text from binary function. return value.data.decode('utf_16_le', 'ignore').split('\x00')[0] return u'' def GetEntries(self, key, **unused_kwargs): """Extract EventObjects from a MRU list.""" mru_list_data = key.GetValue('MRUListEx') # TODO: there is no need to use raw data refactor to use data. raw_data = mru_list_data.raw_data try: mru_list = self.LIST_STRUCT.parse(raw_data) except construct.FieldError: logging.warning(u'Unable to parse the MRU key: {0:s}'.format( key.path)) return event_timestamp = key.last_written_timestamp text_dict = {} for nr, entry in enumerate(mru_list): # MRU lists are terminated with 0xFFFFFFFF. if entry == 0xFFFFFFFF: break value_text = u'Index: {} [MRU Value {:d}]'.format(nr + 1, entry) text_dict[value_text] = self.GetText(key, unicode(entry)) yield event.WinRegistryEvent(key.path, text_dict, timestamp=event_timestamp, source_append=': MRUx List') def Process(self, key=None, **kwargs): """Determine if we can process this registry key or not.""" if 'BagMRU' in key.path or 'Explorer\\StreamMRU' in key.path: return None return super(MRUListExPlugin, self).Process(key=key, **kwargs)
class BaseMRUListPlugin(interface.WindowsRegistryPlugin): """Class for common MRUList Windows Registry plugin functionality.""" _MRULIST_STRUCT = construct.Range(1, 500, construct.ULInt16(u'entry_letter')) _SOURCE_APPEND = u': MRU List' @abc.abstractmethod def _ParseMRUListEntryValue(self, parser_mediator, key, entry_index, entry_letter, **kwargs): """Parses the MRUList entry value. Args: parser_mediator: A parser mediator object (instance of ParserMediator). key: the Registry key (instance of dfwinreg.WinRegistryKey) that contains the MRUList value. entry_index: integer value representing the MRUList entry index. entry_letter: character value representing the entry. Returns: A string containing the value. """ def _ParseMRUListValue(self, key): """Parses the MRUList value in a given Registry key. Args: key: the Registry key (instance of dfwinreg.WinRegistryKey) that contains the MRUList value. Returns: A MRUList value generator, which returns the MRU index number and entry value. """ mru_list_value = key.GetValueByName(u'MRUList') # The key exists but does not contain a value named "MRUList". if not mru_list_value: return enumerate([]) try: mru_list = self._MRULIST_STRUCT.parse(mru_list_value.data) except construct.FieldError: logging.warning( u'[{0:s}] Unable to parse the MRU key: {1:s}'.format( self.NAME, key.path)) return enumerate([]) return enumerate(mru_list) def _ParseMRUListKey(self, parser_mediator, key, codepage=u'cp1252'): """Extract event objects from a MRUList Registry key. Args: parser_mediator: A parser mediator object (instance of ParserMediator). key: the Registry key (instance of dfwinreg.WinRegistryKey). codepage: Optional extended ASCII string codepage. """ values_dict = {} for entry_index, entry_letter in self._ParseMRUListValue(key): # TODO: detect if list ends prematurely. # MRU lists are terminated with \0 (0x0000). if entry_letter == 0: break entry_letter = chr(entry_letter) value_string = self._ParseMRUListEntryValue(parser_mediator, key, entry_index, entry_letter, codepage=codepage) value_text = u'Index: {0:d} [MRU Value {1:s}]'.format( entry_index + 1, entry_letter) values_dict[value_text] = value_string event_object = windows_events.WindowsRegistryEvent( key.last_written_time, key.path, values_dict, offset=key.offset, source_append=self._SOURCE_APPEND) parser_mediator.ProduceEvent(event_object)
class BagMRUPlugin(interface.KeyPlugin): """Class that defines a BagMRU Windows Registry plugin.""" NAME = 'winreg_bagmru' DESCRIPTION = u'Parser for BagMRU Registry data.' # TODO: remove REG_TYPE and use HKEY_CURRENT_USER instead. REG_TYPE = 'any' REG_KEYS = frozenset([ u'\\Software\\Microsoft\\Windows\\Shell\\BagMRU', u'\\Software\\Microsoft\\Windows\\ShellNoRoam\\BagMRU', (u'\\Local Settings\\Software\\Microsoft\\Windows\\' u'Shell\\BagMRU'), (u'\\Local Settings\\Software\\Microsoft\\Windows\\' u'ShellNoRoam\\BagMRU'), (u'\\Wow6432Node\\Local Settings\\Software\\' u'Microsoft\\Windows\\Shell\\BagMRU'), (u'\\Wow6432Node\\Local Settings\\Software\\' u'Microsoft\\Windows\\ShellNoRoam\\BagMRU') ]) URLS = [u'https://code.google.com/p/winreg-kb/wiki/MRUKeys'] _MRULISTEX_STRUCT = construct.Range(1, 500, construct.ULInt32('entry_number')) def _ParseMRUListExEntryValue(self, parser_context, key, entry_index, entry_number, text_dict, value_strings, parent_value_string, codepage='cp1252', **unused_kwargs): """Parses the MRUListEx entry value. Args: parser_context: A parser context object (instance of ParserContext). key: the Registry key (instance of winreg.WinRegKey) that contains the MRUListEx value. entry_index: integer value representing the MRUListEx entry index. entry_number: integer value representing the entry number. text_dict: text dictionary object to append textual strings. value_string: value string dictionary object to append value strings. parent_value_string: string containing the parent value string. """ value = key.GetValue(u'{0:d}'.format(entry_number)) value_string = u'' if value is None: logging.debug( u'[{0:s}] Missing MRUListEx entry value: {1:d} in key: {2:s}.'. format(self.name, entry_number, key.path)) elif not value.DataIsBinaryData(): logging.debug( (u'[{0:s}] Non-binary MRUListEx entry value: {1:d} in key: ' u'{2:s}.').format(self.name, entry_number, key.path)) elif value.data: shell_items_parser = shell_items.ShellItemsParser(key.path) shell_items_parser.Parse(parser_context, value.data, codepage=codepage) value_string = shell_items_parser.CopyToPath() if parent_value_string: value_string = u', '.join([parent_value_string, value_string]) value_strings[entry_number] = value_string value_string = u'Shell item list: [{0:s}]'.format(value_string) value_text = u'Index: {0:d} [MRU Value {1:d}]'.format( entry_index + 1, entry_number) text_dict[value_text] = value_string def _ParseMRUListExValue(self, key): """Parsed the MRUListEx value in a given Registry key. Args: key: the Registry key (instance of winreg.WinRegKey) that contains the MRUListEx value. Returns: A MRUListEx value generator, which returns the MRU index number and entry value. """ mru_list_value = key.GetValue('MRUListEx') if not mru_list_value: return enumerate([]) try: mru_list = self._MRULISTEX_STRUCT.parse(mru_list_value.data) except construct.FieldError: logging.warning( u'[{0:s}] Unable to parse the MRU key: {1:s}'.format( self.name, key.path)) return enumerate([]) return enumerate(mru_list) def _ParseSubKey(self, parser_context, key, parent_value_string, registry_type=None, codepage='cp1252'): """Extract event objects from a MRUListEx Registry key. Args: parser_context: A parser context object (instance of ParserContext). key: the Registry key (instance of winreg.WinRegKey). parent_value_string: string containing the parent value string. registry_type: Optional Registry type string. The default is None. codepage: Optional extended ASCII string codepage. The default is cp1252. """ text_dict = {} value_strings = {} for index, entry_number in self._ParseMRUListExValue(key): # TODO: detect if list ends prematurely. # MRU lists are terminated with 0xffffffff (-1). if entry_number == 0xffffffff: break self._ParseMRUListExEntryValue(parser_context, key, index, entry_number, text_dict, value_strings, parent_value_string, codepage=codepage) event_object = windows_events.WindowsRegistryEvent( key.last_written_timestamp, key.path, text_dict, offset=key.offset, registry_type=registry_type, urls=self.URLS, source_append=': BagMRU') parser_context.ProduceEvent(event_object, plugin_name=self.NAME) for index, entry_number in self._ParseMRUListExValue(key): # TODO: detect if list ends prematurely. # MRU lists are terminated with 0xffffffff (-1). if entry_number == 0xffffffff: break sub_key = key.GetSubkey(u'{0:d}'.format(entry_number)) if not sub_key: logging.debug( u'[{0:s}] Missing BagMRU sub key: {1:d} in key: {2:s}.'. format(self.name, key.path, entry_number)) continue value_string = value_strings.get(entry_number, u'') self._ParseSubKey(parser_context, sub_key, value_string, codepage=codepage) def GetEntries(self, parser_context, key=None, registry_type=None, codepage='cp1252', **unused_kwargs): """Extract event objects from a Registry key containing a MRUListEx value. Args: parser_context: A parser context object (instance of ParserContext). key: Optional Registry key (instance of winreg.WinRegKey). The default is None. registry_type: Optional Registry type string. The default is None. codepage: Optional extended ASCII string codepage. The default is cp1252. """ self._ParseSubKey(parser_context, key, u'', registry_type=registry_type, codepage=codepage)