Skip to content

Commit

Permalink
Changes to Windows time zone preprocessor #2673 (#3734)
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimmetz authored Jun 19, 2021
1 parent 94bd908 commit 26742d5
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 15 deletions.
12 changes: 10 additions & 2 deletions plaso/cli/pinfo_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -862,10 +862,18 @@ def _PrintSourceConfiguration(

table_view = views.ViewsFactory.GetTableView(
self._views_format_type,
column_names=['Name', ''], title=title)
column_names=['Name', 'Offset from UTC'], title=title)

for time_zone in system_configuration.available_time_zones:
table_view.AddRow([time_zone.name, ''])
hours_from_utc, minutes_from_utc = divmod(time_zone.offset, 60)
if hours_from_utc < 0:
sign = '+'
hours_from_utc *= -1
else:
sign = '-'
time_zone_offset = '{0:s}{1:02d}:{2:02d}'.format(
sign, hours_from_utc, minutes_from_utc)
table_view.AddRow([time_zone.name, time_zone_offset])

table_view.Write(self._output_writer)

Expand Down
5 changes: 4 additions & 1 deletion plaso/containers/artifacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,18 +463,21 @@ class TimeZoneArtifact(ArtifactAttributeContainer):
Attributes:
name (str): name describing the time zone for example Greenwich Standard
Time.
offset (int): time zone offset in number of minutes from UTC.
"""
CONTAINER_TYPE = 'time_zone'

def __init__(self, name=None):
def __init__(self, name=None, offset=None):
"""Initializes a time zone artifact.
Args:
name (Optional[str]): name describing the time zone for example Greenwich
Standard Time.
offset (Optional[int]): time zone offset in number of minutes from UTC.
"""
super(TimeZoneArtifact, self).__init__()
self.name = name
self.offset = offset


class UserAccountArtifact(ArtifactAttributeContainer):
Expand Down
10 changes: 8 additions & 2 deletions plaso/parsers/winreg_plugins/appcompatcache.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
"""Windows Registry plugin to parse the Application Compatibility Cache key."""

import os

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

Expand All @@ -9,9 +11,9 @@
from plaso.containers import events
from plaso.containers import time_events
from plaso.lib import definitions
from plaso.lib import dtfabric_helper
from plaso.lib import errors
from plaso.parsers import winreg_parser
from plaso.parsers.winreg_plugins import dtfabric_plugin
from plaso.parsers.winreg_plugins import interface


Expand Down Expand Up @@ -65,7 +67,7 @@ def __init__(self):


class AppCompatCacheWindowsRegistryPlugin(
dtfabric_plugin.DtFabricBaseWindowsRegistryPlugin):
interface.WindowsRegistryPlugin, dtfabric_helper.DtFabricHelper):
"""Application Compatibility Cache data Windows Registry plugin."""

NAME = 'appcompatcache'
Expand All @@ -81,6 +83,10 @@ class AppCompatCacheWindowsRegistryPlugin(

_DEFINITION_FILE = 'appcompatcache.yaml'

# Preserve the absolute path value of __file__ in case it is changed
# at run-time.
_DEFINITION_FILES_PATH = os.path.dirname(__file__)

_FORMAT_TYPE_2000 = 1
_FORMAT_TYPE_XP = 2
_FORMAT_TYPE_2003 = 3
Expand Down
10 changes: 8 additions & 2 deletions plaso/parsers/winreg_plugins/bagmru.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# -*- coding: utf-8 -*-
"""This file contains BagMRU Windows Registry plugins (shellbags)."""

import os

from dtfabric.runtime import data_maps as dtfabric_data_maps

from plaso.containers import events
from plaso.containers import time_events
from plaso.lib import definitions
from plaso.lib import dtfabric_helper
from plaso.lib import errors
from plaso.parsers.shared import shell_items
from plaso.parsers import winreg_parser
from plaso.parsers.winreg_plugins import dtfabric_plugin
from plaso.parsers.winreg_plugins import interface


Expand All @@ -31,7 +33,7 @@ def __init__(self):


class BagMRUWindowsRegistryPlugin(
dtfabric_plugin.DtFabricBaseWindowsRegistryPlugin):
interface.WindowsRegistryPlugin, dtfabric_helper.DtFabricHelper):
"""Class that defines a BagMRU Windows Registry plugin."""

NAME = 'bagmru'
Expand All @@ -58,6 +60,10 @@ class BagMRUWindowsRegistryPlugin(

_DEFINITION_FILE = 'mru.yaml'

# Preserve the absolute path value of __file__ in case it is changed
# at run-time.
_DEFINITION_FILES_PATH = os.path.dirname(__file__)

def _ParseMRUListExEntryValue(
self, parser_mediator, registry_key, entry_number, parent_path_segments,
codepage='cp1252'):
Expand Down
10 changes: 8 additions & 2 deletions plaso/parsers/winreg_plugins/bam.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# -*- coding: utf-8 -*-
"""Windows Registry plugin to parse the Background Activity Moderator keys."""

import os

from dfdatetime import filetime as dfdatetime_filetime

from plaso.containers import events
from plaso.containers import time_events
from plaso.lib import definitions
from plaso.lib import dtfabric_helper
from plaso.lib import errors
from plaso.parsers import winreg_parser
from plaso.parsers.winreg_plugins import interface
from plaso.parsers.winreg_plugins import dtfabric_plugin


class BackgroundActivityModeratorEventData(events.EventData):
Expand All @@ -32,7 +34,7 @@ def __init__(self):


class BackgroundActivityModeratorWindowsRegistryPlugin(
dtfabric_plugin.DtFabricBaseWindowsRegistryPlugin):
interface.WindowsRegistryPlugin, dtfabric_helper.DtFabricHelper):
"""Background Activity Moderator data Windows Registry plugin."""

NAME = 'bam'
Expand All @@ -48,6 +50,10 @@ class BackgroundActivityModeratorWindowsRegistryPlugin(

_DEFINITION_FILE = 'filetime.yaml'

# Preserve the absolute path value of __file__ in case it is changed
# at run-time.
_DEFINITION_FILES_PATH = os.path.dirname(__file__)

def _ParseValue(self, registry_value):
"""Parses the registry value.
Expand Down
9 changes: 7 additions & 2 deletions plaso/parsers/winreg_plugins/mrulist.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@
"""

import abc
import os

from dtfabric.runtime import data_maps as dtfabric_data_maps

from plaso.containers import events
from plaso.containers import time_events
from plaso.lib import definitions
from plaso.lib import dtfabric_helper
from plaso.lib import errors
from plaso.parsers import logger
from plaso.parsers import winreg_parser
from plaso.parsers.shared import shell_items
from plaso.parsers.winreg_plugins import dtfabric_plugin
from plaso.parsers.winreg_plugins import interface


Expand Down Expand Up @@ -69,11 +70,15 @@ def Match(self, registry_key):


class BaseMRUListWindowsRegistryPlugin(
dtfabric_plugin.DtFabricBaseWindowsRegistryPlugin):
interface.WindowsRegistryPlugin, dtfabric_helper.DtFabricHelper):
"""Class for common MRUList Windows Registry plugin functionality."""

_DEFINITION_FILE = 'mru.yaml'

# Preserve the absolute path value of __file__ in case it is changed
# at run-time.
_DEFINITION_FILES_PATH = os.path.dirname(__file__)

@abc.abstractmethod
def _ParseMRUListEntryValue(
self, parser_mediator, registry_key, entry_index, entry_letter, **kwargs):
Expand Down
9 changes: 7 additions & 2 deletions plaso/parsers/winreg_plugins/mrulistex.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@
"""

