Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract Windows event logs messages attributes #2910

Merged
merged 38 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
65e6522
Initial commit
roshanmaskey Sep 26, 2023
c28af94
Added security event in unit test.
roshanmaskey Sep 27, 2023
d753fff
Merge branch 'master' into add_feature_extraction_winevt
jkppr Sep 29, 2023
2d472c7
Updated the code as per feedback
roshanmaskey Oct 9, 2023
3dfd964
Fixed unit test
roshanmaskey Oct 9, 2023
282c329
Merge branch 'master' into add_feature_extraction_winevt
roshanmaskey Oct 9, 2023
40f119b
Merge branch 'master' into add_feature_extraction_winevt
jkppr Oct 19, 2023
77a7ab2
Update timesketch/lib/analyzers/feature.py
roshanmaskey Oct 26, 2023
822899d
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
2774108
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
b61afba
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
6985566
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
cdaf9f6
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
0c9d4b7
Update data/winevt_features.yaml
roshanmaskey Oct 26, 2023
16820c3
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
4223298
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
8409b15
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
ad9643a
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
4097ef5
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
f120d43
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
daa65ae
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
d04e4b5
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
b50cca3
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
467284f
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 26, 2023
24b822b
Update timesketch/lib/analyzers/feature_plugins/winevt_features.py
roshanmaskey Oct 27, 2023
91b0215
Merge branch 'google:master' into add_feature_extraction_winevt
roshanmaskey Oct 27, 2023
59af04f
Updated as per feedback2
roshanmaskey Oct 28, 2023
42add61
fixed linting
roshanmaskey Oct 28, 2023
9130894
fixed formatting issue
roshanmaskey Oct 28, 2023
a092c9a
Adding original feature_extractions analyzer as regex_features plugin
roshanmaskey Oct 30, 2023
d76da25
Adding unit tests for regex_features
roshanmaskey Oct 30, 2023
9351e54
Merge branch 'google:master' into add_feature_extraction_winevt
roshanmaskey Oct 30, 2023
c4f5de2
Merge branch 'master' into add_feature_extraction_winevt
jkppr Oct 30, 2023
69f2042
clean-up & renaming
jkppr Nov 2, 2023
0927308
linter
jkppr Nov 2, 2023
251b1ba
adjusting naming schema & logger
jkppr Nov 2, 2023
7fada3d
linter fix
jkppr Nov 2, 2023
5d56128
fix unittest
jkppr Nov 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
560 changes: 560 additions & 0 deletions data/winevt_features.yaml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions timesketch/lib/analyzers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from timesketch.lib.analyzers import chain
from timesketch.lib.analyzers import domain
from timesketch.lib.analyzers import expert_sessionizers
from timesketch.lib.analyzers import feature
from timesketch.lib.analyzers import feature_extraction
from timesketch.lib.analyzers import gcp_logging
from timesketch.lib.analyzers import geoip
Expand Down
128 changes: 128 additions & 0 deletions timesketch/lib/analyzers/feature.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Copyright 2023 Google Inc. All rights reserved.
#
# 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.
"""Main sketch analyzer for feature extraction."""

import logging
from typing import List, Optional, Dict

from timesketch.lib.analyzers import interface
from timesketch.lib.analyzers import manager
from timesketch.lib.analyzers.feature_plugins import manager as feature_manager

logger = logging.getLogger("timesketch.analyzers.feature")


class FeatureSketchPlugin(interface.BaseAnalyzer):
"""Main sketch analyzer for feature extraction.

This analyzer runs all the feature extractions within the feature_plugins directory.
"""

NAME = "feature_extraction_main"
DISPLAY_NAME = "Feature Extraction Sketch Analyzer"
DESCRIPTION = "This analyzer runs all the feature extractions plugins in the index."
roshanmaskey marked this conversation as resolved.
Show resolved Hide resolved

DEPENDENCIES = frozenset()

def __init__(
self,
index_name: str,
sketch_id: int,
timeline_id: Optional[int] = None,
**kwargs,
) -> None:
"""Initializes the sketch analyzer.

Args:
index_name (str): OpenSearch index name.
sketch_id (int): TimeSketch's sketch ID.
timeline_id (int): The ID of the timeline.
"""
self._plugin_name: str = kwargs.get("plugin_name")
self._feature_name: str = kwargs.get("feature_name")
self._feature_config: Dict = kwargs.get("feature_config")

super().__init__(
index_name=index_name, sketch_id=sketch_id, timeline_id=timeline_id
)

@property
def plugin_name(self) -> str:
return self._plugin_name

@plugin_name.setter
def plugin_name(self, value: str) -> None:
self._plugin_name = value

@property
def feature_name(self) -> str:
return self._feature_name

@feature_name.setter
def feature_name(self, value: str) -> None:
self._feature_name = value

@property
def feature_config(self) -> Dict:
return self._feature_config

@feature_config.setter
def feature_config(self, value: Dict) -> None:
self._feature_config = value

def run(self) -> str:
"""Entry point for the sketch analyzer.

Returns:
str: A summary of sketch analyzer result.
"""
try:
plugin_class = feature_manager.PluginManager.get_plugin(
self._plugin_name, self
)
if not plugin_class:
raise ValueError(
f"Plugin class for plugin name {self._plugin_name} does not exist"
)
roshanmaskey marked this conversation as resolved.
Show resolved Hide resolved

return plugin_class.run_plugin(self._feature_name, self._feature_config)
except ValueError as exception:
logger.error(str(exception))
return f"Error: {str(exception)}"

