264 lines
9.7 KiB
Python
264 lines
9.7 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
# Copyright 2012 The Plaso Project Authors.
|
|
# Please see the AUTHORS file for details on individual authors.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""The Windows Registry plugin objects interface."""
|
|
|
|
import abc
|
|
import logging
|
|
|
|
from plaso.parsers import plugins
|
|
from plaso.winreg import path_expander as winreg_path_expander
|
|
|
|
|
|
class RegistryPlugin(plugins.BasePlugin):
|
|
"""Class that defines the Windows Registry plugin object interface."""
|
|
|
|
__abstract = True
|
|
|
|
NAME = 'winreg'
|
|
DESCRIPTION = u'Parser for Registry data.'
|
|
|
|
# Indicate the type of hive this plugin belongs to (eg. NTUSER, SOFTWARE).
|
|
REG_TYPE = 'any'
|
|
|
|
# URLS should contain a list of URLs with additional information about this
|
|
# key or value.
|
|
URLS = []
|
|
|
|
# WEIGHT is a simple integer value representing the priority of this plugin.
|
|
# The weight can be used by some parser implementation to prioritize the
|
|
# order in which plugins are run against the Windows Registry keys.
|
|
# By default no the Windows Registry plugin should overwrite this value,
|
|
# it should only be defined in interfaces extending the base class, providing
|
|
# higher level of prioritization to Windows Registry plugins.
|
|
WEIGHT = 3
|
|
|
|
def __init__(self, reg_cache=None):
|
|
"""Initializes Windows Registry plugin object.
|
|
|
|
Args:
|
|
reg_cache: Optional Windows Registry objects cache (instance of
|
|
WinRegistryCache). The default is None.
|
|
"""
|
|
super(RegistryPlugin, self).__init__()
|
|
# TODO: Clean this up, this value is stored but not used.
|
|
self._reg_cache = reg_cache
|
|
|
|
@abc.abstractmethod
|
|
def GetEntries(
|
|
self, parser_context, file_entry=None, key=None, registry_type=None,
|
|
parser_chain=None, codepage='cp1252', **kwargs):
|
|
"""Extracts event objects from the Windows Registry key.
|
|
|
|
Args:
|
|
parser_context: A parser context object (instance of ParserContext).
|
|
file_entry: optional file entry object (instance of dfvfs.FileEntry).
|
|
The default is None.
|
|
key: Optional Registry key (instance of winreg.WinRegKey).
|
|
The default is None.
|
|
registry_type: Optional Registry type. The default is None.
|
|
parser_chain: Optional string containing the parsing chain up to this
|
|
point. The default is None.
|
|
codepage: Optional extended ASCII string codepage. The default is cp1252.
|
|
"""
|
|
|
|
def Process(self, parser_context, parser_chain=None, key=None, **kwargs):
|
|
"""Processes a Windows Registry key or value.
|
|
|
|
Args:
|
|
parser_context: A parser context object (instance of ParserContext).
|
|
key: Optional Registry key (instance of winreg.WinRegKey).
|
|
The default is None.
|
|
|
|
Raises:
|
|
ValueError: If the key value is not set.
|
|
"""
|
|
if key is None:
|
|
raise ValueError(u'Key is not set.')
|
|
|
|
del kwargs['file_entry']
|
|
del kwargs['registry_type']
|
|
del kwargs['codepage']
|
|
|
|
# This will raise if unhandled keyword arguments are passed.
|
|
super(RegistryPlugin, self).Process(parser_context, parser_chain, **kwargs)
|
|
|
|
|
|
class KeyPlugin(RegistryPlugin):
|
|
"""Class that defines the Windows Registry key-based plugin interface."""
|
|
|
|
__abstract = True
|
|
|
|
# A list of all the Windows Registry key paths this plugins supports.
|
|
# Each of these key paths can contain a path that needs to be expanded,
|
|
# such as {current_control_set}, etc.
|
|
REG_KEYS = []
|
|
|
|
WEIGHT = 1
|
|
|
|
def __init__(self, reg_cache=None):
|
|
"""Initializes key-based Windows Registry plugin object.
|
|
|
|
Args:
|
|
reg_cache: Optional Windows Registry objects cache (instance of
|
|
WinRegistryCache). The default is None.
|
|
"""
|
|
super(KeyPlugin, self).__init__(reg_cache=reg_cache)
|
|
self._path_expander = winreg_path_expander.WinRegistryKeyPathExpander(
|
|
reg_cache=reg_cache)
|
|
self.expanded_keys = None
|
|
|
|
def ExpandKeys(self, parser_context):
|
|
"""Builds a list of expanded keys this plugin supports.
|
|
|
|
Args:
|
|
parser_context: A parser context object (instance of ParserContext).
|
|
"""
|
|
self.expanded_keys = []
|
|
for registry_key in self.REG_KEYS:
|
|
expanded_key = u''
|
|
try:
|
|
# TODO: deprecate direct use of pre_obj.
|
|
expanded_key = self._path_expander.ExpandPath(
|
|
registry_key, pre_obj=parser_context.knowledge_base.pre_obj)
|
|
except KeyError as exception:
|
|
logging.debug((
|
|
u'Unable to expand Registry key {0:s} for plugin {1:s} with '
|
|
u'error: {2:s}').format(registry_key, self.NAME, exception))
|
|
continue
|
|
|
|
if not expanded_key:
|
|
continue
|
|
|
|
self.expanded_keys.append(expanded_key)
|
|
|
|
# Special case of Wow6432 Windows Registry redirection.
|
|
# URL: http://msdn.microsoft.com/en-us/library/windows/desktop/\
|
|
# ms724072%28v=vs.85%29.aspx
|
|
if expanded_key.startswith('\\Software'):
|
|
_, first, second = expanded_key.partition('\\Software')
|
|
self.expanded_keys.append(u'{0:s}\\Wow6432Node{1:s}'.format(
|
|
first, second))
|
|
|
|
if self.REG_TYPE == 'SOFTWARE' or self.REG_TYPE == 'any':
|
|
self.expanded_keys.append(u'\\Wow6432Node{0:s}'.format(expanded_key))
|
|
|
|
@abc.abstractmethod
|
|
def GetEntries(
|
|
self, parser_context, file_entry=None, key=None, registry_type=None,
|
|
codepage='cp1252', parser_chain=None, **kwargs):
|
|
"""Extracts event objects from the Windows Registry key.
|
|
|
|
Args:
|
|
parser_context: A parser context object (instance of ParserContext).
|
|
file_entry: optional file entry object (instance of dfvfs.FileEntry).
|
|
The default is None.
|
|
key: Optional Registry key (instance of winreg.WinRegKey).
|
|
The default is None.
|
|
registry_type: Optional Registry type. The default is None.
|
|
codepage: Optional extended ASCII string codepage. The default is cp1252.
|
|
"""
|
|
|
|
def Process(
|
|
self, parser_context, file_entry=None, key=None, registry_type=None,
|
|
codepage='cp1252', parser_chain=None, **kwargs):
|
|
"""Processes a Windows Registry key.
|
|
|
|
Args:
|
|
parser_context: A parser context object (instance of ParserContext).
|
|
file_entry: Optional file entry object (instance of dfvfs.FileEntry).
|
|
The default is None.
|
|
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.
|
|
parser_chain: Optional string containing the parsing chain up to this
|
|
point. The default is None.
|
|
"""
|
|
if self.expanded_keys is None:
|
|
self.ExpandKeys(parser_context)
|
|
|
|
parser_chain = self._BuildParserChain(parser_chain)
|
|
|
|
super(KeyPlugin, self).Process(
|
|
parser_context, file_entry=file_entry, key=key,
|
|
registry_type=registry_type, codepage=codepage,
|
|
parser_chain=parser_chain, **kwargs)
|
|
|
|
if key and key.path in self.expanded_keys:
|
|
self.GetEntries(
|
|
parser_context, file_entry=file_entry, key=key,
|
|
registry_type=registry_type, codepage=codepage,
|
|
parser_chain=parser_chain, **kwargs)
|
|
|
|
|
|
class ValuePlugin(RegistryPlugin):
|
|
"""Class that defines the Windows Registry value-based plugin interface."""
|
|
|
|
__abstract = True
|
|
|
|
# REG_VALUES should be defined as a frozenset.
|
|
REG_VALUES = frozenset()
|
|
|
|
WEIGHT = 2
|
|
|
|
@abc.abstractmethod
|
|
def GetEntries(
|
|
self, parser_context, file_entry=None, key=None, registry_type=None,
|
|
parser_chain=None, codepage='cp1252', **kwargs):
|
|
"""Extracts event objects from the Windows Registry key.
|
|
|
|
Args:
|
|
parser_context: A parser context object (instance of ParserContext).
|
|
file_entry: optional file entry object (instance of dfvfs.FileEntry).
|
|
The default is None.
|
|
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.
|
|
"""
|
|
|
|
def Process(
|
|
self, parser_context, file_entry=None, key=None, registry_type=None,
|
|
parser_chain=None, codepage='cp1252', **kwargs):
|
|
"""Processes a Windows Registry value.
|
|
|
|
Args:
|
|
parser_context: A parser context object (instance of ParserContext).
|
|
file_entry: optional file entry object (instance of dfvfs.FileEntry).
|
|
The default is None.
|
|
key: Optional Registry key (instance of winreg.WinRegKey).
|
|
The default is None.
|
|
registry_type: Optional Registry type string. The default is None.
|
|
parser_chain: Optional string containing the parsing chain up to this
|
|
point. The default is None.
|
|
codepage: Optional extended ASCII string codepage. The default is cp1252.
|
|
"""
|
|
|
|
parser_chain = self._BuildParserChain(parser_chain)
|
|
|
|
super(ValuePlugin, self).Process(
|
|
parser_context, file_entry=file_entry, key=key,
|
|
registry_type=registry_type, codepage=codepage, **kwargs)
|
|
|
|
values = frozenset([val.name for val in key.GetValues()])
|
|
if self.REG_VALUES.issubset(values):
|
|
self.GetEntries(
|
|
parser_context, file_entry=file_entry, key=key,
|
|
registry_type=registry_type, parser_chain=parser_chain,
|
|
codepage=codepage, **kwargs)
|