import abc
import os

from dtfabric.runtime import data_maps as dtfabric_data_maps

from plaso.containers import events
from plaso.containers import time_events
from plaso.lib import errors
from plaso.lib import dtfabric_helper
from plaso.lib import definitions
from plaso.parsers import logger
from plaso.parsers import winreg_parser
from plaso.parsers.shared import shell_items
from plaso.parsers.winreg_plugins import dtfabric_plugin
from plaso.parsers.winreg_plugins import interface


Expand Down Expand Up @@ -79,11 +80,15 @@ def Match(self, registry_key):


class BaseMRUListExWindowsRegistryPlugin(
dtfabric_plugin.DtFabricBaseWindowsRegistryPlugin):
interface.WindowsRegistryPlugin, dtfabric_helper.DtFabricHelper):
"""Class for common MRUListEx Windows Registry plugin functionality."""

_DEFINITION_FILE = 'mru.yaml'

# Preserve the absolute path value of __file__ in case it is changed
# at run-time.
_DEFINITION_FILES_PATH = os.path.dirname(__file__)

@abc.abstractmethod
def _ParseMRUListExEntryValue(
self, parser_mediator, registry_key, entry_index, entry_number, **kwargs):
Expand Down
60 changes: 60 additions & 0 deletions plaso/preprocessors/time_zone_information.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: time_zone_information
type: format
description: Time Zone Information (TZI) format
---
name: uint16
type: integer
attributes:
format: unsigned
size: 2
units: bytes
---
name: int32
type: integer
attributes:
format: signed
size: 4
units: bytes
---
name: system_time
type: structure
members:
- name: year
data_type: uint16
- name: month
data_type: uint16
- name: weekday
data_type: uint16
- name: day_of_month
data_type: uint16
- name: hours
data_type: uint16
- name: minutes
data_type: uint16
- name: seconds
data_type: uint16
- name: milliseconds
data_type: uint16
---
name: tzi_record
type: structure
description: Time Zone Information (TZI)
aliases: ['TIME_ZONE_INFORMATION', '_REG_TZI_FORMAT']
attributes:
byte_order: little-endian
members:
- name: bias
aliases: ['Bias']
data_type: int32
- name: standard_bias
aliases: ['StandardBias']
data_type: int32
- name: daylight_bias
aliases: ['DaylightBias']
data_type: int32
- name: standard_date
aliases: ['StandardDate']
data_type: system_time
- name: daylight_date
aliases: ['DaylightDate']
data_type: system_time
53 changes: 51 additions & 2 deletions plaso/preprocessors/windows.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# -*- coding: utf-8 -*-
"""This file contains preprocessors for Windows."""

