From 8acf97c475aab174e183669a104e8fa66ef6d599 Mon Sep 17 00:00:00 2001 From: SolitudePy <47316655+SolitudePy@users.noreply.github.com> Date: Sat, 7 Jun 2025 18:42:13 +0300 Subject: [PATCH 1/2] Plugins: categorize linux.check_creds as a malwarep lugin --- .../framework/plugins/linux/check_creds.py | 75 +++---------------- .../plugins/linux/malware/check_creds.py | 71 ++++++++++++++++++ 2 files changed, 83 insertions(+), 63 deletions(-) create mode 100644 volatility3/framework/plugins/linux/malware/check_creds.py diff --git a/volatility3/framework/plugins/linux/check_creds.py b/volatility3/framework/plugins/linux/check_creds.py index e2b84d679..6c2c6f3d5 100644 --- a/volatility3/framework/plugins/linux/check_creds.py +++ b/volatility3/framework/plugins/linux/check_creds.py @@ -1,71 +1,20 @@ -# This file is Copyright 2019 Volatility Foundation and licensed under the Volatility Software License 1.0 +# This file is Copyright 2025 Volatility Foundation and licensed under the Volatility Software License 1.0 # which is available at https://www.volatilityfoundation.org/license/vsl-v1.0 # +import logging +from volatility3.framework import interfaces, deprecation +from volatility3.plugins.linux.malware import check_creds -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""" +class Check_creds( + interfaces.plugins.PluginInterface, + deprecation.PluginRenameClass, + replacement_class=check_creds.Check_creds, + removal_date="2026-06-07", +): + """Checks if any processes are sharing credential structures (deprecated).""" _required_framework_version = (2, 0, 0) _version = (2, 0, 2) - - @classmethod - def get_requirements(cls): - return [ - requirements.ModuleRequirement( - name="kernel", - description="Linux kernel", - architectures=["Intel32", "Intel64"], - ), - requirements.VersionRequirement( - name="pslist", component=pslist.PsList, version=(4, 0, 0) - ), - ] - - def _generator(self): - vmlinux = self.context.modules[self.config["kernel"]] - - type_task = vmlinux.get_type("task_struct") - - if not type_task.has_member("cred"): - raise TypeError( - "This plugin requires the task_struct structure to have a cred member. " - "This member is not present in the supplied symbol table. " - "This means you are either analyzing an unsupported kernel version or that your symbol table is corrupt." - ) - - creds = {} - - tasks = pslist.PsList.list_tasks(self.context, vmlinux.name) - - for task in tasks: - task_cred_ptr = task.cred - if not (task_cred_ptr and task_cred_ptr.is_readable()): - continue - - cred_addr = task_cred_ptr.dereference().vol.offset - - creds.setdefault(cred_addr, []) - creds[cred_addr].append(task.pid) - - for cred_addr, pids in creds.items(): - if len(pids) > 1: - pid_str = ", ".join(str(pid) for pid in pids) - - fields = [ - format_hints.Hex(cred_addr), - pid_str, - ] - yield (0, fields) - - def run(self): - headers = [ - ("CredVAddr", format_hints.Hex), - ("PIDs", str), - ] - return renderers.TreeGrid(headers, self._generator()) diff --git a/volatility3/framework/plugins/linux/malware/check_creds.py b/volatility3/framework/plugins/linux/malware/check_creds.py new file mode 100644 index 000000000..e2b84d679 --- /dev/null +++ b/volatility3/framework/plugins/linux/malware/check_creds.py @@ -0,0 +1,71 @@ +# This file is Copyright 2019 Volatility Foundation and licensed under the Volatility Software License 1.0 +# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0 +# + +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 + + +class Check_creds(interfaces.plugins.PluginInterface): + """Checks if any processes are sharing credential structures""" + + _required_framework_version = (2, 0, 0) + _version = (2, 0, 2) + + @classmethod + def get_requirements(cls): + return [ + requirements.ModuleRequirement( + name="kernel", + description="Linux kernel", + architectures=["Intel32", "Intel64"], + ), + requirements.VersionRequirement( + name="pslist", component=pslist.PsList, version=(4, 0, 0) + ), + ] + + def _generator(self): + vmlinux = self.context.modules[self.config["kernel"]] + + type_task = vmlinux.get_type("task_struct") + + if not type_task.has_member("cred"): + raise TypeError( + "This plugin requires the task_struct structure to have a cred member. " + "This member is not present in the supplied symbol table. " + "This means you are either analyzing an unsupported kernel version or that your symbol table is corrupt." + ) + + creds = {} + + tasks = pslist.PsList.list_tasks(self.context, vmlinux.name) + + for task in tasks: + task_cred_ptr = task.cred + if not (task_cred_ptr and task_cred_ptr.is_readable()): + continue + + cred_addr = task_cred_ptr.dereference().vol.offset + + creds.setdefault(cred_addr, []) + creds[cred_addr].append(task.pid) + + for cred_addr, pids in creds.items(): + if len(pids) > 1: + pid_str = ", ".join(str(pid) for pid in pids) + + fields = [ + format_hints.Hex(cred_addr), + pid_str, + ] + yield (0, fields) + + def run(self): + headers = [ + ("CredVAddr", format_hints.Hex), + ("PIDs", str), + ] + return renderers.TreeGrid(headers, self._generator()) From 85a5eb5d41ff04b728cacc1cedb4b8a95f4da6cb Mon Sep 17 00:00:00 2001 From: SolitudePy <47316655+SolitudePy@users.noreply.github.com> Date: Sat, 7 Jun 2025 18:42:42 +0300 Subject: [PATCH 2/2] linux.malware.check_creds - fix deps in: test, doc --- doc/source/getting-started-linux-tutorial.rst | 2 +- test/plugins/linux/linux.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/getting-started-linux-tutorial.rst b/doc/source/getting-started-linux-tutorial.rst index 031b49636..4c442c938 100644 --- a/doc/source/getting-started-linux-tutorial.rst +++ b/doc/source/getting-started-linux-tutorial.rst @@ -37,7 +37,7 @@ For plugin requests, please create an issue with a description of the requested banners.Banners Attempts to identify potential linux banners in an linux.bash.Bash Recovers bash command history from memory. linux.check_afinfo.Check_afinfo - linux.check_creds.Check_creds + linux.malware.check_creds.Check_creds linux.check_idt.Check_idt .. note:: Here the command is piped to grep and head to provide the start of the list of linux plugins. diff --git a/test/plugins/linux/linux.py b/test/plugins/linux/linux.py index e39c1d15d..abac11278 100644 --- a/test/plugins/linux/linux.py +++ b/test/plugins/linux/linux.py @@ -200,7 +200,7 @@ class TestLinuxCapabilities: class TestLinuxCheckCreds: def test_linux_generic_check_creds(self, image, volatility, python): rc, out, _err = test_volatility.runvol_plugin( - "linux.check_creds.Check_creds", image, volatility, python + "linux.malware.check_creds.Check_creds", image, volatility, python ) # linux-sample-1.bin has no processes sharing credentials.