From eb2724badb886555f4c2016c665186d4b5e9c628 Mon Sep 17 00:00:00 2001 From: Alejandro Diego Date: Fri, 8 Dec 2023 15:12:11 -0500 Subject: [PATCH 1/2] Windows: Add `--name` option to pslist plugin Add the capability to filter by name the windows.pslist output, where users can define the name of the process they would like to filter out in the process list. The behavior of the filter is described below: - Filter is case-sensitive, e.g. Input `--name Foo` will not return a process named foo. - Filters full match only, e.g Input `--name foo`: return all processes named foo, it would not return foobaz. - Input `--name foo bar`: return all processes named foo and bar. Described below the semantics when `--pid` filter is defined with `--name`: - Input `--name foo --pid 123`: return all processes named foo and all processes with pid 123, if these intersect, meaning the process 123 is also named foo, it will return only that one process. If these cases dont exist return the empty list. - Input `--name foo bar --pid 123 456`: return all processes named foo and bar and all processes with pid 123 and 456. The semantics are the same as previous point but for multiple names and pids. All cases mentioned above were tested manually. --- .../framework/plugins/windows/pslist.py | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/volatility3/framework/plugins/windows/pslist.py b/volatility3/framework/plugins/windows/pslist.py index e7a0d5dd46..8c53972d67 100644 --- a/volatility3/framework/plugins/windows/pslist.py +++ b/volatility3/framework/plugins/windows/pslist.py @@ -50,6 +50,12 @@ def get_requirements(cls): default=False, optional=True, ), + requirements.ListRequirement( + name="name", + element_type=str, + description="Name of the process(es) to include (all other processes are excluded). Filter is case-sensitive and match full process name only", + optional=True, + ), ] @classmethod @@ -171,9 +177,7 @@ def list_processes( context: interfaces.context.ContextInterface, layer_name: str, symbol_table: str, - filter_func: Callable[ - [interfaces.objects.ObjectInterface], bool - ] = lambda _: False, + filter_funcs: List[Callable[[interfaces.objects.ObjectInterface], bool]] = None, ) -> Iterable[interfaces.objects.ObjectInterface]: """Lists all the processes in the primary layer that are in the pid config option. @@ -216,7 +220,10 @@ def list_processes( ) for proc in eproc.ActiveProcessLinks: - if not filter_func(proc): + if filter_funcs: + if any(not filter_func(proc) for filter_func in filter_funcs): + yield proc + else: yield proc def _generator(self): @@ -230,12 +237,21 @@ def _generator(self): if not isinstance(memory, layers.intel.Intel): raise TypeError("Primary layer is not an intel layer") - for proc in self.list_processes( + filter_funcs = [] + + if self.config["pid"]: + filter_funcs.append(self.create_pid_filter(self.config.get("pid"))) + if self.config["name"]: + filter_funcs.append(self.create_name_filter(self.config.get("name"))) + + processes = self.list_processes( self.context, kernel.layer_name, kernel.symbol_table_name, - filter_func=self.create_pid_filter(self.config.get("pid", None)), - ): + filter_funcs=filter_funcs, + ) + + for proc in processes: if not self.config.get("physical", self.PHYSICAL_DEFAULT): offset = proc.vol.offset else: From ed3b49da828c3558ca852808d89023564b5111cf Mon Sep 17 00:00:00 2001 From: Alejandro Diego Date: Fri, 8 Dec 2023 15:12:11 -0500 Subject: [PATCH 2/2] Updated definition of list_processes in other plugins and documentation --- doc/source/simple-plugin.rst | 2 +- volatility3/framework/plugins/windows/cmdline.py | 2 +- volatility3/framework/plugins/windows/dlllist.py | 2 +- volatility3/framework/plugins/windows/dumpfiles.py | 2 +- volatility3/framework/plugins/windows/envars.py | 2 +- volatility3/framework/plugins/windows/getsids.py | 2 +- volatility3/framework/plugins/windows/handles.py | 2 +- volatility3/framework/plugins/windows/ldrmodules.py | 2 +- volatility3/framework/plugins/windows/malfind.py | 2 +- volatility3/framework/plugins/windows/memmap.py | 2 +- volatility3/framework/plugins/windows/modscan.py | 2 +- volatility3/framework/plugins/windows/modules.py | 2 +- volatility3/framework/plugins/windows/privileges.py | 2 +- volatility3/framework/plugins/windows/sessions.py | 2 +- volatility3/framework/plugins/windows/skeleton_key_check.py | 2 +- volatility3/framework/plugins/windows/svcscan.py | 2 +- volatility3/framework/plugins/windows/vadinfo.py | 2 +- volatility3/framework/plugins/windows/vadwalk.py | 2 +- volatility3/framework/plugins/windows/vadyarascan.py | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/doc/source/simple-plugin.rst b/doc/source/simple-plugin.rst index 39670a62dd..b4a294ff66 100644 --- a/doc/source/simple-plugin.rst +++ b/doc/source/simple-plugin.rst @@ -189,7 +189,7 @@ that will be output as part of the :py:class:`~volatility3.framework.interfaces. self._generator(pslist.PsList.list_processes(self.context, kernel.layer_name, kernel.symbol_table_name, - filter_func = filter_func))) + filter_funcs = [filter_func]))) In this instance, the plugin constructs a filter (using the PsList plugin's *classmethod* for creating filters). It checks the plugin's configuration for the ``pid`` value, and passes it in as a list if it finds it, or None if diff --git a/volatility3/framework/plugins/windows/cmdline.py b/volatility3/framework/plugins/windows/cmdline.py index 8cfb5576c2..229cbd4cba 100644 --- a/volatility3/framework/plugins/windows/cmdline.py +++ b/volatility3/framework/plugins/windows/cmdline.py @@ -101,7 +101,7 @@ def run(self): context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ) ), ) diff --git a/volatility3/framework/plugins/windows/dlllist.py b/volatility3/framework/plugins/windows/dlllist.py index d73cea652f..5eb460e577 100644 --- a/volatility3/framework/plugins/windows/dlllist.py +++ b/volatility3/framework/plugins/windows/dlllist.py @@ -237,7 +237,7 @@ def run(self): context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ) ), ) diff --git a/volatility3/framework/plugins/windows/dumpfiles.py b/volatility3/framework/plugins/windows/dumpfiles.py index dd82d897ea..ecd9b8beee 100755 --- a/volatility3/framework/plugins/windows/dumpfiles.py +++ b/volatility3/framework/plugins/windows/dumpfiles.py @@ -327,7 +327,7 @@ def run(self): self.context, kernel.layer_name, kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ) return renderers.TreeGrid( diff --git a/volatility3/framework/plugins/windows/envars.py b/volatility3/framework/plugins/windows/envars.py index 66db03c9c2..ef16208600 100644 --- a/volatility3/framework/plugins/windows/envars.py +++ b/volatility3/framework/plugins/windows/envars.py @@ -237,7 +237,7 @@ def run(self): context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ) ), ) diff --git a/volatility3/framework/plugins/windows/getsids.py b/volatility3/framework/plugins/windows/getsids.py index 3e332f85db..abf7e675a8 100644 --- a/volatility3/framework/plugins/windows/getsids.py +++ b/volatility3/framework/plugins/windows/getsids.py @@ -222,7 +222,7 @@ def run(self): context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ) ), ) diff --git a/volatility3/framework/plugins/windows/handles.py b/volatility3/framework/plugins/windows/handles.py index ddd9cb78e1..c863c19b98 100644 --- a/volatility3/framework/plugins/windows/handles.py +++ b/volatility3/framework/plugins/windows/handles.py @@ -431,7 +431,7 @@ def run(self): self.context, kernel.layer_name, kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ) ), ) diff --git a/volatility3/framework/plugins/windows/ldrmodules.py b/volatility3/framework/plugins/windows/ldrmodules.py index 4c8456fa96..4c4ee6935a 100644 --- a/volatility3/framework/plugins/windows/ldrmodules.py +++ b/volatility3/framework/plugins/windows/ldrmodules.py @@ -120,7 +120,7 @@ def run(self): context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ) ), ) diff --git a/volatility3/framework/plugins/windows/malfind.py b/volatility3/framework/plugins/windows/malfind.py index 6ed078996c..81a2648c48 100644 --- a/volatility3/framework/plugins/windows/malfind.py +++ b/volatility3/framework/plugins/windows/malfind.py @@ -224,7 +224,7 @@ def run(self): context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ) ), ) diff --git a/volatility3/framework/plugins/windows/memmap.py b/volatility3/framework/plugins/windows/memmap.py index b5c9a211e0..de4567d78b 100644 --- a/volatility3/framework/plugins/windows/memmap.py +++ b/volatility3/framework/plugins/windows/memmap.py @@ -118,7 +118,7 @@ def run(self): context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ) ), ) diff --git a/volatility3/framework/plugins/windows/modscan.py b/volatility3/framework/plugins/windows/modscan.py index 99fadac07c..8ac230754e 100644 --- a/volatility3/framework/plugins/windows/modscan.py +++ b/volatility3/framework/plugins/windows/modscan.py @@ -101,7 +101,7 @@ def get_session_layers( context=context, layer_name=layer_name, symbol_table=symbol_table, - filter_func=filter_func, + filter_funcs=[filter_func], ): proc_id = "Unknown" try: diff --git a/volatility3/framework/plugins/windows/modules.py b/volatility3/framework/plugins/windows/modules.py index 7dabf69545..2ab0a9f7c6 100644 --- a/volatility3/framework/plugins/windows/modules.py +++ b/volatility3/framework/plugins/windows/modules.py @@ -122,7 +122,7 @@ def get_session_layers( context=context, layer_name=layer_name, symbol_table=symbol_table, - filter_func=filter_func, + filter_funcs=[filter_func], ): proc_id = "Unknown" try: diff --git a/volatility3/framework/plugins/windows/privileges.py b/volatility3/framework/plugins/windows/privileges.py index 0370dfc921..24ba240960 100644 --- a/volatility3/framework/plugins/windows/privileges.py +++ b/volatility3/framework/plugins/windows/privileges.py @@ -123,7 +123,7 @@ def run(self): context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ) ), ) diff --git a/volatility3/framework/plugins/windows/sessions.py b/volatility3/framework/plugins/windows/sessions.py index d766b40ea4..bd7d39f4b3 100644 --- a/volatility3/framework/plugins/windows/sessions.py +++ b/volatility3/framework/plugins/windows/sessions.py @@ -49,7 +49,7 @@ def _generator(self): self.context, kernel.layer_name, kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ): session_id = proc.get_session_id() diff --git a/volatility3/framework/plugins/windows/skeleton_key_check.py b/volatility3/framework/plugins/windows/skeleton_key_check.py index d321c2cc0c..e9743fbb01 100644 --- a/volatility3/framework/plugins/windows/skeleton_key_check.py +++ b/volatility3/framework/plugins/windows/skeleton_key_check.py @@ -706,7 +706,7 @@ def run(self): context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=self._lsass_proc_filter, + filter_funcs=[self._lsass_proc_filter], ) ), ) diff --git a/volatility3/framework/plugins/windows/svcscan.py b/volatility3/framework/plugins/windows/svcscan.py index 60562915ec..88d86db938 100644 --- a/volatility3/framework/plugins/windows/svcscan.py +++ b/volatility3/framework/plugins/windows/svcscan.py @@ -178,7 +178,7 @@ def _generator(self): context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ): proc_id = "Unknown" try: diff --git a/volatility3/framework/plugins/windows/vadinfo.py b/volatility3/framework/plugins/windows/vadinfo.py index abc6142fe0..9c56e01bd9 100644 --- a/volatility3/framework/plugins/windows/vadinfo.py +++ b/volatility3/framework/plugins/windows/vadinfo.py @@ -275,7 +275,7 @@ def run(self): context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ) ), ) diff --git a/volatility3/framework/plugins/windows/vadwalk.py b/volatility3/framework/plugins/windows/vadwalk.py index 930388b3a4..ccc4566445 100644 --- a/volatility3/framework/plugins/windows/vadwalk.py +++ b/volatility3/framework/plugins/windows/vadwalk.py @@ -87,7 +87,7 @@ def run(self) -> renderers.TreeGrid: context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ) ), ) diff --git a/volatility3/framework/plugins/windows/vadyarascan.py b/volatility3/framework/plugins/windows/vadyarascan.py index d795818e93..866c4a48d4 100644 --- a/volatility3/framework/plugins/windows/vadyarascan.py +++ b/volatility3/framework/plugins/windows/vadyarascan.py @@ -63,7 +63,7 @@ def _generator(self): context=self.context, layer_name=kernel.layer_name, symbol_table=kernel.symbol_table_name, - filter_func=filter_func, + filter_funcs=[filter_func], ): layer_name = task.add_process_layer() layer = self.context.layers[layer_name]