import os

from plaso.containers import artifacts
from plaso.lib import dtfabric_helper
from plaso.lib import errors
from plaso.preprocessors import interface
from plaso.preprocessors import logger
Expand Down Expand Up @@ -195,11 +198,18 @@ def Collect(self, mediator):


class WindowsAvailableTimeZonesPlugin(
interface.WindowsRegistryKeyArtifactPreprocessorPlugin):
interface.WindowsRegistryKeyArtifactPreprocessorPlugin,
dtfabric_helper.DtFabricHelper):
"""The Windows available time zones plugin."""

ARTIFACT_DEFINITION_NAME = 'WindowsAvailableTimeZones'

_DEFINITION_FILE = 'time_zone_information.yaml'

# Preserve the absolute path value of __file__ in case it is changed
# at run-time.
_DEFINITION_FILES_PATH = os.path.dirname(__file__)

def _ParseKey(self, mediator, registry_key, value_name):
"""Parses a Windows Registry key for a preprocessing attribute.
Expand All @@ -212,14 +222,53 @@ def _ParseKey(self, mediator, registry_key, value_name):
Raises:
errors.PreProcessFail: if the preprocessing fails.
"""
tzi_value = registry_key.GetValueByName('TZI')
if not tzi_value:
mediator.ProducePreprocessingWarning(
self.ARTIFACT_DEFINITION_NAME,
'TZI value missing from Windows Registry key: {0:s}'.format(
registry_key.key_path))
return

time_zone_artifact = artifacts.TimeZoneArtifact(name=registry_key.name)
try:
self._ParseTZIValue(tzi_value.data, time_zone_artifact)

except (ValueError, errors.ParseError) as exception:
mediator.ProducePreprocessingWarning(
self.ARTIFACT_DEFINITION_NAME,
'Unable to parse TZI record value in Windows Registry key: {0:s} '
'with error: {2!s}'.format(
registry_key.key_path, exception))
return

try:
mediator.knowledge_base.AddAvailableTimeZone(time_zone_artifact)
except KeyError:
mediator.ProducePreprocessingWarning(
self.ARTIFACT_DEFINITION_NAME,
'Unable to set time zone in knowledge base.')
'Unable to set add time zone: {0:s} to knowledge base.'.format(
registry_key.name))

def _ParseTZIValue(self, value_data, time_zone_artifact):
"""Parses the time zone information (TZI) value data.
Args:
value_data (bytes): time zone information (TZI) value data.
time_zone_artifact (TimeZoneArtifact): time zone artifact.
Raises:
ParseError: if the value data could not be parsed.
"""
data_type_map = self._GetDataTypeMap('tzi_record')

tzi_record = self._ReadStructureFromByteStream(
value_data, 0, data_type_map)

if tzi_record.standard_bias:
time_zone_artifact.offset = tzi_record.standard_bias
else:
time_zone_artifact.offset = tzi_record.bias


class WindowsCodepagePlugin(
Expand Down

0 comments on commit 26742d5

Please sign in to comment.