Linux: pslist: Add the boottime plugin

This commit is contained in:
Gustavo Moreira
2024-10-18 12:59:23 +11:00
parent 69512dc991
commit d25df2357a
2 changed files with 109 additions and 2 deletions
@@ -0,0 +1,98 @@
# This file is Copyright 2024 Volatility Foundation and licensed under the Volatility Software License 1.0
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
#
import datetime
from typing import List, Tuple, Iterable
from volatility3.framework import interfaces, renderers
from volatility3.framework.configuration import requirements
from volatility3.plugins import timeliner
from volatility3.plugins.linux import pslist
class Boottime(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Shows the time the system was started"""
_required_framework_version = (2, 11, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.ModuleRequirement(
name="kernel",
description="Linux kernel",
architectures=["Intel32", "Intel64"],
),
requirements.PluginRequirement(
name="pslist", plugin=pslist.PsList, version=(2, 3, 0)
),
]
@classmethod
def get_time_namespaces_bootime(
cls,
context: interfaces.context.ContextInterface,
vmlinux_module_name: str,
) -> Iterable[Tuple[int, int, int, str, datetime.datetime]]:
"""Enumerates tasks' boot times based on their time namespaces.
Args:
context: The context to retrieve required elements (layers, symbol tables) from
vmlinux_module_name: The name of the kernel module on which to operate
pids: Pid list
unique: Filter unique time namespaces
Yields:
A tuple with the fields to show in the plugin output.
"""
time_namespace_ids = set()
for task in pslist.PsList.list_tasks(context, vmlinux_module_name):
time_namespace_id = task.get_time_namespace_id()
# If it cannot get the time namespace i.e. kernels < 5.6, this still works
# using None to just get the first tasks
if time_namespace_id in time_namespace_ids:
continue
time_namespace_ids.add(time_namespace_id)
boottime = task.get_boottime(root_time_namespace=False)
fields = (
time_namespace_id,
boottime,
)
yield fields
def _generator(self):
for (
time_namespace_id,
boottime,
) in self.get_time_namespaces_bootime(
self.context,
self.config["kernel"],
):
fields = [
time_namespace_id or renderers.NotAvailableValue(),
boottime,
]
yield 0, fields
def generate_timeline(self):
for (
time_namespace_id,
boottime,
) in self.get_time_namespaces_bootime(
self.context,
self.config["kernel"],
):
description = f"System boot time for time namespace {time_namespace_id}"
yield description, timeliner.TimeLinerType.BOOTTIME, boottime
def run(self):
columns = [
("TIME NS", int),
("Boot Time", datetime.datetime),
]
return renderers.TreeGrid(columns, self._generator())
+11 -2
View File
@@ -23,6 +23,7 @@ class TimeLinerType(enum.IntEnum):
MODIFIED = 2
ACCESSED = 3
CHANGED = 4
BOOTTIME = 5
class TimeLinerInterface(metaclass=abc.ABCMeta):
@@ -171,6 +172,10 @@ class Timeliner(interfaces.plugins.PluginInterface):
TimeLinerType.CHANGED,
renderers.NotApplicableValue(),
),
times.get(
TimeLinerType.BOOTTIME,
renderers.NotApplicableValue(),
),
],
)
)
@@ -178,11 +183,11 @@ class Timeliner(interfaces.plugins.PluginInterface):
# Write each entry because the body file doesn't need to be sorted
if fp:
times = self.timeline[(plugin_name, item)]
# Body format is: MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime
# Body format is: MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime|boottime
if self._any_time_present(times):
fp.write(
"|{} - {}|0|0|0|0|0|{}|{}|{}|{}\n".format(
"|{} - {}|0|0|0|0|0|{}|{}|{}|{}|{}\n".format(
plugin_name,
self._sanitize_body_format(item),
self._text_format(
@@ -197,6 +202,9 @@ class Timeliner(interfaces.plugins.PluginInterface):
self._text_format(
times.get(TimeLinerType.CREATED, "0")
),
self._text_format(
times.get(TimeLinerType.BOOTTIME, "0")
),
)
)
except Exception as e:
@@ -320,6 +328,7 @@ class Timeliner(interfaces.plugins.PluginInterface):
("Modified Date", datetime.datetime),
("Accessed Date", datetime.datetime),
("Changed Date", datetime.datetime),
("Boot Date", datetime.datetime),
],
generator=self._generator(plugins_to_run),
)