@staticmethod
def get_kwargs() -> List[Dict]:
"""Get kwargs for the analyzer.

Returns:
List[dict]: A list of dict containing plugin name, feature name and feature
config.
"""
feature_kwargs_list = []

plugin_classes = feature_manager.PluginManager.get_plugins(None)
for plugin in plugin_classes:
feature_list = plugin.get_kwargs()
if not feature_list:
logger.debug("No configuration for %s", plugin.NAME)
continue

for feature_config in feature_list:
feature_config["plugin_name"] = plugin.NAME.lower()
feature_kwargs_list.append(feature_config)

return feature_kwargs_list


manager.AnalysisManager.register_analyzer(FeatureSketchPlugin)
18 changes: 18 additions & 0 deletions timesketch/lib/analyzers/feature_plugins/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2023 Google Inc. All rights reserved.
#
# 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.
"""Imports for the feature extraction plugins."""

from timesketch.lib.analyzers.feature_plugins import winevt_features

# from timesketch.lib.analyzers.feature_plugins import regex_features
53 changes: 53 additions & 0 deletions timesketch/lib/analyzers/feature_plugins/interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright 2023 Google Inc. All rights reserved.
#
# 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.
"""This file contains an interface to feature extraction plugins."""

import abc
from typing import Optional


class BaseFeatureExtractionPlugin(object):
"""A base plugin for feature extraction.

This class serves as an interface for feature extraction plugins.
"""

NAME = "base_feature_extraction"
DISPLAY_NAME = "Base Feature Extraction"
DESCRIPTION = ""

def __init__(self, analyzer_object: Optional["FeatureSketchPlugin"] = None) -> None:
"""Initializes the base plugin.

Args:
analyzer_object (FeatureSketchPlugin): An object of class
FeatureSketchPlugin.
"""
super().__init__()
self.analyzer_object = analyzer_object

@abc.abstractmethod
def run_plugin(self, name: str, config: dict) -> str:
"""Main entry point to feature extraction plugins.

This method should be implemented by subclasses to perform feature extraction.

Args:
name (str): The name of the feature to extract.
config (dict): Configuration parameters for the feature extraction.

Returns:
str: A summary of the feature extraction results.
"""
raise NotImplementedError("Subclass must implement the run_plugin() method")
114 changes: 114 additions & 0 deletions timesketch/lib/analyzers/feature_plugins/manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Copyright 2023 Google Inc. All rights reserved.
#
# 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 feature extraction plugins manager object."""

import logging
from typing import List, Type


class PluginManager(object):
""" "A class that implements the plugins manager."""

_plugin_classes: dict = {}
logger = logging.getLogger(__name__)

@classmethod
def register_plugin(cls, plugin_class: Type["BaseFeatureExtractionPlugin"]) -> None:
"""Registers a plugin class.

Args:
plugin_class (Type[BaseFeatureExtractionPlugin]): A class object of a
plugin.

Raises:
KeyError: If the plugin_class is already registered.
"""
plugin_name = plugin_class.NAME.lower()
if plugin_name in cls._plugin_classes:
raise KeyError(f"Plugin class {plugin_class.NAME} is already registered.")

cls.logger.info("Registering plugin class %s", plugin_class.NAME)
cls._plugin_classes[plugin_name] = plugin_class

@classmethod
def register_plugins(
cls, plugin_classes: List[Type["BaseFeatureExtractionPlugin"]]
) -> None:
"""Registers multiple plugin classes.

Args:
plugin_classes (List[Type[BaseFeatureExtractionPlugin]]): A list of plugin
class objects.

Raises:
KeyError: If plugin classes are already registered.
"""
for plugin_class in plugin_classes:
cls.register_plugin(plugin_class=plugin_class)

@classmethod
def deregister_plugin(
cls, plugin_class: Type["BaseFeatureExtractionPlugin"]
) -> None:
"""Deregisters a plugin class.

Args:
plugin_class (Type[BaseFeatureExtractionPlugin]): A plugin class to be
deregistered.

Raises:
KeyError: If the plugin class is not registered.
"""
plugin_name = plugin_class.NAME.lower()
if plugin_name not in cls._plugin_classes:
raise KeyError(f"Plugin class {plugin_class.NAME} is not registered.")

cls.logger.info("Deregistering plugin class: %s", plugin_class.NAME)
del cls._plugin_classes[plugin_name]

@classmethod
def get_plugin(
cls, plugin_name: str, analyzer_object: "FeatureSketchPlugin"
) -> "BaseFeatureExtractionPlugin":
"""Returns plugin class.

Args:
plugin_name (str): The name of the plugin to retrieve.
analyzer_object (FeatureSketchPlugin): An instance of FeatureSketchPlugin.

Returns:
BaseFeatureExtractionPlugin: The plugin class object.
"""
for plugin_class in cls._plugin_classes.values():
if plugin_class.NAME.lower() == plugin_name:
return plugin_class(analyzer_object)

return None # Return None if plugin not found

@classmethod
def get_plugins(
cls, analyzer_object: "FeatureSketchPlugin"
) -> List["BaseFeatureExtractionPlugin"]:
"""Retrieves plugins classes.

Args:
analayzer_object (FeatureSketchPlugin): An instance of FeatureSketchPlugin.

Returns:
List[BaseFeatureExtractionPlugin]: A list of plugin class objects.
"""
return [
plugin_class(analyzer_object)
for plugin_class in cls._plugin_classes.values()
]
Loading
Loading