From 5c80a66d6dd9b3bc2400a4a8062ed30add10ce4b Mon Sep 17 00:00:00 2001 From: 616c696365 <616c696365@localhost.com> Date: Wed, 30 Aug 2023 20:12:12 +0100 Subject: [PATCH 1/3] Windows: Update pslist.py, add friendly option --- .../framework/plugins/windows/pslist.py | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/volatility3/framework/plugins/windows/pslist.py b/volatility3/framework/plugins/windows/pslist.py index 88697e71a..806bb678e 100644 --- a/volatility3/framework/plugins/windows/pslist.py +++ b/volatility3/framework/plugins/windows/pslist.py @@ -50,6 +50,12 @@ class PsList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): default=False, optional=True, ), + requirements.BooleanRequirement( + name="friendly", + description="Display process name in dump filename", + default=False, + optional=True, + ), ] @classmethod @@ -60,6 +66,7 @@ class PsList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): pe_table_name: str, proc: interfaces.objects.ObjectInterface, open_method: Type[interfaces.plugins.FileHandlerInterface], + friendly: bool = False, ) -> interfaces.plugins.FileHandlerInterface: """Extracts the complete data for a process as a FileHandlerInterface @@ -90,9 +97,20 @@ class PsList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): offset=peb.ImageBaseAddress, layer_name=proc_layer_name, ) - file_handle = open_method( - f"pid.{proc.UniqueProcessId}.{peb.ImageBaseAddress:#x}.dmp" + + process_name = proc.ImageFileName.cast( + "string", + max_length=proc.ImageFileName.vol.count, + errors="replace", ) + if friendly: + file_handle = open_method( + f"{proc.UniqueProcessId}.{process_name}.{peb.ImageBaseAddress:#x}.dmp" + ) + else: + file_handle = open_method( + f"pid.{proc.UniqueProcessId}.{peb.ImageBaseAddress:#x}.dmp" + ) for offset, data in dos_header.reconstruct(): file_handle.seek(offset) file_handle.write(data) @@ -243,6 +261,7 @@ class PsList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): pe_table_name, proc, self.open, + self.config["friendly"], ) file_output = "Error outputting file" if file_handle: From 5d43071f572a4c2aa5cbe573cb5b400e8d27607f Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Tue, 17 Oct 2023 15:54:10 +0100 Subject: [PATCH 2/3] Core: Add (optional) sanitization to the FileHandler class --- volatility3/framework/interfaces/plugins.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/volatility3/framework/interfaces/plugins.py b/volatility3/framework/interfaces/plugins.py index 0de109c5e..29395aadf 100644 --- a/volatility3/framework/interfaces/plugins.py +++ b/volatility3/framework/interfaces/plugins.py @@ -43,7 +43,7 @@ class FileHandlerInterface(io.RawIOBase): return self._preferred_filename @preferred_filename.setter - def preferred_filename(self, filename): + def preferred_filename(self, filename: str): """Sets the preferred filename""" if self.closed: raise IOError("FileHandler name cannot be changed once closed") @@ -57,6 +57,18 @@ class FileHandlerInterface(io.RawIOBase): def close(self): """Method that commits the file and fixes the final filename for use""" + @staticmethod + def sanitize_filename(filename: str) -> str: + """Sanititizes the filename to ensure only a specific whitelist of characters is allowed through""" + allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.- ()[]\{\}!$%^:#~?<>,|" + result = "" + for char in filename: + if char in allowed: + result += char + else: + result += "?" + return result + def __enter__(self): return self From 7323bd3a591a4d989fde5837d51a0a9c2d9061f3 Mon Sep 17 00:00:00 2001 From: 616c696365 <616c696365@localhost.com> Date: Wed, 18 Oct 2023 19:14:02 +0100 Subject: [PATCH 3/3] windows.pslist process name added to dumped file by default --- .../framework/plugins/windows/pslist.py | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/volatility3/framework/plugins/windows/pslist.py b/volatility3/framework/plugins/windows/pslist.py index 806bb678e..e7a0d5dd4 100644 --- a/volatility3/framework/plugins/windows/pslist.py +++ b/volatility3/framework/plugins/windows/pslist.py @@ -50,12 +50,6 @@ class PsList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): default=False, optional=True, ), - requirements.BooleanRequirement( - name="friendly", - description="Display process name in dump filename", - default=False, - optional=True, - ), ] @classmethod @@ -66,7 +60,6 @@ class PsList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): pe_table_name: str, proc: interfaces.objects.ObjectInterface, open_method: Type[interfaces.plugins.FileHandlerInterface], - friendly: bool = False, ) -> interfaces.plugins.FileHandlerInterface: """Extracts the complete data for a process as a FileHandlerInterface @@ -103,14 +96,13 @@ class PsList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): max_length=proc.ImageFileName.vol.count, errors="replace", ) - if friendly: - file_handle = open_method( + + file_handle = open_method( + open_method.sanitize_filename( f"{proc.UniqueProcessId}.{process_name}.{peb.ImageBaseAddress:#x}.dmp" ) - else: - file_handle = open_method( - f"pid.{proc.UniqueProcessId}.{peb.ImageBaseAddress:#x}.dmp" - ) + ) + for offset, data in dos_header.reconstruct(): file_handle.seek(offset) file_handle.write(data) @@ -261,7 +253,6 @@ class PsList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): pe_table_name, proc, self.open, - self.config["friendly"], ) file_output = "Error outputting file" if file_handle: