Skip to content

Commit

Permalink
Merge with 'develop', resolving conflicts and undoing changes volatil…
Browse files Browse the repository at this point in the history
…ityfoundation#1271 for the list_sockets class_method
  • Loading branch information
gcmoreira committed Oct 4, 2024
1 parent 32eaeeb commit ddd8de5
Show file tree
Hide file tree
Showing 22 changed files with 2,080 additions and 130 deletions.
3 changes: 2 additions & 1 deletion volatility3/framework/constants/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,5 @@ def __getattr__(name):
]:
warnings.warn(f"{name} is deprecated", FutureWarning)
return globals()[f"{deprecated_tag}{name}"]
return None

return getattr(__import__(__name__), name)
5 changes: 2 additions & 3 deletions volatility3/framework/interfaces/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,8 +494,7 @@ def unsatisfied(
"""Validates the instance requirement based upon its
`instance_type`."""
config_path = path_join(config_path, self.name)

value = self.config_value(context, config_path, None)
value = self.config_value(context, config_path, self.default)
if not isinstance(value, self.instance_type):
vollog.log(
constants.LOGLEVEL_V,
Expand Down Expand Up @@ -536,7 +535,7 @@ def unsatisfied(
"""Checks to see if a class can be recovered."""
config_path = path_join(config_path, self.name)

value = self.config_value(context, config_path, None)
value = self.config_value(context, config_path, self.default)
self._cls = None
if value is not None and isinstance(value, str):
if "." in value:
Expand Down
35 changes: 21 additions & 14 deletions volatility3/framework/plugins/linux/check_creds.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
#

import logging

from volatility3.framework import interfaces, renderers
from volatility3.framework.renderers import format_hints
from volatility3.framework.configuration import requirements
from volatility3.plugins.linux import pslist

vollog = logging.getLogger(__name__)


class Check_creds(interfaces.plugins.PluginInterface):
"""Checks if any processes are sharing credential structures"""

_required_framework_version = (2, 0, 0)

_version = (2, 0, 0)

@classmethod
def get_requirements(cls):
return [
Expand Down Expand Up @@ -46,20 +45,28 @@ def _generator(self):
tasks = pslist.PsList.list_tasks(self.context, vmlinux.name)

for task in tasks:
cred_addr = task.cred.dereference().vol.offset
task_cred_ptr = task.cred
if not (task_cred_ptr and task_cred_ptr.is_readable()):
continue

if cred_addr not in creds:
creds[cred_addr] = []
cred_addr = task_cred_ptr.dereference().vol.offset

creds.setdefault(cred_addr, [])
creds[cred_addr].append(task.pid)

for _, pids in creds.items():
for cred_addr, pids in creds.items():
if len(pids) > 1:
pid_str = ""
for pid in pids:
pid_str = pid_str + f"{pid:d}, "
pid_str = pid_str[:-2]
yield (0, [str(pid_str)])
pid_str = ", ".join([str(pid) for pid in pids])

fields = [
format_hints.Hex(cred_addr),
pid_str,
]
yield (0, fields)

def run(self):
return renderers.TreeGrid([("PIDs", str)], self._generator())
headers = [
("CredVAddr", format_hints.Hex),
("PIDs", str),
]
return renderers.TreeGrid(headers, self._generator())
14 changes: 4 additions & 10 deletions volatility3/framework/plugins/linux/malfind.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import List
import logging
from volatility3.framework import constants, interfaces
from volatility3.framework import renderers
from volatility3.framework import renderers, symbols
from volatility3.framework.configuration import requirements
from volatility3.framework.objects import utility
from volatility3.framework.renderers import format_hints
Expand Down Expand Up @@ -63,15 +63,9 @@ def _list_injections(self, task):
def _generator(self, tasks):
# determine if we're on a 32 or 64 bit kernel
vmlinux = self.context.modules[self.config["kernel"]]
if (
self.context.symbol_space.get_type(
vmlinux.symbol_table_name + constants.BANG + "pointer"
).size
== 4
):
is_32bit_arch = True
else:
is_32bit_arch = False
is_32bit_arch = not symbols.symbol_table_is_64bit(
self.context, vmlinux.symbol_table_name
)

for task in tasks:
process_name = utility.array_to_string(task.comm)
Expand Down
15 changes: 6 additions & 9 deletions volatility3/framework/plugins/linux/pidhashtable.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class PIDHashTable(plugins.PluginInterface):

_required_framework_version = (2, 0, 0)

_version = (1, 0, 0)
_version = (1, 0, 1)

@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
Expand All @@ -45,9 +45,7 @@ def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]
]

def _is_valid_task(self, task) -> bool:
vmlinux = self.context.modules[self.config["kernel"]]
vmlinux_layer = self.context.layers[vmlinux.layer_name]
return bool(task and task.pid > 0 and vmlinux_layer.is_valid(task.parent))
return bool(task and task.pid > 0 and task.parent.is_readable())

def _get_pidtype_pid(self):
vmlinux = self.context.modules[self.config["kernel"]]
Expand Down Expand Up @@ -96,7 +94,7 @@ def _walk_upid(self, seen_upids, upid):
seen_upids.add(upid.vol.offset)

pid_chain = upid.pid_chain
if not (pid_chain and vmlinux_layer.is_valid(pid_chain.vol.offset)):
if not (pid_chain.next and pid_chain.next.is_readable()):
break

upid = linux.LinuxUtilities.container_of(
Expand All @@ -105,7 +103,6 @@ def _walk_upid(self, seen_upids, upid):

def _get_upids(self):
vmlinux = self.context.modules[self.config["kernel"]]
vmlinux_layer = self.context.layers[vmlinux.layer_name]

# 2.6.24 <= kernels < 4.15
pidhash = self._get_pidhash_array()
Expand All @@ -115,7 +112,7 @@ def _get_upids(self):
# each entry in the hlist is a upid which is wrapped in a pid
ent = hlist.first

while ent and vmlinux_layer.is_valid(ent.vol.offset):
while ent and ent.is_readable():
# upid->pid_chain exists 2.6.24 <= kernel < 4.15
upid = linux.LinuxUtilities.container_of(
ent.vol.offset, "upid", "pid_chain", vmlinux
Expand Down Expand Up @@ -143,7 +140,7 @@ def _pid_hash_implementation(self):
continue

pid_tasks_0 = pid.tasks[pidtype_pid].first
if not pid_tasks_0:
if not (pid_tasks_0 and pid_tasks_0.is_readable()):
continue

task = vmlinux.object(
Expand All @@ -160,7 +157,7 @@ def _task_for_radix_pid_node(self, nodep):
pidtype_pid = self._get_pidtype_pid()

pid_tasks_0 = pid.tasks[pidtype_pid].first
if not pid_tasks_0:
if not (pid_tasks_0 and pid_tasks_0.is_readable()):
return None

task_struct_type = vmlinux.get_type("task_struct")
Expand Down
10 changes: 7 additions & 3 deletions volatility3/framework/plugins/linux/sockstat.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class SockHandlers(interfaces.configuration.VersionableInterface):

_required_framework_version = (2, 0, 0)

_version = (1, 0, 1)
_version = (3, 0, 0)

def __init__(self, vmlinux, task, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand Down Expand Up @@ -439,7 +439,7 @@ class Sockstat(plugins.PluginInterface):

_required_framework_version = (2, 0, 0)

_version = (2, 0, 0)
_version = (3, 0, 0)

@classmethod
def get_requirements(cls):
Expand All @@ -450,7 +450,7 @@ def get_requirements(cls):
architectures=["Intel32", "Intel64"],
),
requirements.VersionRequirement(
name="SockHandlers", component=SockHandlers, version=(1, 0, 0)
name="SockHandlers", component=SockHandlers, version=(3, 0, 0)
),
requirements.PluginRequirement(
name="lsof", plugin=lsof.Lsof, version=(2, 0, 0)
Expand Down Expand Up @@ -608,6 +608,8 @@ def _generator(self, pids: List[int], netns_id_arg: int, symbol_table: str):
if netns_id_arg and netns_id_arg != netns_id:
continue

task_comm = utility.array_to_string(task.comm)

sock, sock_stat, extended = sock_fields
sock_stat, protocol = self._format_fields(sock_stat, protocol)

Expand All @@ -619,6 +621,7 @@ def _generator(self, pids: List[int], netns_id_arg: int, symbol_table: str):

fields = (
netns_id,
task_comm,
task.tgid,
task.pid,
fd_num,
Expand All @@ -639,6 +642,7 @@ def run(self):

tree_grid_args = [
("NetNS", int),
("Process Name", str),
("PID", int),
("TID", int),
("FD", int),
Expand Down
29 changes: 18 additions & 11 deletions volatility3/framework/plugins/timeliner.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class Timeliner(interfaces.plugins.PluginInterface):
orders the results by time."""

_required_framework_version = (2, 0, 0)
_version = (1, 1, 0)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand Down Expand Up @@ -198,9 +199,10 @@ def _generator(
),
)
)
except Exception:
except Exception as e:
vollog.log(
logging.INFO, f"Exception occurred running plugin: {plugin_name}"
logging.INFO,
f"Exception occurred running plugin: {plugin_name}: {e}",
)
vollog.log(logging.DEBUG, traceback.format_exc())

Expand Down Expand Up @@ -245,6 +247,18 @@ def run(self):
filter_list = self.config["plugin-filter"]
# Identify plugins that we can run which output datetimes
for plugin_class in self.usable_plugins:
if not issubclass(plugin_class, TimeLinerInterface):
# get_usable_plugins() should filter this, but adding a safeguard just in case
continue

if filter_list and not any(
[
filter in plugin_class.__module__ + "." + plugin_class.__name__
for filter in filter_list
]
):
continue

try:
automagics = automagic.choose_automagic(self.automagics, plugin_class)

Expand Down Expand Up @@ -276,15 +290,8 @@ def run(self):
config_value,
)

if isinstance(plugin, TimeLinerInterface):
if not len(filter_list) or any(
[
filter
in plugin.__module__ + "." + plugin.__class__.__name__
for filter in filter_list
]
):
plugins_to_run.append(plugin)
plugins_to_run.append(plugin)

except exceptions.UnsatisfiedException as excp:
# Remove the failed plugin from the list and continue
vollog.debug(
Expand Down
8 changes: 6 additions & 2 deletions volatility3/framework/plugins/windows/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,12 @@ def scan(
context, layer_name, nt_symbol_table, constraints
):
try:
if hasattr(mem_object, "is_valid") and not mem_object.is_valid():
continue
if isinstance(mem_object, callbacks._SHUTDOWN_PACKET):
if not mem_object.is_parseable(type_map):
continue
elif hasattr(mem_object, "is_valid"):
if not mem_object.is_valid():
continue

yield cls._process_scanned_callback(mem_object, type_map)
except exceptions.InvalidAddressException:
Expand Down
Loading

0 comments on commit ddd8de5

Please sign in to comment.